001package gudusoft.gsqlparser; 002 003 004import gudusoft.gsqlparser.compiler.*; 005import gudusoft.gsqlparser.nodes.*; 006import gudusoft.gsqlparser.nodes.dax.TDaxFunction; 007import gudusoft.gsqlparser.scriptWriter.TScriptGenerator; 008import gudusoft.gsqlparser.sqlenv.TSQLEnv; 009import gudusoft.gsqlparser.sqlenv.TSQLFunction; 010import gudusoft.gsqlparser.stmt.*; 011import gudusoft.gsqlparser.stmt.dax.TDaxStmt; 012import gudusoft.gsqlparser.stmt.oracle.*; 013import gudusoft.gsqlparser.util.functionChecker; 014import gudusoft.gsqlparser.util.keywordChecker; 015 016import java.util.ArrayList; 017import java.util.Stack; 018import java.util.TreeMap; 019 020/** 021 * TCustomSqlStatement is the root class for all SQL statements. 022 */ 023public class TCustomSqlStatement extends TParseTreeNode implements IRelation{ 024 025 public void setUsingVariableList(TColumnDefinitionList usingVariableList) { 026 this.usingVariableList = usingVariableList; 027 } 028 029 private TColumnDefinitionList usingVariableList; 030 031 /* 032 * Variables defined in teradata using clause. 033 * */ 034 public TColumnDefinitionList getUsingVariableList() { 035 return usingVariableList; 036 } 037 038 protected ArrayList<TAttributeNode> relationAttributes = new ArrayList<>(); 039 040 @Override 041 public ArrayList<TAttributeNode> getAttributes(){ 042 // if (relationAttributes.size() != 0) return relationAttributes; 043 relationAttributes.clear(); 044 for(TTable table:relations){ 045 //relationAttributes.addAll(table.getAttributes()); 046 TAttributeNode.addAllNodesToList(table.getAttributes(),relationAttributes); 047 } 048 049 return relationAttributes; 050 } 051 052 @Override 053 public String getRelationName(){ 054 return null; 055 } 056 057 @Override 058 public int size(){ 059 return relationAttributes.size(); 060 } 061 062 @Override 063 public String toScript(){ 064 String ret = super.toScript(); 065 if ((ret == null)||(ret.isEmpty())){ 066 ret = this.toString(); 067 }else{ 068 if ((this.getEndToken() != null) && (this.getEndToken().tokencode == ';')) { 069 if (!ret.endsWith(";")){ 070 ret = ret + ";"; 071 } 072 } 073 } 074 return ret; 075 } 076 077 protected TFromClause fromClause; 078 079 public void setFromClause(TFromClause fromClause) { 080 this.fromClause = fromClause; 081 } 082 083 public TFromClause getFromClause() { 084 return fromClause; 085 } 086 087 /** 088 * Relations that used in from clause of select statement. 089 * Or tables of other statements such as insert, update, delete and etc 090 * 091 * Please use this property to get the relations instead of {@link #getTables()} and {@link #getJoins()}after version 2.7.4.0 092 * 093 * when a join is used in from clause, then the table in getRelations() is type of ETableSource.join, and you can 094 * use TTable.getJoinExpr() to get this join. 095 * 096 * @return 097 */ 098 public ArrayList<TTable> getRelations() { 099 return relations; 100 } 101 102 private ArrayList<TTable> relations = new ArrayList<>(); 103 104 protected TTable fromSourceTable; 105 106 /** 107 * This is table in from clause if only one table is listed in the from clause, 108 * If more than one table is listed in from clause, please check {@link #getFromSourceJoin()} instead. 109 * 110 * @return table in from clause 111 */ 112 public TTable getFromSourceTable() { 113 return fromSourceTable; 114 } 115 116 /** 117 * This is a join in from clause, including left and right relation. 118 * If only a single table is listed in from clause, please use {@link #getFromSourceTable()} instead 119 * @return 120 */ 121 public TJoinExpr getFromSourceJoin() { 122 return fromSourceJoin; 123 } 124 125 protected TJoinExpr fromSourceJoin; 126 127 private String asCanonicalText = null; 128 129 /** 130 * this method return a canonical form of a SQL statement in plan text. 131 * <br>1. remove all comment inside SQL query. 132 * <br>2. remove redundant parenthesis at the begin/end of a select statement. 133 * <br>3. replace all number in where clause with 999 constant 134 * <br>4. replace all string constant in where clause with 'placeholder_str' 135 * <br>5. all number elements in a list such as (1,2,3,4) will be change to a single element (999) 136 * <br>6. all string elements in a list such as ('a','b','c','d') will be change to a single element ('placeholder_str') 137 * 138 * @return a canonical form of a SQL statement in plan text. 139 */ 140 public String asCanonical(){ 141 if (asCanonicalText != null) return asCanonicalText; 142 143 String ret = null; 144 TSourceToken lcStartToken = getStartToken(); 145 if (lcStartToken == null) return toString(); 146 TSourceToken lcEndToken = getEndToken(); 147 if (lcEndToken == null) return toString(); 148 149 // remove the ; token at the end of statement 150 if (lcEndToken.tokencode == ';') lcEndToken.tokenstatus = ETokenStatus.tsdeleted; 151 152 153 // remove ( ) at the begin and end of the statement 154 TSourceToken lcCurrentToken = lcStartToken; 155 while (lcCurrentToken != null){ 156 if (lcCurrentToken.tokencode != '(') { 157 break; 158 }else{ 159 if (lcCurrentToken.getLinkToken() != null){ 160 lcCurrentToken.tokenstatus = ETokenStatus.tsdeleted; 161 lcCurrentToken.getLinkToken().tokenstatus = ETokenStatus.tsdeleted; 162 } 163 } 164 165 if (lcCurrentToken.equals(lcEndToken)){ 166 break; 167 }else{ 168 lcCurrentToken = lcCurrentToken.getNextTokenInChain(); 169 } 170 } 171 172 // change constant to placeholder, all number change to 999 and string constant change to placeholder_str 173 constantVisitor cv = new constantVisitor(); 174 this.acceptChildren(cv); 175 176 177 boolean chainUnchanged = true, includingComment = false; 178 StringBuffer sb = new StringBuffer(""); 179 TSourceToken lcPrevSt = null; 180 boolean ignoreNextReturnToken = false, isChainModified = false; 181 182 lcCurrentToken = lcStartToken; 183 while (lcCurrentToken != null){ 184 if((lcCurrentToken.tokenstatus == ETokenStatus.tsdeleted) 185 ||(!includingComment && ((lcCurrentToken.tokencode == TBaseType.cmtslashstar) ||(lcCurrentToken.tokencode == TBaseType.cmtdoublehyphen))) 186 ){ 187 // ignore this token, do nothing 188 //System.out.println("out: ignore deleted token:"+lcCurrentToken.astext); 189 }else{ 190 // 191 sb.append(lcCurrentToken.toString()); 192 if (lcCurrentToken.isChangedInAsCanonical()){ 193 lcCurrentToken.restoreText(); 194 } 195 } 196 197 if (lcCurrentToken.equals(lcEndToken)){ 198 break; 199 }else{ 200 lcCurrentToken = lcCurrentToken.getNextTokenInChain(); 201 } 202 203 } 204 asCanonicalText = sb.toString(); 205 return asCanonicalText; 206 } 207 208 private TCTE cteIncludeThisStmt = null; 209 210 public void setCteIncludeThisStmt(TCTE cteIncludeThisStmt) { 211 this.cteIncludeThisStmt = cteIncludeThisStmt; 212 } 213 214 public TCTE getCteIncludeThisStmt() { 215 return cteIncludeThisStmt; 216 } 217 218 private TreeMap<String,TResultColumn> expandedResultColumns = null; 219 220 public TreeMap<String,TResultColumn> getExpandedResultColumns() { 221 if (expandedResultColumns == null){ 222 expandedResultColumns = new TreeMap<>(); 223 } 224 return expandedResultColumns; 225 } 226 227 public TSQLFunction searchFunctionInSQLEnv(String functionName){ 228 if (getSqlEnv() == null) return null; 229 return getSqlEnv().searchFunction(functionName); 230 } 231 232 public TSQLEnv getSqlEnv() { 233 if (getGlobalScope() == null) return null; 234 return getGlobalScope().getSqlEnv(); 235 } 236 237 public TGlobalScope getGlobalScope() { 238 TGlobalScope lcResult = null; 239 if (frameStack != null){ 240 if (frameStack.get(0) != null){ 241 lcResult = (TGlobalScope)frameStack.get(0).getScope(); 242 } 243 } 244 return lcResult; 245 } 246 247 private Stack<TFrame> frameStack; 248 249 public void setFrameStack(Stack<TFrame> frameStack) { 250 this.frameStack = frameStack; 251 } 252 253 public Stack<TFrame> getFrameStack() { 254 return frameStack; 255 } 256 257 private TPTNodeList<TColumnWithSortOrder> indexColumns = null; 258 259 public TPTNodeList<TColumnWithSortOrder> getIndexColumns() { 260 return indexColumns; 261 } 262 263 private Stack<TObjectName> variableStack = null; 264 265 public void setVariableStack(Stack<TObjectName> variableStack) { 266 this.variableStack = variableStack; 267 } 268 269 public Stack<TObjectName> getVariableStack() { 270 if (variableStack == null){ 271 variableStack = new Stack<TObjectName>(); 272 } 273 274 return variableStack; 275 } 276 277 private Stack<TDaxFunction> daxFunctionStack = null; 278 279 public Stack<TDaxFunction> getDaxFunctionStack() { 280 if (daxFunctionStack == null){ 281 daxFunctionStack = new Stack<TDaxFunction>(); 282 } 283 return daxFunctionStack; 284 } 285 286 private TObjectName labelName; 287 288 public void setLabelName(TObjectName lName) { 289 labelName = lName; 290 if (labelName != null){ 291 //labelName.setObjectType(TObjectName.ttobjLabelName); 292 labelName.setDbObjectType(EDbObjectType.label); 293 } 294 } 295 296 /** 297 * 298 * @return label name used in plsql statement. 299 */ 300 public TObjectName getLabelName() { 301 302 return labelName; 303 } 304 305 306 private TObjectName endlabelName; 307 308 public void setEndlabelName(TObjectName endlabelName) { 309 this.endlabelName = endlabelName; 310 } 311 312 public TObjectName getEndlabelName() { 313 314 return endlabelName; 315 } 316 317 /** 318 * Type of this statement. 319 */ 320 public ESqlStatementType sqlstatementtype; 321 /** 322 * Source tokens included in this statement. only source tokens available when this is a top level statement, otherwise, there is no source token in this statement. 323 * Please check {@link gudusoft.gsqlparser.nodes.TParseTreeNode#getStartToken()}, and {@link gudusoft.gsqlparser.nodes.TParseTreeNode#getEndToken()} of this statement. 324 */ 325 public TSourceTokenList sourcetokenlist; 326 327 public TSourceTokenList getTokenList() { 328 return sourcetokenlist; 329 } 330 /** 331 * Parser used to parse this statement. 332 */ 333 public TCustomParser parser; 334 /** 335 * PLSQL parser used to parse this statement. 336 */ 337 public TCustomParser plsqlparser; 338 /** 339 * Tag used by parser internally. 340 */ 341 public int dummytag; 342 343 /** 344 * target table in the delete/insert/update/create table statement. 345 * @see #joins 346 * @see TSelectSqlStatement 347 * @see TDeleteSqlStatement 348 * @see TUpdateSqlStatement 349 * @see TCreateTableSqlStatement 350 * @see gudusoft.gsqlparser.stmt.TMergeSqlStatement 351 */ 352 public TTable getTargetTable() { 353 return targetTable; 354 } 355 356 public void setTargetTable(TTable targetTable) { 357 setNewSubNode(this.targetTable,targetTable,getAnchorNode()); 358 this.targetTable = targetTable; 359 } 360 361 private TTable targetTable ; 362 363 /** 364 * joins represents table sources in the from clause. All structure information was reserved. 365 * <p>SQL 1: 366 * <p><blockquote><pre>select f from t1</pre></blockquote> 367 * <p>size of joins will be 1, t1 can be fetch via joins.getJoin(0).getTable() 368 * <p> 369 * <p>SQL 2: 370 * <p><blockquote><pre>select f from t1,t2</pre></blockquote> 371 * <p>size of joins will be 2, 372 * <p>t1 can be fetch via joins.getJoin(0).getTable() 373 * <p>t2 can be fetch via joins.getJoin(1).getTable() 374 * <p> 375 * <p>SQL 3: 376 * <p><blockquote><pre>select f from t1 join t2 on t1.f1 = t2.f1</pre></blockquote> 377 * <p>size of joins will be 1, 378 * <p>t1 information can be fetch via joins.getJoin(0).getTable() 379 * <p>In order to access t2, we need to introduce a new class {@link TJoinItem} which includes all information about t2 and join condition. 380 * <p>There is a property named joinItems of {@link TJoin} which is type of {@link TJoinItemList} that includes a list of {@link TJoinItem}. 381 * <p>this property can be access via {@link gudusoft.gsqlparser.nodes.TJoin#getJoinItems()}. 382 * <p>Now, t2 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(0).getTable() 383 * <p> 384 * <p>SQL 4: 385 * <p><blockquote><pre>select f from t1 join t2 on t1.f1 = t2.f1 join t3 on t1.f1 = t3.f1</pre></blockquote> 386 * <p>size of joins will be 1, 387 * <p>t1 can be fetch via joins.getJoin(0).getTable() 388 * <p>t2 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(0).getTable() 389 * <p>t3 can be fetch via joins.getJoin(0).getJoinItems().getJoinItem(1).getTable() 390 * 391 * @see #tables 392 */ 393 public TJoinList joins; 394 395 /** 396 * Provides a quick way to access all tables involved in this SQL statement. 397 * <p>It stores all tables in a flat way while {@link #joins} stores all tables in a hierarchical structure. 398 * <p>joins only represents tables in from clause of select/delete statement, and tables in update/insert statement. 399 * <p>{@link #tables} includes all tables in all types of SQL statements such as tables involved in a create table or create trigger statements. 400 */ 401 public TTableList tables; 402 403 public TJoinList getJoins() { 404 return joins; 405 } 406 407 public TTableList getTables() { 408 return tables; 409 } 410 411 /** 412 * Saves all first level sub statements. 413 * <p>By iterating statements recursively, you can fetch all included statements in an easy way. 414 * <p><blockquote><pre> 415 * select f1+(select f2 from t2) from t1 416 * where f2 > all (select f3 from t3 where f4 = (select f5 from t4))</pre> 417 * </blockquote> 418 * <p> Statements included in above SQL was save in a hierarchical way like this: 419 * <ul> 420 * <li>(select f2 from t2)</li> 421 * <li>(select f3 from t3 where f4 = (select f5 from t4)) 422 * <ul> 423 * <li>(select f5 from t4)</li> 424 * </ul> 425 * </li> 426 * </ul> 427 * <p>If this statement is a create procedure/function statement, then all declaration statements and statements in 428 * procedure body can also be fetched quickly by iterating this property recursively. 429 * 430 * 431 */ 432 public TStatementList getStatements() { 433 if (statements == null){ 434 statements = new TStatementList(); 435 } 436 return statements; 437 } 438 439 private TStatementList statements; 440 441 public void setCteList(TCTEList cteList) { 442 setNewSubNode(this.cteList,cteList,getAnchorNode()); 443 this.cteList = cteList; 444 } 445 446 /** 447 * Multiple common table expressions {@link TCTE} can be specified following the single WITH keyword. 448 *<p> Each common table expression specified can also be referenced by name in the FROM clause of subsequent common table expressions. 449 * 450 * <p>Used in select, delete, update statement. 451 * @return List of common table expression. 452 */ 453 454 public TCTEList getCteList() { 455 456 return cteList; 457 } 458 459 private TCTEList cteList = null; 460 461 public void setResultColumnList(TResultColumnList resultColumnList) { 462 setNewSubNode(this.resultColumnList,resultColumnList,getAnchorNode()); 463 this.resultColumnList = resultColumnList; 464 } 465 466 /** 467 * In select statement, this method returns Items in select_list. 468 * Can be *, expr, and name.* 469 * <br><br> 470 * In update statement, this method returns assignments in set clause. 471 * 472 * @return select list of select statement or assignments of update statement. 473 */ 474 public TResultColumnList getResultColumnList() { 475 476 return resultColumnList; 477 } 478 479 private TResultColumnList resultColumnList = null; 480 481 private TWhereClause whereClause = null; 482 private TTopClause topClause = null; 483 private TOutputClause outputClause = null; 484 private TReturningClause returningClause = null; 485 486 public void setReturningClause(TReturningClause returningClause) { 487 setNewSubNode(this.returningClause,returningClause,getAnchorNode()); 488 this.returningClause = returningClause; 489 } 490 491 /** 492 * @return {@link TReturningClause returning clause.} 493 */ 494 495 public TReturningClause getReturningClause() { 496 497 return returningClause; 498 } 499 500 public void setOutputClause(TOutputClause outputClause) { 501 setNewSubNode(this.outputClause,outputClause,getAnchorNode()); 502 this.outputClause = outputClause; 503 } 504 505 /** 506 * @return output clause. 507 */ 508 509 public TOutputClause getOutputClause() { 510 511 return outputClause; 512 } 513 514 public void setTopClause(TTopClause topClause) { 515 setNewSubNode(this.topClause,topClause,getAnchorNode()); 516 this.topClause = topClause; 517 } 518 519 /** 520 * @return {@link TTopClause top clause.} 521 */ 522 public TTopClause getTopClause() { 523 return topClause; 524 } 525 526 public void setWhereClause(TWhereClause newWhereClause){ 527 setNewSubNode(this.whereClause ,newWhereClause,getAnchorNode()); 528 this.whereClause = newWhereClause; 529 } 530 531 532 /** 533 * @deprecated As of 2.0.9.0, use {@link #setWhereClause(TWhereClause)} instead 534 * Or, use {@link TWhereClause#setText(String)} 535 * 536 * @param condition 537 * @return 538 */ 539 public TWhereClause addWhereClause(String condition){ 540 return this.whereClause; 541 } 542 543 /** 544 * restrict the rows selected to those that satisfy one or more conditions. 545 * used in select, delete, update statement. 546 * @return {@link TWhereClause where clause.} 547 */ 548 public TWhereClause getWhereClause() { 549 return whereClause; 550 } 551 552 public void setAlreadyAddToParent(boolean alreadyAddToParent) { 553 this.alreadyAddToParent = alreadyAddToParent; 554 } 555 556 private boolean alreadyAddToParent = false; 557 558 private boolean ableToIncludeCTE(ESqlStatementType sst){ 559 return ((sst == ESqlStatementType.sstselect) 560 ||(sst == ESqlStatementType.sstupdate) 561 ||(sst == ESqlStatementType.sstinsert) 562 ||(sst == ESqlStatementType.sstdelete) 563 ); 564 } 565 566 private TCTEList cteListInAllLevels = new TCTEList(); 567 568 protected TCTEList searchCTEList(Boolean stopAtFirstFinding){ 569 cteListInAllLevels.clear(); 570 if (cteList != null ) { 571 cteListInAllLevels.addAll(cteList); 572 if (stopAtFirstFinding) return cteListInAllLevels; 573 } 574 575 TCustomSqlStatement lcParent = this.parentStmt; 576 while (lcParent != null){ 577 if (!ableToIncludeCTE(lcParent.sqlstatementtype)) break; 578 579 if (lcParent.cteList != null) { 580 cteListInAllLevels.addAll(lcParent.cteList); 581 if (stopAtFirstFinding) break; 582 } 583 lcParent = lcParent.parentStmt; 584 } 585 return cteListInAllLevels; 586 } 587 588 589// protected TCTEList searchCTEList(){ 590// TCTEList ret = null; 591// if (cteList != null ) {return cteList;} 592// TCustomSqlStatement lcParent = this.parentStmt; 593// while (lcParent != null){ 594// if (!ableToIncludeCTE(lcParent.sqlstatementtype)) break; 595// ret = lcParent.cteList; 596// if (ret != null) break; 597// lcParent = lcParent.parentStmt; 598// } 599// return ret; 600// } 601 602 public TCustomSqlStatement getParentStmt() { 603 return parentStmt; 604 } 605 606 public TParseTreeNode getParentObjectName(){ 607 TParseTreeNode result = super.getParentObjectName(); 608 if (result != null) return result; 609 return getParentStmt(); 610 } 611 612 public void setParentStmt(TCustomSqlStatement parentStmt) { 613 if (!alreadyAddToParent){ 614 this.parentStmt = parentStmt; 615 if (this.parentStmt != null){ 616 parentStmt.getStatements().add(this); 617 alreadyAddToParent = true; 618 } 619 } 620 } 621 622 public void setParentStmtToNull() { 623 this.parentStmt = null; 624 } 625 626 private TCustomSqlStatement ancestorStmt = null; 627 628 public TCustomSqlStatement getAncestorStmt() { 629 TCustomSqlStatement lcRet = this; 630 while (lcRet.getParentStmt() != null){ 631 lcRet = lcRet.getParentStmt(); 632 } 633 return lcRet; 634 } 635 636 /** 637 * parent statement of this statement if any 638 */ 639 private TCustomSqlStatement parentStmt = null; 640 641 /** 642 * Original Parse tree node from parser 643 */ 644 public TParseTreeNode rootNode; 645 646 private Stack symbolTable = null; 647 648 /** 649 * 650 * @deprecated since ver 2.5.3.5, please use {@link TStmtScope} instead 651 */ 652 public Stack getSymbolTable() { 653 if (symbolTable == null){ 654 symbolTable = new Stack(); 655 } 656 return symbolTable; 657 } 658 659 TSourceToken semicolonended; 660 boolean isctequery; 661 private ArrayList <TSyntaxError> syntaxErrors; 662 663 public ArrayList<TSyntaxError> getSyntaxErrors() { 664 return syntaxErrors; 665 } 666 667 public String getErrormessage(){ 668 669 String s="",hint="Syntax error"; 670 TSyntaxError t; 671 for (int i= 0; i< syntaxErrors.size(); i++) 672 { 673 t = (TSyntaxError) syntaxErrors.get(i); 674 if (t.hint.length() > 0) hint = t.hint; 675 s= s+hint+"("+t.errorno+") near: "+t.tokentext; 676 s=s+"("+t.lineNo; 677 s=s+","+t.columnNo +")"; 678 //s=s+" expected tokentext:"+t.hint; 679 680 // break;//get only one message, remove this one and uncomment next line to get all error messages 681 if (i != syntaxErrors.size() - 1) 682 s = s +TBaseType.linebreak; 683 } 684 685 return s; 686 } 687 688 public ArrayList<TSyntaxError> getSyntaxHints() { 689 return syntaxHints; 690 } 691 692 private ArrayList <TSyntaxError> syntaxHints; 693 694 protected boolean isparsed; 695 TSourceToken _semicolon; 696 697 /** 698 * Number of syntax errors for this statement. 699 * @return 0 means no syntax error. 700 */ 701 public int getErrorCount() { 702 return syntaxErrors.size(); 703 } 704 705 706 public TCustomSqlStatement(EDbVendor dbvendor){ 707 super(); 708 this.dbvendor = dbvendor; 709 sqlstatementtype = ESqlStatementType.sstunknown; 710 dummytag = 0; 711 sourcetokenlist = new TSourceTokenList(); 712 syntaxErrors = new ArrayList<TSyntaxError>(4); 713 syntaxHints = new ArrayList<TSyntaxError>(4); 714 tables = new TTableList(); 715 joins = new TJoinList(); 716 indexColumns = new TPTNodeList<TColumnWithSortOrder>(); 717 } 718 719 /** 720 * Log error messages if syntax errors found while parsing this statement. 721 * @param se syntax error structure. 722 * @return type of error 723 */ 724 public EActionOnParseError parseerrormessagehandle(TSyntaxError se){ 725 if (se.errortype == EErrorType.sphint){ 726 this.getAncestorStmt().syntaxHints.add(se); 727 }else 728 this.getAncestorStmt().syntaxErrors.add(se); 729 return EActionOnParseError.aopcontinue; 730 } 731 732 public int parsestatement(TCustomSqlStatement pparentsql,boolean isparsetreeavailable){ 733 return parsestatement(pparentsql,isparsetreeavailable,false); 734 } 735 736 /** 737 * Parse this statement. 738 * @param pparentsql 739 * @param isparsetreeavailable 740 * @return parse result, zero means no syntax error found. 741 */ 742 public int parsestatement(TCustomSqlStatement pparentsql,boolean isparsetreeavailable, boolean onlyNeedRawParseTree){ 743 int ret = 0; 744 isparsed = false; 745 if (!isparsetreeavailable){ 746 ret = checksyntax(pparentsql); 747 } 748 if (ret == 0) 749 { 750 isparsed = true; 751 if (!onlyNeedRawParseTree){ 752 ret = doParseStatement(pparentsql); 753 } 754 }else if (dbvendor == EDbVendor.dbvsybase){ 755 if ((this.rootNode != null)&& 756 ((sqlstatementtype == ESqlStatementType.sstmssqlcreateprocedure) 757 ||(sqlstatementtype == ESqlStatementType.sstmssqlcreatefunction) 758 ||(sqlstatementtype == ESqlStatementType.sstcreatetrigger) 759 )){ 760 if (!onlyNeedRawParseTree){ 761 doParseStatement(pparentsql); 762 } 763 764 } 765 } 766 return ret; 767 } 768 769 public boolean OracleStatementCanBeSeparatedByBeginEndPair(){ 770 return ( 771 772 (this.sqlstatementtype == ESqlStatementType.sstplsql_createprocedure) 773 //|| (this.sqlstatementtype == ESqlStatementType.sst_block_with_label) 774 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createfunction) 775 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createpackage) 776 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtype_placeholder) 777 ||(this.sqlstatementtype == ESqlStatementType.sstoraclecreatepackagebody) 778 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtrigger) 779// ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtypebody) 780// ||(this.sqlstatementtype == ESqlStatementType.sstplsql_tabletypedef) 781 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_varraytypedef) 782 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createprocedure) 783 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_execimmestmt) 784 ||(this.sqlstatementtype == ESqlStatementType.sstoraclecreatelibrary) 785 ); 786 } 787 788 public boolean VerticaStatementCanBeSeparatedByBeginEndPair(){ 789 return ( 790 791 (this.sqlstatementtype == ESqlStatementType.sstcreatefunction) 792 ); 793 } 794 795 public boolean isnzplsql(){ 796 return ( 797 (this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 798 ); 799 } 800 801 public boolean ispgplsql(){ 802 return (this instanceof TCommonBlock) 803 ||(this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 804 ||(this.sqlstatementtype == ESqlStatementType.sstcreatefunction) 805 ||(this.sqlstatementtype == ESqlStatementType.sstDoExecuteBlock) 806 ; 807 } 808 809 public boolean isGaussDBStoredProcedure(){ 810 return (this instanceof TCommonBlock) 811 ||(this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 812 ||(this.sqlstatementtype == ESqlStatementType.sstcreatefunction) 813 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createpackage) 814 ||(this.sqlstatementtype == ESqlStatementType.sstoraclecreatepackagebody) 815 ||(this.sqlstatementtype == ESqlStatementType.sstDoExecuteBlock) 816 ; 817 } 818 819 public boolean isdatabricksplsql(){ 820 return (this instanceof TCommonBlock) 821 ; 822 } 823 824 public boolean isgreeplumplsql(){ 825 return (this instanceof TCommonBlock) 826 ||(this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 827 ||(this.sqlstatementtype == ESqlStatementType.sstcreatefunction) 828 ||(this.sqlstatementtype == ESqlStatementType.sstDoExecuteBlock) 829 ; 830 } 831 832 public boolean isathenaplsql(){ 833 return (this instanceof TCommonBlock) 834 ; 835 } 836 837 public boolean isprestoplsql(){ 838 return (this instanceof TCommonBlock) 839 ; 840 } 841 842 public boolean issnowflakeplsql(){ 843 return ((this instanceof TCommonBlock) 844 ||(this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 845 ); 846 } 847 848 public boolean isBigQueryplsql(){ 849 return ((this instanceof TCommonBlock) 850 ||(this.sqlstatementtype == ESqlStatementType.sstcreateprocedure) 851 ); 852 } 853 854 public boolean isverticaplsql(){ 855 return ( 856 (this.sqlstatementtype == ESqlStatementType.sstcreatefunction) 857 ); 858 } 859 860 public boolean isoracleplsql(){ 861 return ( 862 (this.sqlstatementtype == ESqlStatementType.sst_plsql_block) 863 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createprocedure) 864 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createfunction) 865 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createpackage) 866 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtype_placeholder) 867 ||(this.sqlstatementtype == ESqlStatementType.sstoraclecreatepackagebody) 868 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtrigger) 869 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createtypebody) 870 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_tabletypedef) 871 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_varraytypedef) 872 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_createprocedure) 873 ||(this.sqlstatementtype == ESqlStatementType.sstplsql_execimmestmt) 874 ||(this.sqlstatementtype == ESqlStatementType.sstoraclecreatelibrary) 875 ); 876 } 877 878 int checksyntax(TCustomSqlStatement psql){ 879 return dochecksyntax(psql); 880 } 881 882 protected int dochecksyntax(TCustomSqlStatement psql){ 883 int ret = -1; 884 clear(); 885 if (sourcetokenlist.size() == 0) return ret; 886 887// TCustomParser lcparser; 888// lcparser = new TLzParserOracleSql(sourcetokenlist); 889// lcparser.sql = this; 890// ret = lcparser.yyparse(); 891 892 893 if ((this.dbvendor == EDbVendor.dbvoracle)&&(this.isoracleplsql()&&(plsqlparser!=null)) 894// || ((this.dbvendor == EDbVendor.dbvgaussdb) // gaussdb 中用 oracle plsql 写的存储过程,用 oracle plsql parser 来解析 895// &&( 896// ((this instanceof TCreateFunctionStmt)&&(((TCreateFunctionStmt)this).isGaussDBSpInOracle())) 897// ||((this instanceof TCreateProcedureStmt)&&(((TCreateProcedureStmt)this).isGaussDBSpInOracle())) 898// ||(this instanceof TPlsqlCreatePackage) 899// ) 900// ) 901 ){ 902 plsqlparser.sql = this; 903// if (this.dbvendor == EDbVendor.dbvgaussdb){ 904// // 原来用 gaussDB lexer tokenize 的 token 需要用 Oracle lexer 重新 tokenize 一边 905// String sqlText=""; 906// for(int k = 0;k<sourcetokenlist.size();k++){ 907// sqlText = sqlText + sourcetokenlist.get(k).toString(); 908// } 909// // TODO, need to use singleton pattern to get a single instance of Oracle parser. 910// TGSqlParser sqlParser = new TGSqlParser(EDbVendor.dbvoracle); 911// // keep coordinate of the origin query 912// long originalLineNo = sourcetokenlist.get(0).lineNo; 913// long originalColumnNo = sourcetokenlist.get(0).columnNo; 914// sqlParser.sqltext = TBaseType.stringBlock((int) originalLineNo - 1,(int) originalColumnNo - 1)+ sqlText;; 915// 916// int r = sqlParser.getrawsqlstatements(); 917// sourcetokenlist.clear(); 918// for(int k=0;k<sqlParser.sourcetokenlist.size();k++){ 919// sourcetokenlist.add(sqlParser.sourcetokenlist.get(k)); 920// } 921// } 922 923 plsqlparser.sourcetokenlist = sourcetokenlist; 924 925 if ((this instanceof TCommonStoredProcedureSqlStatement) 926 &&((TCommonStoredProcedureSqlStatement)this).isWrapped()){ 927 // don't parse wrapped oracle plsql 928 ret = 0; 929 this.rootNode = this; 930 }else { 931 ret = plsqlparser.yyparse(); 932 this.rootNode = plsqlparser.rootNode; 933 } 934 } 935 else{ 936 if ((this.sqlstatementtype == ESqlStatementType.sstExplain)&&(dbvendor != EDbVendor.dbvhana)){ 937 // EXPLAIN PLAN ... FOR statement; only parse token after FOR keyword 938 boolean isFoundStopToken = false; 939 940 for(int k=0;k<sourcetokenlist.size();k++){ 941 TSourceToken st = sourcetokenlist.get(k); 942 switch (dbvendor){ 943 case dbvoracle: 944 if (st.tokencode == TBaseType.rrw_for) { 945 st.tokencode = TBaseType.sqlpluscmd; 946 isFoundStopToken = true; 947 } 948 break; 949 case dbvredshift: 950 if (st.tokencode == TBaseType.rrw_explain){ 951 st.tokencode = TBaseType.sqlpluscmd; 952 TSourceToken nextst = st.nextSolidToken(); 953 if (nextst.tokencode == TBaseType.rrw_redshift_verbose){ 954 nextst.tokencode = TBaseType.sqlpluscmd; 955 //System.out.println("Found verbose after explain"); 956 } 957 isFoundStopToken = true; 958 } 959 break; 960 case dbvvertica: 961 if ((st.tokencode == TBaseType.rrw_select) 962 ||(st.tokencode == TBaseType.rrw_insert) 963 ||(st.tokencode == TBaseType.rrw_update) 964 ||(st.tokencode == TBaseType.rrw_merge) 965 ) 966 { 967 isFoundStopToken = true; 968 } 969 break; 970 case dbvmysql: 971 case dbvsparksql: 972 case dbvdatabricks: 973 case dbvpostgresql: 974 if ((st.tokencode == TBaseType.rrw_select) 975 ||(st.tokencode == TBaseType.rrw_insert) 976 ||(st.tokencode == TBaseType.rrw_update) 977 ||(st.tokencode == TBaseType.rrw_delete) 978 ||(st.tokencode == TBaseType.rrw_replace) 979 ||(st.tokencode == '(') 980 ) 981 { 982 isFoundStopToken = true; 983 } 984 break; 985 case dbvcouchbase: 986 if (st.tokencode == TBaseType.rrw_explain){ 987 st.tokencode = TBaseType.sqlpluscmd; 988 isFoundStopToken = true; 989 } 990 break; 991 case dbvpresto: 992 case dbvathena: 993 case dbvnetezza: 994 if ((st.tokencode == TBaseType.rrw_select) 995 ||(st.tokencode == TBaseType.rrw_insert) 996 ||(st.tokencode == TBaseType.rrw_update) 997 ||(st.tokencode == TBaseType.rrw_delete) 998 ) 999 { 1000 isFoundStopToken = true; 1001 } 1002 break; 1003 case dbvteradata: 1004 if ((st.tokencode == TBaseType.rrw_select) 1005 ||(st.tokencode == TBaseType.rrw_insert) 1006 ||(st.tokencode == TBaseType.rrw_update) 1007 ||(st.tokencode == TBaseType.rrw_delete) 1008 ||(st.tokencode == TBaseType.rrw_teradata_collect) 1009 ) 1010 { 1011 isFoundStopToken = true; 1012 } 1013 break; 1014 }//switch 1015 1016 if (isFoundStopToken) break; 1017 st.tokencode = TBaseType.sqlpluscmd; 1018 } 1019 }else if (this.sqlstatementtype == ESqlStatementType.sstProfile){ 1020 for(int k=0;k<sourcetokenlist.size();k++) { 1021 TSourceToken st = sourcetokenlist.get(k); 1022 if (dbvendor == EDbVendor.dbvvertica){ 1023 if ((st.tokencode == TBaseType.rrw_select) 1024 ||(st.tokencode == TBaseType.rrw_insert) 1025 ||(st.tokencode == TBaseType.rrw_update) 1026 ||(st.tokencode == TBaseType.rrw_merge) 1027 ) 1028 { 1029 break; 1030 } 1031 } 1032 st.tokencode = TBaseType.sqlpluscmd; 1033 } 1034 }else if (this.sqlstatementtype == ESqlStatementType.sstprepare){ 1035 if ((dbvendor == EDbVendor.dbvcouchbase)||(dbvendor == EDbVendor.dbvpresto)||(dbvendor == EDbVendor.dbvathena)){ 1036 int keywordCount = 0; 1037 for(int k=0;k<sourcetokenlist.size();k++) { 1038 TSourceToken st = sourcetokenlist.get(k); 1039 if (st.tokencode == TBaseType.rrw_prepare) 1040 { 1041 keywordCount++; 1042 }else if ((st.tokentype == ETokenType.ttkeyword) 1043 &&(st.tokencode != TBaseType.rrw_from) 1044 &&(st.tokencode != TBaseType.rrw_as)){ 1045 keywordCount++; 1046 if (keywordCount > 1) break; 1047 } 1048 st.tokencode = TBaseType.sqlpluscmd; 1049 } 1050 } 1051 } 1052 1053 if (parser == null){ 1054 // statement such as select/insert and etc inside plsql 1055 if (psql != null){ 1056 parser = psql.getTopStatement().parser; 1057 this.setParentStmt(psql); 1058 } 1059 // parser = new TParserOracleSql(null); 1060 //parser.lexer = new TLexerOracle(); 1061 //parser.lexer.delimiterchar = '/'; 1062 } 1063 parser.sql = this; 1064 parser.sourcetokenlist = sourcetokenlist; 1065 ret = parser.yyparse(); 1066 this.rootNode = parser.rootNode; 1067 } 1068 1069 if (ret == 0){ 1070 ret = syntaxErrors.size(); 1071 } 1072 // if (rootNode == null) { 1073 if (rootNode == null) { 1074 ret = TBaseType.MSG_ERROR_NO_ROOT_NODE; 1075 // todo , uncomment next line when all sql statements in .y file was processed 1076 parseerrormessagehandle( new TSyntaxError("no root node",0,0,"no_root_node",EErrorType.sperror,TBaseType.MSG_ERROR_NO_ROOT_NODE,this,-1)); 1077 } 1078 return ret; 1079 } 1080 1081 public void clearError(){ 1082 syntaxErrors.clear(); 1083 syntaxHints.clear(); 1084 } 1085 1086 void clear(){ 1087 syntaxErrors.clear(); 1088 syntaxHints.clear(); 1089// todo all subclass should add super() 1090 } 1091 1092 public void setStmtScope(TStmtScope stmtScope) { 1093 this.stmtScope = stmtScope; 1094 } 1095 1096 public TStmtScope getStmtScope() { 1097 return stmtScope; 1098 } 1099 1100 /** 1101 * Original SQL fragment of this statement. 1102 * @return Original statement text. 1103 */ 1104 1105 /* 1106 public String toString(){ 1107 StringBuffer sb = new StringBuffer(""); 1108 for(int i=0; i<sourcetokenlist.size();i++){ 1109 sb.append(sourcetokenlist.get(i).toString()); 1110 } 1111 return sb.toString(); 1112 } 1113 */ 1114 protected TStmtScope stmtScope = null; 1115 void buildsql(){} 1116 public int doParseStatement(TCustomSqlStatement psql){ 1117 if (psql != null){ 1118 this.setParentStmt(psql); 1119 this.setFrameStack(psql.getFrameStack()); 1120 stmtScope = new TStmtScope(psql.stmtScope,this); 1121 // psql.statements.add(this); 1122 }else{ 1123 stmtScope = new TStmtScope(this); 1124 } 1125 1126 if ((this.getStartToken() == null)&&(rootNode != null)){ 1127 this.setStartToken(rootNode.getStartToken()); 1128 } 1129 if ((this.getEndToken() == null)&&(rootNode != null)){ 1130 this.setEndToken(rootNode.getEndToken()); 1131 } 1132 1133 if(this.getGsqlparser() == null){ 1134 if (rootNode != null){ 1135 this.setGsqlparser(rootNode.getGsqlparser()); 1136 } 1137 } 1138 return 0; 1139 } 1140 1141 void addtokentolist(TSourceToken st){ 1142 st.stmt = this; 1143 sourcetokenlist.add(st); 1144 } 1145 1146 public TTable analyzeTablename(TObjectName tableName){ 1147 TTable lcTable = new TTable(); 1148 lcTable.setTableType(ETableSource.objectname); 1149 lcTable.setStartToken(tableName.getStartToken()); 1150 lcTable.setEndToken(tableName.getEndToken()); 1151 lcTable.setGsqlparser(this.getGsqlparser()); 1152 lcTable.setTableName(tableName); 1153 1154 tables.addTable(lcTable); 1155 return lcTable; 1156 } 1157 1158 protected boolean isTableACTE(TTable pTable){ 1159 boolean lcResult = false; 1160 TCTEList cteList1 = getCteList(); 1161 if (cteList1 == null){ 1162 TCustomSqlStatement lcStmt = getParentStmt(); 1163 while (lcStmt != null){ 1164 if (lcStmt.getCteList() != null){ 1165 cteList1 = lcStmt.getCteList(); 1166 break; 1167 }else { 1168 lcStmt = lcStmt.getParentStmt(); 1169 } 1170 } 1171 } 1172 if (cteList1 == null) return false; 1173 // TCTE lcCTE = cteList1.cteNames.get(TBaseType.getTextWithoutQuoted(pTable.toString()).toUpperCase()); 1174 if (pTable.toString() == null) return false; 1175 1176 int searchPos = pTable.getStartToken().posinlist; 1177 if (this.getCteIncludeThisStmt() != null){ 1178 searchPos = this.getCteIncludeThisStmt().getStartToken().posinlist; 1179 } 1180 TCTE lcCTE = cteList1.searchCTEByName(TBaseType.getTextWithoutQuoted(pTable.toString()).toUpperCase(),searchPos); 1181 if ( lcCTE != null ){ 1182 if (pTable.setCTE(lcCTE)){ 1183 pTable.setCTEName(true); 1184 lcResult = true; 1185 } 1186 } 1187// for (int i=0;i<cteList1.size();i++){ 1188// lcCTE = cteList1.getCTE(i); 1189// if (TBaseType.getTextWithoutQuoted(lcCTE.getTableName().toString()).equalsIgnoreCase(TBaseType.getTextWithoutQuoted(pTable.toString()))){ 1190// pTable.setCTEName(true); 1191// pTable.setCTE(lcCTE); 1192// lcResult = true; 1193// break; 1194// } 1195// } 1196 1197 return lcResult; 1198 1199 } 1200 1201 public TTable findTable(ETableEffectType[] tableEffectTypes){ 1202 TTable lcResult = null; 1203 for(int i=0;i<tables.size();i++){ 1204 for(int j=0;j<tableEffectTypes.length;j++){ 1205 if (tables.getTable(i).getEffectType() == tableEffectTypes[j]){ 1206 lcResult = tables.getTable(i); 1207 return lcResult; 1208 } 1209 } 1210 } 1211 return lcResult; 1212 } 1213 public void addToTables(TTable pTable){ 1214 tables.addTable(pTable); 1215 if (isTableACTE(pTable)) return; 1216 1217 if (pTable.getTableName() == null) return; 1218 if (pTable.getTableName().getTableToken() == null) return; 1219 if ((pTable.getTableName().getTableString().toString().equalsIgnoreCase("inserted"))||(pTable.getTableName().getTableString().toString().equalsIgnoreCase("deleted"))){ 1220 if ((getAncestorStmt().sqlstatementtype == ESqlStatementType.sstcreatetrigger) 1221 ||(getAncestorStmt().sqlstatementtype == ESqlStatementType.sstmssqlaltertrigger)){ 1222 //pTable.setLinkTable(true); 1223 ETableEffectType[] effectTypes = new ETableEffectType[]{ 1224 ETableEffectType.tetTriggerOn,ETableEffectType.tetTriggerInsert,ETableEffectType.tetTriggerDelete,ETableEffectType.tetTriggerUpdate,ETableEffectType.tetTriggerInsteadOf 1225 }; 1226 pTable.setLinkTable(getAncestorStmt().findTable(effectTypes)); 1227 } 1228 } 1229 1230 } 1231 1232 public TJoin analyzeTableOrJoin(TFromTable pfromTable){ 1233 TFromTable lcFromTable = pfromTable; 1234 TJoin lcJoin; 1235 TTable lcTable; 1236 1237 if (lcFromTable.getFromtableType() != ETableSource.join){ 1238 lcJoin = new TJoin(); 1239 lcTable = analyzeFromTable(lcFromTable,true); 1240 lcTable.setEffectType(ETableEffectType.tetSelect); 1241 lcJoin.setTable(lcTable); 1242 lcJoin.setStartToken(lcJoin.getTable().getStartToken()); 1243 lcJoin.setEndToken(lcJoin.getTable().getEndToken()); 1244 lcJoin.setGsqlparser(getGsqlparser()); 1245 this.fromSourceTable = lcTable; 1246 this.getRelations().add(lcTable); 1247 }else{ 1248 this.fromSourceJoin = lcFromTable.getJoinExpr(); 1249 1250 this.fromSourceTable = new TTable(); 1251 this.fromSourceTable.setTableType(ETableSource.join); 1252 this.fromSourceTable.setAliasClause(lcFromTable.getJoinExpr().getAliasClause()); 1253 this.fromSourceTable.setStartToken(lcFromTable.getStartToken()); 1254 this.fromSourceTable.setEndToken(lcFromTable.getEndToken()); 1255 this.fromSourceTable.setGsqlparser(lcFromTable.getGsqlparser()); 1256 this.fromSourceTable.setJoinExpr(this.fromSourceJoin); 1257 this.getRelations().add(this.fromSourceTable); 1258 1259 lcJoin = analyzeJoin(lcFromTable.getJoinExpr(),null,true); 1260 lcJoin.doParse(this, ESqlClause.join); 1261 1262 if (lcFromTable.getLateralViewList() != null){ 1263 for(TLateralView lateralView:lcFromTable.getLateralViewList()){ 1264 TTable t = lateralView.createATable(this); 1265 addToTables(t); 1266 this.relations.add(t); 1267 } 1268 } 1269 } 1270 1271 return lcJoin; 1272 } 1273 1274 public TTable analyzeFromTable(TFromTable pfromTable, Boolean addToTableList){ 1275 return analyzeFromTable(pfromTable,addToTableList,ESqlClause.unknown); 1276 } 1277 1278 public TTable analyzeFromTable(TFromTable pfromTable, Boolean addToTableList, ESqlClause pLocation){ 1279 TTable lcTable = new TTable(); 1280 lcTable.setTableType(pfromTable.getFromtableType()); 1281 lcTable.setAliasClause(pfromTable.getAliasClause()); 1282 lcTable.setStartToken(pfromTable.getStartToken()); 1283 lcTable.setEndToken(pfromTable.getEndToken()); 1284 lcTable.setGsqlparser(pfromTable.getGsqlparser()); 1285 lcTable.setTableHintList(pfromTable.getTableHintList()); 1286 lcTable.setTableSample(pfromTable.getTableSample()); 1287 lcTable.setLateralViewList(pfromTable.getLateralViewList()); 1288 lcTable.setTableProperties(pfromTable.getTableProperties()); 1289 lcTable.setPivotedTable(pfromTable.getPivotedTable()); 1290 lcTable.setParenthesisCount(pfromTable.getParenthesisCount()); 1291 lcTable.setParenthesisAfterAliasCount(pfromTable.getParenthesisAfterAliasCount()); 1292 lcTable.setTableKeyword(pfromTable.isTableKeyword()); 1293 lcTable.setOnlyKeyword(pfromTable.isOnlyKeyword()); 1294 lcTable.setFlashback(pfromTable.getFlashback()); 1295 lcTable.setPxGranule(pfromTable.getPxGranule()); 1296 lcTable.setTimeTravelClause(pfromTable.getTimeTravelClause()); 1297 //lcTable.setPartitionClause(pfromTable.getPartitionClause()); 1298 1299 if(getFrameStack().firstElement() != null){ 1300 TFrame stackFrame = getFrameStack().firstElement(); 1301 TGlobalScope globalScope = (TGlobalScope)stackFrame.getScope(); 1302 lcTable.setSqlEnv(globalScope.getSqlEnv()); 1303 } 1304 1305 switch(lcTable.getTableType()){ 1306 case objectname:{ 1307 // tables.addTableByTableRefernce(pfromTable.getTableObjectName()); 1308 boolean insertedInTrigger = false; 1309 if (getTopStatement().sqlstatementtype == ESqlStatementType.sstcreatetrigger){ 1310 insertedInTrigger = (pfromTable.getTableObjectName().toString().compareToIgnoreCase("inserted")==0); 1311 } 1312 1313 if (insertedInTrigger){ 1314 // change table name from inserted to onTable name in create trigger 1315 lcTable.setTableName(((TCreateTriggerStmt)getTopStatement()).getOnTable().getTableName()); 1316 //lcTable.setLinkTable(true); 1317 lcTable.setLinkTable(((TCreateTriggerStmt)getTopStatement()).getOnTable()); 1318 }else{ 1319 lcTable.setTableName(pfromTable.getTableObjectName()); 1320 lcTable.getTableName().setSqlEnv(getSqlEnv()); 1321 1322// if (getSqlEnv().getDefaultCatalogName() != null){ 1323// if (lcTable.getTableName().getDatabaseToken() == null){ 1324// lcTable.getTableName().setDatabaseToken(new TSourceToken(getSqlEnv().getDefaultCatalogName()),true); 1325// } 1326// } 1327 1328// if ((lcTable.getTableName().getSchemaToken() == null)&&(TSQLEnv.supportSchema(this.dbvendor))){ 1329// // let find schema name for this table in env 1330// TSQLTable t = getSqlEnv().searchTable(".."+lcTable.getFullName()); 1331// if (t != null){ 1332// TSQLSchema s = t.getSchema(); 1333// if (s != null){ 1334// lcTable.getTableName().setSchemaToken(new TSourceToken(s.getName()),true); 1335// } 1336// } 1337// } 1338 1339 } 1340 // let's check is it cte name or ordinary table name 1341 TCTEList lcCteList = searchCTEList(false); 1342 TCTE lcCte = null; 1343 if (lcCteList != null){ 1344 for(int i=0;i<lcCteList.size();i++){ 1345 lcCte = lcCteList.getCTE(i); 1346 if (lcCte.getTableName().toString().compareToIgnoreCase(TBaseType.getTextWithoutQuoted(lcTable.getTableName().toString()))==0){ 1347 // this is cte name 1348 if (lcTable.setCTE(lcCte)){ 1349 lcTable.setCTEName(true); 1350 lcTable.setCteColomnReferences(lcCte.getColumnList()); 1351 break; 1352 } 1353 } 1354 } 1355 } 1356 1357 break; 1358 } 1359 case tableExpr:{ 1360 ESqlClause location = ESqlClause.tableExpr; //ESqlClause.resultColumn; 1361 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1362 // change location here 1363 } 1364 lcTable.setTableExpr(pfromTable.getTableExpr()); 1365 lcTable.getTableExpr().doParse(this,location); 1366 // teradata: SELECT table1.* FROM table(strtok_split_to_table(1, 'dm-calcite-raven/td/bq', '-') RETURNS (outkey integer, tokennum integer, token varchar(20)) ) as table1; 1367 // RETURNS (outkey integer, tokennum integer, token varchar(20)) 1368 lcTable.setColumnDefinitions(pfromTable.getColumnDefinitions()); 1369 break; 1370 } 1371 case subquery:{ 1372// if (pfromTable.getSubquerynode().isHiveFromQuery()){ 1373// THiveFromQuery fromQuery = new THiveFromQuery(dbvendor); 1374// lcTable.setHiveFromQuery(fromQuery); 1375// fromQuery.rootNode = pfromTable.getSubquerynode(); 1376// fromQuery.setStartToken(pfromTable.getSubquerynode()); 1377// fromQuery.setEndToken(pfromTable.getSubquerynode()); 1378// fromQuery.setLabelName(this.labelName); 1379// fromQuery.doParseStatement(this); 1380// }else{ 1381// lcTable.subquery = new TSelectSqlStatement(dbvendor); 1382// lcTable.subquery.rootNode = pfromTable.getSubquerynode(); 1383// lcTable.subquery.setLocation(ESqlClause.elTable); 1384// //lcTable.subquery.resultColumnList = ((TSelectSqlNode)lcTable.subquery.rootNode).getResultColumnList(); 1385// lcTable.subquery.doParseStatement(this); 1386// } 1387 1388 lcTable.subquery = new TSelectSqlStatement(dbvendor); 1389 lcTable.subquery.rootNode = pfromTable.getSubquerynode(); 1390 if (pLocation == ESqlClause.unknown){ 1391 lcTable.subquery.setLocation(ESqlClause.elTable); 1392 }else{ 1393 lcTable.subquery.setLocation(pLocation); 1394 } 1395 //lcTable.subquery.resultColumnList = ((TSelectSqlNode)lcTable.subquery.rootNode).getResultColumnList(); 1396 lcTable.subquery.doParseStatement(this); 1397 1398 break; 1399 } 1400 case function:{ 1401 ESqlClause location = ESqlClause.tableFunction;// resultColumn; 1402 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1403 // change location here 1404 } 1405 lcTable.setFuncCall(pfromTable.getFuncCall()); 1406 lcTable.getFuncCall().doParse(this,location); 1407 break; 1408 } 1409 case containsTable:{ 1410 ESqlClause location = ESqlClause.containsTable;//resultColumn; 1411 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1412 // change location here 1413 } 1414 lcTable.setContainsTable(pfromTable.getContainsTable()); 1415 lcTable.getContainsTable().doParse(this,location); 1416 break; 1417 } 1418 1419 case openrowset:{ 1420 ESqlClause location = ESqlClause.openrowset;//resultColumn; 1421 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1422 // change location here 1423 } 1424 lcTable.setOpenRowSet(pfromTable.getOpenRowSet()); 1425 lcTable.getOpenRowSet().doParse(this,location); 1426 break; 1427 } 1428 1429 case openxml:{ 1430 ESqlClause location = ESqlClause.openxml;//resultColumn; 1431 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1432 // change location here 1433 } 1434 lcTable.setOpenXML(pfromTable.getOpenXML()); 1435 lcTable.getOpenXML().doParse(this,location); 1436 break; 1437 } 1438 1439 case opendatasource:{ 1440 ESqlClause location = ESqlClause.opendatasource;//resultColumn; 1441 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1442 // change location here 1443 } 1444 lcTable.setOpenDatasource(pfromTable.getOpenDatasource()); 1445 lcTable.getOpenDatasource().doParse(this,location); 1446 break; 1447 } 1448 1449 case openquery:{ 1450 ESqlClause location = ESqlClause.openquery;//resultColumn; 1451 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1452 // change location here 1453 } 1454 lcTable.setOpenquery(pfromTable.getOpenQuery()); 1455 lcTable.getOpenquery().doParse(this,location); 1456 lcTable.setSubquery(lcTable.getOpenquery().getSubquery()); 1457 break; 1458 } 1459 1460 case datachangeTable:{ 1461 ESqlClause location = ESqlClause.datachangeTable;//resultColumn; 1462 if (sqlstatementtype == ESqlStatementType.sstinsert ){ 1463 // change location here 1464 } 1465 lcTable.setDatachangeTable(pfromTable.getDatachangeTable()); 1466 lcTable.getDatachangeTable().doParse(this,location); 1467 break; 1468 } 1469 case rowList:{ 1470 ESqlClause location = ESqlClause.rowList;//resultColumn; 1471 lcTable.setValueClause(pfromTable.getValueClause()); 1472 lcTable.getValueClause().doParse(this,location); 1473 break; 1474 } 1475 case pivoted_table:{ 1476 ESqlClause location = ESqlClause.pivoted_table;//resultColumn; 1477 lcTable.getPivotedTable().doParse(this,location); 1478 addToTableList = false; 1479 targetTable = lcTable; 1480 break; 1481 } 1482 case xmltable:{ 1483 ESqlClause location = ESqlClause.xmltable;//resultColumn; 1484 lcTable.setXmlTable(pfromTable.getXmlTable()); 1485 lcTable.getXmlTable().doParse(this,location); 1486 break; 1487 } 1488 1489 case informixOuter:{ 1490 ESqlClause location = ESqlClause.outerTable;//resultColumn; 1491 lcTable.setOuterClause(pfromTable.getOuterClause()); 1492 lcTable.getOuterClause().doParse(this,location); 1493 break; 1494 } 1495 1496 case table_ref_list:{ 1497 lcTable.setFromTableList(pfromTable.getFromTableList()); 1498 break; 1499 } 1500// case hiveFromQuery:{ 1501// THiveFromQuery fromQuery = new THiveFromQuery(EDbVendor.dbvhive); 1502// fromQuery.rootNode = pfromTable.getFromQuerySqlNode(); 1503// fromQuery.doParseStatement(this); 1504// lcTable.setHiveFromQuery(fromQuery); 1505// break; 1506// } 1507 case output_merge:{ 1508 TMergeSqlStatement outputMerge = new TMergeSqlStatement(EDbVendor.dbvmssql); 1509 outputMerge.rootNode = pfromTable.getMergeSqlNode(); 1510 outputMerge.doParseStatement(this); 1511 lcTable.setOutputMerge(outputMerge); 1512 break; 1513 } 1514 case td_unpivot:{ 1515 pfromTable.getTdUnpivot().doParse(this,ESqlClause.tdUnPivot); 1516 lcTable.setTdUnpivot(pfromTable.getTdUnpivot()); 1517 break; 1518 } 1519 case unnest:{ 1520 pfromTable.getUnnestClause().doParse(this,ESqlClause.elTable); 1521 lcTable.setUnnestClause(pfromTable.getUnnestClause()); 1522 if (lcTable.getAliasClause() != null){ 1523 if (lcTable.getAliasClause().getColumns() != null){ 1524 for(TObjectName pColumn:lcTable.getAliasClause().getColumns()){ 1525 lcTable.getLinkedColumns().addObjectName(pColumn); 1526 pColumn.setSourceTable(lcTable); 1527 } 1528 }else if (lcTable.getAliasClause().getAliasName() != null){ 1529// SELECT * 1530// FROM UNNEST(['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred']) AS element 1531// WITH OFFSET AS offset 1532 1533 // add element as column of unnest table. 1534 TObjectName newColumn = TObjectName.createObjectName(this.dbvendor,EDbObjectType.column,lcTable.getAliasClause().getAliasName().getStartToken()); 1535 lcTable.getLinkedColumns().addObjectName(newColumn); 1536 newColumn.setSourceTable(lcTable); 1537 } 1538 } 1539 1540 if (lcTable.getUnnestClause().getWithOffset() != null){ 1541 if (lcTable.getUnnestClause().getWithOffsetAlais() != null){ 1542 // with offset as offsetAlias 1543 TAliasClause aliasClause = lcTable.getUnnestClause().getWithOffsetAlais(); 1544 if (aliasClause.getAliasName() != null){ 1545 TObjectName newColumn = TObjectName.createObjectName(this.dbvendor,EDbObjectType.column,aliasClause.getAliasName().getStartToken()); 1546 lcTable.getLinkedColumns().addObjectName(newColumn); 1547 newColumn.setSourceTable(lcTable); 1548 } 1549 }else{ 1550 // with offset 1551 TObjectName newColumn = TObjectName.createObjectName(this.dbvendor,EDbObjectType.column,new TSourceToken("offset")); 1552 lcTable.getLinkedColumns().addObjectName(newColumn); 1553 newColumn.setSourceTable(lcTable); 1554 } 1555 } 1556 1557 // link columns in the select list to unnest() 1558 // select emp_id,name,state,city,zipcode from `absolute-runner-302907.gudu_sqlflow.ADDRESS_NESTED`, UNNEST(address) 1559 if (lcTable.getUnnestClause().getDerivedColumnList() != null){ 1560 TObjectNameList derivedColumns = lcTable.getUnnestClause().getDerivedColumnList(); 1561 for(int i=0;i<derivedColumns.size();i++){ 1562 //System.out.println(derivedColumns.getObjectName(i).toString()); 1563 lcTable.getLinkedColumns().addObjectName(derivedColumns.getObjectName(i)); 1564 } 1565 } 1566 1567 break; 1568 } 1569 case jsonTable:{ 1570 ESqlClause location = ESqlClause.jsonTable;//resultColumn; 1571 lcTable.setJsonTable(pfromTable.getJsonTable()); 1572 lcTable.getJsonTable().doParse(this,location); 1573 break; 1574 } 1575 case externalTable: 1576 lcTable.setTableName(pfromTable.getTableObjectName()); 1577 lcTable.setColumnDefinitions(pfromTable.getColumnDefinitions()); 1578 lcTable.getColumnDefinitions().doParse(this,pLocation); 1579 lcTable.setTableType(ETableSource.externalTable); // tableType is reset in setTableName() method, so we reset it here 1580 break; 1581 case caseJoin: 1582 lcTable.setCaseJoin(pfromTable.getCaseJoin()); 1583 lcTable.getCaseJoin().doParse(this,pLocation); 1584 break; 1585 case stageReference: 1586 lcTable.setStageReference(pfromTable.getStageReference()); 1587 lcTable.getStageReference().doParse(this,pLocation); 1588 1589 lcTable.setTableName(lcTable.getStageReference().getStageName()); 1590 lcTable.setTableType(ETableSource.stageReference); 1591 lcTable.getTableName().setSqlEnv(getSqlEnv()); 1592 1593 break; 1594 1595 }//switch 1596 1597// if (pfromTable.getPivotClause() != null){ 1598// lcTable.setPivotClause(pfromTable.getPivotClause()); 1599// lcTable.getPivotClause().doParse(this,ESqlClause.resultColumn); 1600// } 1601 1602 lcTable.setPartitionExtensionClause(pfromTable.getPartitionExtensionClause()); 1603 1604 //tables.addTable(lcTable); 1605 if (addToTableList) { 1606 addToTables(lcTable); 1607 } 1608 1609 if (lcTable.getTableHintList() != null){ 1610 for(int i=0;i<lcTable.getTableHintList().size();i++){ 1611 TTableHint hint = lcTable.getTableHintList().getElement(i); 1612 hint.setOwnerTable(lcTable); 1613 hint.doParse(this,ESqlClause.tableHint); 1614 } 1615 } 1616 1617 if (lcTable.getLateralViewList() != null){ 1618 for(TLateralView lateralView:lcTable.getLateralViewList()){ 1619 TTable t = lateralView.createATable(this); 1620 addToTables(t); 1621 this.relations.add(t); 1622 } 1623 } 1624 1625 if (lcTable.getAliasClause() != null){ 1626 if (lcTable.getAliasClause().toString().equalsIgnoreCase("and")){ 1627 // end keyword can't be alias name 1628 TSourceToken st1 = lcTable.getAliasClause().getStartToken(); 1629 TSyntaxError err = new TSyntaxError(st1.toString() 1630 ,st1.lineNo,st1.columnNo 1631 ,String.format("AND keyword can't be table alias") 1632 ,EErrorType.sperror 1633 ,TBaseType.MSG_ERROR_AND_KEYWORD_CANT_USED_AS_TABLE_ALIAS 1634 ,this,st1.posinlist); 1635 this.parseerrormessagehandle( err); 1636 1637 } 1638 } 1639 1640 return lcTable; 1641 } 1642 1643 public TJoin analyzeJoin(TJoinExpr pJoinExpr,TJoin pJoin,Boolean isSub){ 1644 TJoin retval = pJoin; 1645 TJoinItem lcJoinItem = null ; 1646 1647 if (pJoinExpr == null) {return retval;} 1648 1649 if (pJoinExpr.getJointype() == EJoinType.nested) 1650 { 1651 if (isSub) 1652 { 1653 if (retval == null) { // top level, left side is a join 1654 retval = new TJoin(); 1655 retval.setStartToken(pJoinExpr.getStartToken()); 1656 retval.setEndToken(pJoinExpr.getEndToken()); 1657 } 1658 1659 pJoinExpr.setJointype(pJoinExpr.original_jontype); 1660 retval.setJoin(analyzeJoin(pJoinExpr,null,true)); 1661 //retval =analyzeJoin(pJoinExpr,null,true); 1662 retval.setKind(TBaseType.join_source_join); 1663 retval.getJoin().setAliasClause(pJoinExpr.getAliasClause()); 1664 retval.getJoin().setWithParen(true); 1665 retval.getJoin().setNestedParen(pJoinExpr.getNestedParen()); 1666 } 1667 else 1668 { 1669 if (retval == null) 1670 { 1671 retval = new TJoin(); 1672 retval.setStartToken(pJoinExpr.getStartToken()); 1673 retval.setEndToken(pJoinExpr.getEndToken()); 1674 retval.setGsqlparser(this.getGsqlparser()); 1675 } 1676 else 1677 { 1678 } 1679 pJoinExpr.setJointype(pJoinExpr.original_jontype); 1680 retval = analyzeJoin(pJoinExpr,retval,false); 1681 //retval.setJoin(analyzeJoin(pJoinExpr,retval,false)); 1682 //retval = analyzeJoin(pJoinExpr,retval,false); 1683 //retval.setKind(TBaseType.join_source_join); 1684 //retval.setKind(TBaseType.join_source_table); 1685 //retval.setAliasClause(pJoinExpr.getAliasClause()); 1686 retval.setAliasClause(pJoinExpr.getAliasClause()); 1687 retval.setWithParen(true); 1688 retval.setNestedParen(pJoinExpr.getNestedParen()); 1689 } 1690 return retval; 1691 } 1692 1693 if (pJoinExpr.getLeftOperand().getFromtableType() != ETableSource.join){ 1694 if (retval == null) { 1695 retval = new TJoin(); 1696 retval.setStartToken(pJoinExpr.getStartToken()); 1697 retval.setEndToken(pJoinExpr.getEndToken()); 1698 retval.setGsqlparser(this.getGsqlparser()); 1699 1700 // retval.setStartToken(pJoinExpr.getLeftOperand().getStartToken()); 1701 // retval.setEndToken(pJoinExpr.getLeftOperand().getEndToken()); 1702 } 1703 TTable lcTable = analyzeFromTable(pJoinExpr.getLeftOperand(),true,ESqlClause.join); 1704 lcTable.setEffectType(ETableEffectType.tetSelect); 1705 retval.setTable(lcTable); 1706 //retval.joinTable.OwnerJoin = result; 1707 retval.setKind(TBaseType.join_source_table); 1708 pJoinExpr.setLeftTable(lcTable); 1709 }else{ 1710 TJoinExpr lcJoinItemJoinExpr = pJoinExpr.getLeftOperand().getJoinExpr(); 1711 //if (lcJoinItemJoinExpr.getJointype() == TBaseType.join_nested){ 1712 // lcJoinItemJoinExpr.setJointype(lcJoinItemJoinExpr.original_jontype); 1713 //} 1714 1715 if (retval != null) { 1716 retval = analyzeJoin(lcJoinItemJoinExpr,retval,true); 1717 } else { 1718 retval = analyzeJoin(lcJoinItemJoinExpr,retval,isSub); 1719 } 1720 retval.setStartToken(lcJoinItemJoinExpr.getStartToken()); 1721 retval.setEndToken(lcJoinItemJoinExpr.getEndToken()); 1722 1723 1724 TTable lcTable = new TTable(); 1725 lcTable.setTableType(pJoinExpr.getLeftOperand().getFromtableType()); 1726 lcTable.setAliasClause(lcJoinItemJoinExpr.getAliasClause()); 1727 lcTable.setStartToken(lcJoinItemJoinExpr.getStartToken()); 1728 lcTable.setEndToken(lcJoinItemJoinExpr.getEndToken()); 1729 pJoinExpr.setLeftTable(lcTable); 1730 lcTable.setJoinExpr(lcJoinItemJoinExpr); 1731 } 1732 1733 if (pJoinExpr.getRightOperand().getFromtableType() != ETableSource.join){ 1734 if (retval != null) 1735 { 1736 lcJoinItem = new TJoinItem(); 1737 TTable lcTable = analyzeFromTable(pJoinExpr.getRightOperand(),true,ESqlClause.join); 1738 lcTable.setEffectType(ETableEffectType.tetSelect); 1739 lcJoinItem.setTable(lcTable); 1740 lcJoinItem.setStartToken(lcJoinItem.getTable().getStartToken()); 1741 lcJoinItem.setEndToken(lcJoinItem.getTable().getEndToken()); 1742 // lcJoinItem.JoinItemTable.OwnerJoinItem := lcJoinItem; 1743 lcJoinItem.setKind(TBaseType.join_source_table); 1744 retval.getJoinItems().addJoinItem(lcJoinItem); 1745 pJoinExpr.setRightTable(lcTable); 1746 } 1747 }else{ 1748 if (retval != null) 1749 { 1750 lcJoinItem = new TJoinItem(); 1751 lcJoinItem.setKind(TBaseType.join_source_join); 1752 TJoinExpr lcJoinItemJoinExpr = pJoinExpr.getRightOperand().getJoinExpr(); 1753 //if (lcJoinItemJoinExpr.getJointype() == TBaseType.join_nested){ 1754 // lcJoinItemJoinExpr.setJointype(lcJoinItemJoinExpr.original_jontype); 1755 //} 1756 lcJoinItem.setJoin(analyzeJoin(pJoinExpr.getRightOperand().getJoinExpr(),null,false)); 1757 lcJoinItem.getJoin().setAliasClause(lcJoinItemJoinExpr.getAliasClause()); 1758 lcJoinItem.setStartToken(lcJoinItem.getJoin().getStartToken()); 1759 lcJoinItem.setEndToken(lcJoinItem.getJoin().getEndToken()); 1760 retval.getJoinItems().addJoinItem(lcJoinItem); 1761 1762 TTable lcTable = new TTable(); 1763 lcTable.setTableType(pJoinExpr.getRightOperand().getFromtableType()); 1764 lcTable.setAliasClause(lcJoinItemJoinExpr.getAliasClause()); 1765 lcTable.setStartToken(lcJoinItemJoinExpr.getStartToken()); 1766 lcTable.setEndToken(lcJoinItemJoinExpr.getEndToken()); 1767 pJoinExpr.setRightTable(lcTable); 1768 lcTable.setJoinExpr(lcJoinItemJoinExpr); 1769 } 1770 } 1771 1772 if (lcJoinItem == null) return retval; 1773 1774 lcJoinItem.setJoinType(pJoinExpr.getJointype()); 1775 lcJoinItem.setUsingColumns(pJoinExpr.usingColumns); 1776 if ((lcJoinItem.getUsingColumns() != null) && (tables.size()>1)){ 1777 TObjectName crf ; 1778 for (int i=0;i<lcJoinItem.getUsingColumns().size();i++){ 1779 crf = lcJoinItem.getUsingColumns().getObjectName(i); 1780 // link this column to last 2 tables 1781 tables.getTable(tables.size()-1).getObjectNameReferences().addObjectName(crf); 1782 tables.getTable(tables.size()-2).getObjectNameReferences().addObjectName(crf); 1783 1784 tables.getTable(tables.size()-1).getLinkedColumns().addObjectName(crf); 1785 crf.setSourceTable(tables.getTable(tables.size()-1)); 1786 tables.getTable(tables.size()-2).getLinkedColumns().addObjectName(crf); 1787 crf.setSourceTable(tables.getTable(tables.size()-2)); 1788 1789 } 1790 lcJoinItem.setEndToken(lcJoinItem.getUsingColumns().getEndToken()); 1791 } 1792 lcJoinItem.setOnCondition(pJoinExpr.onCondition); 1793 if (lcJoinItem.getOnCondition() != null) 1794 { 1795 lcJoinItem.getOnCondition().doParse(this,ESqlClause.joinCondition); 1796 lcJoinItem.setEndToken(lcJoinItem.getOnCondition().getEndToken()); 1797 } 1798 1799 1800 return retval; 1801 } 1802 1803 public boolean locateVariableOrParameter(TObjectName cr){ 1804 return locateVariableOrParameter(cr,false); 1805 } 1806 public boolean locateVariableOrParameter(TObjectName cr, boolean checkVariableDeclaredInProcedure){ 1807 boolean ret = false; 1808 if (cr.getDbObjectType() == EDbObjectType.variable) return true; 1809 if (cr.toString().equalsIgnoreCase("*")) return false; 1810 //search variable in framestack 1811 1812 TVariable symbolVariable = null; 1813 1814 if (cr.getTableToken() != null){ 1815 // record_variable.column 1816 symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),cr.getTableToken().toString()); 1817 if (symbolVariable != null){ 1818 cr.getTableToken().setDbObjectType(EDbObjectType.variable); 1819 //TTable sourceTable = new TTable(new TObjectName(EDbObjectType.table,symbolVariable.getVariableName().getStartToken())); 1820 TTable sourceTable = new TTable(TObjectName.createObjectName (this.dbvendor, EDbObjectType.variable,symbolVariable.getVariableName().getStartToken())); 1821 sourceTable.getLinkedColumns().addObjectName(cr); 1822 cr.setSourceTable(sourceTable); 1823 // symbolVariable.getVariableName().getReferencedObjects().addObjectName(cr); 1824 // System.out.println("find variable:"+cr.toString()); 1825 cr.setResolveStatus(TBaseType.RESOLVED_AND_FOUND); // set resolve status to resolved,避免在 TAttributeResolver 中关联到其他 table 1826 return true; 1827 } 1828 1829 }else{ 1830 // variable 1831 symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),cr.toString()); 1832 if (symbolVariable != null){ 1833 cr.setDbObjectType(EDbObjectType.variable); 1834 symbolVariable.getVariableName().getReferencedObjects().addObjectName(cr); 1835 return true; 1836 } 1837 } 1838 1839 // check parameters in plsql only, may add support for sql server later. 1840 if(! ((dbvendor == EDbVendor.dbvoracle)||(dbvendor == EDbVendor.dbvmysql))) return false; 1841 if (cr.getObjectType() == TObjectName.ttobjVariable) return true; 1842 1843 Stack symbolTable = this.getTopStatement().getSymbolTable(); 1844 TSymbolTableItem item = null; 1845 TObjectName objName = null; 1846 TObjectName qualifiedName = null; // function/procedure name or label name of plsql block 1847 for (int i = symbolTable.size()-1;i>=0;i--){ 1848 item = (TSymbolTableItem)symbolTable.get(i); 1849 if (item.getData() instanceof TParameterDeclaration){ 1850 objName = ((TParameterDeclaration)item.getData()).getParameterName(); 1851 }else if (item.getData() instanceof TVarDeclStmt){ 1852 objName = ((TVarDeclStmt)item.getData()).getElementName(); 1853 }else if (item.getData() instanceof TObjectName){ 1854 objName = (TObjectName)item.getData(); 1855 } 1856 1857 if (objName == null) continue; 1858 1859 if (cr.toString().compareToIgnoreCase(objName.toString()) == 0){ 1860 ret = true; 1861 if (checkVariableDeclaredInProcedure) break; // return true if variable declared in procedure 1862 for(int j=0;i<tables.size();i++){ 1863 TTable lcTable = tables.getTable(j); 1864 if (lcTable.isBaseTable()){ 1865 if (fireOnMetaDatabaseTableColumn( 1866 lcTable.getPrefixServer() 1867 ,lcTable.getPrefixDatabase() 1868 ,lcTable.getPrefixSchema() 1869 ,lcTable.getName() 1870 ,cr.getColumnNameOnly())){ 1871 ret = false; 1872 break; 1873 } 1874 } 1875 } 1876 1877 if (ret) break; 1878 }else if (cr.toString().indexOf(".")>0){ 1879 // qualified object reference, compare it with procedure/function/block label prefixed 1880 if (item.getStmt() instanceof TPlsqlCreateFunction){ 1881 qualifiedName = ((TPlsqlCreateFunction)item.getStmt()).getFunctionName(); 1882 }else if (item.getStmt() instanceof TPlsqlCreateProcedure){ 1883 qualifiedName = ((TPlsqlCreateProcedure)item.getStmt()).getProcedureName(); 1884 }else if (item.getStmt() instanceof TCommonBlock){ 1885 qualifiedName = ((TCommonBlock)item.getStmt()).getLabelName(); 1886 } 1887 1888 if (qualifiedName != null){ 1889 if (cr.toString().compareToIgnoreCase(qualifiedName.toString()+'.'+objName.toString()) == 0){ 1890 ret = true; 1891 } 1892 } 1893 1894 if (ret ) break; 1895 } 1896 1897 } 1898 if (ret){ 1899 //add this parameter or variable reference to original parameter/variable 1900 objName.getReferencedObjects().addObjectName(cr); 1901 cr.setObjectType(TObjectName.ttobjVariable); 1902 } 1903 return ret; 1904 } 1905 1906 TCTE findCTEByName(String cteName){ 1907 TCTEList lcCteList = searchCTEList(false); 1908 TCTE lcCte = null; 1909 if (lcCteList != null){ 1910 for(int i=0;i<lcCteList.size();i++){ 1911 if (lcCteList.getCTE(i).getTableName().toString().compareToIgnoreCase(cteName)==0){ 1912 lcCte = lcCteList.getCTE(i); 1913 break; 1914 } 1915 } 1916 } 1917 return lcCte; 1918 } 1919 1920 /** 1921 * @deprecated since 2.3.8.2, use {@link TTable#getExpandedStarColumns()} instead. 1922 * 1923 * @param lcTable 1924 * @return 1925 */ 1926 public ArrayList<String> getColumnsInTable(TTable lcTable){ 1927 if (lcTable.isCTEName()){ 1928 ArrayList<String> columns = new ArrayList<>(); 1929 if (lcTable.getCteColomnReferences()!=null){ 1930 for(TObjectName n:lcTable.getCteColomnReferences()){ 1931 columns.add(n.toString()); 1932 } 1933 }else if (lcTable.getCTE().getSubquery() != null && lcTable.getCTE().getSubquery().getResultColumnList() != null){ 1934 for(TResultColumn resultColumn:lcTable.getCTE().getSubquery().getResultColumnList()){ 1935 columns.add(resultColumn.getDisplayName()); 1936 } 1937 } 1938 return columns; 1939 }else{ 1940 return getColumnsInTable( 1941 lcTable.getPrefixServer() 1942 ,lcTable.getPrefixDatabase() 1943 ,lcTable.getPrefixSchema() 1944 ,lcTable.getName() 1945 ); 1946 } 1947 } 1948 1949 1950 /** 1951 * @deprecated since 2.3.8.2, use {@link TTable#getExpandedStarColumns()} instead. 1952 * 1953 * @param pServer 1954 * @param pDatabase 1955 * @param pSchema 1956 * @param pTable 1957 * @return 1958 */ 1959 public ArrayList<String> getColumnsInTable(String pServer,String pDatabase,String pSchema,String pTable){ 1960 TFrame stackFrame = getFrameStack().firstElement(); 1961 TGlobalScope globalScope = (TGlobalScope)stackFrame.getScope(); 1962 1963 if (globalScope.getSqlEnv() != null){ 1964 return globalScope.getSqlEnv().getColumnsInTable(pDatabase+"."+pSchema+"."+pTable,false); 1965 }else{ 1966 return null; 1967 } 1968 } 1969 1970 1971 public boolean fireOnMetaDatabaseTableColumn(String pServer,String pDatabase,String pSchema,String pTable,String pColumn){ 1972// boolean lcResult = false; 1973// if (this.getGsqlparser().getMetaDatabase() != null){ 1974// lcResult = this.getGsqlparser().getMetaDatabase().checkColumn(pServer,pDatabase,pSchema,pTable,pColumn); 1975// } 1976 1977 TFrame stackFrame = getFrameStack().firstElement(); 1978 TGlobalScope globalScope = (TGlobalScope)stackFrame.getScope(); 1979 1980 if (globalScope.getSqlEnv() != null){ 1981 // System.out.println(globalScope.getSqlEnv().toString()); 1982 1983 return globalScope.getSqlEnv().columnInTable(pDatabase+"."+pSchema+"."+pTable,pColumn); 1984 }else{ 1985 return false; 1986 } 1987 1988// return lcResult; 1989 } 1990 1991 public TTable getFirstPhysicalTable(){ 1992 TTable ret = null; 1993 if (tables.size() == 0) return null; 1994 for(int i=0;i<tables.size();i++){ 1995 if (tables.getTable(i).isBaseTable()) { 1996 ret = tables.getTable(i); 1997 break; 1998 } 1999 } 2000 return ret; 2001 } 2002 private TObjectNameList orphanColumns = null; 2003 2004 public TObjectNameList getOrphanColumns() { 2005 if (orphanColumns == null) orphanColumns = new TObjectNameList(); 2006 return orphanColumns; 2007 } 2008 2009 protected boolean linkToFirstTable(TObjectName pColumn,int pCandidateTableCnt){ 2010 boolean lcResult = false; 2011 if ((dbvendor == EDbVendor.dbvteradata)&&(pColumn.isQualified())&&(pColumn.getTableToken().getDbObjectType() != EDbObjectType.subquery_alias)){ 2012 // update table1 set col = 'value' where table1.id = table2.id2 2013 boolean isFoundLinkedTable = false; 2014 TCustomSqlStatement lcSql = this; 2015 while (lcSql != null){ 2016 int i = 0; 2017 i = lcSql.tables.searchTableByNameOrAlias(pColumn.getTableToken().toString()); 2018 isFoundLinkedTable = ( i != -1); 2019 if (isFoundLinkedTable) { 2020 if (tables.getTable(i).getEffectType() == ETableEffectType.tetImplicitLateralDerivedTable ){ 2021 // 如果不查重table,会导致 employee.first_name 中的 employee 被第二次加到 tables 中 2022// DELETE FROM foodmart.trimmed_employee ACT 2023// WHERE ACT.employee_id = employee.employee_id 2024// AND employee.first_name = 'Walter' 2025// AND trimmed_salary.employee_id = -1 2026 2027 TTable newTable = tables.getTable(i); 2028 newTable.getLinkedColumns().addObjectName(pColumn); 2029 pColumn.setSourceTable(newTable); 2030 pColumn.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 2031 } 2032 break; 2033 } 2034 lcSql = lcSql.getParentStmt(); 2035 } 2036 if (!isFoundLinkedTable){ 2037 TTable newTable = null; 2038 if (pColumn.getDatabaseToken() == null){ 2039 2040 //newTable = new TTable(new TObjectName(EDbObjectType.table,pColumn.getTableToken())); 2041 newTable = new TTable(TObjectName.createObjectName (this.dbvendor, EDbObjectType.table,pColumn.getTableToken())); 2042 newTable.setStartToken(pColumn.getTableToken()); 2043 newTable.setEndToken(pColumn.getTableToken()); 2044 }else{ 2045 2046 //newTable = new TTable(new TObjectName(EDbObjectType.table,pColumn.getSchemaToken(), pColumn.getTableToken())); 2047 newTable = new TTable(TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,pColumn.getDatabaseToken(), pColumn.getTableToken())); 2048 newTable.setStartToken(pColumn.getSchemaToken()); 2049 newTable.setEndToken(pColumn.getTableToken()); 2050 } 2051 2052 newTable.setTableType(ETableSource.objectname); 2053 newTable.setEffectType(ETableEffectType.tetImplicitLateralDerivedTable); 2054 newTable.getLinkedColumns().addObjectName(pColumn); 2055 pColumn.setSourceTable(newTable); 2056 pColumn.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 2057 this.addToTables(newTable); 2058 2059 // 2024 年 2060 // 不能加入到 relations 中,否则会导致 下面 SQL 中 star column 同时链接到 SPCOMM.L_FIXED_RATE_PLAN_REF, ipshare_ofccplv.cprof_d_period_dates_ref 2061 // 从而导致 本来不该有的歧义产生 2062 2063 // UPDATE b_rate_plan 2064 //FROM 2065 //( 2066 //SELECT * FROM SPCOMM.L_FIXED_RATE_PLAN_REF 2067 //WHERE rate_plan_ref_eff_dt<= ipshare_ofccplv.cprof_d_period_dates_ref.PERIOD 2068 //) AS ref 2069 //SET accs_fee = REF.accs_fee, 2070 //SVC_TYPE = REF.prod_grp_lvl_1, 2071 //rate_plan_lvl3 = REF.rate_plan_lvl_3, 2072 //prod_grp_lvl3 = REF.prod_grp_lvl_2 2073 //WHERE b_rate_plan.svc_type IS NULL 2074 2075 // 2025/2/25, v3.0.4.8 2076 // 需要加入到 relations 中,新的 gudusoft.gsqlparser.resolver package 中的算法会处理这种情况 2077 // teradata 的隐式横向派生表不能加入到关系解析器中 2078 // this.getRelations().add(newTable); 2079 } 2080 return true; 2081 } 2082 if (pColumn.getCandidateTables().size() == 1){ 2083 TTable table = pColumn.getCandidateTables().getTable(0); 2084 table.getLinkedColumns().addObjectName(pColumn); 2085 pColumn.setSourceTable(table); 2086 lcResult = true; 2087 } 2088 else if ((tables.size() == 1) || (pCandidateTableCnt == 1)){ 2089 TTable table = tables.getTable(0); 2090 2091 if(table.getTableType() == ETableSource.function){ 2092 //lcResult = linkToFunctionTable(table, pColumn); 2093 int iRet = table.getFuncCall().isColumnInThisTableFunction(this.getSqlEnv(),this.dbvendor,pColumn); 2094 if ( iRet == TBaseType.COLUMN_IN_TABEL_FUNCTION_YES){ 2095 lcResult = true; 2096 table.getLinkedColumns().addObjectName(pColumn); 2097 pColumn.setSourceTable(table); 2098 lcResult = true; 2099 }else if ( iRet == TBaseType.COLUMN_IN_TABEL_FUNCTION_NO){ 2100 lcResult = false; 2101 }else{ 2102 table.getLinkedColumns().addObjectName(pColumn); 2103 pColumn.setSourceTable(table); 2104 lcResult = true; 2105 } 2106 }else if(table.getTableType() == ETableSource.subquery){ 2107 if (! table.getSubquery().searchColumnInResultSet(pColumn,(tables.size()==1))){ 2108 getOrphanColumns().addObjectName(pColumn); 2109 pColumn.setOrphanColumn(true); 2110 TSourceToken st = pColumn.getStartToken(); 2111 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 2112 TBaseType.log(String.format("Add orphan column <%s> to statement in old algorithm in subquery %s",pColumn.toString(),table.getAliasName()),TLog.WARNING,table); 2113 } 2114 this.parseerrormessagehandle(new TSyntaxError(st.astext, st.lineNo, st.columnNo 2115 ,"find orphan column", EErrorType.sphint 2116 , TBaseType.MSG_HINT_FIND_ORPHAN_COLUMN,this,st.posinlist,pColumn)); 2117 } 2118 } 2119 else{ 2120 table.getLinkedColumns().addObjectName(pColumn); 2121 pColumn.setSourceTable(table); 2122 lcResult = true; 2123 if ((dbvendor == EDbVendor.dbvbigquery)&&(pCandidateTableCnt == 0) && (pColumn.isQualified())){ 2124 // bigquery struct column used in query 2125// create view test as (SELECT rollNo, 2126// info.name as n1, 2127// info2.name as n2, 2128// info.age from my_first_dataset.student_records); 2129 2130 pColumn.columnToProperty(); 2131 } 2132 } 2133 }else if (tables.size() > 1){ 2134 // if there is only a table without table alias, then, link to this table 2135 boolean foundOnlyOneTable = false; 2136 TTable tableWithoutAlias = null; 2137 for(TTable table:tables){ 2138 if (table.isCTEName()) continue; // CTE 即便没有 指定alias,也不作为考虑对象 2139 if (table.getAliasClause() == null){ 2140 tableWithoutAlias = table; 2141 if (foundOnlyOneTable){ 2142 foundOnlyOneTable = false; 2143 break; 2144 }else{ 2145 foundOnlyOneTable = true; 2146 } 2147 } 2148 } 2149 2150 if (foundOnlyOneTable){ 2151 tableWithoutAlias.getLinkedColumns().addObjectName(pColumn); 2152 pColumn.setSourceTable(tableWithoutAlias); 2153 lcResult = true; 2154 }else{ 2155 getOrphanColumns().addObjectName(pColumn); 2156 pColumn.setOrphanColumn(true); 2157 TSourceToken st = pColumn.getStartToken(); 2158 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 2159 TBaseType.log(String.format("Add orphan column <%s> to statement in old algorithm ",pColumn.toString()),TLog.WARNING,this); 2160 } 2161 2162 this.parseerrormessagehandle(new TSyntaxError(st.astext, st.lineNo, st.columnNo 2163 ,"find orphan column", EErrorType.sphint 2164 , TBaseType.MSG_HINT_FIND_ORPHAN_COLUMN,this,st.posinlist,pColumn)); 2165 } 2166 2167 } 2168 return lcResult; 2169 } 2170 2171 private boolean linkToFunctionTable(TTable table, TObjectName pColumn) { 2172 if(table.getTableName().toString().toUpperCase().equals("STRING_SPLIT")){ 2173 if(pColumn.getColumnNameOnly().toUpperCase().equals("VALUE")){ 2174 table.getLinkedColumns().addObjectName(pColumn); 2175 pColumn.setSourceTable(table); 2176 return true; 2177 } 2178 else return false; 2179 } 2180 else { 2181 table.getLinkedColumns().addObjectName(pColumn); 2182 pColumn.setSourceTable(table); 2183 return true; 2184 } 2185 } 2186 2187 boolean isSQLServerInsertedDelete(TObjectName pColumn){ 2188 if (((pColumn.toString().toUpperCase().startsWith("INSERTED")) 2189 ||(pColumn.toString().toUpperCase().startsWith("DELETED"))) 2190 //&&(plocation == ESqlClause.output) 2191 &&(targetTable != null)){ 2192 targetTable.getObjectNameReferences().addObjectName(pColumn); 2193 pColumn.setSourceTable(targetTable); 2194 return true; 2195 }else 2196 { 2197 return false; 2198 } 2199 } 2200 2201 boolean isOracleNewOldTable(TObjectName pColumn){ 2202 boolean ret = false; 2203 if (dbvendor != EDbVendor.dbvoracle) return false; 2204 if (!(pColumn.isQualified())) return false; 2205 if ((pColumn.getTableString().equalsIgnoreCase(":new")) 2206 ||(pColumn.getTableString().equalsIgnoreCase(":old"))){ 2207 if (getAncestorStmt().tables != null){ 2208 if (getAncestorStmt().tables.size() > 0){ 2209 getAncestorStmt().tables.getTable(0).getLinkedColumns().addObjectName(pColumn); 2210 pColumn.setSourceTable(getAncestorStmt().tables.getTable(0)); 2211 ret = true; 2212 } 2213 } 2214 } 2215 2216 return ret; 2217 } 2218 2219 public boolean searchDaxVariableInStack(TObjectName pName){ 2220 boolean ret = false; 2221 if (getVariableStack().size() == 0) return false; 2222 if (pName.getDbObjectType() == EDbObjectType.column) return false; 2223 for(int i=0;i<variableStack.size();i++){ 2224 if (pName.toString().equalsIgnoreCase(((TObjectName) variableStack.get(i)).toString())){ 2225 ret = true; 2226 break; 2227 } 2228 } 2229 return ret; 2230 } 2231 2232 boolean linkColumnToTableDax(TObjectName pColumn, ESqlClause pLocation){ 2233 boolean lcResult = true ; 2234 TDaxFunction daxFunction = null; 2235 if (searchDaxVariableInStack(pColumn)) return false; 2236 if (getDaxFunctionStack().size() > 0){ 2237 daxFunction = daxFunctionStack.peek(); 2238 } 2239 2240 if (pColumn.getTableToken() != null){ 2241 //TTable sourceTable = new TTable(new TObjectName(EDbObjectType.table,pColumn.getTableToken())); 2242 TTable sourceTable = new TTable(TObjectName.createObjectName (this.dbvendor,EDbObjectType.table,pColumn.getTableToken())); 2243 sourceTable.getLinkedColumns().addObjectName(pColumn); 2244 addToTables(sourceTable); 2245 if ((daxFunction != null) && (daxFunction.getDefaultTable() == null)){ 2246 daxFunction.setDefaultTable(sourceTable); 2247 } 2248 }else{ 2249 if ((daxFunction != null) &&(daxFunction.getDefaultTable() != null)){ 2250 daxFunction.getDefaultTable().getLinkedColumns().addObjectName(pColumn); 2251 }else{ 2252 ((TDaxStmt)this).getDefaultTable().getLinkedColumns().addObjectName(pColumn); 2253 } 2254 } 2255 return lcResult; 2256 } 2257 2258 public boolean linkColumnToTable(TObjectName pColumn, ESqlClause pLocation){ 2259 boolean lcResult = false,isContinue = false; 2260 int candidateTableCnt = 0; 2261 if (dbvendor == EDbVendor.dbvdax){ 2262 return linkColumnToTableDax(pColumn,pLocation); 2263 } 2264 2265 if (pColumn.getSourceTable() != null) { 2266 lcResult = true; 2267 return lcResult; 2268 } 2269 2270 if (pColumn.getResolveStatus() == TBaseType.RESOLVE_DELAY_TO_COLUMN_RESOLVER) return true; 2271 2272 pColumn.setLocation(pLocation); 2273 2274 if (! pColumn.isValidColumnName(dbvendor)) { 2275 if (pColumn.isReservedKeyword()){ 2276 if ( 2277 ((pColumn.getStartToken().tokencode != TBaseType.rrw_mysql_true)&&(!(pColumn.getStartToken().toString().equalsIgnoreCase("true")))) 2278 &&((pColumn.getStartToken().tokencode != TBaseType.rrw_mysql_false)&&(!(pColumn.getStartToken().toString().equalsIgnoreCase("false")))) 2279 &&(pColumn.getStartToken().tokencode != TBaseType.rrw_mysql_default) 2280 ) { 2281 boolean mysqlBuiltFunction = false; 2282 if (dbvendor == EDbVendor.dbvmysql){ 2283 mysqlBuiltFunction = functionChecker.isBuiltInFunction(pColumn.toString(),EDbVendor.dbvmysql,"6.0"); 2284 } 2285 if (!mysqlBuiltFunction){ 2286 TSourceToken st1 = pColumn.getStartToken(); 2287 TSyntaxError err = new TSyntaxError(st1.toString() 2288 , st1.lineNo, st1.columnNo 2289 , String.format("Reserved keyword can't be column name") 2290 , EErrorType.sperror 2291 , TBaseType.MSG_ERROR_RESERVED_KEYWORD_CANT_USED_AS_COLUMN_NAME 2292 ,this,st1.posinlist); 2293 this.parseerrormessagehandle(err); 2294 } 2295 } 2296 } 2297 return false; 2298 } 2299 2300 if (isOracleNewOldTable(pColumn)) return true; 2301 if (isSQLServerInsertedDelete(pColumn)) return true; 2302 2303 // oracle insert all statement, 2304 // WHEN id <= 3 THEN INTO dest_tab1 VALUES(id, description1) 2305 // column in values clause must be in the subquery of insert all statement 2306 if (pColumn.getLocation() == ESqlClause.insertValues){ 2307 if (this instanceof TInsertSqlStatement){ 2308 TInsertSqlStatement insertSqlStatement = (TInsertSqlStatement)this; 2309 if (insertSqlStatement.isInsertAll()){ 2310 // if (pColumn.getStartToken().tokencode == TBaseType.rrw_snowflake_default) return true; 2311 lcResult = insertSqlStatement.getSubQuery().searchColumnInResultSet(pColumn, true); 2312 } 2313 } 2314 2315 if (lcResult) return true; 2316 2317 // value in values clause maybe parameter of the procedure/function parameter 2318 lcResult = locateVariableOrParameter(pColumn,true); 2319 if (lcResult) return true; 2320 } 2321 2322 for(int i=0;i<tables.size();i++){ 2323 TTable lcTable = tables.getTable(i); 2324 if (lcTable.getEffectType() == ETableEffectType.tetSelectInto) continue; 2325 if (lcTable.getEffectType() == ETableEffectType.tetImplicitLateralDerivedTable) continue; 2326 2327 if (pColumn.isQualified()){ 2328 lcResult = pColumn.resolveWithThisTable(lcTable); 2329 if ((lcResult) && (lcTable.getTableType() == ETableSource.subquery)){ 2330 pColumn.getTableToken().setDbObjectType(EDbObjectType.subquery_alias); 2331 2332 int lcPos = lcTable.searchColumnInAlias(pColumn); 2333 lcResult = lcPos>=0; 2334 if (lcResult){ 2335 // 在 alias 中找到 source column, 还需要对应到 subquery select 中的 select list 2336 // sql 见 https://e.gitee.com/gudusoft/projects/151613/tasks/list?issue=I8JR0W#note_23051633 2337 if ((lcTable.getSubquery() != null)&&(lcTable.getSubquery().getResultColumnList() != null)){ 2338 pColumn.setSourceColumn(lcTable.getSubquery().getResultColumnList().getResultColumn(lcPos)); 2339 } 2340 }else{ 2341 lcResult = lcTable.getSubquery().searchColumnInResultSet(pColumn,true); 2342 } 2343 // lcTable.getSubquery().searchColumnInResultSet(pColumn,true); 2344 2345 }else if ((lcResult) && (lcTable.isCTEName())){ 2346 lcTable.getCTE().searchColumnInResultSet(this,lcTable,pColumn,true); 2347 }else if ((lcResult) && (lcTable.getTableType() == ETableSource.openquery)&&(lcTable.getSubquery() != null)){ 2348 pColumn.getTableToken().setDbObjectType(EDbObjectType.subquery_alias); 2349 lcTable.getSubquery().searchColumnInResultSet(pColumn,true); 2350// }else if ((lcResult) && (lcTable.getTableType() == ETableSource.unnest)&&(lcTable.getUnnestClause() != null)){ 2351// pColumn.getTableToken().setDbObjectType(EDbObjectType.subquery_alias); 2352// lcTable.getSubquery().searchColumnInResultSet(pColumn,true); 2353 } 2354 if (lcResult&&pColumn.toString().endsWith("*")){ 2355 pColumn.getSourceTableList().add(lcTable); 2356// ArrayList<String> lcColumns = getColumnsInTable(lcTable); 2357// if (lcColumns != null){ 2358// pColumn.getColumnsLinkedToStarColumn().addAll(lcColumns); 2359// } 2360 } 2361 }else { 2362 // column not qualified 2363 2364 // check if this is the column alias in current select list. 2365 if((!lcResult)&& ((!pColumn.isQualified()) && (this instanceof TSelectSqlStatement)&&(getResultColumnList() !=null)) 2366 && (TBaseType.isSupportLateralColumn(dbvendor)) 2367 ){ 2368 for(int j=0;j<getResultColumnList().size();j++){ 2369 TResultColumn lcField = getResultColumnList().getResultColumn(j); 2370 lcResult = lcField.isMatchedUsingAlias(pColumn); 2371 if ( 2372 (!TSQLEnv.isAliasReferenceForbidden[this.dbvendor.ordinal()])&& 2373 ((lcResult)&&(pColumn.getStartToken().posinlist > lcField.getAliasClause().getStartToken().posinlist))){ 2374 pColumn.setSourceColumn(lcField); 2375 lcField.getTargetColumns().addObjectName(pColumn); 2376 pColumn.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_COLUMN_ALIAS_IN_OLD_ALGORITHM); 2377 break; 2378 }else{ 2379 lcResult = false; 2380 } 2381 } 2382 2383 if (lcResult) return true; 2384 } 2385 2386 if (pColumn.getColumnNameOnly().equalsIgnoreCase("*")){ 2387 lcResult = true; 2388 isContinue = true; // in order to match next table in the from clause 2389 pColumn.getSourceTableList().add(lcTable); 2390// ArrayList<String> lcColumns = getColumnsInTable(lcTable); 2391// if (lcColumns != null){ 2392// pColumn.getColumnsLinkedToStarColumn().addAll(lcColumns); 2393// } 2394 }else if (lcTable.isBaseTable()){ 2395 lcResult = fireOnMetaDatabaseTableColumn( 2396 lcTable.getPrefixServer() 2397 ,lcTable.getPrefixDatabase() 2398 ,lcTable.getPrefixSchema() 2399 ,lcTable.getName() 2400 ,pColumn.getColumnNameOnly()); 2401 if (! lcResult) { 2402 candidateTableCnt++; 2403 pColumn.getCandidateTables().addTable(lcTable); 2404 } 2405 2406 }else if ((lcTable.getTableType() == ETableSource.subquery) 2407 ||((lcTable.getTableType() == ETableSource.openquery)&&(lcTable.getSubquery() != null))){ 2408 2409 lcResult = lcTable.searchColumnInAlias(pColumn)>=0; 2410 if (!lcResult){ 2411 lcResult = lcTable.getSubquery().searchColumnInResultSet(pColumn,(tables.size() == 1) 2412 &&(pColumn.getCandidateTables().size() == 0)); 2413 if (! lcResult) { 2414 candidateTableCnt++; 2415 pColumn.getCandidateTables().addTable(lcTable); 2416 } 2417 } 2418 2419 2420// if (lcTable.isIncludeColumnAlias()){ 2421// // System.out.println("subquery with alias:"+lcTable.getAliasClause().toString()+", skip search:"+pColumn.toString()); 2422// 2423// }else{ 2424// lcResult = lcTable.getSubquery().searchColumnInResultSet(pColumn,(tables.size() == 1)&&(pColumn.getCandidateTables().size() == 0)); 2425// if (! lcResult) candidateTableCnt++; 2426// } 2427 }else if (lcTable.isCTEName()){ 2428 lcResult = lcTable.getCTE().searchColumnInResultSet(this,lcTable,pColumn,tables.size() == 1); 2429 if (! lcResult) { 2430 candidateTableCnt++; 2431 pColumn.getCandidateTables().addTable(lcTable); 2432 } 2433 }else if (lcTable.getTableType() == ETableSource.function){ 2434 // search in this table function 2435 if(tables.size() == 1){ 2436 lcResult = ( lcTable.getFuncCall().isColumnInThisTableFunction(this.getSqlEnv(),this.dbvendor,pColumn) 2437 != TBaseType.COLUMN_IN_TABEL_FUNCTION_NO); 2438 } 2439 else{ 2440 lcResult = ( lcTable.getFuncCall().isColumnInThisTableFunction(this.getSqlEnv(),this.dbvendor,pColumn) 2441 == TBaseType.COLUMN_IN_TABEL_FUNCTION_YES); 2442 } 2443 }else if (lcTable.getTableType() == ETableSource.tableExpr 2444 && lcTable.getTableExpr().getExpressionType() == EExpressionType.function_t 2445 && lcTable.getTableExpr().getFunctionCall() != null){ 2446 // search in this table function 2447 lcResult = ( lcTable.getTableExpr().getFunctionCall().isColumnInThisTableFunction(this.getSqlEnv(),this.dbvendor,pColumn) 2448 == TBaseType.COLUMN_IN_TABEL_FUNCTION_YES); 2449 }else if (lcTable.getTableType() == ETableSource.pivoted_table){ 2450 lcResult = fireOnMetaDatabaseTableColumn( 2451 lcTable.getPrefixServer() 2452 ,lcTable.getPrefixDatabase() 2453 ,lcTable.getPrefixSchema() 2454 ,lcTable.getName() 2455 ,pColumn.getColumnNameOnly()); 2456 }else if (lcTable.getTableType() == ETableSource.unnest){ 2457 for(TObjectName objectName:lcTable.getLinkedColumns()){ 2458 if (objectName.toString().equalsIgnoreCase(pColumn.toString())){ 2459 lcResult = true; 2460 break; 2461 } 2462 } 2463 2464 if (!lcResult){ 2465 if (lcTable.getAliasClause() == null){ 2466 // this unnest() clause generate column with default name: "value" 2467 if (pColumn.toString().equalsIgnoreCase("value")){ 2468 lcResult = true; 2469 } 2470 }else{ 2471 } 2472 } 2473 }//unnest 2474 } 2475 2476 if (lcResult) { 2477 lcTable.getLinkedColumns().addObjectName(pColumn); 2478 pColumn.setSourceTable(lcTable); 2479 // pColumn.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 2480 if (!isContinue) break; 2481 } 2482 } 2483 2484 // check variable after metadata checking 2485 if (locateVariableOrParameter(pColumn)) return false; 2486 2487 // check if this is the column alias in current select list. 2488// if((!lcResult)&& ((!pColumn.isPrefixed()) && (this instanceof TSelectSqlStatement)&&(getResultColumnList() !=null))){ 2489// for(int j=0;j<getResultColumnList().size();j++){ 2490// TResultColumn lcField = getResultColumnList().getResultColumn(j); 2491// lcResult = lcField.isMatchedUsingAlias(pColumn); 2492// if ((lcResult)&&(pColumn.getStartToken().posinlist > lcField.getAliasClause().getStartToken().posinlist)){ 2493// pColumn.setSourceColumn(lcField); 2494// lcField.getTargetColumns().addObjectName(pColumn); 2495// break; 2496// }else{ 2497// lcResult = false; 2498// } 2499// } 2500// } 2501 2502 if (lcResult) return true; 2503 2504 boolean isSearchUpLevel = (this.parentStmt != null); 2505 2506 if ((isSearchUpLevel) && (sqlstatementtype == ESqlStatementType.sstselect)){ 2507 isSearchUpLevel = (pColumn.isQualified() 2508 || ( 2509// (((TSelectSqlStatement)(this)).getLocation() != ESqlClause.elTable) && 2510 (! ((TSelectSqlStatement)(this)).isQueryOfCTE()) 2511 ) 2512 ) 2513 && (parentStmt.sqlstatementtype != ESqlStatementType.sstinsert) 2514 && (!((pColumn.getLocation() == ESqlClause.selectList)&&(((TSelectSqlStatement)(this)).getLocation() == ESqlClause.join))) 2515 && ((((TSelectSqlStatement)(this)).getLocation() != ESqlClause.pivot_in)) 2516 && (!((parentStmt.sqlstatementtype == ESqlStatementType.sstcreatetable))) 2517 && (!((parentStmt.sqlstatementtype == ESqlStatementType.sstcreateview))) 2518// && (!((pColumn.getLocation() == ESqlClause.selectList)&&(parentStmt.sqlstatementtype == ESqlStatementType.sstcreatetable))) 2519// && (!((pColumn.getLocation() == ESqlClause.selectList)&&(parentStmt.sqlstatementtype == ESqlStatementType.sstcreateview))) 2520 && (! ((pColumn.getLocation() == ESqlClause.selectList) 2521 &&(candidateTableCnt == 1) && (this instanceof TSelectSqlStatement) 2522 && (((TSelectSqlStatement)(this)).getLocation() == ESqlClause.elTable) 2523 ) ) // ref:mantis: #2628 2524 // && ( ((TSelectSqlStatement)(this.parentStmt)).getSetOperatorType() == ESetOperatorType.none) 2525 ; 2526 2527 if (isSearchUpLevel){ 2528 isSearchUpLevel = !((!pColumn.isQualified())&&(((TSelectSqlStatement) this).getLocation() == ESqlClause.where)); 2529 } 2530 } 2531 2532 if (isSearchUpLevel&&(pColumn.isContinueToSearch())){ // only search one level up, c:\prg\gsp_sqlfiles\TestCases\java\oracle\dbobject\berger_sqltest_04.sql 2533 boolean increaseLevel = true; 2534 if (parentStmt instanceof TSelectSqlStatement){ 2535 if( ((TSelectSqlStatement)parentStmt).getSetOperatorType() != ESetOperatorType.none){ 2536 increaseLevel = false; 2537 } 2538 } 2539 if (increaseLevel){ 2540 pColumn.searchLevel++; 2541 } 2542 2543 lcResult = parentStmt.linkColumnToTable(pColumn,pLocation); 2544 2545 if (increaseLevel){ 2546 pColumn.searchLevel--; 2547 } 2548 } 2549 2550 if ((! lcResult) && (pColumn.searchLevel == 0)) { 2551 if (this.sqlstatementtype == ESqlStatementType.sstselect){ 2552 if( ((TSelectSqlStatement)this).getSetOperatorType() == ESetOperatorType.none){ 2553 // USING _spVV0 (INTEGER) 2554 // INSERT INTO table3 2555 // SELECT :_spVV0,x. *,m.col3 2556 // from (( select table1.col1, (table1.col1 + table5.col2) c from table1 2557 // union all select col3,col4 from table2) x 2558 // cross join (select id from table2) m ) 2559 2560 // table5 in the above sql only link to the nearest level sql, but not to up-level which is union all 2561 2562 linkToFirstTable(pColumn,candidateTableCnt); 2563 } 2564 }else{ 2565 linkToFirstTable(pColumn,candidateTableCnt); 2566 } 2567 } 2568 2569 return lcResult; 2570 } 2571 2572 2573 /** 2574 * 2575 * @deprecated As of v1.6.0.1, use {@link #linkColumnToTable} instead 2576 */ 2577 public void linkColumnReferenceToTable(TObjectName cr, ESqlClause plocation){ 2578 // this is the column name, link it to table 2579 if (cr == null) return; 2580 cr.setLocation(plocation); 2581 if (cr.getObjectType() == TObjectName.ttobjVariable) return; 2582 if (cr.getObjectType() == TObjectName.ttobjColumnAlias) return; 2583 if (this.dbvendor == EDbVendor.dbvsybase){ 2584 TSourceToken pt = cr.getPartToken(); 2585 if ( pt != null){ 2586 if (pt.tokentype == ETokenType.ttdqstring){ 2587 //"0123", quoted string start with a number can't a column 2588 if ((pt.toString().charAt(1) >= '0') 2589 &&(pt.toString().charAt(1) <= '9')){ 2590 return; 2591 }else if (pt.toString().length() == 2){ 2592 //"", empty 2593 return; 2594 }else if (pt.toString().substring(1,pt.toString().length()-1).trim().length() == 0){ 2595 //" " 2596 return; 2597 } 2598 } 2599 } 2600 } 2601 2602 2603 if (cr.getPartToken() != null){ 2604 if (cr.getPartToken().tokentype == ETokenType.ttkeyword){ 2605 boolean reservedKeyword = false; 2606 switch (dbvendor){ 2607 case dbvmssql: 2608 //reservedKeyword = ! this.getGsqlparser().getFlexer().canBeColumnName(cr.getPartToken().tokencode); 2609 reservedKeyword = ! TLexerMssql.canBeColumnName(cr.getPartToken().tokencode); 2610 break; 2611 case dbvsybase: 2612 reservedKeyword = keywordChecker.isKeyword(cr.getPartToken().toString(), EDbVendor.dbvsybase, "15.7", true); 2613 break; 2614 default: 2615 break; 2616 } 2617 if (reservedKeyword) return; 2618 } 2619 } 2620 2621 // let's check is this columnreference is variable or parameter of plsql function/procedure 2622 // if (locateVariableOrParameter(cr)) return; 2623 2624// if ((cr.getPartToken() != null)&&((dbvendor == EDbVendor.dbvmssql)||(dbvendor == EDbVendor.dbvsybase))){ 2625// if ((cr.getPartToken().tokentype == ETokenType.ttkeyword)&&(!(this.getGsqlparser().getFlexer().canBeColumnName(cr.getPartToken().tokencode)))){ 2626// // keyword can't be column name: 2627// //select * From dbo.table Where DATEDIFF(day, create_date, expiry_date) < 14 2628// return; 2629// } 2630// } 2631 2632 if ((cr.toString().startsWith("@"))) 2633// if ((cr.toString().endsWith("*"))||(cr.toString().startsWith("@"))) 2634 { 2635 cr.setObjectType(TObjectName.ttobjNotAObject); 2636 return; 2637 } 2638 2639 if (dbvendor == EDbVendor.dbvoracle){ 2640 if ( //(cr.toString().compareToIgnoreCase ("rowid") == 0)|| 2641 (cr.toString().compareToIgnoreCase ("sysdate") == 0) 2642 || (cr.toString().compareToIgnoreCase ("nextval") == 0) 2643 || (cr.toString().compareToIgnoreCase ("rownum") == 0) 2644 || (cr.toString().compareToIgnoreCase ("level") == 0) 2645 ){ 2646 cr.setObjectType(TObjectName.ttobjNotAObject); 2647 if (cr.getDbObjectType() == EDbObjectType.unknown){ 2648 cr.setDbObjectType(EDbObjectType.notAColumn); 2649 } 2650 return; 2651 } 2652 } 2653 2654 if (((cr.toString().toUpperCase().startsWith("INSERTED"))||(cr.toString().toUpperCase().startsWith("DELETED")))&&(plocation == ESqlClause.output)&&(targetTable != null)){ 2655 targetTable.getObjectNameReferences().addObjectName(cr); 2656 return; 2657 } 2658 2659 if ( ((cr.toString().toUpperCase().startsWith(":NEW")) 2660 ||(cr.toString().toUpperCase().startsWith(":OLD"))) 2661 &&(this.getTopStatement() instanceof TPlsqlCreateTrigger) 2662 &&(dbvendor == EDbVendor.dbvoracle)){ 2663 this.getTopStatement().tables.getTable(0).getObjectNameReferences().addObjectName(cr); 2664 return; 2665 } 2666 2667 2668 2669 int ret = this.tables.checkColumnReferenceInTables(cr); 2670 if (ret >= 0) { 2671 TTable lcTable = this.tables.getTable(ret); 2672 if (lcTable.isBaseTable()){ 2673 lcTable.getObjectNameReferences().addObjectName(cr); 2674 }else if (lcTable.isCTEName()){ 2675 //WITH temp 2676 // AS (SELECT * 2677 // FROM sysibm.systables), 2678 // temp1 2679 // AS (SELECT * 2680 // FROM sysibm.syscolumns) 2681 //SELECT * 2682 //FROM temp A 2683 // INNER JOIN temp1 B 2684 // ON A.creator = B.tbcreator 2685 // AND A.name = B.tbname 2686 TCTE lccte = findCTEByName(lcTable.toString()); 2687 if (lccte != null){ 2688 TObjectName objectName = new TObjectName(); 2689 objectName.init(cr.getPartToken()); 2690 if (lccte.getSubquery() != null){ 2691 lccte.getSubquery().linkColumnReferenceToTable(objectName,plocation); 2692 } 2693 } 2694 }else if (lcTable.getTableType() == ETableSource.subquery){ 2695 // link s2t1a1 to subselect2table1 via s2 2696 //select 2697 // s2.s2t1a1 2698 //from 2699 // ( 2700 // select s2t1.* 2701 // from subselect2table1 s2t1 2702 // ) s2 2703 TSelectSqlStatement subquery = lcTable.getSubquery(); 2704 2705 if(((subquery.getValueClause() == null))&&(!subquery.isCombinedQuery())&&(subquery.getResultColumnList() != null)&&(subquery.getResultColumnList().size() == 1)){ 2706 TResultColumn lcColumn = subquery.getResultColumnList().getResultColumn(0); 2707 if (lcColumn.toString().endsWith("*")){ 2708 boolean isfound = false; 2709 2710 for(int i=0;i<subquery.tables.size();i++){ 2711 if (subquery.tables.getTable(i).getTableType() == ETableSource.subquery) continue; 2712 String columnStr = null; 2713 if (cr.getPartToken() != null){ 2714 //cr.getObjectType() is not ttObjColumn, so we can't use 2715 // getColumnToken, this is a bug, need to check it later. 2716 columnStr = cr.getPartToken().toString(); 2717 } 2718 if (this.fireOnMetaDatabaseTableColumn( 2719 subquery.tables.getTable(i).getTableName().getServerString(), 2720 subquery.tables.getTable(i).getTableName().getDatabaseString(), 2721 subquery.tables.getTable(i).getTableName().getSchemaString(), 2722 subquery.tables.getTable(i).getName(),columnStr)){ 2723 subquery.tables.getTable(i).getObjectNameReferences().addObjectName(cr); 2724 isfound = true; 2725 break; 2726 } 2727 } 2728 2729 2730 2731 if (!isfound) 2732 { 2733 if(subquery.tables.size() > 1){ 2734 cr.setTableDetermined(false); 2735 } 2736 for(int i=0;i<subquery.tables.size();i++){ 2737 subquery.tables.getTable(i).getObjectNameReferences().addObjectName(cr); 2738 } 2739 } 2740 2741 } // "*" 2742 } 2743 } 2744 }else if (ret == -2){ 2745 // no qualifier before column, check is this column of a cte, if not,set it to non-cte table 2746 boolean isfound = false; 2747 for (int i=0;i<this.tables.size();i++){ 2748 if ((this.tables.getTable(i).isCTEName()) &&(this.tables.getTable(i).getCteColomnReferences() != null)){ 2749 if (this.tables.getTable(i).getCteColomnReferences().searchColumnReference(cr) >= 0){ 2750 this.tables.getTable(i).getObjectNameReferences().addObjectName(cr); 2751 isfound = true; 2752 break; 2753 } 2754 } 2755 } 2756 2757 // no qualifier before column, but we still need to check uplevel table like this: 2758 //SELECT 2759 // col1 , 2760 // 2761 // ( SELECT col2 2762 // FROM tab1 2763 // WHERE col2 = col1 ) 2764 // FROM tab2 2765 // we need to link col1 to tab2 in up level, but not to tab1 2766 if ((!isfound) &&( 2767 (cr.getLocation() != ESqlClause.resultColumn) 2768 &&(cr.getLocation() != ESqlClause.insertColumn) 2769 &&(cr.getLocation() != ESqlClause.mergeInsert) 2770 &&(cr.getLocation() != ESqlClause.selectList) 2771 ) ){ // code #111 2772 TCustomSqlStatement lcParent = null; 2773 lcParent = this.getParentStmt(); 2774 while ( lcParent != null) { 2775 TTable lcTable; 2776 //ret = lcParent.tables.checkColumnReferenceInTables(cr); 2777 if (lcParent.sqlstatementtype != ESqlStatementType.sstselect) { 2778 break; 2779 } 2780 for (int i=0;i<lcParent.tables.size();i++){ 2781 lcTable = lcParent.tables.getTable(i); 2782 if (lcTable.getTableType() == ETableSource.objectname) { 2783 for(int k = 0; k< lcTable.getObjectNameReferences().size();k++){ 2784 if (lcTable.getObjectNameReferences().getObjectName(k).isTableDetermined()){ 2785 if (cr.toString().equalsIgnoreCase(lcTable.getObjectNameReferences().getObjectName(k).toString())){ 2786 isfound = true; 2787 break; 2788 } 2789 } 2790 } 2791 if (isfound) break; 2792 } 2793 } 2794 2795 if (isfound){ 2796 break; 2797 }else{ 2798 lcParent = lcParent.getParentStmt(); 2799 } 2800 } // while 2801 2802 } // end of code #111 2803 2804 if (!isfound){ 2805 isfound = checkNonQualifiedColumnReferenceInSubQueryOfUplevelStmt(cr 2806 , ((plocation == ESqlClause.resultColumn) 2807 ||(plocation == ESqlClause.insertColumn) 2808 ||(plocation == ESqlClause.mergeInsert) 2809 ||(plocation == ESqlClause.selectList) 2810 ) 2811 ); 2812 } 2813 2814 if ((!isfound)&&(this.tables.size() > 0)){ 2815 int candidate = 0, firstCandidate = -1; 2816 // add this column reference to first non-cte( or cte with column list is null) and non-subquery table 2817 for (int i=0;i<this.tables.size();i++){ 2818 // no qualified column can't belong to a table with alias, that column must be qualified if it's belong to a table with alias 2819 //if (this.tables.getTable(i).aliasClause != null) continue; 2820 if ( 2821 ( 2822 (!this.tables.getTable(i).isCTEName()) 2823 ||((this.tables.getTable(i).isCTEName())&&(this.tables.getTable(i).getCteColomnReferences() == null)) 2824 )&&((this.tables.getTable(i).getTableType() != ETableSource.subquery)) 2825 ) 2826 { 2827 candidate++; 2828 if (firstCandidate == -1) firstCandidate = i; 2829 if (this.fireOnMetaDatabaseTableColumn( 2830 this.tables.getTable(i).getTableName().getServerString(), 2831 this.tables.getTable(i).getTableName().getDatabaseString(), 2832 this.tables.getTable(i).getTableName().getSchemaString(), 2833 this.tables.getTable(i).getName(),cr.toString())){ 2834 this.tables.getTable(i).getObjectNameReferences().addObjectName(cr); 2835 isfound = true; 2836 break; 2837 } 2838 else{ 2839 this.tables.getTable(i).getObjectNameReferences().addObjectName(cr); 2840 if (this.tables.size() > 1){ 2841 cr.setTableDetermined(false); 2842 } 2843 isfound = true; 2844 break; 2845 } 2846 } 2847 } 2848 if ((!isfound) && (candidate == 1)){ 2849 this.tables.getTable(firstCandidate).getObjectNameReferences().addObjectName(cr); 2850 } 2851 } 2852 }else if (ret == -1){ 2853 TCustomSqlStatement lcParent = null; 2854 lcParent = this.getParentStmt(); 2855 while ( lcParent != null) { 2856 ret = lcParent.tables.checkColumnReferenceInTables(cr); 2857 if (ret >= 0){ 2858 lcParent.tables.getTable(ret).getObjectNameReferences().addObjectName(cr); 2859 break; 2860 }else{ 2861 lcParent = lcParent.getParentStmt(); 2862 } 2863 } // while 2864 } //-1 2865 2866 } 2867 2868 /** 2869 * Found out is a non qualified column is a column in uplevel subquery table like this: 2870 * take ma_parkey for example: ma_parkey is not a physical column 2871 * 2872 SELECT c_mandant 2873 , CASE WHEN EXISTS (SELECT 1 2874 FROM CDS_H_GRUPPE GRP1 2875 WHERE GRP1.c_mandant = c_mandant 2876 AND GRP1.parkey1 = ma_parkey) 2877 THEN 1 2878 ELSE NULL 2879 END MA_ME 2880 FROM (SELECT c_mandant 2881 , CASE WHEN funktionscode = 'U' 2882 THEN parkey1 2883 ELSE parkey2 2884 END MA_PARKEY 2885 FROM 2886 CDS_H_GRUPPE 2887 ) 2888 */ 2889 public boolean checkNonQualifiedColumnReferenceInSubQueryOfUplevelStmt(TObjectName crf,boolean sameLevelOnly){ 2890 boolean ret = false; 2891 2892 TCustomSqlStatement lcParent = null; 2893 lcParent = this;//getParentStmt(); 2894 while ( lcParent != null) { 2895 TTable lcTable; 2896 for (int i=0;i<lcParent.tables.size();i++){ 2897 lcTable = lcParent.tables.getTable(i); 2898 2899 if ((lcTable.getTableType() != ETableSource.subquery)) {continue;} 2900 2901 ret = isColumnNameInSelectList(crf.toString(),lcTable.subquery); 2902 if (ret) {break;} 2903 2904 } 2905 if (ret) {break;} 2906 else{ 2907 if (sameLevelOnly){ 2908 lcParent = null; 2909 }else{ 2910 lcParent = lcParent.getParentStmt(); 2911 } 2912 } 2913 } // while 2914 2915 return ret; 2916 } 2917 2918 private boolean isColumnNameInSelectList(String pColumn, TSelectSqlStatement pSelect){ 2919 boolean ret = false; 2920 TResultColumn lcColumn; 2921 if (pSelect.isCombinedQuery()){ 2922 ret = isColumnNameInSelectList(pColumn,pSelect.getLeftStmt()); 2923 if (!ret){ 2924 ret = isColumnNameInSelectList(pColumn,pSelect.getRightStmt()); 2925 } 2926 }else{ 2927 if (pSelect.getResultColumnList() != null){ //if it's a db2 value row, then pSelect.getResultColumnList() will be null 2928 for(int j=0;j<pSelect.getResultColumnList().size();j++){ 2929 lcColumn = pSelect.getResultColumnList().getResultColumn(j); 2930 if (lcColumn.getAliasClause() != null){ 2931 ret = pColumn.equalsIgnoreCase(lcColumn.getAliasClause().toString()); 2932 } 2933 if (ret) break; 2934 ret = pColumn.equalsIgnoreCase(lcColumn.getExpr().toString()); 2935 if (ret) break; 2936 } 2937 } 2938 } 2939 return ret; 2940 } 2941 2942 public TCustomSqlStatement getTopStatement(){ 2943 TCustomSqlStatement ret = this; 2944 while (ret.getParentStmt() != null){ 2945 ret = ret.getParentStmt(); 2946 } 2947 return ret; 2948 } 2949 2950 2951// public String toScript(){ 2952// if (!isChanged()){ 2953// return this.toString(); 2954// } 2955// return super.toScript(); 2956// } 2957 2958} 2959 2960class constantVisitor extends TParseTreeVisitor { 2961 private boolean inWhere = false,inExprList = false; 2962 public void preVisit(TWhereClause node){ 2963 inWhere = true; 2964 } 2965 2966 public void postVisit(TWhereClause node){ 2967 inWhere = false; 2968 } 2969 2970 public void preVisit(TExpression node){ 2971 if (inWhere){ 2972 switch (node.getExpressionType()){ 2973 case list_t: 2974 inExprList = true; 2975 boolean isNumber = true; 2976 if (node.getExprList().size() > 0){ 2977 // check the type of the constant in the expr list 2978 TExpression expr = node.getExprList().getExpression(0); 2979 if (expr.getExpressionType() == EExpressionType.simple_constant_t){ 2980 if (expr.getConstantOperand().getLiteralType() == ELiteralType.etString){ 2981 isNumber = false; 2982 } 2983 } 2984 } 2985 2986 TSourceToken lcStartToken = node.getStartToken(); 2987 TSourceToken lcEndToken = node.getEndToken(); 2988 int tokenPos = 0; 2989 if ((lcEndToken != null) && (lcStartToken != null)){ 2990 TSourceToken lcCurrentToken = lcStartToken; 2991 while (lcCurrentToken != null){ 2992 2993 if (lcCurrentToken.equals(lcEndToken)){ 2994 break; 2995 }else{ 2996 2997 if (tokenPos == 1){ 2998 if (isNumber){ 2999 lcCurrentToken.setTextWithBackup("999"); 3000 }else{ 3001 lcCurrentToken.setTextWithBackup("'placeholder_str'"); 3002 } 3003 }else if (tokenPos > 1){ 3004 lcCurrentToken.tokenstatus = ETokenStatus.tsdeleted; 3005 } 3006 3007 lcCurrentToken = lcCurrentToken.getNextTokenInChain(); 3008 tokenPos++; 3009 } 3010 } 3011 } 3012 3013 break; 3014 } 3015 } // where 3016 } 3017 3018 public void postVisit(TExpression node){ 3019 if (inWhere){ 3020 switch (node.getExpressionType()){ 3021 case list_t: 3022 inExprList = false; 3023 break; 3024 } 3025 } 3026 } 3027 3028 public void preVisit(TConstant node){ 3029 if (inWhere&&(!inExprList)){ 3030 switch (node.getLiteralType()){ 3031 case etNumber: 3032 case etFloat: 3033 node.getStartToken().setTextWithBackup("999"); 3034 break; 3035 case etString: 3036 node.getStartToken().setTextWithBackup("'placeholder_str'"); 3037 break; 3038 } 3039 } 3040 } 3041 3042 public void preVisit(TFunctionCall node){ 3043 if (TBaseType.as_canonical_f_decrypt_replace_password){ 3044 int i = TBaseType.searchCryptFunction(node.getFunctionName().toString()); 3045 3046 if (i>0){ // find this function 3047 if (node.getArgs().size() >= i){ 3048 TExpression secondArg = node.getArgs().getExpression(i-1); 3049 if (secondArg.getExpressionType() == EExpressionType.simple_constant_t){ 3050 TConstant constant = secondArg.getConstantOperand(); 3051 constant.getValueToken().setTextWithBackup("'***'"); 3052 //System.out.println(node.toString()+":"+constant.toString()); 3053 }else if (secondArg.getExpressionType() == EExpressionType.simple_object_name_t){ 3054 TObjectName objectName = secondArg.getObjectOperand(); 3055 objectName.getStartToken().setTextWithBackup("'***'"); 3056 //System.out.println(node.toString()+":"+constant.toString()); 3057 } 3058 } 3059 } 3060 3061 } 3062 } 3063 3064 void processConstant(TConstant node){ 3065 switch (node.getLiteralType()){ 3066 case etNumber: 3067 case etFloat: 3068 node.getStartToken().setTextWithBackup("999"); 3069 break; 3070 case etString: 3071 node.getStartToken().setTextWithBackup("'placeholder_str'"); 3072 break; 3073 } 3074 } 3075 3076}