001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.compiler.TStmtScope; 005import gudusoft.gsqlparser.nodes.hive.THiveKeyValueProperty; 006import gudusoft.gsqlparser.nodes.mssql.TForXMLClause; 007import gudusoft.gsqlparser.nodes.snowflake.TAtBeforeClause; 008import gudusoft.gsqlparser.nodes.snowflake.TStageReference; 009import gudusoft.gsqlparser.nodes.teradata.TTDUnpivot; 010import gudusoft.gsqlparser.resolver.TResolverHelpUtils; 011import gudusoft.gsqlparser.sqlenv.TSQLEnv; 012import gudusoft.gsqlparser.sqlenv.TSQLTable; 013import gudusoft.gsqlparser.stmt.TMergeSqlStatement; 014import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 015import gudusoft.gsqlparser.stmt.hive.THiveFromQuery; 016 017import java.util.ArrayList; 018 019/** 020 * Represents various kinds of table source in from clause. Can also be a simple table/view name in create table and all other places. 021 * result of {@link #getTableType} can be one of: 022 *<ul> 023 * <li>ftt_objectname, in from clause, a simple table/view name, reference: {@link TTable#tableName}<li> 024 * <li>ftt_subquery, is a subquery that retrieves rows from the database, also known as derived table. reference: {@link TTable#subquery}</li> 025 * <li>ftt_tableExpr,it's usually a table-valued expression., reference: {@link TTable#tableExpr}</li> 026 * <li>ftt_function, it's usually a table-valued function., reference: {@link TTable#funcCall}</li> 027 * <li>{@link ETableSource#rowList}, it's constructed rows, reference: {@link TTable#rowList}</li> 028 * <li>ftt_containsTable, CONTAINSTABLE clause of sql server. reference: {@link TTable#containsTable}, type of {@link TContainsTable}</li> 029 * <li>ftt_freetextTable, FREETEXTTABLE clause of sql server. reference: {@link TTable#containsTable}, type of {@link TContainsTable}</li> 030 * <li>ftt_openrowset, OPENROWSET clause of sql server. reference: {@link TTable#openRowSet}, type of {@link TOpenRowSet}</li> 031 * <li>ftt_openxml, OPENXML clause of sql server. reference: {@link TTable#openXML}, type of {@link TOpenXML }</li> 032 * <li>ftt_opendatasource, OPENDATASOURCE clause of sql server. reference: {@link TTable#openDatasource}, type of {@link TOpenDatasource}</li> 033 * <li>ftt_openquery, OPENQUERY clause of sql server. reference: {@link TTable#openquery}, type of (@link TOpenQuery)</li> 034 * </ul> 035 * 036 * 037*/ 038 039public class TTable extends TNodeWithAliasClause implements IRelation { 040 ArrayList<TAttributeNode> relationAttributes = new ArrayList<>(); 041 042 @Override 043 public ArrayList<TAttributeNode> getAttributes(){ 044 return relationAttributes; 045 } 046 047 @Override 048 public String getRelationName(){ 049 return this.getName(); 050 } 051 052 @Override 053 public int size(){ 054 return relationAttributes.size(); 055 } 056 057 public void setStageReference(TStageReference stageReference) { 058 this.stageReference = stageReference; 059 } 060 061 private TStageReference stageReference; 062 063 public TStageReference getStageReference() { 064 return stageReference; 065 } 066 private TAtBeforeClause timeTravelClause; 067 068 public void setTimeTravelClause(TAtBeforeClause timeTravelClause) { 069 this.timeTravelClause = timeTravelClause; 070 } 071 072 public TAtBeforeClause getTimeTravelClause() { 073 return timeTravelClause; 074 } 075 076 private TCaseJoinClause caseJoin; 077 078 public void setCaseJoin(TCaseJoinClause caseJoin) { 079 this.caseJoin = caseJoin; 080 } 081 082 public TCaseJoinClause getCaseJoin() { 083 return caseJoin; 084 } 085 086 public String getStageName(){ 087 if (this.getTableName() == null) return null; 088 if (this.getTableName().getDbObjectType() != EDbObjectType.stage) return null; 089 return this.getTableName().getObjectString(); 090 } 091 public final static String PIVOT_CLAUSE_ALIAS = "(pivot_table)"; 092 public final static String UNPIVOT_CLAUSE_ALIAS = "(unpivot_table)"; 093 public final static String TABLE_COLLECTION_ALIAS = "(table_collection)"; 094 095 096 boolean isAttributesInitialized = false; 097 098 public void initAttributeForXMLTable(){ 099 // if (isAttributesInitialized) return; 100 //relationAttributes.add(new TAttributeNode( getDisplayName()+".*",this)); 101 TAttributeNode.addNodeToList(new TAttributeNode( getDisplayName()+".*",this),relationAttributes); 102 isAttributesInitialized = true; 103 } 104 105 public void initAttributeForTableFunction(){ 106 // if (isAttributesInitialized) return; 107 //relationAttributes.add( new TAttributeNode( getDisplayName()+".value",this)); 108 TAttributeNode.addNodeToList(new TAttributeNode( getDisplayName()+".value",this),relationAttributes); 109 if (this.getName().equals("STRING_SPLIT")){ 110 // TRING_SPLIT函数生成的表只有两个字段:value和可选的ordinal 111 TAttributeNode.addNodeToList(new TAttributeNode( getDisplayName()+".ordinal",this),relationAttributes); 112 } 113 isAttributesInitialized = true; 114 } 115 116 public void initAttributeForRowList(){ 117 // if (isAttributesInitialized) return; 118 // relationAttributes.add( new TAttributeNode( getDisplayName()+".value",this)); 119 if (getValueClause() == null) return; 120 if (getValueClause().getRows().size() == 0) return; 121 122 int i = 0; 123 String columnName = ""; 124 TObjectNameList aliasColumnNameList = null; 125 // 1. 如果有 table alias 中指定 column, 遍历alias column 126 // 2. 如果 table alias 没有指定column, 遍历 subquery or values() 中的 resultcolumn 127 // 如果遍历alias column,可能存在 alias column 中column 数量和 subquery or values() 中的 resultcolumn 中不等的现象 128 // 例如 subquery or values() 中的 resultcolumn 中为 * column, 129 // 或者 snowflake 中的 pivot clause.(c:\prg\gsp_sqlfiles\TestCases\private\dataflow\snowflake\pivot_clause_1.sql) 130 131 TAliasClause aliasClause = this.getAliasClause(); 132 if (aliasClause != null){ 133 aliasColumnNameList = aliasClause.getColumns(); 134 } 135 for(TResultColumn resultColumn:getValueClause().getRows().get(0)){ 136 columnName = resultColumn.getDisplayName(); 137 if ((aliasColumnNameList != null)&&(aliasColumnNameList.size()>i)){ 138 columnName = aliasColumnNameList.getObjectName(i).getColumnNameOnly(); 139 } 140 TAttributeNode newNode = new TAttributeNode(this.getDisplayName() + "." + columnName, this, resultColumn); 141 //newNode.setAttributeCreatedFromAliasColumn(true); 142 //relationAttributes.add(newNode); 143 TAttributeNode.addNodeToList(newNode,relationAttributes); 144 i++; 145 } 146 147 TBaseType.log(String.format("Prepare attributes (num = %d) for rowList (values) : <%s>",this.getAttributes().size() ,this.getDisplayName()),TLog.DEBUG,this.getTableName()); 148 int c = 0; 149 for(TAttributeNode node: this.getAttributes()){ 150 TBaseType.log(String.format("\tAttribute: <%s>, result column: <%s>",node.getName(), node.getSubLevelResultColumn()!=null?node.getSubLevelResultColumn().toString():"N/A" ),TLog.DEBUG); 151 c++; 152 if (c > TLog.OUTPUT_ATTRIBUTES_MAX){ 153 TBaseType.log(String.format("\t...skipped after output %d attributes",c-1),TLog.DEBUG,this.getTableName().getStartToken()); 154 break; 155 } 156 } 157 158 159 isAttributesInitialized = true; 160 } 161 162 163 public void initAttributesFromCTE(TCTE cte){ 164 // if (isAttributesInitialized) return; 165 166 for (TAttributeNode node1 : cte.getAttributes()) { 167 TAttributeNode newNode = new TAttributeNode(this.getDisplayName() + "." + node1.getLastPartOfName(), this, node1.getSqlColumn(), node1.getSubLevelResultColumn()); 168 if (node1.getAccompaniedAttributeNodes().size() > 0){ 169 for(TAttributeNode n:node1.getAccompaniedAttributeNodes()){ 170 newNode.getAccompaniedAttributeNodes().add(n); 171 } 172 } 173 //relationAttributes.add(newNode); 174 TAttributeNode.addNodeToList(newNode,relationAttributes); 175 } 176 177 TBaseType.log(String.format("Prepare attributes (num = %d) for cte ref: <%s>",this.getAttributes().size() ,this.getTableName().toString()),TLog.DEBUG,this.getTableName()); 178 int c = 0; 179 for(TAttributeNode node: this.getAttributes()){ 180 if (node.getSqlColumn() != null){ 181 TBaseType.log(String.format("\tAttribute: <%s>, SQL column: <%s>",node.getName(), node.getSqlColumn()!=null?node.getSqlColumn().toString():"N/A" ),TLog.DEBUG); 182 }else{ 183 TBaseType.log(String.format("\tAttribute: <%s>, Select list column: <%s>",node.getName(), node.getSubLevelResultColumn()!=null?node.getSubLevelResultColumn().toString():"N/A" ),TLog.DEBUG); 184 } 185 c++; 186 if (c > TLog.OUTPUT_ATTRIBUTES_MAX){ 187 TBaseType.log(String.format("\t...skipped after output %d attributes",c-1),TLog.DEBUG,this.getTableName().getStartToken()); 188 break; 189 } 190 } 191 192 isAttributesInitialized = true; 193 } 194 public void initAttributesFromSubquery(TSelectSqlStatement subquery, String prefix){ 195 // TODO, not thread safe? 196 // if ((isAttributesInitialized) && (!relationAttributes.isEmpty())) return; 197 if (subquery.getResultColumnList() == null) return; 198 int i = 0; 199 if (subquery.getResultColumnList() != null) { 200 for(TResultColumn column: subquery.getResultColumnList()){ 201 if (column.getAliasNameList().size() > 0){ 202 // 如果 column 有 alias name list, 则遍历 alias name list, 并把每个 alias name 作为 attribute node 添加到 relationAttributes 中 203 // as (b1, b2, b3, b4, b5) 204 // select t.a1, t.a2, stack(2, 'T', t.a1, t.a2, t.a3/t.a4, t.a5/t.a6, 'T+0', t.a7, t.a8, t.a9/t.a10, t.a11/t.a12) as (b1, b2, b3, b4, b5) from db1.table1 t 205 206 for(TObjectName aliasName: column.getAliasNameList()){ 207 this.addAttribute(new TAttributeNode(prefix + TBaseType.removeQuoteChar(aliasName.toString()),this,column,i)); 208 i++; 209 } 210 }else { 211 if (column.getDisplayName().endsWith("*")){ 212 TObjectName objectName = column.getExpr().getObjectOperand(); 213 if (objectName.getAttributeNodesDerivedFromFromClause().size() > 0){ 214 for(TAttributeNode attributeNode:objectName.getAttributeNodesDerivedFromFromClause()){ 215 //relationAttributes.add(new TAttributeNode( prefix + attributeNode.getLastPartOfName() ,this, attributeNode.getSqlColumn(), column,i)); 216 this.addAttribute(new TAttributeNode( prefix + attributeNode.getLastPartOfName() ,this, attributeNode.getSqlColumn(), column,i)); 217 } 218 }else{ 219 // no attribute node derived from from clause, add the object name directly 220 //relationAttributes.add(new TAttributeNode(prefix +"*",this,column,i)); 221 this.addAttribute(new TAttributeNode(prefix +"*",this,column,i)); 222 } 223 }else{ 224 //relationAttributes.add(new TAttributeNode(prefix +column.getDisplayName(),this,column,i)); 225 this.addAttribute(new TAttributeNode(prefix +column.getDisplayName(),this,column,i)); 226 } 227 i++; 228 } 229 } 230 } 231 232 // 如果 subQuery 是 combined query, 需要把所有 query 中的 select list 都加入进来。上面处理的仅仅为最右面的那个 subQuery 233 if (subquery.isCombinedQuery()){ 234 TSelectSqlStatement left = subquery.getLeftStmt(); 235 addNewAttributeFromSubQuery(left.getResultColumnList(),relationAttributes,prefix); 236 while (left.isCombinedQuery()){ 237 left = left.getLeftStmt(); 238 addNewAttributeFromSubQuery(left.getResultColumnList(),relationAttributes,prefix); 239 } 240 } 241 isAttributesInitialized = true; 242 } 243 244 void addNewAttributeFromSubQuery(TResultColumnList resultColumnList, ArrayList<TAttributeNode> attributeNodes, String prefix){ 245 addNewAttributeFromSubQuery(resultColumnList,attributeNodes,prefix,null); 246 } 247 248 /** 249 * 当 subQuery 为 combined query 时,不仅仅把 right most 那个 subQuery 的 select list 作为 子查询的 attribute node list 添加上来 250 * 还需要把 其他 combined query 中的 subQuery 加入进来 251 * 252 * 253 * 254 * @param resultColumnList subQuery 中的 select list 255 * @param attributeNodes 需要在该 attribute node 的 getAccompaniedAttributeNodes() 中添加新 node 256 * @param prefix 该前缀为 subQuery 的 alias,或 CTE 的 name 决定 257 * @param specifiedColumnList 当 table 为 CTE 时,并且 CTE 自己指定了 column list, 那么 attribute node 的 name 由该 column list 决定, 258 * 而不是 subQuery 中的 select list 确定 259 * 260 */ 261 void addNewAttributeFromSubQuery(TResultColumnList resultColumnList, ArrayList<TAttributeNode> attributeNodes, String prefix, TObjectNameList specifiedColumnList){ 262 if (resultColumnList == null) return; 263 if (resultColumnList.size() != attributeNodes.size()){ 264 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 265 TBaseType.log(String.format("When add attribute from subQuery, the size of select list and attributes is not the same: %d <> %d",resultColumnList.size(),attributeNodes.size()) 266 ,TLog.ERROR,resultColumnList.getStartToken()); 267 } 268 return; 269 } 270 int i = 0; 271 for(TResultColumn column: resultColumnList){ 272 TAttributeNode node = attributeNodes.get(i); // 根据 i 的值,找到原来对应位置的 attribute node,用来添加 accompanied node 273 274 if (column.getDisplayName().endsWith("*")){ 275 TObjectName objectName = column.getExpr().getObjectOperand(); 276 for(TAttributeNode attributeNode:objectName.getAttributeNodesDerivedFromFromClause()){ 277 if (specifiedColumnList == null){ 278 node.getAccompaniedAttributeNodes().add(new TAttributeNode( prefix + attributeNode.getLastPartOfName() ,this, attributeNode.getSqlColumn(), column,i)); 279 }else{ 280 TObjectName c = specifiedColumnList.getObjectName(i); 281 node.getAccompaniedAttributeNodes().add(new TAttributeNode( prefix + c.toString() ,this, attributeNode.getSqlColumn(), column,i)); 282 } 283 } 284 }else{ 285 if (specifiedColumnList == null){ 286 node.getAccompaniedAttributeNodes().add(new TAttributeNode(prefix +column.getDisplayName(),this,column,i)); 287 }else{ 288 TObjectName c = specifiedColumnList.getObjectName(i); 289 node.getAccompaniedAttributeNodes().add(new TAttributeNode(prefix + c.toString(),this,column,i)); 290 } 291 } 292 i++; 293 } 294 } 295 296 public String getDisplayName(){ 297 if (getAliasClause() != null) return getAliasName(); 298 String ret = null; 299 switch (getTableType()){ 300 case objectname: 301 ret = getFullName(); 302 break; 303 case tableExpr: 304 ret = TTable.TABLE_COLLECTION_ALIAS; 305 break; 306 default: 307 ret = toString(); 308 break; 309 } 310 return ret; 311 } 312 /** 313 * 在 sql script 中,和该 relation 关联的 attribute。 314 * select a from t; 315 * attribute a 就是 relation t 的 referenceAttribute, 如果没有 metadata and ddl, 316 * relation t 的 relationAttributes 应该可以推断出包含 a, 但 t 是否还包含其他的 attribute 就无从得知。 317 */ 318 ArrayList<TObjectName> referenceAttributes = new ArrayList<>(); 319 320// public ArrayList<TObjectName> getReferenceAttributes(){ 321// return null; 322// } 323 324 public void initAttributesForPivotTable(){ 325 // if (isAttributesInitialized) return; 326 TPivotClause pivotClause = this.getPivotedTable().getPivotClauseList().getElement(0); 327 if (pivotClause.getType() == TPivotClause.pivot){ 328 329 // 先添加 pivot clause 中的 attribute,以防止 先处理 [p].[3] -> p.*, 而导致 [p].[3] -> [p].[3] 没能正确匹配 330 331 // SELECT [p].[ADDRESS_ID] 332 // ,[p].[3] AS ADDRESS_LINE3 333 // ,[p].[2] AS ADDRESS_LINE2 334 // ,[p].[1] AS ADDRESS_LINE1 FROM [ADDRESS_LINES_CTE] 335 // PIVOT(MAX(value) FOR id IN ([1],[2],[3])) p 336 337 //relationAttributes.addAll(pivotClause.getAttributes()); 338 TAttributeNode.addAllNodesToList(pivotClause.getAttributes(),relationAttributes); 339 340 TTable sourceTable = this.getPivotedTable().getRelations().get(0); 341 // 如果 pivot alias clause 不为空,整个table的 prefix 都用这个alias 342 // 否则使用当前table的display name 343 String prefix; 344 if (pivotClause.getAliasClause() != null){ 345 prefix = pivotClause.getDisplayName(); 346 }else{ 347 prefix = sourceTable.getDisplayName(); 348 } 349 350 for(TAttributeNode node: sourceTable.getAttributes()){ 351 //relationAttributes.add(new TAttributeNode(prefix+"."+ TBaseType.getLastPartOfQualifiedName(node.getName()),sourceTable,node.getSubLevelResultColumn())); 352 TAttributeNode.addNodeToList(new TAttributeNode(prefix+"."+ TBaseType.getLastPartOfQualifiedName(node.getName()),sourceTable,node.getSubLevelResultColumn()),relationAttributes); 353 } 354 355 356 } 357 358 isAttributesInitialized = true; 359 } 360 361 /** 362 * 主要是在处理列级别的信息, 363 * 它的主要目的是确保 JOIN 操作后的表对象包含所有参与 JOIN 的表的列信息,这对于后续的查询处理(特别是列引用解析)是必要的。 364 */ 365 public void initAttributesForJoin(){ 366 //if (isAttributesInitialized) return; 367 //relationAttributes.addAll(getJoinExpr().getAttributes()); 368 TAttributeNode.addAllNodesToList(getJoinExpr().getAttributes(),relationAttributes); 369 isAttributesInitialized = true; 370 } 371 372 public void initAttributesForUnnest(TSQLEnv sqlEnv, TSelectSqlStatement select ){ 373 // if (isAttributesInitialized) return; 374 if (this.getAliasClause() != null){ 375 if (this.getAliasClause().getColumns() != null){ 376 for(TObjectName pColumn:this.getAliasClause().getColumns()){ 377 //relationAttributes.add( new TAttributeNode( this.getDisplayName()+"."+pColumn.toString() ,this)); 378 TAttributeNode.addNodeToList(new TAttributeNode( this.getDisplayName()+"."+pColumn.toString() ,this),relationAttributes); 379 } 380 }else if (this.getAliasClause().getAliasName() != null){ 381// SELECT * 382// FROM UNNEST(['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred']) AS element 383// WITH OFFSET AS offset 384 // add element as column of unnest table. 385 if (this.getUnnestClause().getColumns() != null){ 386 // UNCOVERED_MOVE_Stage1 AS 387 // (SELECT 388 // Instrument_Partition_Key , 389 // Consolidation_Entity_Levels , 390 // FOTC_UDF_calc_uncovered_roll_off(ARRAY_AGG(STRUCT<Partition_Key STRING , Order_Number INT64 , Movement_In_Short FLOAT64 , Short_Increase_Uncovered FLOAT64 , Short_Increase_Covered_CS FLOAT64 , Short_Increase_Covered_RR FLOAT64> (Instrument_Partition_Key , Order_Number , Movement_In_Short_Balance_LCY , Short_Increase_Uncovered , Maturing_CS_Covering_Short_Increase , Maturing_RR_Covering_Short_Increase) 391 // ORDER BY Order_Number)) AS result_uncovered_moves , 392 // FOTC_UDF_calc_uncovered_roll_off(ARRAY_AGG(STRUCT<Partition_Key STRING , Order_Number INT64 , Movement_In_Short FLOAT64 , Short_Increase_Uncovered FLOAT64 , Short_Increase_Covered_CS FLOAT64 , Short_Increase_Covered_RR FLOAT64> (Instrument_Partition_Key , Order_Number , Movement_In_Short_Balance_LCY , Short_Increase_Uncovered_By_Settled_RR , Maturing_CS_Covering_Short_Increase , Maturing_Settled_RR_Covering_Short_Increase) 393 // ORDER BY Order_Number)) AS result_uncovered_by_settled_moves 394 // FROM SHORTS_COVERING_RR 395 // GROUP BY 396 // Instrument_Partition_Key , 397 // Consolidation_Entity_Levels) , 398 // UNCOVERED_MOVE AS 399 // (SELECT 400 // Consolidation_Entity_Levels , 401 // X.* , 402 // Y.uncovered_move AS Move_Uncovered_By_Settled_RR_Short , 403 // Y.covered_cs_move AS Move_Covered_By_Settled_CS_Short , 404 // Y.covered_rr_move AS Move_Covered_By_Settled_RR_Short 405 // FROM 406 // UNCOVERED_MOVE_Stage1 , 407 // UNNEST(result_uncovered_moves) AS X 408 // JOIN UNNEST(result_uncovered_by_settled_moves) AS Y ON X.Partition_Key = Y.Partition_Key 409 // AND X.order_key= Y.order_key) 410 411 // UNNEST(result_uncovered_moves) 中的 result_uncovered_moves 来自 ARRAY_AGG(), 412 // 这时候因为还没有进行 column resolver,所以无法知道 result_uncovered_moves 到底包含哪些 column 413 // 因为 UNNEST(result_uncovered_moves) AS X 指定了 X 作为 Alias, 因此增加 X.* 作为 attributeNode 414 // 不会导致问题。 415 416 ArrayList<String> tf = null; 417 TObjectName objectName = this.getUnnestClause().getColumns().getObjectName(0); 418 for(TTable table: select.getRelations()){ 419 if (TParseTreeNode.subNodeInNode(this,table)) break; 420 for(TAttributeNode attributeNode:table.getAttributes()){ 421 int matchResult = TStmtScope.matchAttribute(objectName.toString(), attributeNode.getName(),0,select); 422 if (matchResult == TBaseType.MATCH_COLUMN_RESULT_MATCHED ) { 423 objectName.setSourceTable2(select,attributeNode,table); 424 objectName.setSourceAttributeNode(attributeNode); 425 break; 426 } 427 } 428 if (objectName.getSourceAttributeNode() != null){ 429 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 430 TBaseType.log(String.format("Unnest table from source column: <%s>, linked to attribute node: <%s>" 431 ,objectName.toString(),objectName.getSourceAttributeNode().getName()),TLog.DEBUG,objectName); 432 } 433 434 // unnest(column), 其中的 column 可能对应array, 或者是 struct 435 // 找一下看看是否有 struct 436 437 tf = TResolverHelpUtils.searchTypedStruct(sqlEnv, objectName.getSourceAttributeNode().getSubLevelResultColumn()); 438 break; 439 } 440 } 441 if (tf != null){ 442 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 443 TBaseType.log(String.format("Prepare attribute node for unnest %s",this.getDisplayName()),TLog.DEBUG,this.getStartToken()); 444 } 445 for(String columnName:tf){ 446 TAttributeNode newNode = new TAttributeNode(String.format("%s.%s",this.getDisplayName(),columnName),this,objectName.getSourceAttributeNode().getSubLevelResultColumn()); 447 //relationAttributes.add(newNode); 448 TAttributeNode.addNodeToList(newNode,relationAttributes); 449 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 450 TBaseType.log(String.format("\t attribute node from struct: %s.%s with source column: %s" 451 , this.getDisplayName(),columnName, objectName.getSourceAttributeNode().getSubLevelResultColumn()==null?"N/A":objectName.getSourceAttributeNode().getSubLevelResultColumn().toString() ),TLog.DEBUG,this.getStartToken()); 452 } 453 } 454 }else{ 455 //relationAttributes.add( new TAttributeNode( this.getDisplayName()+".*",this)); 456 TAttributeNode.addNodeToList(new TAttributeNode( this.getDisplayName()+".*",this),relationAttributes); 457 } 458 459 }else{ 460 //relationAttributes.add( new TAttributeNode( this.getDisplayName()+"."+this.getAliasClause().getAliasName().toString() ,this)); 461 TAttributeNode.addNodeToList(new TAttributeNode( this.getDisplayName()+"."+this.getAliasClause().getAliasName().toString() ,this),relationAttributes); 462 } 463 } 464 }else{ 465 //SELECT value FROM UNNEST(nested_attribute) 466 // #TODO, 未处理 UNNEST 中的 nested_attribute, nested_attribute 一般是一个 struct,那么应该把 struct 中的 column 也加入进来 467 // 没有指定输出 column 的name,默认为 value 468 //relationAttributes.add( new TAttributeNode( this.getDisplayName()+"."+"value" ,this)); 469 TAttributeNode.addNodeToList(new TAttributeNode( this.getDisplayName()+"."+"value" ,this),relationAttributes); 470 } 471 472 for(int i=0;i<relationAttributes.size();i++){ 473 TAttributeNode node = relationAttributes.get(i); 474 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 475 TBaseType.log(String.format("Prepare attribute node <%d> for unnest %s: %s",i+1,this.getDisplayName(),node.getName()),TLog.DEBUG,this.getStartToken()); 476 } 477 } 478 479 isAttributesInitialized = true; 480 } 481 482 483 484 485// private ArrayList<String> expandedAttributes = new ArrayList<>(); 486// 487// public ArrayList<String> getExpandedAttributes() { 488// return expandedAttributes; 489// } 490 491 492 public void addAttribute(TAttributeNode node) { 493 if (node == null) return; 494 495 // 检查是否已存在同名节点 496 for (TAttributeNode existing : relationAttributes) { 497 if (existing.getName().equals(node.getName())) { 498 return; 499 } 500 } 501 502 //relationAttributes.add(node); 503 TAttributeNode.addNodeToList(node,relationAttributes); 504 } 505 506 private ArrayList<TObjectName> attributesReferenceToThisRelation = new ArrayList<>(); 507 508 public ArrayList<TObjectName> getAttributesReferenceToThisRelation() { 509 return attributesReferenceToThisRelation; 510 } 511 512// public boolean resolveAttribute(TObjectName attribute){ 513// boolean result = false; 514// if (attribute.isQualified()) { 515// result = attribute.resolveWithThisTable(this); 516// if (result) { 517// attributesReferenceToThisRelation.add(attribute); 518// attribute.setResolvedRelation(this); 519// } 520// return result; 521// } 522// if (this.getResolvedTable() != null){ 523// result = this.getResolvedTable().searchColumn(attribute.toString()); 524// if (result){ 525// attribute.setResolvedRelation(this); 526// return result; 527// } 528// } 529// return result; 530// } 531 532 private TSQLTable resolvedTable = null; 533 private boolean isResolved = false; 534 535 public void setResolvedTable(TSQLTable resolvedTable) { 536 this.resolvedTable = resolvedTable; 537 isResolved = true; 538 } 539 540 public void setResolved(boolean resolved) { 541 isResolved = resolved; 542 } 543 544 public TSQLTable getResolvedTable() { 545 return resolvedTable; 546 } 547 548 public boolean isResolved() { 549 return isResolved; 550 } 551 552 private ArrayList<TObjectName> columnsFromSQLEnv; 553 554 public ArrayList<TObjectName> getColumnsFromSQLEnv(TSQLEnv sqlEnv) { 555 if (columnsFromSQLEnv == null){ 556 columnsFromSQLEnv = new ArrayList<>(); 557 } 558 559 ArrayList<String> columns = sqlEnv.getColumnsInTable(this.tableName.toString(),true); 560 if (columns == null) return null; 561 562 for(String s:columns){ 563 TObjectName column = TObjectName.createObjectName(this.dbvendor, EDbObjectType.column,new TSourceToken(s)); 564 columnsFromSQLEnv.add(column); 565 } 566 567 return columnsFromSQLEnv; 568 } 569 570 private TJoinExpr joinExpr; 571 572 public void setJoinExpr(TJoinExpr joinExpr) { 573 this.joinExpr = joinExpr; 574 } 575 576 public TJoinExpr getJoinExpr() { 577 return joinExpr; 578 } 579 580 /** 581 * 该 table 对应的 sqlenv 中的 table 定义,包含具体的字段信息,有字段名称、数据类型等。 582 * 583 */ 584// private TSQLTable sqlTable; 585// 586// public void setSqlTable(TSQLTable sqlTable) { 587// this.sqlTable = sqlTable; 588// } 589// 590// public TSQLTable getSqlTable() { 591// return sqlTable; 592// } 593 594 595 596 private TForXMLClause forXMLClause; 597 598 public void setForXMLClause(TForXMLClause forXMLClause) { 599 this.forXMLClause = forXMLClause; 600 } 601 602 /** 603 * SQL Server for xml clause 604 * @return SQL Server for xml clause 605 */ 606 public TForXMLClause getForXMLClause() { 607 return forXMLClause; 608 } 609 610 private TColumnDefinitionList columnDefinitions; 611 612 public TColumnDefinitionList getColumnDefinitions() { 613 return columnDefinitions; 614 } 615 616 private TSQLEnv sqlEnv; 617 618 public void setSqlEnv(TSQLEnv sqlEnv) { 619 this.sqlEnv = sqlEnv; 620 } 621 622 public TSQLEnv getSqlEnv() { 623 return sqlEnv; 624 } 625 626 private TValueClause valueClause; 627 628 public TValueClause getValueClause() { 629 return valueClause; 630 } 631 632 public void setValueClause(TValueClause valueClause) { 633 this.valueClause = valueClause; 634 } 635 636 private TTable sourceTableOfPivot; 637 638 public void setSourceTableOfPivot(TTable sourceTableOfPivot) { 639 this.sourceTableOfPivot = sourceTableOfPivot; 640 } 641 642 public TTable getSourceTableOfPivot() { 643 return sourceTableOfPivot; 644 } 645 646 private TJsonTable jsonTable; 647 648 public void setJsonTable(TJsonTable jsonTable) { 649 this.jsonTable = jsonTable; 650 } 651 652 public TJsonTable getJsonTable() { 653 return jsonTable; 654 } 655 656 public void setPropertyFromObjectName(TObjectName objectName, ETableEffectType tableEffectType){ 657 setStartToken(objectName.getStartToken()); 658 setEndToken(objectName.getEndToken()); 659 setGsqlparser(objectName.getGsqlparser()); 660 setEffectType(tableEffectType); 661 setTableType(ETableSource.objectname); 662 } 663 private TTDUnpivot tdUnpivot; 664 665 public void setTdUnpivot(TTDUnpivot tdUnpivot) { 666 this.tdUnpivot = tdUnpivot; 667 } 668 669 public TTDUnpivot getTdUnpivot() { 670 671 return tdUnpivot; 672 } 673 674 private TUnnestClause unnestClause; 675 676 public void setUnnestClause(TUnnestClause unnestClause) { 677 this.unnestClause = unnestClause; 678 } 679 680 public TUnnestClause getUnnestClause() { 681 682 return unnestClause; 683 } 684 //select b.TemaTakipNo, b.SevkID, db.FromDepo, db.ToDepo, d.UrunID UrunID1, r.UrunID2, d.Miktar AsortiMiktar, r.Miktar ReceteMiktar 685 //into #tmpIrsaliye 686 /** 687 * list of columns in select list, used as metadata to determine whether a column belong to this temp table in TCustomSqlStatement.linkColumnToTable 688 */ 689 private TResultColumnList columnListInTempTable; 690 691 public void setColumnListInTempTable(TResultColumnList columnListInTempTable) { 692 this.columnListInTempTable = columnListInTempTable; 693 } 694 695 public TResultColumnList getColumnListInTempTable() { 696 697 return columnListInTempTable; 698 } 699 700 public void setPxGranule(TPxGranule pxGranule) { 701 this.pxGranule = pxGranule; 702 } 703 704 public TPxGranule getPxGranule() { 705 706 return pxGranule; 707 } 708 709 private TPxGranule pxGranule; 710 private TFlashback flashback; 711 712 public void setFlashback(TFlashback flashback) { 713 this.flashback = flashback; 714 } 715 716 public TFlashback getFlashback() { 717 return flashback; 718 } 719 720 private int parenthesisCount = 0; 721 private int parenthesisAfterAliasCount = 0; 722 private boolean tableKeyword = false; 723 private boolean onlyKeyword = false; 724 725 public void setTableKeyword(boolean tableKeyword) { 726 this.tableKeyword = tableKeyword; 727 } 728 729 public void setOnlyKeyword(boolean onlyKeyword) { 730 this.onlyKeyword = onlyKeyword; 731 } 732 733 public boolean isTableKeyword() { 734 735 return tableKeyword; 736 } 737 738 public boolean isOnlyKeyword() { 739 return onlyKeyword; 740 } 741 742 public void setParenthesisCount(int parenthesisCount) { 743 this.parenthesisCount = parenthesisCount; 744 } 745 746 public void setParenthesisAfterAliasCount(int parenthesisAfterAliasCount) { 747 this.parenthesisAfterAliasCount = parenthesisAfterAliasCount; 748 } 749 750 public int getParenthesisCount() { 751 752 return parenthesisCount; 753 } 754 755 public int getParenthesisAfterAliasCount() { 756 return parenthesisAfterAliasCount; 757 } 758 759 private TMergeSqlStatement outputMerge; 760 761 public void setOutputMerge(TMergeSqlStatement outputMerge) { 762 this.outputMerge = outputMerge; 763 } 764 765 public TMergeSqlStatement getOutputMerge() { 766 767 return outputMerge; 768 } 769 770 private TPivotedTable pivotedTable; 771 772 public void setPivotedTable(TPivotedTable pivotedTable) { 773 this.pivotedTable = pivotedTable; 774 } 775 776 public TPivotedTable getPivotedTable() { 777 778 return pivotedTable; 779 } 780 781 private ETableEffectType effectType; 782 783 public void setEffectType(ETableEffectType effectType) { 784 this.effectType = effectType; 785 } 786 787 public ETableEffectType getEffectType() { 788 789 return effectType; 790 } 791 792 private TTable linkTable; 793 794 public void setLinkTable(TTable linkTable) { 795 this.linkTable = linkTable; 796 isLinkTable = (this.linkTable != null); 797 } 798 799 public TTable getLinkTable() { 800 801 return linkTable; 802 } 803 804 public boolean isLinkTable() { 805 return isLinkTable; 806 } 807 808 /** 809 * @deprecated As of v1.8.4.6, set in {@link #setLinkTable} 810 */ 811 public void setLinkTable(boolean isLinkTable) { 812 813 this.isLinkTable = isLinkTable; 814 } 815 816 private boolean isLinkTable; 817 818 819 public String getAliasName(){ 820 if (getAliasClause() == null) return ""; 821 TObjectName aliasName = getAliasClause().getAliasName(); 822 return (aliasName == null) ? "" : aliasName.toString(); 823 } 824 825 public boolean equalByName(String pTableName){ 826 if (getAliasClause() != null){ 827 return getAliasClause().getAliasName().toString().equalsIgnoreCase(pTableName); 828 }else{ 829 return getName().equalsIgnoreCase(pTableName); 830 } 831 } 832 833 private TPTNodeList<THiveKeyValueProperty> tableProperties; 834 835 public void setTableProperties(TPTNodeList<THiveKeyValueProperty> tableProperties) { 836 this.tableProperties = tableProperties; 837 } 838 839 /** 840 * 841 * @return hive table property list 842 */ 843 844 public TPTNodeList<THiveKeyValueProperty> getTableProperties() { 845 return tableProperties; 846 } 847 848 private ArrayList<TLateralView> lateralViewList = null; 849 850 public void setLateralViewList(ArrayList<TLateralView> lateralViewList) { 851 this.lateralViewList = lateralViewList; 852 } 853 854 public ArrayList<TLateralView> getLateralViewList() { 855 return lateralViewList; 856 857 } 858 859 private TTableSample tableSample; 860 861 public void setTableSample(TTableSample tableSample) { 862 this.tableSample = tableSample; 863 } 864 865 public TTableSample getTableSample() { 866 867 return tableSample; 868 } 869 870 public void setPartitionExtensionClause(TPartitionExtensionClause partitionExtensionClause) { 871 this.partitionExtensionClause = partitionExtensionClause; 872 } 873 874 private TPartitionExtensionClause partitionExtensionClause; 875 876 public TPartitionExtensionClause getPartitionExtensionClause() { 877 return partitionExtensionClause; 878 } 879 880 public void setOuterClause(TInformixOuterClause outerClause) { 881 this.outerClause = outerClause; 882 } 883 884 public TInformixOuterClause getOuterClause() { 885 886 return outerClause; 887 } 888 889 private TInformixOuterClause outerClause; 890 891 private TXmlTable xmlTable; 892 893 private TFromTableList fromTableList; 894 895 public void setFromTableList(TFromTableList fromTableList) { 896 this.fromTableList = fromTableList; 897 } 898 899 public TFromTableList getFromTableList() { 900 901 return fromTableList; 902 } 903 904 public TXmlTable getXmlTable() { 905 return xmlTable; 906 } 907 908 public void setXmlTable(TXmlTable xmlTable) { 909 910 this.xmlTable = xmlTable; 911 } 912 913 private TOpenQuery openquery = null; 914 915 public void setTableHintList(TPTNodeList<TTableHint> tableHintList) { 916 this.tableHintList = tableHintList; 917 } 918 919 920 public TPTNodeList<TTableHint> getTableHintList() { 921 922 return tableHintList; 923 } 924 925 private TPTNodeList<TTableHint> tableHintList; 926 927 public TOpenQuery getOpenquery() { 928 return openquery; 929 } 930 931 public TSelectSqlStatement getSubquery() { 932 return subquery; 933 } 934 935 public void setOpenquery(TOpenQuery openquery) { 936 937 this.openquery = openquery; 938 } 939 940 public void setOpenDatasource(TOpenDatasource openDatasource) { 941 this.openDatasource = openDatasource; 942 } 943 944 /** 945 * Valid when {@link #tableType} is ftt_opendatasource. 946 * @return 947 */ 948 public TOpenDatasource getOpenDatasource() { 949 950 return openDatasource; 951 } 952 953 private TOpenDatasource openDatasource = null; 954 955 public void setOpenXML(TOpenXML openXML) { 956 this.openXML = openXML; 957 } 958 959 public TOpenXML getOpenXML() { 960 961 return openXML; 962 } 963 964 private TOpenXML openXML = null; 965 966 public TOpenRowSet getOpenRowSet() { 967 return openRowSet; 968 } 969 970 public void setOpenRowSet(TOpenRowSet openRowSet) { 971 972 this.openRowSet = openRowSet; 973 } 974 975 private TOpenRowSet openRowSet = null; 976 977 public TContainsTable getContainsTable() { 978 return containsTable; 979 } 980 981 public void setContainsTable(TContainsTable containsTable) { 982 this.containsTable = containsTable; 983 } 984 985 private TContainsTable containsTable = null; 986 987 public TFunctionCall getFuncCall() { 988 return funcCall; 989 } 990 991 public void setFuncCall(TFunctionCall funcCall) { 992 this.funcCall = funcCall; 993 } 994 995 996 private TFunctionCall funcCall = null; 997 998 private TMultiTargetList rowList; 999 1000 /** 1001 * @deprecated As of v2.3.6.9, please use {@link #getValueClause()} instead 1002 * 1003 * row constructor like this: '(' RW_VALUES MultiTargets ')' 1004 * @return TMultiTargetList 1005 */ 1006 public TMultiTargetList getRowList() { 1007 return rowList; 1008 } 1009 1010 public boolean isBaseTable(){ 1011 boolean retval = (tableType == ETableSource.objectname); 1012 if (retval){ 1013 if (isCTEName()){ 1014 retval = false; 1015 } 1016 } 1017 1018 if (retval){ 1019 if (getFullName().startsWith("@")) { 1020 retval = false; 1021 } 1022 } 1023 return retval; 1024 } 1025 1026 public void setCteColomnReferences(TObjectNameList cteColomnReferences) { 1027 this.cteColomnReferences = cteColomnReferences; 1028 } 1029 1030 private TObjectNameList cteColomnReferences = null; 1031 1032 public TObjectNameList getCteColomnReferences() { 1033 return cteColomnReferences; 1034 } 1035 1036 public void setObjectNameReferences(TObjectNameList objectNameReferences) { 1037 1038 this.objectNameReferences = objectNameReferences; 1039 } 1040 1041 private TCTE CTE; 1042 1043 public boolean setCTE(TCTE pCTE) { 1044 if (pCTE == null){ 1045 this.CTE = null; 1046 return true; 1047 } 1048 1049 if ((!pCTE.isRecursive()) && (pCTE.getSubquery() != null) && (TParseTreeNode.subNodeInNode(this,pCTE.getSubquery()))){ 1050 // 如果这个table是属于一个CTE的子查询,那么不再设置CTE,因为该table不可能是该CTE的引用, 但前提条件是 1051 // 1. 该 subquery 非 combined query 1052 // 2. 如果该 subquery 是 combined query , 该 table 属于第一个subquery 中的 table 1053 1054 // 如果不是以上两种情况,那么该table就是该CTE的引用,需要返回 true 1055 // refer to: public void testSearchTable1() 1056 1057 if (!pCTE.getSubquery().isCombinedQuery()) return false; 1058 1059 if (TParseTreeNode.subNodeInNode(this,pCTE.getSubquery().getLeftStmt())){ 1060 return false; 1061 } 1062 1063 } 1064 1065 this.CTE = pCTE; 1066 return true; 1067 } 1068 1069 public TCTE getCTE() { 1070 1071 return CTE; 1072 } 1073 1074 public boolean isCTEName() { 1075 1076 return isCTEName; 1077 } 1078 1079 public void setCTEName(boolean CTEName) { 1080 isCTEName = CTEName; 1081 } 1082 1083 private boolean isCTEName = false; 1084 1085 public TSelectSqlStatement subquery = null; 1086 private THiveFromQuery hiveFromQuery; 1087 1088 public void setHiveFromQuery(THiveFromQuery hiveFromQuery) { 1089 this.hiveFromQuery = hiveFromQuery; 1090 } 1091 1092 /** 1093 * @deprecated As of v2.1.0.0, please use {@link #getSubquery()} 1094 * @return 1095 */ 1096 public THiveFromQuery getHiveFromQuery() { 1097 1098 return hiveFromQuery; 1099 } 1100 1101 public TExpression getTableExpr() { 1102 return tableExpr; 1103 } 1104 1105 public void setTableExpr(TExpression tableExpr) { 1106 this.tableExpr = tableExpr; 1107 } 1108 1109 private TExpression tableExpr; 1110 1111 public void setTableType(ETableSource tableType) { 1112 this.tableType = tableType; 1113 } 1114 1115 /** 1116 * 1117 * @return what's kind of type this table is. 1118 *<ul> 1119 * <li>{@link ETableSource#objectname}, in from clause, a simple table/view name, reference: {@link TTable#tableName}<li> 1120 * <li>{@link ETableSource#subquery}, is a subquery that retrieves rows from the database, also known as derived table. reference: {@link TTable#subquery}</li> 1121 * <li>{@link ETableSource#tableExpr},it's usually a table-valued expression., reference: {@link TTable#tableExpr}</li> 1122 * <li>{@link ETableSource#function}, it's usually a table-valued function., reference: {@link TTable#funcCall}</li> 1123 * <li>{@link ETableSource#rowList}, it's constructed rows, reference: {@link TTable#rowList}</li> 1124 * <li>{@link ETableSource#containsTable}, CONTAINSTABLE clause of sql server. reference: {@link TTable#containsTable}, type of {@link TContainsTable}</li> 1125 * <li>{@link ETableSource#freetextTable}, FREETEXTTABLE clause of sql server. reference: {@link TTable#containsTable}, type of {@link TContainsTable}</li> 1126 * <li>{@link ETableSource#openrowset}, OPENROWSET clause of sql server. reference: {@link TTable#openRowSet}, type of {@link TOpenRowSet}</li> 1127 * <li>{@link ETableSource#openxml}, OPENXML clause of sql server. reference: {@link TTable#openXML}, type of {@link TOpenXML }</li> 1128 * <li>{@link ETableSource#opendatasource}, OPENDATASOURCE clause of sql server. reference: {@link TTable#openDatasource}, type of {@link TOpenDatasource}</li> 1129 * <li>{@link ETableSource#openquery}, OPENQUERY clause of sql server. reference: {@link TTable#openquery}, type of (@link TOpenQuery)</li> 1130 * </ul> 1131 */ 1132 public ETableSource getTableType() { 1133 1134 return tableType; 1135 } 1136 1137 private ETableSource tableType; 1138 1139 public void setTableName(TObjectName tableName) { 1140 this.tableName = tableName; 1141 tableType = ETableSource.objectname; 1142 this.tableName.splitNameInQuotedIdentifier(); 1143 if (this.getStartToken() == null){ 1144 this.setStartToken(tableName.getStartToken()); 1145 } 1146 1147 if (this.getEndToken() == null){ 1148 this.setEndToken(tableName.getEndToken()); 1149 } 1150 } 1151 1152 public TObjectName getTableName() { 1153 TObjectName ret = tableName; 1154 1155 if (tableType == null) return ret; 1156 1157 switch (tableType){ 1158 case tableExpr: 1159 if (tableExpr.getExpressionType() == EExpressionType.function_t){ 1160 ret = tableExpr.getFunctionCall().getFunctionName(); 1161 } 1162 break; 1163 case function: 1164 ret = getFuncCall().getFunctionName(); 1165 break; 1166 case openrowset: 1167 ret = TObjectName.createObjectName (this.dbvendor, EDbObjectType.table,new TSourceToken("openrowset")); 1168 break; 1169 case rowList: 1170 ret = TObjectName.createObjectName (this.dbvendor, EDbObjectType.table,new TSourceToken("(values_table)")); 1171 break; 1172 case subquery: 1173 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("subquery")); 1174 break; 1175 case td_unpivot: 1176 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("td_unpivot")); 1177 break; 1178 case pivoted_table: 1179 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken(tableName+"(piviot_table)")); 1180 break; 1181 case xmltable: 1182 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("xmltable")); 1183 break; 1184 case jsonTable: 1185 ret = getJsonTable().getFunctionName();// TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("jsontable"));// 1186 break; 1187 case containsTable: 1188 if (containsTable.getType() == TContainsTable.containstable){ 1189 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("containsTable")); 1190 }else { 1191 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("freetexttable")); 1192 } 1193 break; 1194 case opendatasource: 1195 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("opendatasource")); 1196 break; 1197 case unnest: 1198 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken(getAliasName()+"(unnest table)")); 1199 break; 1200 case openxml: 1201 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("openxml")); 1202 break; 1203 case openquery: 1204 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("openquery")); 1205 break; 1206 case output_merge: 1207 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("merge")); 1208 break; 1209 case externalTable: 1210 ret = this.tableName; 1211 break; 1212 case join: 1213 ret = TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("join_expr")); 1214 break; 1215 } 1216 if (ret == null) { 1217 return TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,new TSourceToken("unknown")); 1218 } 1219 else return ret; 1220 } 1221 1222 private TObjectName tableName; 1223 1224 public TTable(TObjectName pobjectname){ 1225 this.tableName = pobjectname; 1226 this.setStartToken(this.tableName.getStartToken()); 1227 this.setEndToken(this.tableName.getEndToken()); 1228 } 1229 1230 1231 public TTable(){ 1232 this.tableName = null; 1233 } 1234 1235 public String getName() { 1236 if (tableName != null) 1237 return tableName.getObjectString(); 1238 else 1239 return getTableName().toString(); 1240 } 1241 1242 1243 public String getPrefixServer(){ 1244 if (tableName != null) return tableName.getServerString(); 1245 else return ""; 1246 } 1247 public String getPrefixDatabase(){ 1248 if (tableName != null) return tableName.getDatabaseString(); 1249 else return ""; 1250 } 1251 public String getPrefixSchema(){ 1252 if (tableName != null) return tableName.getSchemaString(); 1253 else return ""; 1254 } 1255 1256 public boolean isIncludeColumnAlias(){ 1257 // return (this.getAliasClause() != null); 1258 return false; 1259 // ToDo 1260 } 1261 1262 1263 public int searchColumnInAlias(TObjectName pColumn){ 1264 if (getAliasClause() == null) return -1; 1265 return getAliasClause().searchColumn(pColumn); 1266 } 1267 1268 public boolean checkTableByName(String pTablename){ 1269 boolean lcResult = false; 1270 String a,b,c; 1271 b = TBaseType.getTextWithoutQuoted(pTablename); 1272 if (this.getAliasClause() != null){ 1273 a = TBaseType.getTextWithoutQuoted(this.getAliasName()); 1274 lcResult = a.equalsIgnoreCase(b); 1275 } 1276 if (lcResult) return true; 1277 c = TBaseType.getTextWithoutQuoted(this.getTableName().toString()); 1278 lcResult = c.equalsIgnoreCase(b); 1279 return lcResult; 1280 } 1281 1282 public boolean searchColumn(TSelectSqlStatement select, String tableName, TObjectName pColumn, boolean pMustIn){ 1283 // pColumn maybe qualified, so check the table name at first 1284 boolean lcResult = false, isSameTable = false; 1285 if ( tableName.length() == 0){ 1286 isSameTable = true; 1287 }else { 1288 isSameTable = checkTableByName(tableName); 1289 } 1290 1291 if (!isSameTable) return lcResult; 1292 1293 if (this.isBaseTable()){ 1294 lcResult = select.fireOnMetaDatabaseTableColumn(this.getPrefixServer(),this.getPrefixDatabase(),this.getPrefixSchema(),this.getName(),pColumn.getColumnNameOnly()); 1295 }else{ 1296 if (this.getTableType() == ETableSource.subquery){ 1297 if (this.isIncludeColumnAlias()){ 1298 lcResult = this.searchColumnInAlias(pColumn)>=0; 1299 }else{ 1300 lcResult = this.getSubquery().searchColumnInResultSet(pColumn,pMustIn); 1301 } 1302 }else if (this.isCTEName()){ 1303 lcResult = this.getCTE().searchColumnInResultSet(select,this,pColumn,pMustIn); 1304 } 1305 } 1306 1307 if (lcResult){ 1308 this.getLinkedColumns().addObjectName(pColumn); 1309 pColumn.setSourceTable(this); 1310 }else if (pMustIn){ 1311 this.getLinkedColumns().addObjectName(pColumn); 1312 pColumn.setSourceTable(this); 1313 lcResult = true; 1314 } 1315 1316 if (!lcResult){ 1317 if (this.getTableType() == ETableSource.pivoted_table){ 1318 if (this.getLinkedColumns().size() > 0){ 1319 for(TObjectName c: this.getLinkedColumns()){ 1320 lcResult = c.toString().equalsIgnoreCase(pColumn.getColumnNameOnly()); 1321 if (lcResult) break; 1322 } 1323 } 1324 } 1325 } 1326 1327 return lcResult; 1328 } 1329 1330 private TObjectNameList linkedColumns = null; 1331 1332 public TObjectNameList getLinkedColumns() { 1333 if (linkedColumns == null) { 1334 linkedColumns = new TObjectNameList(); 1335 linkedColumns.setObjectType(TObjectName.ttobjColumn); 1336 } 1337 return linkedColumns; 1338 } 1339 1340 1341 1342 public String getFullNameWithAliasString() { 1343 if (getAliasClause() != null){ 1344 return getFullName()+" "+getAliasClause().toString(); 1345 }else{ 1346 return getFullName(); 1347 } 1348 } 1349 1350 public String getFullName() { 1351 if (tableName == null) return null; 1352 return tableName.toString(); 1353 /* 1354 if (tableName.getSchemaString() == null) 1355 {return this.getName();} 1356 else{ 1357 return tableName.getSchemaString()+"."+this.getName(); 1358 } 1359 */ 1360 1361 } 1362 1363 /** 1364 * 1365 * @return column name related to this table. 1366 * @deprecated As of v1.6.0.1, use {@link #getLinkedColumns()} instead 1367 */ 1368 public TObjectNameList getObjectNameReferences() { 1369 if (objectNameReferences == null){ 1370 objectNameReferences = new TObjectNameList(); 1371 objectNameReferences.setObjectType(TObjectName.ttobjColumn); 1372 } 1373 return objectNameReferences; 1374 } 1375 1376 private TPivotClause pivotClause = null; 1377 1378 public void setPivotClause(TPivotClause pivotClause) { 1379 this.pivotClause = pivotClause; 1380 } 1381 1382 /** 1383 * @deprecated As of v1.6.2.4, replaced by {@link gudusoft.gsqlparser.nodes.TPivotedTable} 1384 * @return 1385 */ 1386 public TPivotClause getPivotClause() { 1387 1388 return pivotClause; 1389 } 1390 1391 /** 1392 * Stored all column names that belong to this table. 1393 */ 1394 private TObjectNameList objectNameReferences = null; 1395 1396 public TTableReferenceList tablerefs = new TTableReferenceList(); 1397 1398 private TDataChangeTable datachangeTable = null; 1399 1400 public void setDatachangeTable(TDataChangeTable datachangeTable) { 1401 this.datachangeTable = datachangeTable; 1402 } 1403 1404 /** 1405 * DB2 data change 1406 * @return 1407 */ 1408 public TDataChangeTable getDatachangeTable() { 1409 return datachangeTable; 1410 } 1411 1412 1413 public boolean isTableRefBelongToThisTable(TTableReference tableref){ 1414 1415 boolean retval = (this.tableName == tableref.objectname); 1416 if (retval) {return retval;} 1417 if (this.tableName.getObjectString().equalsIgnoreCase(tableref.objectname.getObjectString())){ 1418 if ((this.tableName.getSchemaString() == null) 1419 ||(tableref.objectname.getSchemaString() == null) 1420 ) { 1421 retval = true; 1422 }else{ 1423 retval = (this.tableName.getSchemaString().equalsIgnoreCase(tableref.objectname.getSchemaString())); 1424 } 1425 } 1426 return retval; 1427 } 1428 1429 public void accept(TParseTreeVisitor v){ 1430 v.preVisit(this); 1431 1432 v.postVisit(this); 1433 } 1434 1435 public void setColumnDefinitions(TColumnDefinitionList columnDefinitions) { 1436 this.columnDefinitions = columnDefinitions; 1437 } 1438 1439 public void acceptChildren(TParseTreeVisitor v){ 1440 v.preVisit(this); 1441 1442 switch(getTableType()){ 1443 case objectname:{ 1444 getTableName().acceptChildren(v); 1445 if (getFlashback() != null){ 1446 getFlashback().acceptChildren(v); 1447 } 1448 break; 1449 } 1450 case tableExpr:{ 1451 getTableExpr().acceptChildren(v); 1452 break; 1453 } 1454 case subquery:{ 1455 getSubquery().acceptChildren(v); 1456 break; 1457 } 1458 case function:{ 1459 getFuncCall().acceptChildren(v); 1460 break; 1461 } 1462 case pivoted_table:{ 1463 if (this.getEffectType() == ETableEffectType.tetPivot) break; 1464 getPivotedTable().acceptChildren(v); 1465 break; 1466 } 1467 case output_merge:{ 1468 //e_table_reference.setTextContent(node.getOutputMerge().toString()); 1469 break; 1470 } 1471 case containsTable:{ 1472 getContainsTable().acceptChildren(v); 1473 break; 1474 } 1475 1476 case openrowset:{ 1477 getOpenRowSet().acceptChildren(v); 1478 break; 1479 } 1480 1481 case openxml:{ 1482 getOpenXML().acceptChildren(v); 1483 break; 1484 } 1485 1486 case opendatasource:{ 1487 getOpenDatasource().acceptChildren(v); 1488 break; 1489 } 1490 1491 case openquery:{ 1492 getOpenquery().acceptChildren(v); 1493 break; 1494 } 1495 1496 case datachangeTable:{ 1497 getDatachangeTable().acceptChildren(v); 1498 break; 1499 } 1500 case rowList:{ 1501 getValueClause().acceptChildren(v); 1502 break; 1503 } 1504 case xmltable:{ 1505 getXmlTable().acceptChildren(v); 1506 break; 1507 } 1508 case jsonTable:{ 1509 getJsonTable().acceptChildren(v); 1510 break; 1511 } 1512 case informixOuter:{ 1513 getOuterClause().acceptChildren(v); 1514 break; 1515 } 1516 1517 case table_ref_list:{ 1518 getFromTableList().acceptChildren(v); 1519 break; 1520 } 1521 case hiveFromQuery:{ 1522 getHiveFromQuery().acceptChildren(v); 1523 break; 1524 } 1525 case externalTable: 1526 this.columnDefinitions.acceptChildren(v); 1527 break; 1528 case join: 1529 this.joinExpr.acceptChildren(v); 1530 break; 1531 case unnest: 1532 this.getUnnestClause().acceptChildren(v); 1533 break; 1534 default: 1535 //sb.append(node.toString().replace(">",">").replace("<","<")); 1536 break; 1537 1538 } 1539 1540 1541 if (getPxGranule() != null){ 1542 getPxGranule().acceptChildren(v); 1543 } 1544 1545 if (getTableSample() != null){ 1546 getTableSample().acceptChildren(v); 1547 } 1548 1549 if (getAliasClause() != null){ 1550 getAliasClause().acceptChildren(v); 1551 } 1552 1553 1554 if (getTableHintList() != null){ 1555 for(int i=0;i<getTableHintList().size();i++){ 1556 TTableHint tableHint = getTableHintList().getElement(i); 1557 tableHint.acceptChildren(v); 1558 } 1559 } 1560 1561 if (getLateralViewList() != null){ 1562 for(TLateralView lateralView:getLateralViewList()){ 1563 lateralView.acceptChildren(v); 1564 } 1565 } 1566 1567 1568 v.postVisit(this); 1569 } 1570 1571 public void setRowList(TMultiTargetList rowList) { 1572 this.rowList = rowList; 1573 } 1574 1575 public void setSubquery(TSelectSqlStatement subquery) { 1576 this.subquery = subquery; 1577 } 1578 1579 public void setLinkedColumns(TObjectNameList linkedColumns) { 1580 this.linkedColumns = linkedColumns; 1581 } 1582 1583 public void setTablerefs(TTableReferenceList tablerefs) { 1584 this.tablerefs = tablerefs; 1585 } 1586 1587 private boolean starColumnExpanded = false; 1588 1589 private ArrayList<String> expandedStarColumns = new ArrayList<String>(); 1590 1591 private void getExpandStarColumnsFromSubquery(TSelectSqlStatement subquery, ArrayList<String> expandedStarColumns){ 1592 1593 for(TResultColumn resultColumn:subquery.getResultColumnList()){ 1594 if (resultColumn.toString().endsWith("*")){ 1595 TTable srcTable = resultColumn.getExpr().getObjectOperand().getSourceTable(); 1596 if ( srcTable!= null){ 1597 ArrayList<String> list = srcTable.getExpandedStarColumns(); 1598 expandedStarColumns.addAll(list); 1599 } 1600 }else{ 1601 expandedStarColumns.add(resultColumn.getDisplayName()); 1602 } 1603 } 1604 } 1605 1606 /** 1607 * If a star column is linked to this table, use this method to returns all underlying columns that represented by 1608 * the star column. 1609 * <br> 1610 * <br> The returned column always prefixed with 1611 * <br> 1. the table alias. 1612 * <br> 2. the table name 1613 * <br> 3. the alias of query (if the table is a subquery) 1614 * <br> 4. empty if the no alias is specified for a subquery 1615 * 1616 * @return a list of columns 1617 */ 1618 public ArrayList<String> getExpandedStarColumns(){ 1619 if (starColumnExpanded) return expandedStarColumns; 1620 1621 switch (getTableType()){ 1622 case objectname: 1623 if (this.isCTEName()){ 1624 if (this.getCteColomnReferences()!=null){ 1625 for(TObjectName n:this.getCteColomnReferences()){ 1626 expandedStarColumns.add(n.toString()); 1627 } 1628 }else if (this.getCTE().getSubquery() != null){ 1629 this.getExpandStarColumnsFromSubquery(this.getCTE().getSubquery(),this.expandedStarColumns); 1630 } 1631 }else{ 1632 if (this.getSqlEnv() != null){ 1633 ArrayList<String> columns = this.getSqlEnv().getColumnsInTable(this.getPrefixDatabase() +"."+this.getPrefixSchema()+"."+this.getName(),false); 1634 if (columns != null) expandedStarColumns = columns; 1635 if (this.getAliasClause() != null){ 1636 //replace table name with alias 1637 } 1638 } 1639 if ((expandedStarColumns.size() == 0)&&(getLinkedColumns().size()>0)){ 1640 for(TObjectName linkColumn:getLinkedColumns()){ 1641 if (linkColumn.toString().endsWith("*")) continue; 1642 String s = linkColumn.getColumnNameOnly(); 1643 if (this.getAliasClause() != null){ 1644 s = this.getAliasName()+"."+s; 1645 }else{ 1646 s = this.getName()+"."+s; 1647 } 1648 if (expandedStarColumns.indexOf(s) == -1) expandedStarColumns.add(s); 1649 } 1650 } 1651 } 1652 1653 break; 1654 case subquery: 1655 this.getExpandStarColumnsFromSubquery(this.getSubquery(),this.expandedStarColumns); 1656 break; 1657 default: 1658 break; 1659 } 1660 1661 starColumnExpanded = true; 1662 return expandedStarColumns; 1663 } 1664 1665// @Override 1666// public String toString(){ 1667// if (getAliasClause() != null) return getAliasClause().toString(); 1668// 1669// switch (getTableType()){ 1670// case objectname: 1671// return getName().toString(); 1672// break; 1673// default: 1674// 1675// break; 1676// } 1677// } 1678 1679 @Override 1680 public String toString(){ 1681 String ret = super.toString(); 1682 if (ret != null) return ret; 1683 if (tableName != null) return tableName.getObjectString(); 1684 return null; 1685 } 1686 1687}