Working with Different Databases¶
Continue the Java learning path by selecting the grammar that matches the database which produced the SQL. You will compare vendor-specific constructs and learn where automatic dialect detection is useful—and where it is ambiguous.
What you will learn¶
- Configure GSP for different database vendors
- Handle vendor-specific SQL features and extensions
- Parse Oracle PL/SQL blocks
- Work with SQL Server T-SQL specifics
- Manage PostgreSQL and MySQL syntax differences
- Switch dialect context effectively
Before you begin¶
- Completed Basic SQL Parsing
- Familiarity with SQL differences across database systems
Supported vendors¶
The vendor is a member of the EDbVendor enum, and the two editions cover
different lists.
EDbVendor declares 45 constants; 43 parse ordinary SQL and none throw.
The per-vendor SQL Syntax Support pages are
the authoritative list. The vendors used in this tutorial:
| Vendor | Constant | Notes |
|---|---|---|
| Oracle | EDbVendor.dbvoracle |
Includes PL/SQL |
| Microsoft SQL Server | EDbVendor.dbvmssql |
Full T-SQL |
| PostgreSQL | EDbVendor.dbvpostgresql |
|
| MySQL | EDbVendor.dbvmysql |
Plus MariaDB |
| Amazon Redshift | EDbVendor.dbvredshift |
PostgreSQL-derived |
| Snowflake | EDbVendor.dbvsnowflake |
|
| Teradata | EDbVendor.dbvteradata |
Includes BTEQ + SPL |
| Sybase ASE | EDbVendor.dbvsybase |
T-SQL family |
EDbVendor declares 23 constants, of which 15 are dedicated dialect
grammars, all present in the published NuGet package:
| Vendor | Constant | Notes |
|---|---|---|
| IBM DB2 | EDbVendor.dbvdb2 |
DB2 LUW + iSeries |
| Greenplum | EDbVendor.dbvgreenplum |
PostgreSQL fork |
| Apache Hive | EDbVendor.dbvhive |
HiveQL |
| Apache Impala | EDbVendor.dbvimpala |
Impala SQL |
| IBM Informix | EDbVendor.dbvinformix |
|
| MDX | EDbVendor.dbvmdx |
OLAP; not ordinary SQL |
| Microsoft SQL Server | EDbVendor.dbvmssql |
Full T-SQL |
| MySQL | EDbVendor.dbvmysql |
Plus MariaDB |
| IBM Netezza | EDbVendor.dbvnetezza |
|
| Oracle | EDbVendor.dbvoracle |
Includes PL/SQL |
| PostgreSQL | EDbVendor.dbvpostgresql |
|
| Amazon Redshift | EDbVendor.dbvredshift |
PostgreSQL-derived |
| Snowflake | EDbVendor.dbvsnowflake |
|
| Sybase ASE | EDbVendor.dbvsybase |
T-SQL family |
| Teradata | EDbVendor.dbvteradata |
Includes BTEQ + SPL |
Building from source lets you drop unused dialects with /p:includeXxx=false.
Three constants throw, five are T-SQL in disguise
dbvbigquery, dbvhana and dbvdax throw NotSupportedException from the
constructor. dbvaccess, dbvansi, dbvgeneric, dbvodbc and dbvfirebird
resolve to the T-SQL grammar. See
Database Compatibility.
dbvaccess is not an alias of dbvmssql
Older versions of this page said it was. They are distinct enum constants in both
editions (Java ordinals 0 and 22; .NET values 0 and 11). What dbvaccess actually
does is route to the T-SQL grammar.
Work with database-specific SQL¶
1. Switching vendors¶
The vendor is selected at construction time and embedded in the parser. You cannot change it on an existing instance — to analyse the same SQL against several dialects, construct one parser per vendor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Output:
1 2 3 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Output:
1 2 3 | |
Each of those three statements is a syntax error under the other two vendors, which is the point: the parser is strict about the dialect you asked for.
2. Oracle PL/SQL¶
Oracle is the vendor with a separate PL/SQL grammar. TGSqlParser reaches for it
automatically when it sees a BEGIN ... END; block, a
CREATE PROCEDURE/FUNCTION/PACKAGE, or an anonymous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Output:
1 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Output:
1 | |
See Parse Oracle PL/SQL for the deep dive.
Java 8 and text blocks
The C# examples use raw string literals. The equivalent Java feature, text blocks
("""), needs Java 15+. The parser JAR is Java 8 bytecode and this documentation
targets Java 8, so the Java examples use concatenation. Use text blocks freely if
your own project targets a newer JDK.
3. SQL Server T-SQL¶
The MSSQL vendor handles full T-SQL — variables, control-of-flow, OUTPUT
clauses, MERGE, CTEs, OPENJSON, and so on.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Output, identical in both editions:
1 2 3 | |
Two statements, not one — the DECLARE is a statement in its own right. Any
code that assumes sqlstatements.get(0) is "the interesting one" will pick up the
variable declaration instead of the MERGE.
Sybase ASE shares much of the MSSQL grammar; use EDbVendor.dbvsybase for
ASE-specific syntax (raiserror, sp_* extensions).
4. PostgreSQL, Greenplum and Redshift¶
These three share grammar ancestry. If your SQL targets a fork, pick the matching vendor — they recognise different reserved-word sets and dialect extensions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Output:
1 2 | |
The PostgreSQL example reports sstinsert, not a CTE type: the WITH clause hangs
off the INSERT that consumes it.
5. MySQL specifics¶
1 2 3 4 5 6 | |
1 2 3 4 5 6 7 | |
LIMIT 5, 10 means "skip 5, take 10" — the reverse of the
LIMIT 10 OFFSET 5 form. Backtick-quoted identifiers and FORCE INDEX hints also
parse only under dbvmysql.
6. Snowflake¶
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 8 | |
QUALIFY filters on a window function without a wrapping subquery. It is a
syntax error under every other vendor in this tutorial.
7. Teradata¶
Teradata has its own SPL (stored procedure language) and BTEQ commands; both are handled.
1 2 3 4 5 6 7 8 9 10 | |
Output:
1 | |
1 2 3 4 5 6 7 8 9 10 11 | |
Output:
1 | |
One statement type differs between the editions
The same Teradata procedure reports sstcreateprocedure in Java and
sstteradatacreateprocedure in .NET. Both parse successfully and produce the same
tree; only the ESqlStatementType constant differs. If you switch on statement
type across both editions, do not assume the names match.
Building a vendor auto-detector¶
When you do not know the dialect ahead of time, try each vendor and take the first that parses cleanly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
This is deliberately a sketch. For real workloads, weight the candidate order by
the mix of SQL you actually expect, and remember that a plain SELECT parses
identically under most vendors — so first-match wins and tells you very little.
Detection only discriminates when the SQL contains something dialect-specific.
Note also that on .NET the candidate list must avoid dbvbigquery, dbvhana and
dbvdax, since constructing those throws rather than returning an error.
What you can do now¶
You learned how to:
- Pick the right
EDbVendorfor each dialect, and why you cannot change it later - Parse Oracle PL/SQL through the same
TGSqlParserentry point - Handle T-SQL constructs (
MERGE,OUTPUT, variables) and spot thatDECLAREcounts as its own statement - Distinguish PostgreSQL from Greenplum and Redshift
- Recognise MySQL and Snowflake specific syntax
- Sketch a vendor auto-detector, and see why first-match detection is weak
Continue learning¶
- Advanced Features — AST modification, custom visitors
- Vendor-specific how-to guides:
- Database Compatibility — the conceptual picture behind per-vendor grammars