postprocessing

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EnsureStatementSpacing

func EnsureStatementSpacing(sql string) string

EnsureStatementSpacing is the main entry point for formatting It ensures proper spacing between all types of SQL statements

func FixDropPolicyDeparseCorruption

func FixDropPolicyDeparseCorruption(sql string) string

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

func FixExtensionOrder(sql string) string

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

func FixFunctionLanguageConflicts(sql string) string

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

func FixIncorrectLanguageDeclarations(sql string) string

FixIncorrectLanguageDeclarations fixes functions that have incorrect LANGUAGE declarations based on their body content.

Fixes TWO directions:

  1. LANGUAGE SQL → LANGUAGE plpgsql (when body has plpgsql constructs like BEGIN/END)
  2. 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

func FixMalformedDropTriggers(sql string) string

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

func FixMalformedFunctions(sql string) string

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

func FixMissingLanguageClauses(sql string) string

FixMissingLanguageClauses adds LANGUAGE plpgsql to functions that are missing it. This is critical for PostgreSQL - functions without explicit LANGUAGE will fail.

func FixMissingLanguageDeclarations

func FixMissingLanguageDeclarations(sql string) string

FixMissingLanguageDeclarations adds LANGUAGE declarations to functions that are missing them. PostgreSQL requires all functions to have a LANGUAGE clause.

func FixMissingSemicolons

func FixMissingSemicolons(sql string) string

FixMissingSemicolons adds missing semicolons to SQL statements. PostgreSQL requires all statements to end with a semicolon.

func FixRedundantTrailingLanguageClauses

func FixRedundantTrailingLanguageClauses(sql string) string

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:

  1. Functions with LANGUAGE before AS $ (from AST normalization) → remove trailing LANGUAGE
  2. 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

func FixReturnNextWithOutParamsSimple(sql string) string

FixReturnNextWithOutParamsSimple is a backward-compatible wrapper that fixes RETURN NEXT without tracking transformations. For new code, prefer FixReturnNextWithOutParams with a callback.

func RemoveDuplicateLanguageDeclarations

func RemoveDuplicateLanguageDeclarations(sql string) string

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

func RemoveOrphanedAlterStatements(sql string) string

This happens when an object is created and altered in different migrations, but the consolidation removes the CREATE.

func SortExtensionsByDependency

func SortExtensionsByDependency(extensionLines []string) []string

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

func NewProcessor(cfg *config.Config) *Processor

NewProcessor creates a new post-processing processor with the given configuration.

func (*Processor) Apply

func (p *Processor) Apply(sql string, enumReplacements map[string]string) (string, error)

Apply runs all post-processing fixes in the correct order. The order is critical and should not be changed without careful consideration.

Processing Pipeline:

  1. Basic Syntax Fixes - Fix malformed SQL constructs
  2. Extension Ordering - Ensure extension dependencies are correct
  3. Function Language Normalization - Fix LANGUAGE clause issues
  4. Function Body Fixes - Fix RETURN NEXT patterns
  5. 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

func (p *ProcessorAST) Apply(sql string, enumReplacements map[string]string) (string, error)

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

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL