public class TCustomSqlStatement extends TParseTreeNode implements IRelation
| Modifier and Type | Class and Description |
|---|---|
static class |
TCustomSqlStatement.SqlNormalizationProfile
Normalization profiles for SQL hashing.
|
| Modifier and Type | Field and Description |
|---|---|
int |
dummytag
Tag used by parser internally.
|
protected TFromClause |
fromClause |
protected TJoinExpr |
fromSourceJoin |
protected TTable |
fromSourceTable |
boolean |
isctequery |
protected boolean |
isparsed |
TJoinList |
joins
joins represents table sources in the from clause.
|
TCustomParser |
parser
Parser used to parse this statement.
|
TCustomParser |
plsqlparser
PLSQL parser used to parse this statement.
|
protected ArrayList<TAttributeNode> |
relationAttributes |
TParseTreeNode |
rootNode
Original Parse tree node from parser
|
TSourceToken |
semicolonended |
TSourceTokenList |
sourcetokenlist
Source tokens included in this statement.
|
ESqlStatementType |
sqlstatementtype
Type of this statement.
|
protected gudusoft.gsqlparser.compiler.TStmtScope |
stmtScope
Original SQL fragment of this statement.
|
TTableList |
tables
Provides a quick way to access all tables involved in this SQL statement.
|
dbvendor, doubleLinkedTokenListToString, nodeActionAppend, nodeActionInsert, nodeActionRemove, nodeActionUnknown, nodeActionUpdate, nodeActionUpdateText, nodeChangeEndToken, nodeChangeStartToken| Constructor and Description |
|---|
TCustomSqlStatement(EDbVendor dbvendor) |
| Modifier and Type | Method and Description |
|---|---|
void |
addToTables(TTable pTable) |
TWhereClause |
addWhereClause(String condition)
Deprecated.
As of 2.0.9.0, use
setWhereClause(TWhereClause) instead
Or, use TWhereClause.setText(String) |
TTable |
analyzeFromTable(TFromTable pfromTable,
Boolean addToTableList) |
TTable |
analyzeFromTable(TFromTable pfromTable,
Boolean addToTableList,
ESqlClause pLocation) |
TJoin |
analyzeJoin(TJoinExpr pJoinExpr,
TJoin pJoin,
Boolean isSub) |
TTable |
analyzeTablename(TObjectName tableName) |
TJoin |
analyzeTableOrJoin(TFromTable pfromTable) |
String |
asCanonical()
this method return a canonical form of a SQL statement in plan text.
|
boolean |
checkNonQualifiedColumnReferenceInSubQueryOfUplevelStmt(TObjectName crf,
boolean sameLevelOnly)
Found out is a non qualified column is a column in uplevel subquery table like this:
take ma_parkey for example: ma_parkey is not a physical column
SELECT c_mandant
, CASE WHEN EXISTS (SELECT 1
FROM CDS_H_GRUPPE GRP1
WHERE GRP1.c_mandant = c_mandant
AND GRP1.parkey1 = ma_parkey)
THEN 1
ELSE NULL
END MA_ME
FROM (SELECT c_mandant
, CASE WHEN funktionscode = 'U'
THEN parkey1
ELSE parkey2
END MA_PARKEY
FROM
CDS_H_GRUPPE
)
|
void |
clearError() |
String |
computeSqlHash(TCustomSqlStatement.SqlNormalizationProfile profile,
String normVersion)
Compute a SQL hash using the given normalization profile and version.
|
protected int |
dochecksyntax(TCustomSqlStatement psql) |
int |
doParseStatement(TCustomSqlStatement psql) |
TTable |
findTable(ETableEffectType[] tableEffectTypes) |
boolean |
fireOnMetaDatabaseTableColumn(String pServer,
String pDatabase,
String pSchema,
String pTable,
String pColumn) |
TCustomSqlStatement |
getAncestorStmt() |
ArrayList<TAttributeNode> |
getAttributes()
每个 relation 包含的 attributes
当它为 base table 时,这些 attributes 的来源有三种可能
1.
|
ArrayList<String> |
getColumnsInTable(String pServer,
String pDatabase,
String pSchema,
String pTable)
Deprecated.
since 2.3.8.2, use
TTable.getExpandedStarColumns() instead. |
ArrayList<String> |
getColumnsInTable(TTable lcTable)
Deprecated.
since 2.3.8.2, use
TTable.getExpandedStarColumns() instead. |
TCTE |
getCteIncludeThisStmt() |
TCTEList |
getCteList()
Multiple common table expressions
TCTE can be specified following the single WITH keyword. |
Stack<TDaxFunction> |
getDaxFunctionStack() |
TObjectName |
getEndlabelName() |
int |
getErrorCount()
Number of syntax errors for this statement.
|
String |
getErrormessage() |
TreeMap<String,TResultColumn> |
getExpandedResultColumns() |
TTable |
getFirstPhysicalTable() |
Stack<gudusoft.gsqlparser.compiler.TFrame> |
getFrameStack() |
TFromClause |
getFromClause() |
TJoinExpr |
getFromSourceJoin()
This is a join in from clause, including left and right relation.
|
TTable |
getFromSourceTable()
This is table in from clause if only one table is listed in the from clause,
If more than one table is listed in from clause, please check
getFromSourceJoin() instead. |
gudusoft.gsqlparser.compiler.TGlobalScope |
getGlobalScope() |
TPTNodeList<TColumnWithSortOrder> |
getIndexColumns() |
TJoinList |
getJoins() |
TObjectName |
getLabelName() |
TObjectNameList |
getOrphanColumns() |
TOutputClause |
getOutputClause() |
TParseTreeNode |
getParentObjectName() |
TCustomSqlStatement |
getParentStmt() |
String |
getQueryId()
Retrieves the unique and stable identifier for this SQL statement.
|
String |
getRelationName() |
ArrayList<TTable> |
getRelations()
Relations that used in from clause of select statement.
|
TResultColumnList |
getResultColumnList()
In select statement, this method returns Items in select_list.
|
TReturningClause |
getReturningClause() |
TSQLEnv |
getSqlEnv() |
String |
getSqlHash()
Backward compatible overload equivalent to
getSqlHash(false). |
String |
getSqlHash(boolean forceReCalculate)
Returns a stable, vendor-aware hash of this statement's SQL text for
lineage grouping and statement identity.
|
TStatementList |
getStatements()
Saves all first level sub statements.
|
gudusoft.gsqlparser.compiler.TStmtScope |
getStmtScope() |
Stack |
getSymbolTable()
Deprecated.
since ver 2.5.3.5, please use
TStmtScope instead |
ArrayList<TSyntaxError> |
getSyntaxErrors() |
ArrayList<TSyntaxError> |
getSyntaxHints() |
TTableList |
getTables() |
TTable |
getTargetTable()
target table in the delete/insert/update/create table statement.
|
TSourceTokenList |
getTokenList() |
TTopClause |
getTopClause() |
TCustomSqlStatement |
getTopStatement() |
TColumnDefinitionList |
getUsingVariableList() |
Stack<TObjectName> |
getVariableStack() |
TWhereClause |
getWhereClause()
restrict the rows selected to those that satisfy one or more conditions.
|
boolean |
isathenaplsql() |
boolean |
isBigQueryplsql() |
boolean |
isdatabricksplsql() |
boolean |
isGaussDBStoredProcedure() |
boolean |
isgreeplumplsql() |
boolean |
isnzplsql() |
boolean |
isoracleplsql() |
boolean |
ispgplsql() |
boolean |
isprestoplsql() |
boolean |
issnowflakeplsql() |
protected boolean |
isTableACTE(TTable pTable) |
boolean |
isverticaplsql() |
void |
linkColumnReferenceToTable(TObjectName cr,
ESqlClause plocation)
Deprecated.
As of v1.6.0.1, use
linkColumnToTable(gudusoft.gsqlparser.nodes.TObjectName, gudusoft.gsqlparser.ESqlClause) instead |
boolean |
linkColumnToTable(TObjectName pColumn,
ESqlClause pLocation)
将列引用解析并绑定到其来源(表、子查询、CTE、表函数、OPENQUERY/UNNEST 等)。
功能概述:
1) 针对 DAX 语法直接走 DAX 分支。
2) 已绑定或标记“延迟到列解析器”的列直接返回。
3) 设定列所在语法位置,并校验列名/保留字(含 MySQL true/false/default、内置函数等)。
4) 处理厂商伪表/特殊前缀(Oracle :new/:old;SQL Server INSERTED/DELETED)。
5) Insert All/VALUES 场景:优先在子查询结果集中/变量或过程参数中匹配。
6) 在当前语句的 FROM 表集合中查找并建立绑定:
- 限定列 table.col:按别名/表名匹配;对子查询/CTE/OPENQUERY 进一步在结果集中定位源列;
命中后写入 linkedColumns,必要时将 TableToken 标记为 subquery_alias。
- 非限定列 col:
a.
|
protected boolean |
linkToFirstTable(TObjectName pColumn,
int pCandidateTableCnt) |
boolean |
locateVariableOrParameter(TObjectName cr) |
boolean |
locateVariableOrParameter(TObjectName cr,
boolean checkVariableDeclaredInProcedure) |
boolean |
OracleStatementCanBeSeparatedByBeginEndPair() |
EActionOnParseError |
parseerrormessagehandle(TSyntaxError se)
Log error messages if syntax errors found while parsing this statement.
|
int |
parsestatement(TCustomSqlStatement pparentsql,
boolean isparsetreeavailable) |
int |
parsestatement(TCustomSqlStatement pparentsql,
boolean isparsetreeavailable,
boolean onlyNeedRawParseTree)
Parse this statement.
|
protected TCTEList |
searchCTEList(Boolean stopAtFirstFinding) |
boolean |
searchDaxVariableInStack(TObjectName pName) |
TSQLFunction |
searchFunctionInSQLEnv(String functionName) |
void |
setAlreadyAddToParent(boolean alreadyAddToParent) |
void |
setCteIncludeThisStmt(TCTE cteIncludeThisStmt) |
void |
setCteList(TCTEList cteList) |
void |
setEndlabelName(TObjectName endlabelName) |
void |
setFrameStack(Stack<gudusoft.gsqlparser.compiler.TFrame> frameStack) |
void |
setFromClause(TFromClause fromClause) |
void |
setLabelName(TObjectName lName) |
void |
setOutputClause(TOutputClause outputClause) |
void |
setParentStmt(TCustomSqlStatement parentStmt) |
void |
setParentStmtToNull() |
void |
setQueryId(String queryId) |
void |
setResultColumnList(TResultColumnList resultColumnList) |
void |
setReturningClause(TReturningClause returningClause) |
void |
setSqlHash(String sqlHash) |
void |
setStmtScope(gudusoft.gsqlparser.compiler.TStmtScope stmtScope) |
void |
setTargetTable(TTable targetTable) |
void |
setTopClause(TTopClause topClause) |
void |
setUsingVariableList(TColumnDefinitionList usingVariableList) |
void |
setVariableStack(Stack<TObjectName> variableStack) |
void |
setWhereClause(TWhereClause newWhereClause) |
int |
size() |
String |
toNormalizedSql(TCustomSqlStatement.SqlNormalizationProfile profile)
Produce a normalized textual representation of this statement according
to the supplied profile.
|
String |
toScript()
Return the text string of this node, the return value is the same as
TParseTreeNode.toString() if this node is not modified manually
after created by parser. |
boolean |
VerticaStatementCanBeSeparatedByBeginEndPair() |
accept, acceptChildren, addAllMyTokensToTokenList, addToTokenChain, appendNewNode, calculateTokenCount, doAppendNewNode, doParse, fastSetString, getAnchorNode, getColumnNo, getCommentAfterNode, getCommentBeforeNode, getCompactString, getDummyTag, getEndToken, getEvaluateDatatype, getEvalValue, getGsqlparser, getLineNo, getLocation, getMd5, getNodeStatus, getNodeType, getPlainText, getStartToken, getTokenCount, hasNext, init, init, init, init, init, init, init, init, init, init, insertAfterAToken, insertNewNodeBeforeMe, isChanged, isTokensInChain, next, refreshAllNodesTokenCount, remove, removeAllMyTokensFromTokenList, removeTokens, removeTokensBetweenNodes, removeTokensBetweenToken, replaceWithNewNode, resetIterator, setAnchorNode, setChanged, setDummyTag, setEndToken, setEndToken, setEndToken, setEndToken, setEndToken, setEndTokenDirectly, setEvaluateDatatype, setEvalValue, setGsqlparser, setIncludingComment, setLocation, setNewSubNode, setNodeStatus, setNodeType, setParent, setPlainText, setStartToken, setStartToken, setStartToken, setStartToken, setStartTokenDirectly, setString, setString2, subNodeInNode, toString, toString2clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitforEachRemainingprotected ArrayList<TAttributeNode> relationAttributes
protected TFromClause fromClause
protected TTable fromSourceTable
protected TJoinExpr fromSourceJoin
public ESqlStatementType sqlstatementtype
public TSourceTokenList sourcetokenlist
TParseTreeNode.getStartToken(), and TParseTreeNode.getEndToken() of this statement.public TCustomParser parser
public TCustomParser plsqlparser
public int dummytag
public TJoinList joins
SQL 1:
select f from t1
size of joins will be 1, t1 can be fetch via joins.getJoin(0).getTable()
SQL 2:
select f from t1,t2
size of joins will be 2,
t1 can be fetch via joins.getJoin(0).getTable()
t2 can be fetch via joins.getJoin(1).getTable()
SQL 3:
select f from t1 join t2 on t1.f1 = t2.f1
size of joins will be 1,
t1 information can be fetch via joins.getJoin(0).getTable()
In order to access t2, we need to introduce a new class TJoinItem which includes all information about t2 and join condition.
There is a property named joinItems of TJoin which is type of TJoinItemList that includes a list of TJoinItem.
this property can be access via TJoin.getJoinItems().
Now, t2 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(0).getTable()
SQL 4:
select f from t1 join t2 on t1.f1 = t2.f1 join t3 on t1.f1 = t3.f1
size of joins will be 1,
t1 can be fetch via joins.getJoin(0).getTable()
t2 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(0).getTable()
t3 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(1).getTable()
tablespublic TTableList tables
It stores all tables in a flat way while joins stores all tables in a hierarchical structure.
joins only represents tables in from clause of select/delete statement, and tables in update/insert statement.
tables includes all tables in all types of SQL statements such as tables involved in a create table or create trigger statements.
public TParseTreeNode rootNode
public TSourceToken semicolonended
public boolean isctequery
protected boolean isparsed
protected gudusoft.gsqlparser.compiler.TStmtScope stmtScope
public TCustomSqlStatement(EDbVendor dbvendor)
public void setSqlHash(String sqlHash)
public String getSqlHash(boolean forceReCalculate)
Purpose:
statementKey
for lineage grouping: statementKey = sqlHash + "#" + queryId.getStartToken() and
getEndToken().TSQLEnv.columnCollationCaseSensitive).
For delimited identifiers (quoted identifiers), the quotes are
removed via TBaseType.removeQuoteChar(String)
before case normalization. String literals are kept as-is.normVersion + "\n" + vendor + "\n" + normalizedSql.getSqlHash(false) for cached result or lazy
calculation with Profile A (identity-safe) normalization.getSqlHash(true) to force recalculation (e.g., after
mutating the underlying token chain).computeSqlHash(SqlNormalizationProfile, String)
with TCustomSqlStatement.SqlNormalizationProfile.GROUPING_FRIENDLY.forceReCalculate - if true, recompute the hash even if a cached
value existspublic String getSqlHash()
getSqlHash(false).public String computeSqlHash(TCustomSqlStatement.SqlNormalizationProfile profile, String normVersion)
getSqlHash(boolean) for details.profile - normalization profilenormVersion - version tag embedded in the hash inputpublic String toNormalizedSql(TCustomSqlStatement.SqlNormalizationProfile profile)
TBaseType.removeQuoteChar(String) prior to case
handling.
- Minimal operator unification: "!=" becomes "<>".
- Profile B adds date/time string masking: '1970-01-01'.profile - normalization profilepublic void setQueryId(String queryId)
public String getQueryId()
The queryId provides a reliable way to reference any statement, including subqueries, within a parsed SQL script. It is generated hierarchically based on the statement's position within the Abstract Syntax Tree (AST), ensuring that the ID is reproducible across identical SQL inputs.
ID Format:
"stmt_0_select", where 0 is the index
of the statement in the script and select is the statement type.INSERT statement containing a SELECT subquery might have an ID for the
subquery like "stmt_0_insert#stmt_1_select".null if it has not been set.public void setUsingVariableList(TColumnDefinitionList usingVariableList)
public TColumnDefinitionList getUsingVariableList()
public ArrayList<TAttributeNode> getAttributes()
IRelationgetAttributes in interface IRelationpublic String getRelationName()
getRelationName in interface IRelationpublic String toScript()
TParseTreeNodeTParseTreeNode.toString() if this node is not modified manually
after created by parser.
TParseTreeNode.toString() method.toScript in class TParseTreeNodepublic void setFromClause(TFromClause fromClause)
public TFromClause getFromClause()
public ArrayList<TTable> getRelations()
getTables() and getJoins()after version 2.7.4.0
when a join is used in from clause, then the table in getRelations() is type of ETableSource.join, and you can
use TTable.getJoinExpr() to get this join.public TTable getFromSourceTable()
getFromSourceJoin() instead.public TJoinExpr getFromSourceJoin()
getFromSourceTable() insteadpublic String asCanonical()
public void setCteIncludeThisStmt(TCTE cteIncludeThisStmt)
public TCTE getCteIncludeThisStmt()
public TreeMap<String,TResultColumn> getExpandedResultColumns()
public TSQLFunction searchFunctionInSQLEnv(String functionName)
public gudusoft.gsqlparser.compiler.TGlobalScope getGlobalScope()
public void setFrameStack(Stack<gudusoft.gsqlparser.compiler.TFrame> frameStack)
public Stack<gudusoft.gsqlparser.compiler.TFrame> getFrameStack()
public TPTNodeList<TColumnWithSortOrder> getIndexColumns()
public void setVariableStack(Stack<TObjectName> variableStack)
public Stack<TObjectName> getVariableStack()
public Stack<TDaxFunction> getDaxFunctionStack()
public void setLabelName(TObjectName lName)
public TObjectName getLabelName()
public void setEndlabelName(TObjectName endlabelName)
public TObjectName getEndlabelName()
public TSourceTokenList getTokenList()
public TTable getTargetTable()
public void setTargetTable(TTable targetTable)
public TTableList getTables()
public TStatementList getStatements()
By iterating statements recursively, you can fetch all included statements in an easy way.
select f1+(select f2 from t2) from t1 where f2 > all (select f3 from t3 where f4 = (select f5 from t4))
Statements included in above SQL was save in a hierarchical way like this:
If this statement is a create procedure/function statement, then all declaration statements and statements in procedure body can also be fetched quickly by iterating this property recursively.
public void setCteList(TCTEList cteList)
public TCTEList getCteList()
TCTE can be specified following the single WITH keyword.
Each common table expression specified can also be referenced by name in the FROM clause of subsequent common table expressions.
Used in select, delete, update statement.
public void setResultColumnList(TResultColumnList resultColumnList)
public TResultColumnList getResultColumnList()
public void setReturningClause(TReturningClause returningClause)
public TReturningClause getReturningClause()
returning clause.public void setOutputClause(TOutputClause outputClause)
public TOutputClause getOutputClause()
public void setTopClause(TTopClause topClause)
public TTopClause getTopClause()
top clause.public void setWhereClause(TWhereClause newWhereClause)
public TWhereClause addWhereClause(String condition)
setWhereClause(TWhereClause) instead
Or, use TWhereClause.setText(String)condition - public TWhereClause getWhereClause()
where clause.public void setAlreadyAddToParent(boolean alreadyAddToParent)
protected TCTEList searchCTEList(Boolean stopAtFirstFinding)
public TCustomSqlStatement getParentStmt()
public TParseTreeNode getParentObjectName()
getParentObjectName in class TParseTreeNodepublic void setParentStmt(TCustomSqlStatement parentStmt)
public void setParentStmtToNull()
public TCustomSqlStatement getAncestorStmt()
public Stack getSymbolTable()
TStmtScope insteadpublic ArrayList<TSyntaxError> getSyntaxErrors()
public String getErrormessage()
public ArrayList<TSyntaxError> getSyntaxHints()
public int getErrorCount()
public EActionOnParseError parseerrormessagehandle(TSyntaxError se)
se - syntax error structure.public int parsestatement(TCustomSqlStatement pparentsql, boolean isparsetreeavailable)
public int parsestatement(TCustomSqlStatement pparentsql, boolean isparsetreeavailable, boolean onlyNeedRawParseTree)
pparentsql - isparsetreeavailable - public boolean OracleStatementCanBeSeparatedByBeginEndPair()
public boolean VerticaStatementCanBeSeparatedByBeginEndPair()
public boolean isnzplsql()
public boolean ispgplsql()
public boolean isGaussDBStoredProcedure()
public boolean isdatabricksplsql()
public boolean isgreeplumplsql()
public boolean isathenaplsql()
public boolean isprestoplsql()
public boolean issnowflakeplsql()
public boolean isBigQueryplsql()
public boolean isverticaplsql()
public boolean isoracleplsql()
protected int dochecksyntax(TCustomSqlStatement psql)
public void clearError()
public void setStmtScope(gudusoft.gsqlparser.compiler.TStmtScope stmtScope)
public gudusoft.gsqlparser.compiler.TStmtScope getStmtScope()
public int doParseStatement(TCustomSqlStatement psql)
public TTable analyzeTablename(TObjectName tableName)
protected boolean isTableACTE(TTable pTable)
public TTable findTable(ETableEffectType[] tableEffectTypes)
public void addToTables(TTable pTable)
public TJoin analyzeTableOrJoin(TFromTable pfromTable)
public TTable analyzeFromTable(TFromTable pfromTable, Boolean addToTableList)
public TTable analyzeFromTable(TFromTable pfromTable, Boolean addToTableList, ESqlClause pLocation)
public TJoin analyzeJoin(TJoinExpr pJoinExpr, TJoin pJoin, Boolean isSub)
public boolean locateVariableOrParameter(TObjectName cr)
public boolean locateVariableOrParameter(TObjectName cr, boolean checkVariableDeclaredInProcedure)
public ArrayList<String> getColumnsInTable(TTable lcTable)
TTable.getExpandedStarColumns() instead.lcTable - public ArrayList<String> getColumnsInTable(String pServer, String pDatabase, String pSchema, String pTable)
TTable.getExpandedStarColumns() instead.pServer - pDatabase - pSchema - pTable - public boolean fireOnMetaDatabaseTableColumn(String pServer, String pDatabase, String pSchema, String pTable, String pColumn)
public TTable getFirstPhysicalTable()
public TObjectNameList getOrphanColumns()
protected boolean linkToFirstTable(TObjectName pColumn, int pCandidateTableCnt)
public boolean searchDaxVariableInStack(TObjectName pName)
public boolean linkColumnToTable(TObjectName pColumn, ESqlClause pLocation)
linkToFirstTable(TObjectName, int)。
参数:pColumn - 需要绑定的列名对象(方法会更新其 location、sourceTable、sourceColumn 等)pLocation - 列出现的语法位置(如 selectList、where、insertValues 等)
返回值:linkColumnToTableDax(TObjectName, ESqlClause)
副作用:
- 更新 pColumn 的 location/searchLevel/sourceTable/sourceColumn/validate 状态
- 向命中的表写入 linkedColumns 或向别名列写入 targetColumns
- 对“*”列填充 sourceTableList;对子查询命中时可能将 TableToken 标为 subquery_alias
- 记录候选表数量并填充 pColumn.candidateTables,用于后续兜底
复杂度与顺序:
- 优先使用同层信息(别名/元数据/子查询结果),再逐层向外查找;避免无谓的上层搜索
注意:
- 本方法完成“旧算法”的快速联接,新的解析/消歧逻辑在解析器(如 TStmtScope/TAttributeResolver)中继续处理public void linkColumnReferenceToTable(TObjectName cr, ESqlClause plocation)
linkColumnToTable(gudusoft.gsqlparser.nodes.TObjectName, gudusoft.gsqlparser.ESqlClause) insteadpublic boolean checkNonQualifiedColumnReferenceInSubQueryOfUplevelStmt(TObjectName crf, boolean sameLevelOnly)
public TCustomSqlStatement getTopStatement()