How to Parse PostgreSQL SQL in Java¶
To parse PostgreSQL in Java, create a TGSqlParser with EDbVendor.dbvpostgresql and call parse() — GSP understands PostgreSQL-specific syntax natively, including dollar-quoted ($$ ... $$) PL/pgSQL function bodies, RETURNING clauses on DML, WITH / recursive CTEs, and COPY. This guide shows how each construct maps to the AST and which accessors extract the information you need.
Prerequisites¶
- GSP installed per the Quick Start
- Familiarity with basic SQL parsing
Dollar-Quoted PL/pgSQL Functions¶
CREATE FUNCTION ... AS $$ ... $$ LANGUAGE plpgsql parses to TCreateFunctionStmt (package gudusoft.gsqlparser.stmt, statement type sstcreatefunction). GSP does not treat the dollar-quoted body as an opaque string — it parses the PL/pgSQL inside in the same pass, so the function's declarations and body statements are directly available:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
Key accessors on TCreateFunctionStmt:
getFunctionName()/getReturnDataType()— signature informationgetDeclareStatements()— theDECLAREsection (variable and cursor declarations)getBodyStatements()— theBEGIN ... ENDexecutable statementsgetProcedureLanguage()— theLANGUAGEclause
To pull every embedded SELECT/INSERT/UPDATE/DELETE out of function bodies — however deeply nested in IF/LOOP blocks — use the recursive getStatements() walk shown in Parse Oracle PL/SQL; it is vendor-independent.
RETURNING Clauses¶
PostgreSQL's RETURNING turns DML into a row source. GSP exposes it via getReturningClause(), available on TInsertSqlStatement, TUpdateSqlStatement, TDeleteSqlStatement, and TMergeSqlStatement:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
RETURNING columns are outputs of the statement — for column-level lineage they behave like a SELECT list on top of the DML.
Common Table Expressions (WITH)¶
Any statement carrying a WITH clause exposes it through getCteList(), which returns a TCTEList of TCTE nodes. This includes PostgreSQL's writable CTEs (WITH upd AS (UPDATE ... RETURNING *) INSERT ...):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
Useful TCTE accessors:
getTableName()— the CTE's namegetColumnList()— the optional explicit column listgetSubquery()— the definingSELECT(aTSelectSqlStatement)getInsertStmt()/getUpdateStmt()/getDeleteStmt()— for data-modifying CTEsisRecursive()—trueunderWITH RECURSIVE
When extracting table dependencies, remember that a CTE name is a derived relation: references to upd above should resolve to the CTE definition, not to a physical table.
COPY Statements¶
COPY — PostgreSQL's bulk import/export — parses to TCopyStmt (package gudusoft.gsqlparser.stmt, statement type sstCopy):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
getTargetTable()/getColumnList()identify the affected table and columnsgetFilename()returns the file (or program) operandgetSubQuery()returns theSELECTfor theCOPY (SELECT ...) TO ...form, wheregetTargetTable()isnull
For lineage purposes, COPY table FROM file is a data source edge into the table and COPY table TO file is a data sink — both are worth capturing when auditing data movement.
Vendor Notes¶
- Casts and operators: PostgreSQL-style
::typecasts, array subscripts, andILIKEparse underdbvpostgresqlwithout preprocessing. - Identifier folding: unquoted identifiers fold to lowercase (PostgreSQL behavior); override this with custom identifier rules if your environment differs.
- Related dialects: Greenplum and Amazon Redshift descend from PostgreSQL, but parse them with their own vendors (
dbvgreenplum,dbvredshift) — their syntax has diverged.
Related Pages¶
- Parse Oracle PL/SQL — the recursive statement walk for stored code
- Error Handling — diagnosing syntax errors with line/column detail
- PostgreSQL syntax support — coverage reference
- SQL Parser Use Cases — lineage and impact analysis on PostgreSQL codebases