Skip to content

TTable - Table Nodes

Overview

The TTable node represents various kinds of table sources in SQL FROM clauses and other contexts. It can represent simple table names, subqueries, table-valued functions, and many database-specific table sources. It implements the IRelation interface and provides comprehensive attribute management.

Table Types

The ETableSource enum defines different types of table sources:

Type Description Reference Property
objectname Simple table/view name tableName
subquery Derived table (subquery) subquery
tableExpr Table-valued expression tableExpr
function Table-valued function funcCall
rowList VALUES clause valueClause
containsTable SQL Server CONTAINSTABLE containsTable
freetextTable SQL Server FREETEXTTABLE containsTable
openrowset SQL Server OPENROWSET openRowSet
openxml SQL Server OPENXML openXML
opendatasource SQL Server OPENDATASOURCE openDatasource
openquery SQL Server OPENQUERY openquery
pivoted_table PIVOT/UNPIVOT table pivotedTable
join JOIN expression joinExpr
unnest UNNEST operation unnestClause
xmltable XML table xmlTable
jsonTable JSON table jsonTable

SQL to AST Mapping

Simple Table Reference

1
2
3
SELECT * FROM users;
SELECT * FROM schema.table_name;
SELECT * FROM database.schema.table_name;

AST Structure:

1
2
3
4
TTable
├── tableType: ETableSource.objectname
├── tableName: TObjectName (users)
└── aliasClause: null

Table with Alias

1
2
SELECT * FROM users u;
SELECT * FROM users AS u (id, name, email);

AST Structure:

1
2
3
4
5
TTable
├── tableType: ETableSource.objectname
├── tableName: TObjectName (users)
└── aliasClause: TAliasClause (u)
    └── columns: TObjectNameList (id, name, email) -- optional

Derived Table (Subquery)

1
2
3
4
5
SELECT * FROM (
    SELECT customer_id, SUM(amount) as total
    FROM orders 
    GROUP BY customer_id
) AS customer_totals;

AST Structure:

1
2
3
4
5
6
7
TTable
├── tableType: ETableSource.subquery
├── subquery: TSelectSqlStatement
│   ├── resultColumnList: TResultColumnList
│   ├── fromClause: TFromClause (orders)
│   └── groupByClause: TGroupByClause
└── aliasClause: TAliasClause (customer_totals)

VALUES Clause

1
2
3
4
5
SELECT * FROM (VALUES 
    (1, 'John', 'Doe'),
    (2, 'Jane', 'Smith'),
    (3, 'Bob', 'Johnson')
) AS t(id, first_name, last_name);

AST Structure:

1
2
3
4
5
6
7
8
9
TTable
├── tableType: ETableSource.rowList
├── valueClause: TValueClause
│   └── rows: TMultiTargetList
│       ├── TMultiTarget (1, 'John', 'Doe')
│       ├── TMultiTarget (2, 'Jane', 'Smith')
│       └── TMultiTarget (3, 'Bob', 'Johnson')
└── aliasClause: TAliasClause (t)
    └── columns: TObjectNameList (id, first_name, last_name)

Table-Valued Function

1
2
3
4
5
6
7
8
-- SQL Server
SELECT * FROM OPENROWSET('SQLNCLI', 'connection_string', 'SELECT * FROM table');

-- PostgreSQL
SELECT * FROM unnest(ARRAY[1,2,3]) AS t(id);

-- Generic function
SELECT * FROM my_table_function(param1, param2);

AST Structure:

1
2
3
4
5
6
TTable
├── tableType: ETableSource.function
├── funcCall: TFunctionCall
│   ├── functionName: TObjectName
│   └── args: TExpressionList
└── aliasClause: TAliasClause (optional)

Key Properties

Property Type Description Access Method
tableName TObjectName Table name for objectname type getTableName()
tableType ETableSource Type of table source getTableType()
subquery TSelectSqlStatement Subquery for derived tables getSubquery()
funcCall TFunctionCall Function call for table functions getFuncCall()
valueClause TValueClause VALUES clause getValueClause()
joinExpr TJoinExpr JOIN expression getJoinExpr()
aliasClause TAliasClause Table alias getAliasClause()
relationAttributes ArrayList<TAttributeNode> Available attributes getAttributes()

Common Usage Patterns

Basic Table Analysis

 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
public void analyzeTable(TTable table) {
    System.out.println("Table Type: " + table.getTableType());
    System.out.println("Display Name: " + table.getDisplayName());

    // Handle different table types
    switch (table.getTableType()) {
        case objectname:
            analyzeObjectNameTable(table);
            break;
        case subquery:
            analyzeSubqueryTable(table);
            break;
        case function:
            analyzeFunctionTable(table);
            break;
        case rowList:
            analyzeValuesTable(table);
            break;
        case join:
            analyzeJoinTable(table);
            break;
        default:
            System.out.println("Other table type: " + table.getTableType());
    }

    // Analyze alias
    if (table.getAliasClause() != null) {
        analyzeTableAlias(table.getAliasClause());
    }
}

Object Name Table Analysis

 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
public void analyzeObjectNameTable(TTable table) {
    TObjectName tableName = table.getTableName();

    System.out.println("Table name: " + table.getName());
    System.out.println("Full name: " + table.getFullName());

    // Check qualified name parts
    if (tableName.getDatabaseString() != null) {
        System.out.println("Database: " + table.getPrefixDatabase());
    }
    if (tableName.getSchemaString() != null) {
        System.out.println("Schema: " + table.getPrefixSchema());
    }
    if (tableName.getServerString() != null) {
        System.out.println("Server: " + table.getPrefixServer());
    }

    // Check if it's a base table or CTE
    if (table.isBaseTable()) {
        System.out.println("This is a base table");
    }
    if (table.isCTEName()) {
        System.out.println("This references a CTE: " + table.getCTE().getName());
    }
}

Subquery Table Analysis

 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
public void analyzeSubqueryTable(TTable table) {
    TSelectSqlStatement subquery = table.getSubquery();
    if (subquery == null) return;

    System.out.println("Derived table from subquery:");

    // Analyze result columns
    if (subquery.getResultColumnList() != null) {
        System.out.println("Subquery columns:");
        for (int i = 0; i < subquery.getResultColumnList().size(); i++) {
            TResultColumn col = subquery.getResultColumnList().getResultColumn(i);
            System.out.println("  " + col.getDisplayName());
        }
    }

    // Check for combined queries
    if (subquery.isCombinedQuery()) {
        System.out.println("Combined query detected:");
        System.out.println("  Operator: " + subquery.getCombinedOperatorType());
        analyzeSubqueryTable(createTableFromSubquery(subquery.getLeftStmt()));
    }

    // Extract referenced tables from subquery
    Set<String> referencedTables = extractTablesFromSubquery(subquery);
    System.out.println("Referenced tables: " + referencedTables);
}

Function Table Analysis

 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
public void analyzeFunctionTable(TTable table) {
    TFunctionCall funcCall = table.getFuncCall();
    if (funcCall == null) return;

    System.out.println("Table-valued function:");
    System.out.println("  Function: " + funcCall.getFunctionName());

    // Analyze arguments
    if (funcCall.getArgs() != null) {
        System.out.println("  Arguments:");
        for (int i = 0; i < funcCall.getArgs().size(); i++) {
            TExpression arg = funcCall.getArgs().getExpression(i);
            System.out.println("    " + (i + 1) + ": " + arg.toString());
        }
    }

    // Check for specific function types
    String funcName = funcCall.getFunctionName().toString().toUpperCase();
    switch (funcName) {
        case "UNNEST":
            System.out.println("  UNNEST function - array expansion");
            break;
        case "OPENROWSET":
            System.out.println("  SQL Server OPENROWSET");
            break;
        case "STRING_SPLIT":
            System.out.println("  SQL Server STRING_SPLIT");
            break;
        default:
            System.out.println("  User-defined table function");
    }
}

VALUES Table Analysis

 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
public void analyzeValuesTable(TTable table) {
    TValueClause valueClause = table.getValueClause();
    if (valueClause == null) return;

    System.out.println("VALUES clause:");
    System.out.println("  Row count: " + valueClause.getRows().size());

    // Analyze first row to determine structure
    if (valueClause.getRows().size() > 0) {
        TMultiTarget firstRow = valueClause.getRows().get(0);
        if (firstRow.getColumnList() != null) {
            System.out.println("  Column count: " + firstRow.getColumnList().size());

            // Show sample values from first row
            System.out.println("  Sample values:");
            for (int i = 0; i < firstRow.getColumnList().size(); i++) {
                TResultColumn col = firstRow.getColumnList().getResultColumn(i);
                System.out.println("    Column " + (i + 1) + ": " + col.getExpr());
            }
        }
    }

    // Check for data type patterns
    analyzeValuesDataTypes(valueClause);
}

Attribute Management

 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
39
40
41
42
43
44
45
46
47
48
public void analyzeTableAttributes(TTable table) {
    // Initialize attributes if not already done
    if (!table.relationAttributes.isEmpty() || table.isAttributesInitialized) {
        initializeTableAttributes(table);
    }

    System.out.println("Available attributes:");
    for (TAttributeNode attr : table.getAttributes()) {
        System.out.println("  " + attr.getName());

        if (attr.getSourceTable() != null) {
            System.out.println("    Source table: " + attr.getSourceTable().getDisplayName());
        }

        if (attr.getSubLevelResultColumn() != null) {
            System.out.println("    Source column: " + attr.getSubLevelResultColumn());
        }
    }
}

private void initializeTableAttributes(TTable table) {
    switch (table.getTableType()) {
        case subquery:
            if (table.getSubquery() != null) {
                table.initAttributesFromSubquery(table.getSubquery(), table.getDisplayName() + ".");
            }
            break;
        case rowList:
            table.initAttributeForRowList();
            break;
        case function:
            table.initAttributeForTableFunction();
            break;
        case xmltable:
            table.initAttributeForXMLTable();
            break;
        case join:
            table.initAttributesForJoin();
            break;
        case pivoted_table:
            table.initAttributesForPivotTable();
            break;
        case unnest:
            // Would need TSelectSqlStatement and TSQLEnv for full initialization
            // table.initAttributesForUnnest(sqlEnv, select);
            break;
    }
}

Database-Specific Features

SQL Server

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
-- OPENROWSET
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=server;Database=db;', 'SELECT * FROM table');

-- OPENXML
DECLARE @xml xml = '<root><item id="1" name="test"/></root>'
SELECT * FROM OPENXML(@xml, '/root/item') WITH (id int '@id', name varchar(50) '@name');

-- CONTAINSTABLE
SELECT * FROM CONTAINSTABLE(documents, content, 'search terms');

-- PIVOT
SELECT * FROM (
    SELECT year, quarter, sales FROM sales_data
) AS src
PIVOT (SUM(sales) FOR quarter IN ([Q1], [Q2], [Q3], [Q4])) AS pvt;

Access via: - getOpenRowSet() - OPENROWSET clause - getOpenXML() - OPENXML clause
- getContainsTable() - CONTAINSTABLE/FREETEXTTABLE - getPivotedTable() - PIVOT/UNPIVOT operations

PostgreSQL

1
2
3
4
5
6
7
8
-- UNNEST
SELECT * FROM unnest(ARRAY[1,2,3]) AS t(id);

-- JSON table functions
SELECT * FROM json_to_recordset('[{"id":1,"name":"John"}]') AS t(id int, name text);

-- Table functions with LATERAL
SELECT * FROM table1 t1, LATERAL my_function(t1.id) AS f;

Access via: - getUnnestClause() - UNNEST operations - getFuncCall() - Table-valued functions

Oracle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
-- XML table
SELECT * FROM XMLTable('/employees/employee' 
    PASSING xml_data 
    COLUMNS 
        id NUMBER PATH '@id',
        name VARCHAR2(50) PATH 'name'
);

-- Flashback queries
SELECT * FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR);

-- External tables
SELECT * FROM external_table_name;

Access via: - getXmlTable() - XMLTable operations - getFlashback() - Flashback clauses

MySQL

1
2
3
4
5
6
7
8
-- JSON table functions
SELECT * FROM JSON_TABLE(
    '{"items": [{"id": 1, "name": "Item1"}]}',
    '$.items[*]' COLUMNS (
        id INT PATH '$.id',
        name VARCHAR(50) PATH '$.name'
    )
) AS jt;

Access via: - getJsonTable() - JSON table operations

Hive/Spark

1
2
3
4
5
6
-- Lateral view with explode
SELECT * FROM table1 
LATERAL VIEW explode(array_column) exploded_table AS item;

-- Table properties
SELECT * FROM table_name ('prop1'='value1', 'prop2'='value2');

Access via: - getLateralViewList() - LATERAL VIEW operations - getTableProperties() - Table properties

Advanced Usage Patterns

CTE (Common Table Expression) Handling

 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
public void analyzeCTEReference(TTable table) {
    if (table.isCTEName()) {
        TCTE cte = table.getCTE();
        System.out.println("CTE Reference:");
        System.out.println("  CTE Name: " + cte.getName());
        System.out.println("  Is Recursive: " + cte.isRecursive());

        // Initialize attributes from CTE
        if (cte != null) {
            table.initAttributesFromCTE(cte);
            System.out.println("  Available columns from CTE:");
            for (TAttributeNode attr : table.getAttributes()) {
                System.out.println("    " + attr.getName());
            }
        }

        // Check CTE column references
        if (table.getCteColomnReferences() != null) {
            System.out.println("  Explicit column list:");
            for (TObjectName col : table.getCteColomnReferences()) {
                System.out.println("    " + col.toString());
            }
        }
    }
}

Table Lineage Analysis

 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
39
public Set<String> extractTableLineage(TTable table) {
    Set<String> lineage = new HashSet<>();

    switch (table.getTableType()) {
        case objectname:
            if (!table.isCTEName()) {
                lineage.add(table.getFullName());
            } else {
                // For CTE, get lineage from its definition
                TCTE cte = table.getCTE();
                if (cte.getSubquery() != null) {
                    lineage.addAll(extractTablesFromSubquery(cte.getSubquery()));
                }
            }
            break;

        case subquery:
            lineage.addAll(extractTablesFromSubquery(table.getSubquery()));
            break;

        case join:
            lineage.addAll(extractTablesFromJoin(table.getJoinExpr()));
            break;

        case pivoted_table:
            if (table.getPivotedTable() != null) {
                for (TTable sourceTable : table.getPivotedTable().getRelations()) {
                    lineage.addAll(extractTableLineage(sourceTable));
                }
            }
            break;

        default:
            // For other types like functions, VALUES, etc.
            lineage.add(table.getDisplayName());
    }

    return lineage;
}

Table Hint Analysis (SQL Server)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void analyzeTableHints(TTable table) {
    if (table.getTableHintList() != null) {
        System.out.println("Table hints detected:");
        for (int i = 0; i < table.getTableHintList().size(); i++) {
            TTableHint hint = table.getTableHintList().getElement(i);
            System.out.println("  " + hint.toString());

            // Analyze hint performance impact
            analyzeHintPerformance(hint);
        }
    }
}

private void analyzeHintPerformance(TTableHint hint) {
    String hintText = hint.toString().toUpperCase();

    if (hintText.contains("NOLOCK")) {
        System.out.println("    WARNING: NOLOCK hint - may read uncommitted data");
    } else if (hintText.contains("INDEX")) {
        System.out.println("    NOTE: Index hint - forces specific index usage");
    } else if (hintText.contains("TABLOCK")) {
        System.out.println("    NOTE: Table lock hint - may impact concurrency");
    }
}

Column Reference Tracking

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public void trackColumnReferences(TTable table) {
    System.out.println("Linked columns for " + table.getDisplayName() + ":");

    for (TObjectName column : table.getLinkedColumns()) {
        System.out.println("  " + column.toString());

        // Show column source information
        if (column.getSourceTable() != null) {
            System.out.println("    Resolved to table: " + 
                column.getSourceTable().getDisplayName());
        }
    }

    // Show attributes that reference this table
    for (TObjectName attr : table.getAttributesReferenceToThisRelation()) {
        System.out.println("  Referenced by: " + attr.toString());
    }
}

Expanded Star Column Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public void analyzeExpandedStarColumns(TTable table) {
    ArrayList<String> expandedColumns = table.getExpandedStarColumns();

    if (!expandedColumns.isEmpty()) {
        System.out.println("Star column expansion for " + table.getDisplayName() + ":");
        for (String column : expandedColumns) {
            System.out.println("  " + column);
        }
    } else {
        System.out.println("No star column expansion available for " + table.getDisplayName());
    }
}

Performance Considerations

Table Type Performance Impact

 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
public void analyzeTablePerformance(TTable table) {
    switch (table.getTableType()) {
        case objectname:
            if (table.isCTEName()) {
                System.out.println("CTE reference - check for recursion and materialization");
            } else {
                System.out.println("Base table - generally efficient");
            }
            break;

        case subquery:
            System.out.println("Derived table - may benefit from materialization");
            analyzeSubqueryComplexity(table.getSubquery());
            break;

        case function:
            System.out.println("Table function - check function efficiency");
            break;

        case rowList:
            int rowCount = table.getValueClause().getRows().size();
            if (rowCount > 1000) {
                System.out.println("WARNING: Large VALUES clause (" + rowCount + " rows)");
            }
            break;

        case join:
            System.out.println("JOIN table - analyze join conditions and indexes");
            break;

        default:
            System.out.println("Special table type - review implementation details");
    }
}

Memory Usage Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public void analyzeMemoryUsage(TTable table) {
    int attributeCount = table.getAttributes().size();

    if (attributeCount > 100) {
        System.out.println("WARNING: High attribute count (" + attributeCount + 
            ") may impact memory usage");
    }

    // Check for large VALUES clauses
    if (table.getTableType() == ETableSource.rowList && table.getValueClause() != null) {
        int rowCount = table.getValueClause().getRows().size();
        if (rowCount > 10000) {
            System.out.println("WARNING: Large VALUES clause may consume significant memory");
        }
    }
}

Complete Example: Comprehensive Table Analysis

  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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
public class TableAnalyzer {

    public void analyzeTable(TTable table) {
        System.out.println("=== Comprehensive Table Analysis ===");
        System.out.println("Table: " + table.getDisplayName());
        System.out.println("Type: " + table.getTableType());

        // Basic information
        printBasicInfo(table);

        // Type-specific analysis
        analyzeByType(table);

        // Attribute analysis
        analyzeAttributes(table);

        // Performance analysis
        analyzePerformance(table);

        // Database-specific features
        analyzeDbSpecificFeatures(table);
    }

    private void printBasicInfo(TTable table) {
        System.out.println("\n--- Basic Information ---");
        System.out.println("Display name: " + table.getDisplayName());
        System.out.println("Full name: " + table.getFullName());
        System.out.println("Is base table: " + table.isBaseTable());
        System.out.println("Is CTE: " + table.isCTEName());

        if (table.getAliasClause() != null) {
            System.out.println("Alias: " + table.getAliasName());
            if (table.getAliasClause().getColumns() != null) {
                System.out.println("Alias columns: " + 
                    table.getAliasClause().getColumns().toString());
            }
        }
    }

    private void analyzeByType(TTable table) {
        System.out.println("\n--- Type-Specific Analysis ---");

        switch (table.getTableType()) {
            case objectname:
                analyzeObjectNameTable(table);
                break;
            case subquery:
                analyzeSubqueryTable(table);
                break;
            case function:
                analyzeFunctionTable(table);
                break;
            case rowList:
                analyzeValuesTable(table);
                break;
            case join:
                System.out.println("JOIN expression - see JOIN documentation");
                break;
            case pivoted_table:
                analyzePivotTable(table);
                break;
            default:
                System.out.println("Other table type: " + table.getTableType());
        }
    }

    private void analyzeAttributes(TTable table) {
        System.out.println("\n--- Attribute Analysis ---");
        System.out.println("Attribute count: " + table.getAttributes().size());

        for (int i = 0; i < Math.min(10, table.getAttributes().size()); i++) {
            TAttributeNode attr = table.getAttributes().get(i);
            System.out.println("  " + (i + 1) + ": " + attr.getName());
        }

        if (table.getAttributes().size() > 10) {
            System.out.println("  ... and " + (table.getAttributes().size() - 10) + " more");
        }
    }

    private void analyzePerformance(TTable table) {
        System.out.println("\n--- Performance Analysis ---");
        analyzeTablePerformance(table);
        analyzeMemoryUsage(table);
    }

    private void analyzeDbSpecificFeatures(TTable table) {
        System.out.println("\n--- Database-Specific Features ---");

        if (table.getTableHintList() != null) {
            analyzeTableHints(table);
        }

        if (table.getTableSample() != null) {
            System.out.println("TABLESAMPLE clause present");
        }

        if (table.getFlashback() != null) {
            System.out.println("Oracle Flashback query");
        }

        if (table.getLateralViewList() != null) {
            System.out.println("Hive LATERAL VIEW operations: " + 
                table.getLateralViewList().size());
        }
    }
}

See Also