Skip to content

GSP Java v3.x to v4 Migration Guide

Version: 4.0 Last Updated: January 2026 Applies to: GSP Java SQL Parser Library


Table of Contents

  1. Executive Summary
  2. Quick Start
  3. Switching Between Resolvers
  4. Why TSQLResolver2 is Better
  5. Deprecated APIs Reference
  6. New APIs Reference
  7. API Comparison and Migration Table
  8. Class Location Changes
  9. Code Migration Examples
  10. Best Practices for Migration
  11. Known Limitations and Considerations
  12. Troubleshooting
  13. Support and Resources

1. Executive Summary

Purpose of the Upgrade

GSP Java v4 introduces TSQLResolver2, a completely redesigned semantic analysis engine that replaces the existing TSQLResolver. The primary focus is on name resolution - building correct relationships between columns and tables used in SQL statements.

Backward Compatibility

Good News: No immediate code changes are required for basic usage.

TSQLResolver2 automatically synchronizes resolution data back to existing APIs (like TTable.getLinkedColumns() and TObjectName.getSourceTable()), ensuring your existing code continues to work without modification.

Deprecation Timeline

Important: APIs marked as deprecated will be removed after 2026/12/31.

Plan your migration to new APIs before this deadline to ensure continued compatibility.

Production Readiness Warning

Caution: Do NOT use v4 in production environments without thorough testing.

Due to the significant refactoring, not all SQL syntax variations have been fully tested. Carefully validate your specific SQL patterns before deploying to production.


2. Quick Start

For Users Who Just Want v4 to Work

If you're currently using GSP Java v3.x and want to upgrade to v4 with minimal changes:

  1. Update your dependency to GSP Java v4.x
  2. Run your existing code - it should work without modifications
  3. Test thoroughly - verify output matches your expectations
  4. Monitor deprecation warnings - plan to update deprecated API usage before 2026/12/31

For Users Who Want to Leverage New Features

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import gudusoft.gsqlparser.*;
import gudusoft.gsqlparser.resolver2.*;
import gudusoft.gsqlparser.resolver2.model.*;

TGSqlParser parser = new TGSqlParser(EDbVendor.dbvoracle);
parser.setResolverType(EResolverType.RESOLVER2);  // Explicitly use new resolver
parser.sqltext = "SELECT a.id, b.name FROM table_a a JOIN table_b b ON a.id = b.id";
parser.parse();

// Access new resolution APIs
for (TCustomSqlStatement stmt : parser.sqlstatements) {
    for (int i = 0; i < stmt.tables.size(); i++) {
        TTable table = stmt.tables.getTable(i);
        // ... use new ColumnSource APIs for detailed resolution info
    }
}

3. Switching Between Resolvers

3.1 Global Level Configuration (TBaseType)

Control the default resolver for all parser instances:

1
2
3
4
5
// Enable TSQLResolver2 (new resolver - default in v4)
TBaseType.setEnableResolver2(true);

// Enable TSQLResolver (old resolver)
TBaseType.setEnableResolver(true);

Important Notes: - TBaseType.isEnableResolver2() returns true by default in v4 - You cannot enable both resolvers simultaneously - an IllegalStateException will be thrown - To switch resolvers, disable one before enabling the other:

1
2
3
// Switch from RESOLVER2 to RESOLVER
TBaseType.setEnableResolver2(false);
TBaseType.setEnableResolver(true);

3.2 Parser Level Configuration (TGSqlParser)

Override global settings for individual parser instances:

1
2
TGSqlParser parser = new TGSqlParser(EDbVendor.dbvoracle);
parser.setResolverType(EResolverType resolverType);

EResolverType Values:

Value Description
EResolverType.DEFAULT Use global TBaseType setting (resolution order: RESOLVER2 > RESOLVER > NONE)
EResolverType.RESOLVER Force legacy TSQLResolver
EResolverType.RESOLVER2 Force new TSQLResolver2
EResolverType.NONE Disable resolution entirely

3.3 Configuration Precedence

  1. Instance-level setResolverType() takes highest precedence
  2. If DEFAULT, falls back to global TBaseType settings
  3. If both disabled in TBaseType, no resolution is performed

4. Why TSQLResolver2 is Better

TSQLResolver2 provides significant improvements over the legacy resolver:

4.1 Namespace-based Architecture

Uses a proper namespace hierarchy for accurate column resolution: - GlobalScopeSelectScopeFromScope - TableNamespace, SubqueryNamespace, CTENamespace, UnionNamespace

4.2 Better Subquery and CTE Handling

Correctly traces columns through nested subqueries and CTEs:

1
2
3
// SQL: SELECT sub.col1 FROM (SELECT t.id AS col1 FROM my_table t) sub
ColumnSource source = column.getColumnSource();
TTable finalTable = source.getFinalTable();  // Returns my_table, not sub

4.3 Confidence Scoring

Provides confidence scores [0.0, 1.0] for resolution results:

1
2
ColumnSource source = column.getColumnSource();
double confidence = source.getConfidence();  // e.g., 1.0 for exact match

4.4 Evidence-based Resolution

Tracks evidence explaining how each column was resolved:

1
2
String evidence = source.getEvidence();
// e.g., "Matched by qualified name against table alias"

4.5 Physical Table Tracing

Traces columns back to their final physical table through subqueries/CTEs:

Method Returns
column.getSourceTable() Immediate source (subquery, CTE, or physical table)
source.getFinalTable() Final physical table after tracing
source.getAllFinalTables() All final tables (for UNION queries)

4.6 Improved Star Column Handling

Better expansion and tracking of SELECT * columns with proper scope awareness.

4.7 Union Query Support

Correctly handles columns from UNION queries with multiple source tables:

1
List<TTable> allTables = source.getAllFinalTables();  // Returns all source tables

4.8 Ambiguous Column Detection

Better detection and handling of ambiguous column references:

1
2
3
if (source.isAmbiguous()) {
    List<TTable> candidates = source.getCandidateTables();
}

5. Deprecated APIs Reference

The following APIs are deprecated and will be removed after 2026/12/31:

5.1 TTable Class

Deprecated API Location Deprecated Since Removal Date
getLinkedColumns() TTable.java:1405-1417 v3.3.1.0 2026/12/31
getAttributes() TTable.java:43-53 v3.3.1.0 2026/12/31

5.2 TCustomSqlStatement Class

Deprecated API Location Deprecated Since Removal Date
getAttributes() TCustomSqlStatement.java:387-399 Implicit 2026/12/31

5.3 TObjectName Class

Deprecated API Location Deprecated Since Removal Date
getSourceAttributeNode() TObjectName.java:108-110 v3.4.0.5 2026/12/31
setSourceAttributeNode() TObjectName.java:92-98 v3.4.0.5 2026/12/31
getCandidateAttributeNodes() TObjectName.java:456-461 Implicit 2026/12/31

5.4 TResultColumn Class

Deprecated API Location Deprecated Since Removal Date
getAttributesFromUpLevelReferenceToStarColumn() TResultColumn.java:46-63 Implicit 2026/12/31

5.5 APIs NOT Deprecated (Still Valid)

The following APIs remain valid and work with both resolvers:

API Class Notes
getSourceTable() TObjectName Enhanced to work with both resolvers; returns null for ambiguous columns in RESOLVER2
getSourceColumn() TObjectName Still used by both resolvers
getLinkedColumnDef() TObjectName Still valid for DDL statements

6. New APIs Reference

6.1 TObjectName New Methods

Package: gudusoft.gsqlparser.nodes.TObjectName

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * Get the resolution result containing column source information.
 * @return ResolutionResult or null if not resolved
 */
public ResolutionResult getResolution()

/**
 * Get the column source directly (shortcut).
 * @return ColumnSource or null if not resolved
 */
public ColumnSource getColumnSource()

/**
 * Set resolution result (called by TSQLResolver2).
 * @param resolution the resolution result to set
 */
public void setResolution(ResolutionResult resolution)

/**
 * Get source table (enhanced to work with both resolvers).
 * Returns null if the column is ambiguous in RESOLVER2.
 * @return TTable representing the immediate source, or null
 */
public TTable getSourceTable()

6.2 ColumnSource Class

Package: gudusoft.gsqlparser.resolver2.model.ColumnSource

This is the primary class for accessing detailed resolution information:

 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
// Namespace information
INamespace getSourceNamespace()    // Where this column is exposed
String getExposedName()            // Name by which column is exposed

// Definition node
TParseTreeNode getDefinitionNode() // AST node where column is defined

// Confidence and evidence
double getConfidence()             // Score [0.0, 1.0]
String getEvidence()               // Why this resolution was chosen

// Table tracing
TTable getFinalTable()             // Final physical table
List<TTable> getAllFinalTables()   // All final tables (for UNION)

// Ambiguity handling
boolean isAmbiguous()              // Is resolution ambiguous?
List<TTable> getCandidateTables()  // Possible source tables

// Column characteristics
boolean isCalculatedColumn()       // Is column computed?
boolean isColumnAlias()            // Is column renamed via AS?
boolean isCTEExplicitColumn()      // Is CTE explicit column?

// Struct/record field access
boolean hasFieldPath()             // Has field path?
boolean isStructFieldAccess()      // Is struct field access?
List<String> getFieldPath()        // Get field path

6.3 ResolutionResult Class

Package: gudusoft.gsqlparser.resolver2.model.ResolutionResult

Container for resolution outcomes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// Factory methods
static ResolutionResult exactMatch(ColumnSource source)
static ResolutionResult ambiguous(AmbiguousColumnSource source)
static ResolutionResult notFound(String columnName)
static ResolutionResult notFound(String columnName, String errorMessage)

// Status checks
ResolutionStatus getStatus()       // EXACT_MATCH, AMBIGUOUS, NOT_FOUND
boolean isExactMatch()
boolean isAmbiguous()
boolean isNotFound()
boolean isResolved()               // True if not NOT_FOUND

// Access results
ColumnSource getColumnSource()     // Get exact match result
AmbiguousColumnSource getAmbiguousSource()  // Get ambiguous details
String getErrorMessage()           // Get error for unresolved columns

6.4 IResolutionResult Interface

Package: gudusoft.gsqlparser.resolver2.result.IResolutionResult

Statement-level query interface for resolution results:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Statement-level queries
IScope getScope(TCustomSqlStatement stmt)
List<TTable> getTables(TCustomSqlStatement stmt)
List<TTable> getTables(TCustomSqlStatement stmt, TableFilterOptions options)
List<TObjectName> getColumns(TCustomSqlStatement stmt)
List<TObjectName> getColumnsForTable(TCustomSqlStatement stmt, TTable table)
List<TObjectName> getOrphanColumns(TCustomSqlStatement stmt)
List<TCTE> getCTEs(TCustomSqlStatement stmt)

// Global queries
List<String> getAllTableNames()
List<String> getAllFieldNames()    // table.column format
List<String> getAllCTENames()
List<TObjectName> getAllResolvedColumns()
List<TObjectName> getAllUnresolvedColumns()
ResolutionStatistics getStatistics()

6.5 TSQLResolver2 Main Class

Package: gudusoft.gsqlparser.resolver2.TSQLResolver2

Main entry point for the new resolver:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Construction
TSQLResolver2(TContext context, TStatementList statements)
TSQLResolver2(TContext context, TStatementList statements, TSQLResolverConfig config)

// Execution
boolean resolve()                  // Main entry point

// Result access
IResolutionResult getResult()      // Statement-level result interface
ScopeBuildResult getScopeBuildResult()  // Scope tree and mappings
ResolutionStatistics getStatistics()

// Configuration
TSQLResolverConfig getConfig()
void setSqlEnv(TSQLEnv sqlEnv)     // Set table metadata
TSQLEnv getSqlEnv()

6.6 TSQLResolverConfig Class

Package: gudusoft.gsqlparser.resolver2.TSQLResolverConfig

Configuration options for TSQLResolver2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Core settings
INameMatcher nameMatcher           // Name matching rules
boolean legacyCompatibilityEnabled // Sync to TTable.linkedColumns (default: true)
double legacySyncMinConfidence     // Min confidence for legacy sync (default: 1.0)
int maxIterations                  // Max iterations for resolution (default: 10)

// Display settings
boolean showDatatype               // Include column datatypes
boolean showCTE                    // Include CTE tables

// Confidence thresholds
double minDefiniteConfidence       // Min for "definite" results (default: 0.9)
double minConfidenceToGuess        // Min to allow guessing (default: 0.95)

// Factory methods
static TSQLResolverConfig createDefault()
static TSQLResolverConfig createCaseSensitive()
static TSQLResolverConfig createStandalone()     // No legacy sync
static TSQLResolverConfig createWithDatatype()
static TSQLResolverConfig createWithCTE()
static TSQLResolverConfig createForVendor(EDbVendor vendor)

7. API Comparison and Migration Table

7.1 Complete Migration Reference

Use Case Old API (v3.x) New API (v4) Notes
Get columns linked to a table table.getLinkedColumns() Iterate resolver.getResult().getColumnsForTable(stmt, table) Use IResolutionResult interface
Get table attributes table.getAttributes() Use namespace classes: TableNamespace.getAllColumnSources() Direct namespace access
Get source table for column column.getSourceTable() column.getSourceTable() (still works) or column.getColumnSource().getSourceNamespace().getSourceTable() Both work
Get final physical table N/A (limited support) column.getColumnSource().getFinalTable() New capability
Get all final tables (UNION) N/A column.getColumnSource().getAllFinalTables() New capability
Check resolution confidence N/A column.getColumnSource().getConfidence() New capability
Get resolution evidence N/A column.getColumnSource().getEvidence() New capability
Handle ambiguous columns column.getCandidateAttributeNodes() column.getColumnSource().getCandidateTables() Simplified API
Get source attribute node column.getSourceAttributeNode() column.getResolution().getColumnSource() Complete replacement
Get CTE columns cteTable.getAttributes() CTENamespace.getAllColumnSources() Direct namespace access
Get unresolved columns Manual tracking resolver.getResult().getOrphanColumns(stmt) New capability
Get all table names Manual iteration resolver.getResult().getAllTableNames() New capability
Get resolution statistics N/A resolver.getStatistics() New capability

7.2 Deprecated Method Replacement Summary

Deprecated Method Direct Replacement
TTable.getLinkedColumns() IResolutionResult.getColumnsForTable(stmt, table)
TTable.getAttributes() INamespace.getAllColumnSources()
TCustomSqlStatement.getAttributes() Iterate through resolved columns via IResolutionResult
TObjectName.getSourceAttributeNode() TObjectName.getColumnSource()
TObjectName.getCandidateAttributeNodes() TObjectName.getColumnSource().getCandidateTables()
TResultColumn.getAttributesFromUpLevelReferenceToStarColumn() Integrated into TSQLResolver2's star column handling

8. Class Location Changes

Class Old Package (v3.x) New Package (v4)
TGetTableColumn demos.gettablecolumns gudusoft.gsqlparser.util

Update your import statements:

1
2
3
4
5
// Old import (v3.x)
import demos.gettablecolumns.TGetTableColumn;

// New import (v4)
import gudusoft.gsqlparser.util.TGetTableColumn;

9. Code Migration Examples

9.1 Example 1: Iterating Through Table Columns

Old Way (v3.x):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
TGSqlParser parser = new TGSqlParser(EDbVendor.dbvoracle);
parser.sqltext = "SELECT a.id, b.name FROM table_a a JOIN table_b b ON a.id = b.id";
parser.parse();

TCustomSqlStatement stmt = parser.sqlstatements.get(0);
for (int i = 0; i < stmt.tables.size(); i++) {
    TTable table = stmt.tables.getTable(i);
    System.out.println("Table: " + table.getName());

    // Old way - using deprecated getLinkedColumns()
    for (int j = 0; j < table.getLinkedColumns().size(); j++) {
        TObjectName col = table.getLinkedColumns().getObjectName(j);
        System.out.println("  Column: " + col.getColumnNameOnly());
    }
}

New Way (v4):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TGSqlParser parser = new TGSqlParser(EDbVendor.dbvoracle);
parser.setResolverType(EResolverType.RESOLVER2);
parser.sqltext = "SELECT a.id, b.name FROM table_a a JOIN table_b b ON a.id = b.id";
parser.parse();

// Get resolution result
TSQLResolver2 resolver = parser.getResolver2();
IResolutionResult result = resolver.getResult();

TCustomSqlStatement stmt = parser.sqlstatements.get(0);
for (TTable table : result.getTables(stmt)) {
    System.out.println("Table: " + table.getFullName());

    for (TObjectName col : result.getColumnsForTable(stmt, table)) {
        System.out.println("  Column: " + col.getColumnNameOnly());

        // New: Access resolution details
        ColumnSource source = col.getColumnSource();
        if (source != null) {
            System.out.println("    Confidence: " + source.getConfidence());
            System.out.println("    Final Table: " + source.getFinalTable());
        }
    }
}

9.2 Example 2: Tracing Column Through Subquery

New Capability in v4:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// SQL: SELECT sub.col1 FROM (SELECT t.id AS col1 FROM my_table t) sub
TGSqlParser parser = new TGSqlParser(EDbVendor.dbvoracle);
parser.setResolverType(EResolverType.RESOLVER2);
parser.sqltext = "SELECT sub.col1 FROM (SELECT t.id AS col1 FROM my_table t) sub";
parser.parse();

// Find the column reference
TSelectSqlStatement selectStmt = (TSelectSqlStatement) parser.sqlstatements.get(0);
TResultColumn resultCol = selectStmt.getResultColumnList().getResultColumn(0);
TObjectName column = resultCol.getExpr().getObjectOperand();

ColumnSource source = column.getColumnSource();
if (source != null) {
    // Get immediate source (the subquery 'sub')
    TTable immediateSource = column.getSourceTable();
    System.out.println("Immediate source: " + immediateSource.getAliasName()); // "sub"

    // Get final physical table (my_table)
    TTable finalTable = source.getFinalTable();
    System.out.println("Final physical table: " + finalTable.getName()); // "my_table"

    // Get confidence score
    System.out.println("Confidence: " + source.getConfidence()); // 1.0
}

9.3 Example 3: Handling Ambiguous Columns

Old Way (v3.x):

1
2
3
4
5
TObjectName column = /* some ambiguous column */;
ArrayList<TColumnTableMatch> candidates = column.getCandidateAttributeNodes();
for (TColumnTableMatch match : candidates) {
    System.out.println("Candidate: " + match.getTable().getName());
}

New Way (v4):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
TObjectName column = /* some ambiguous column */;
ColumnSource source = column.getColumnSource();

if (source != null && source.isAmbiguous()) {
    System.out.println("Column is ambiguous!");
    List<TTable> candidates = source.getCandidateTables();
    for (TTable candidate : candidates) {
        System.out.println("Candidate: " + candidate.getName());
    }
}

9.4 Example 4: Using TGetTableColumn (Works with Both Resolvers)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import gudusoft.gsqlparser.util.TGetTableColumn;  // Note: new package location

// TGetTableColumn works seamlessly with both resolvers
TGetTableColumn gtc = new TGetTableColumn(EDbVendor.dbvoracle);

// Optional: Force specific resolver
gtc.setResolverType(EResolverType.RESOLVER2);

// Configure display options
gtc.showCTE = true;
gtc.showDatatype = true;
gtc.showColumnLocation = true;

gtc.runText("SELECT * FROM employees WHERE dept_id = 10");

// Output is consistent regardless of resolver used
System.out.println(gtc.getInfos().toString());

9.5 Example 5: Supporting Both Resolvers During Transition

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
TObjectName column = /* some column */;

// Check if new resolution is available
ResolutionResult resolution = column.getResolution();
if (resolution != null && resolution.isExactMatch()) {
    // Use new API
    ColumnSource source = resolution.getColumnSource();
    TTable finalTable = source.getFinalTable();
    double confidence = source.getConfidence();
    System.out.println("Final table: " + finalTable.getName() +
                       " (confidence: " + confidence + ")");
} else {
    // Fall back to old API
    TTable sourceTable = column.getSourceTable();
    if (sourceTable != null) {
        System.out.println("Source table: " + sourceTable.getName());
    }
}

10. Best Practices for Migration

10.1 Migration Strategy

Phase 1: Validation (Recommended Duration: 2-4 weeks) 1. Update dependency to GSP Java v4 2. Run existing code without modifications 3. Compare output with v3.x behavior 4. Document any differences

Phase 2: Testing (Recommended Duration: 2-4 weeks) 1. Create comprehensive tests comparing both resolvers 2. Enable debug logging: TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE = true 3. Test with your specific SQL patterns 4. Identify any behavioral changes

Phase 3: API Migration (Before 2026/12/31) 1. Update deprecated API calls to new APIs 2. Remove deprecation warnings 3. Leverage new capabilities where beneficial

10.2 Code Migration Recommendations

  1. Start with Backward Compatible APIs: Since TSQLResolver2 syncs data back to existing APIs, your existing code should work without changes. Verify this first.

  2. Gradual Migration: Start by testing with EResolverType.DEFAULT (uses TSQLResolver2), then gradually update code to use new APIs.

  3. Leverage New Capabilities: Take advantage of new features like getFinalTable() for data lineage and confidence scoring.

  4. Update Tests: Ensure your test suite covers both resolvers during the transition period.

  5. Monitor Deprecation Warnings: If your IDE shows deprecation warnings, prioritize updating those usages.

10.3 Configuration Recommendations

For Legacy Compatibility:

1
2
3
4
TSQLResolverConfig config = TSQLResolverConfig.createDefault();
config.setLegacyCompatibilityEnabled(true);  // Default
config.setLegacySyncMinConfidence(1.0);       // Only sync definite results
parser.setResolver2Config(config);

For New Code (No Legacy Dependencies):

1
2
3
TSQLResolverConfig config = TSQLResolverConfig.createStandalone();
// Disables legacy sync for better performance
parser.setResolver2Config(config);

For Vendor-Specific Behavior:

1
2
3
TSQLResolverConfig config = TSQLResolverConfig.createForVendor(EDbVendor.dbvoracle);
// Uses Oracle-specific name matching rules
parser.setResolver2Config(config);

11. Known Limitations and Considerations

11.1 SQL Syntax Coverage

Due to the significant refactoring, not all SQL syntax variations have been fully tested. If you encounter unexpected behavior:

  1. Enable debug logging: TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE = true
  2. Compare with old resolver: parser.setResolverType(EResolverType.RESOLVER)
  3. Report issues with reproducible SQL examples

11.2 Performance Considerations

TSQLResolver2 may have different performance characteristics:

  • Three-phase resolution: Scope building, initial resolution, iterative enhancement
  • Namespace hierarchy: More sophisticated but potentially slower
  • Iterative passes: Complex queries may require multiple passes

Optimization Tips: - Profile specific queries if performance is critical - Use TSQLResolverConfig.createStandalone() to disable legacy sync if not needed - Consider EResolverType.RESOLVER for specific performance-critical cases

11.3 Metadata Requirements

Some advanced resolution features require providing database metadata:

1
2
3
TSQLEnv sqlEnv = new TSQLEnv();
// Load table/column metadata
resolver.setSqlEnv(sqlEnv);

Without metadata, the resolver relies on inference which may have lower confidence.

11.4 Ambiguous Column Handling

TSQLResolver2 handles ambiguous columns differently:

  • TObjectName.getSourceTable() returns null for ambiguous columns (except star columns)
  • Use ColumnSource.isAmbiguous() to check
  • Use ColumnSource.getCandidateTables() to get all possibilities

11.5 Star Column Special Cases

Star columns (SELECT *) receive special handling:

  • getSourceTable() preserves Phase 1 resolution for star columns
  • Use resolver's star column expansion for detailed tracking
  • ColumnSource.getAllFinalTables() returns all contributing tables

12. Troubleshooting

12.1 Common Issues and Solutions

Issue Possible Cause Solution
Column resolution differs from v3.x TSQLResolver2 resolves ambiguous cases differently Review resolution via getEvidence(), provide metadata via TSQLEnv
Missing table/column relationships Star column expansion handling changed Enable showCTE option, verify subquery handling
Performance regression TSQLResolver2 architecture overhead Profile specific queries, consider resolver switching
Deprecation warnings Using deprecated APIs Update to new APIs per migration table
getSourceTable() returns null Column is ambiguous in RESOLVER2 Check isAmbiguous(), use getCandidateTables()
Class not found: TGetTableColumn Package location changed Update import to gudusoft.gsqlparser.util.TGetTableColumn

12.2 Debug Logging

Enable detailed resolution logging:

1
TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE = true;

This outputs: - Scope tree construction - Column resolution attempts - Namespace lookups - Star column expansion - Iterative pass progress

12.3 Comparing Resolvers

To compare output between resolvers:

1
2
3
4
5
6
7
8
9
// Test with RESOLVER2
parser.setResolverType(EResolverType.RESOLVER2);
parser.parse();
// ... capture output ...

// Reset and test with RESOLVER
parser.setResolverType(EResolverType.RESOLVER);
parser.parse();
// ... compare output ...

13. Support and Resources

13.1 Documentation

  • API Reference: See JavaDoc for gudusoft.gsqlparser.resolver2 package
  • Developer Guide: resolver2/TSQLResolver2_Developer_Guide.md

13.2 Reporting Issues

When reporting issues, please include: 1. GSP Java version 2. Database vendor (EDbVendor) 3. SQL statement causing the issue 4. Expected vs actual behavior 5. Debug log output if available

13.3 Version Compatibility

GSP Java Version Default Resolver TSQLResolver2 Status
v3.x TSQLResolver Not available
v4.0 TSQLResolver2 Production (with testing)

13.4 Deprecation Schedule

Date Event
v4.0 Release TSQLResolver2 becomes default
2026/12/31 Deprecated APIs removed

Appendix A: Complete New API Package Structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
gudusoft.gsqlparser.resolver2/
├── TSQLResolver2.java              # Main resolver entry point
├── TSQLResolverConfig.java         # Configuration options
├── TSQLResolver2ResultFormatter.java # Output formatting
├── ScopeBuilder.java               # Builds scope tree
├── NameResolver.java               # Resolves column names
├── ScopeBuildResult.java           # Scope building result
├── model/
│   ├── ColumnSource.java           # Column resolution details
│   ├── ResolutionResult.java       # Resolution outcome container
│   └── AmbiguousColumnSource.java  # Ambiguous resolution details
├── result/
│   ├── IResolutionResult.java      # Statement-level result interface
│   └── ResolutionResultImpl.java   # Default implementation
├── scope/
│   ├── GlobalScope.java
│   ├── SelectScope.java
│   ├── FromScope.java
│   └── ... other scope types
└── namespace/
    ├── TableNamespace.java
    ├── SubqueryNamespace.java
    ├── CTENamespace.java
    └── ... other namespace types

Appendix B: Quick Reference Card

Resolver Configuration

1
2
3
4
5
6
7
8
// Global level
TBaseType.setEnableResolver2(true);   // Enable RESOLVER2
TBaseType.setEnableResolver(true);    // Enable RESOLVER (legacy)

// Parser level
parser.setResolverType(EResolverType.RESOLVER2);  // Force RESOLVER2
parser.setResolverType(EResolverType.RESOLVER);   // Force RESOLVER
parser.setResolverType(EResolverType.DEFAULT);    // Use global setting

Key New APIs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Get resolution result
ResolutionResult result = column.getResolution();
ColumnSource source = column.getColumnSource();

// Key ColumnSource methods
source.getFinalTable()          // Physical table after tracing
source.getAllFinalTables()      // All tables (for UNION)
source.getConfidence()          // Resolution confidence [0.0, 1.0]
source.getEvidence()            // Why this resolution
source.isAmbiguous()            // Is ambiguous?
source.getCandidateTables()     // Candidate tables

Deprecated API Quick Migration

Old New
table.getLinkedColumns() result.getColumnsForTable(stmt, table)
table.getAttributes() namespace.getAllColumnSources()
column.getSourceAttributeNode() column.getColumnSource()
column.getCandidateAttributeNodes() source.getCandidateTables()

This migration guide is maintained by the GSP Java team. For the latest updates, refer to the official documentation.