1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.iapi.services.context.ContextManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 import org.apache.derby.iapi.sql.compile.CompilerContext; 30 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 31 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 32 33 import org.apache.derby.iapi.services.sanity.SanityManager; 34 35 import org.apache.derby.iapi.util.JBitSet; 36 37 import java.util.Properties ; 38 39 50 public class FromSubquery extends FromTable 51 { 52 boolean generatedForGroupByClause; 53 boolean generatedForHavingClause; 54 ResultSetNode subquery; 55 56 64 public void init( 65 Object subquery, 66 Object correlationName, 67 Object derivedRCL, 68 Object tableProperties) 69 { 70 super.init(correlationName, tableProperties); 71 this.subquery = (ResultSetNode) subquery; 72 resultColumns = (ResultColumnList) derivedRCL; 73 } 74 75 81 82 public String toString() 83 { 84 if (SanityManager.DEBUG) 85 { 86 return 87 "generatedForGroupByClause: " + generatedForGroupByClause + "\n" + 88 "generatedForHavingClause: " + generatedForHavingClause + "\n" + 89 super.toString(); 90 } 91 else 92 { 93 return ""; 94 } 95 } 96 97 103 104 public void printSubNodes(int depth) 105 { 106 if (SanityManager.DEBUG) { 107 super.printSubNodes(depth); 108 109 if (subquery != null) 110 { 111 printLabel(depth, "subquery: "); 112 subquery.treePrint(depth + 1); 113 } 114 } 115 } 116 117 122 public ResultSetNode getSubquery() 123 { 124 return subquery; 125 } 126 127 134 public void markAsForGroupByClause() 135 { 136 generatedForGroupByClause = true; 137 } 138 139 145 public void markAsForHavingClause() 146 { 147 generatedForHavingClause = true; 148 } 149 150 163 protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch) 164 throws StandardException 165 { 166 if (generatedForGroupByClause || generatedForHavingClause) 167 { 168 return subquery.getFromTableByName(name, schemaName, exactMatch); 169 } 170 else 171 { 172 return super.getFromTableByName(name, schemaName, exactMatch); 173 } 174 } 175 176 186 187 public ResultSetNode bindNonVTITables(DataDictionary dataDictionary, 188 FromList fromListParam) 189 throws StandardException 190 { 191 192 if (tableNumber == -1) tableNumber = getCompilerContext().getNextTableNumber(); 194 195 subquery = subquery.bindNonVTITables(dataDictionary, fromListParam); 196 197 return this; 198 } 199 200 209 210 public ResultSetNode bindVTITables(FromList fromListParam) 211 throws StandardException 212 { 213 subquery = subquery.bindVTITables(fromListParam); 214 215 return this; 216 } 217 218 226 227 public void rejectParameters() throws StandardException 228 { 229 subquery.rejectParameters(); 230 } 231 232 239 240 public void bindExpressions(FromList fromListParam) 241 throws StandardException 242 { 243 FromList emptyFromList = 244 (FromList) getNodeFactory().getNode( 245 C_NodeTypes.FROM_LIST, 246 getNodeFactory().doJoinOrderOptimization(), 247 getContextManager()); 248 ResultColumnList derivedRCL = resultColumns; 249 ResultColumnList subqueryRCL; 250 FromList nestedFromList; 251 252 258 if ( generatedForGroupByClause || generatedForHavingClause ) 259 { nestedFromList = fromListParam; } 260 else { nestedFromList = emptyFromList; } 261 262 subquery.bindExpressions(nestedFromList); 263 subquery.bindResultColumns(nestedFromList); 264 265 277 subqueryRCL = subquery.getResultColumns(); 278 if (resultColumns != null && resultColumns.getCountMismatchAllowed() && 279 resultColumns.size() < subqueryRCL.size()) 280 { 281 for (int index = subqueryRCL.size() - 1; 282 index >= resultColumns.size(); 283 index--) 284 { 285 subqueryRCL.removeElementAt(index); 286 } 287 } 288 289 subquery.setResultColumns(subqueryRCL.copyListAndObjects()); 290 subqueryRCL.genVirtualColumnNodes(subquery, subquery.getResultColumns()); 291 resultColumns = subqueryRCL; 292 293 294 if (derivedRCL != null) 295 { 296 resultColumns.propagateDCLInfo(derivedRCL, correlationName); 297 } 298 } 299 300 313 314 public ResultColumn getMatchingColumn(ColumnReference columnReference) throws StandardException 315 { 316 ResultColumn resultColumn = null; 317 String columnsTableName; 318 319 324 325 columnsTableName = columnReference.getTableName(); 326 327 358 if (columnReference.getGeneratedToReplaceAggregate()) { 360 resultColumn = resultColumns.getResultColumn(columnReference.getColumnName()); 361 } 362 else if (generatedForGroupByClause && generatedForHavingClause && 363 (columnsTableName != null || 364 columnReference.getClause() != ValueNode.IN_SELECT_LIST)) { 366 if (SanityManager.DEBUG) 367 { 368 SanityManager.ASSERT(correlationName == null, 369 "correlationName expected to be null"); 370 SanityManager.ASSERT(subquery instanceof SelectNode, 371 "subquery expected to be instanceof SelectNode, not " + 372 subquery.getClass().getName()); 373 } 374 375 SelectNode select = (SelectNode) subquery; 376 377 resultColumn = select.getFromList().bindColumnReference(columnReference); 378 379 382 if (resultColumn != null) 383 { 384 385 resultColumn = subquery.getResultColumns().findParentResultColumn( 386 resultColumn); 387 if (resultColumn != null) 388 { 389 390 resultColumn = resultColumns.findParentResultColumn( 391 resultColumn); 392 } 393 } 394 } 395 else if ((generatedForHavingClause && ! generatedForGroupByClause) && (columnReference.getClause() != ValueNode.IN_SELECT_LIST) ) 397 { 398 resultColumn = null; 399 } 400 else if (generatedForGroupByClause) { 402 resultColumn = resultColumns.getResultColumn( 403 columnsTableName, 404 columnReference.getColumnName()); 405 } 406 else if (columnsTableName == null || columnsTableName.equals(correlationName)) { 408 resultColumn = resultColumns.getAtMostOneResultColumn(columnReference, correlationName); 409 } 410 411 412 if (resultColumn != null) 413 { 414 columnReference.setTableNumber(tableNumber); 415 } 416 417 return resultColumn; 418 } 419 420 438 439 public ResultSetNode preprocess(int numTables, 440 GroupByList gbl, 441 FromList fromList) 442 throws StandardException 443 { 444 464 465 subquery = subquery.preprocess(numTables, gbl, fromList); 466 467 479 if ((gbl == null || gbl.size() == 0) && 480 tableProperties == null && 481 subquery.flattenableInFromSubquery(fromList)) 482 { 483 484 setReferencedTableMap(subquery.getReferencedTableMap()); 485 return this; 486 } 487 488 return extractSubquery(numTables); 489 } 490 491 501 502 public ResultSetNode extractSubquery(int numTables) 503 throws StandardException 504 { 505 JBitSet newJBS; 506 ResultSetNode newPRN; 507 508 newPRN = (ResultSetNode) getNodeFactory().getNode( 509 C_NodeTypes.PROJECT_RESTRICT_NODE, 510 subquery, 511 resultColumns, 512 null, 513 null, 514 null, 515 null, 516 tableProperties, 517 getContextManager() ); 518 519 520 newJBS = new JBitSet(numTables); 521 newJBS.set(tableNumber); 522 newPRN.setReferencedTableMap(newJBS); 523 ((FromTable) newPRN).setTableNumber(tableNumber); 524 525 return newPRN; 526 } 527 528 554 public FromList flatten(ResultColumnList rcl, 555 PredicateList outerPList, 556 SubqueryList sql, 557 GroupByList gbl) 558 559 throws StandardException 560 { 561 FromList fromList = null; 562 SelectNode selectNode; 563 564 resultColumns.setRedundant(); 565 566 subquery.getResultColumns().setRedundant(); 567 568 571 if (subquery instanceof SelectNode) 572 { 573 selectNode = (SelectNode) subquery; 574 fromList = selectNode.getFromList(); 575 576 578 if (selectNode.getWherePredicates().size() > 0) 579 { 580 outerPList.destructiveAppend(selectNode.getWherePredicates()); 581 } 582 583 if (selectNode.getWhereSubquerys().size() > 0) 584 { 585 sql.destructiveAppend(selectNode.getWhereSubquerys()); 586 } 587 } 588 else if ( ! (subquery instanceof RowResultSetNode)) 589 { 590 if (SanityManager.DEBUG) 591 { 592 SanityManager.THROWASSERT("subquery expected to be either a SelectNode or a RowResultSetNode, but is a " + subquery.getClass().getName()); 593 } 594 } 595 596 600 rcl.remapColumnReferencesToExpressions(); 601 outerPList.remapColumnReferencesToExpressions(); 602 if (gbl != null) 603 { 604 gbl.remapColumnReferencesToExpressions(); 605 } 606 607 return fromList; 608 } 609 610 616 617 public String getExposedName() 618 { 619 return correlationName; 620 } 621 622 627 public ResultColumnList getAllResultColumns(TableName allTableName) 628 throws StandardException 629 { 630 ResultColumnList rcList = null; 631 TableName exposedName; 632 TableName toCompare; 633 634 635 if(allTableName != null) 636 toCompare = makeTableName(allTableName.getSchemaName(),correlationName); 637 else 638 toCompare = makeTableName(null,correlationName); 639 640 if ( allTableName != null && 641 ! allTableName.equals(toCompare)) 642 { 643 return null; 644 } 645 646 650 exposedName = makeTableName(null, correlationName); 651 652 rcList = (ResultColumnList) getNodeFactory().getNode( 653 C_NodeTypes.RESULT_COLUMN_LIST, 654 getContextManager()); 655 656 660 int rclSize = resultColumns.size(); 661 for (int index = 0; index < rclSize; index++) 662 { 663 ResultColumn resultColumn = (ResultColumn) resultColumns.elementAt(index); 664 ValueNode valueNode; 665 String columnName; 666 667 if (resultColumn.isGenerated()) 668 { 669 continue; 670 } 671 672 columnName = resultColumn.getName(); 674 boolean isNameGenerated = resultColumn.isNameGenerated(); 675 676 679 TableName tableName; 680 681 if (correlationName == null && generatedForGroupByClause) 682 { 683 tableName = makeTableName(null, resultColumn.getTableName()); 684 } 685 else 686 { 687 tableName = exposedName; 688 } 689 valueNode = (ValueNode) getNodeFactory().getNode( 690 C_NodeTypes.COLUMN_REFERENCE, 691 columnName, 692 tableName, 693 getContextManager()); 694 resultColumn = (ResultColumn) getNodeFactory().getNode( 695 C_NodeTypes.RESULT_COLUMN, 696 columnName, 697 valueNode, 698 getContextManager()); 699 700 resultColumn.setNameGenerated(isNameGenerated); 701 rcList.addResultColumn(resultColumn); 703 } 704 return rcList; 705 } 706 707 710 public void disablePrivilegeCollection() 711 { 712 super.disablePrivilegeCollection(); 713 subquery.disablePrivilegeCollection(); 714 } 715 716 726 public boolean referencesTarget(String name, boolean baseTable) 727 throws StandardException 728 { 729 return subquery.referencesTarget(name, baseTable); 730 } 731 732 739 public boolean referencesSessionSchema() 740 throws StandardException 741 { 742 return subquery.referencesSessionSchema(); 743 } 744 745 752 public void bindUntypedNullsToResultColumns(ResultColumnList bindingRCL) 753 throws StandardException 754 { 755 subquery.bindUntypedNullsToResultColumns(bindingRCL); 756 } 757 758 764 void decrementLevel(int decrement) 765 { 766 super.decrementLevel(decrement); 767 subquery.decrementLevel(decrement); 768 } 769 } 770 | Popular Tags |