Documentation
¶
Index ¶
- func EnsureStatementSpacing(sql string) string
- func FixDropPolicyDeparseCorruption(sql string) string
- func FixExtensionOrder(sql string) string
- func FixFunctionLanguageConflicts(sql string) string
- func FixIncorrectLanguageDeclarations(sql string) string
- func FixMalformedDropTriggers(sql string) string
- func FixMalformedFunctions(sql string) string
- func FixMissingLanguageClauses(sql string) string
- func FixMissingLanguageDeclarations(sql string) string
- func FixMissingSemicolons(sql string) string
- func FixRedundantTrailingLanguageClauses(sql string) string
- func FixReturnNextWithOutParams(sql string, callback FixCallback) string
- func FixReturnNextWithOutParamsSimple(sql string) string
- func RemoveDuplicateLanguageDeclarations(sql string) string
- func RemoveOrphanedAlterStatements(sql string) string
- func SortExtensionsByDependency(extensionLines []string) []string
- type FixCallback
- type Processor
- type ProcessorAST
- type StatementFormatter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EnsureStatementSpacing ¶
EnsureStatementSpacing is the main entry point for formatting It ensures proper spacing between all types of SQL statements
func FixDropPolicyDeparseCorruption ¶
FixDropPolicyDeparseCorruption fixes pg_query deparser bug where DROP POLICY object name includes full qualification. IncorrectFromDeparse: DROP POLICY IF EXISTS schema.table.policy ON schema.table CorrectPostgresSQL: DROP POLICY IF EXISTS policy ON schema.table
func FixExtensionOrder ¶
FixExtensionOrder ensures extensions are in correct dependency order. Some PostgreSQL extensions have dependencies on other extensions and must be created in the proper order. For example, earthdistance depends on cube.
func FixFunctionLanguageConflicts ¶
FixFunctionLanguageConflicts fixes functions with conflicting VOLATILE/LANGUAGE placement. This is a safety net post-processor that catches any functions where normalization didn't run or where SQL transformation added volatility markers incorrectly.
Problem Pattern (Invalid PostgreSQL syntax):
CREATE FUNCTION foo() RETURNS text VOLATILE AS $$ ... $$ LANGUAGE plpgsql;
Fixed Pattern (Valid):
CREATE FUNCTION foo() RETURNS text LANGUAGE plpgsql VOLATILE AS $$ ... $$;
Root Cause: When volatility markers (VOLATILE/STABLE/IMMUTABLE) are added before AS $$, PostgreSQL requires LANGUAGE to also be before AS $$, not after the function body.
This function detects and fixes three scenarios: 1. VOLATILE AS $$ ... $$ LANGUAGE plpgsql → LANGUAGE plpgsql VOLATILE AS $$ ... $$ 2. STABLE AS $$ ... $$ LANGUAGE plpgsql → LANGUAGE plpgsql STABLE AS $$ ... $$ 3. IMMUTABLE AS $$ ... $$ LANGUAGE plpgsql → LANGUAGE plpgsql IMMUTABLE AS $$ ... $$
func FixIncorrectLanguageDeclarations ¶
FixIncorrectLanguageDeclarations fixes functions that have incorrect LANGUAGE declarations based on their body content.
Fixes TWO directions:
- LANGUAGE SQL → LANGUAGE plpgsql (when body has plpgsql constructs like BEGIN/END)
- LANGUAGE plpgsql → LANGUAGE sql (when body is simple SQL without plpgsql constructs)
Common patterns:
- RETURNS TRIGGER + LANGUAGE SQL → should be LANGUAGE plpgsql (triggers require plpgsql)
- Body has BEGIN/END + LANGUAGE SQL → should be LANGUAGE plpgsql
- Body has bare SELECT + LANGUAGE plpgsql → should be LANGUAGE sql
- Body has DECLARE + LANGUAGE SQL → should be LANGUAGE plpgsql
- Body has PERFORM + LANGUAGE SQL → should be LANGUAGE plpgsql
func FixMalformedDropTriggers ¶
FixMalformedDropTriggers fixes DROP TRIGGER statements with incorrect syntax. PostgreSQL requires: DROP TRIGGER IF EXISTS trigger_name ON table_name; This function fixes: DROP TRIGGER IF EXISTS table_name.trigger_name;
func FixMalformedFunctions ¶
FixMalformedFunctions repairs common function definition issues from consolidation. Issues fixed: 1. Missing AS keyword before function body 2. Duplicate LANGUAGE clauses 3. Standalone LANGUAGE lines after $$ 4. Multiple volatility markers (STABLE and IMMUTABLE together) 5. Orphaned function bodies without CREATE FUNCTION headers
func FixMissingLanguageClauses ¶
FixMissingLanguageClauses adds LANGUAGE plpgsql to functions that are missing it. This is critical for PostgreSQL - functions without explicit LANGUAGE will fail.
func FixMissingLanguageDeclarations ¶
FixMissingLanguageDeclarations adds LANGUAGE declarations to functions that are missing them. PostgreSQL requires all functions to have a LANGUAGE clause.
func FixMissingSemicolons ¶
FixMissingSemicolons adds missing semicolons to SQL statements. PostgreSQL requires all statements to end with a semicolon.
func FixRedundantTrailingLanguageClauses ¶
FixRedundantTrailingLanguageClauses removes redundant LANGUAGE clauses that appear after the closing $$ delimiter in function definitions. PostgreSQL rejects these as "conflicting or redundant options" when LANGUAGE is also in the header.
This function uses a line-by-line state machine to intelligently detect:
- Functions with LANGUAGE before AS $ (from AST normalization) → remove trailing LANGUAGE
- Functions without LANGUAGE before AS $ → keep trailing LANGUAGE (it's the only one)
This avoids regex complexity and only removes truly redundant clauses.
EXECUTION: Called in post-processing phase BEFORE FixFunctionLanguageConflicts.
func FixReturnNextWithOutParams ¶
func FixReturnNextWithOutParams(sql string, callback FixCallback) string
FixReturnNextWithOutParams fixes RETURN NEXT usage in RETURNS TABLE functions.
PostgreSQL Issue: RETURNS TABLE creates implicit OUT parameters. Using RETURN NEXT with arguments in such functions causes: "pq: RETURN NEXT cannot have a parameter in function with OUT parameters"
Patterns Fixed: 1. RETURN NEXT record_var; → RETURN QUERY SELECT record_var.field1, record_var.field2; 2. RETURN NEXT; (no argument) → RETURN QUERY SELECT field1, field2;
This function is called in post-processing to fix any functions that slipped through the SQL transformation phase (when EnableTransformation is false).
The optional callback parameter allows tracking transformations for reporting. Pass nil if tracking is not needed.
func FixReturnNextWithOutParamsSimple ¶
FixReturnNextWithOutParamsSimple is a backward-compatible wrapper that fixes RETURN NEXT without tracking transformations. For new code, prefer FixReturnNextWithOutParams with a callback.
func RemoveDuplicateLanguageDeclarations ¶
RemoveDuplicateLanguageDeclarations removes duplicate LANGUAGE clauses from functions. Example: "LANGUAGE plpgsql STABLE LANGUAGE plpgsql" → "LANGUAGE plpgsql STABLE" NOTE: This function is currently disabled in the processing pipeline due to regex complexity. It should be reimplemented using AST-based approach instead of regex.
func RemoveOrphanedAlterStatements ¶
This happens when an object is created and altered in different migrations, but the consolidation removes the CREATE.
func SortExtensionsByDependency ¶
SortExtensionsByDependency sorts extension CREATE statements by dependency order. Some extensions depend on others and must be created in the right order. This is a utility function reserved for future enhancements.
Types ¶
type FixCallback ¶
type FixCallback func(description, before, after string)
FixCallback is called when a fix is applied, allowing tracking of transformations. Parameters: description, before (original SQL), after (fixed SQL)
type Processor ¶
type Processor struct {
// contains filtered or unexported fields
}
Processor orchestrates all post-processing operations on consolidated SQL. It applies fixes in a specific order to ensure correctness.
func NewProcessor ¶
NewProcessor creates a new post-processing processor with the given configuration.
func (*Processor) Apply ¶
Apply runs all post-processing fixes in the correct order. The order is critical and should not be changed without careful consideration.
Processing Pipeline:
- Basic Syntax Fixes - Fix malformed SQL constructs
- Extension Ordering - Ensure extension dependencies are correct
- Function Language Normalization - Fix LANGUAGE clause issues
- Function Body Fixes - Fix RETURN NEXT patterns
- Final Cleanup - Add missing semicolons and fix enum references
Each phase builds on the previous one, so order matters.
type ProcessorAST ¶
type ProcessorAST struct {
// contains filtered or unexported fields
}
ProcessorAST orchestrates AST-based post-processing operations. This is an alternative to regex-based processing with better accuracy and maintainability.
func NewProcessorAST ¶
func NewProcessorAST(cfg *config.Config) *ProcessorAST
NewProcessorAST creates a new AST-based post-processing processor.
func (*ProcessorAST) Apply ¶
Apply runs all post-processing fixes using AST where possible, falling back to regex. This provides a migration path from regex to AST.
func (*ProcessorAST) SetUseASTForEnums ¶
func (p *ProcessorAST) SetUseASTForEnums(use bool)
SetUseASTForEnums enables or disables AST-based ENUM processing.
type StatementFormatter ¶
type StatementFormatter struct {
// contains filtered or unexported fields
}
StatementFormatter provides AST-aware SQL statement formatting to ensure proper spacing, line breaks, and readability
func NewStatementFormatter ¶
func NewStatementFormatter() *StatementFormatter
NewStatementFormatter creates a new statement formatter
func (*StatementFormatter) FormatFunctionBody ¶
func (f *StatementFormatter) FormatFunctionBody(functionSQL string) string
FormatFunctionBody formats the body of a CREATE FUNCTION statement ensuring proper indentation and line breaks
func (*StatementFormatter) FormatSQL ¶
func (f *StatementFormatter) FormatSQL(sql string) string