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
| SELECT * FROM users;
SELECT * FROM schema.table_name;
SELECT * FROM database.schema.table_name;
|
AST Structure:
| TTable
├── tableType: ETableSource.objectname
├── tableName: TObjectName (users)
└── aliasClause: null
|
Table with Alias
| SELECT * FROM users u;
SELECT * FROM users AS u (id, name, email);
|
AST Structure:
| TTable
├── tableType: ETableSource.objectname
├── tableName: TObjectName (users)
└── aliasClause: TAliasClause (u)
└── columns: TObjectNameList (id, name, email) -- optional
|
Derived Table (Subquery)
| SELECT * FROM (
SELECT customer_id, SUM(amount) as total
FROM orders
GROUP BY customer_id
) AS customer_totals;
|
AST Structure:
| TTable
├── tableType: ETableSource.subquery
├── subquery: TSelectSqlStatement
│ ├── resultColumnList: TResultColumnList
│ ├── fromClause: TFromClause (orders)
│ └── groupByClause: TGroupByClause
└── aliasClause: TAliasClause (customer_totals)
|
VALUES Clause
| SELECT * FROM (VALUES
(1, 'John', 'Doe'),
(2, 'Jane', 'Smith'),
(3, 'Bob', 'Johnson')
) AS t(id, first_name, last_name);
|
AST Structure:
| 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
| -- 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:
| 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
| -- 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
| -- 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
| -- 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());
}
}
|
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