1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.sql.compile.CompilerContext; 25 import org.apache.derby.iapi.sql.compile.CostEstimate; 26 import org.apache.derby.iapi.sql.compile.RequiredRowOrdering; 27 import org.apache.derby.iapi.sql.compile.RowOrdering; 28 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 29 30 import org.apache.derby.iapi.error.StandardException; 31 import org.apache.derby.iapi.services.sanity.SanityManager; 32 33 import org.apache.derby.impl.sql.compile.ActivationClassBuilder; 34 35 import org.apache.derby.iapi.sql.Activation; 36 import org.apache.derby.iapi.sql.ResultSet; 37 38 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 39 40 import org.apache.derby.iapi.services.compiler.MethodBuilder; 41 42 import org.apache.derby.iapi.services.loader.GeneratedMethod; 43 44 import org.apache.derby.iapi.store.access.ColumnOrdering; 45 import org.apache.derby.iapi.store.access.SortCostController; 46 import org.apache.derby.iapi.store.access.TransactionController; 47 48 import org.apache.derby.iapi.types.DataValueDescriptor; 49 50 import org.apache.derby.iapi.reference.ClassName; 51 import org.apache.derby.iapi.reference.Limits; 52 import org.apache.derby.iapi.reference.SQLState; 53 54 import org.apache.derby.iapi.util.JBitSet; 55 import org.apache.derby.iapi.services.classfile.VMOpcode; 56 57 import java.util.Properties ; 58 59 67 public class OrderByList extends OrderedColumnList 68 implements RequiredRowOrdering { 69 70 private boolean allAscending = true; 71 private boolean alwaysSort; 72 private ResultSetNode resultToSort; 73 private SortCostController scc; 74 private Object [] resultRow; 75 private ColumnOrdering[] columnOrdering; 76 private int estimatedRowSize; 77 private boolean sortNeeded = true; 78 79 84 public void addOrderByColumn(OrderByColumn column) 85 { 86 addElement(column); 87 88 if (! column.isAscending()) 89 allAscending = false; 90 } 91 92 97 boolean allAscending() 98 { 99 return allAscending; 100 } 101 102 107 public OrderByColumn getOrderByColumn(int position) { 108 if (SanityManager.DEBUG) 109 SanityManager.ASSERT(position >=0 && position < size()); 110 return (OrderByColumn) elementAt(position); 111 } 112 113 118 public void printSubNodes(int depth) { 119 120 if (SanityManager.DEBUG) 121 { 122 for (int index = 0; index < size(); index++) 123 { 124 ( (OrderByColumn) (elementAt(index)) ).treePrint(depth); 125 } 126 } 127 } 128 129 137 public void bindOrderByColumns(ResultSetNode target) 138 throws StandardException { 139 140 141 resultToSort = target; 142 143 int size = size(); 144 145 146 if (size > Limits.DB2_MAX_ELEMENTS_IN_ORDER_BY) 147 { 148 throw StandardException.newException(SQLState.LANG_TOO_MANY_ELEMENTS); 149 } 150 151 for (int index = 0; index < size; index++) 152 { 153 OrderByColumn obc = (OrderByColumn) elementAt(index); 154 obc.bindOrderByColumn(target); 155 156 160 if ( ! 161 (obc.getResultColumn().getExpression() instanceof ColumnReference)) 162 { 163 alwaysSort = true; 164 } 165 } 166 } 167 168 175 public void pullUpOrderByColumns(ResultSetNode target) 176 throws StandardException { 177 178 179 resultToSort = target; 180 181 int size = size(); 182 for (int index = 0; index < size; index++) 183 { 184 OrderByColumn obc = (OrderByColumn) elementAt(index); 185 obc.pullUpOrderByColumn(target); 186 } 187 188 } 189 190 199 boolean isInOrderPrefix(ResultColumnList sourceRCL) 200 { 201 boolean inOrderPrefix = true; 202 int rclSize = sourceRCL.size(); 203 204 if (SanityManager.DEBUG) 205 { 206 if (size() > sourceRCL.size()) 207 { 208 SanityManager.THROWASSERT( 209 "size() (" + size() + 210 ") expected to be <= sourceRCL.size() (" + 211 sourceRCL.size() + ")"); 212 } 213 } 214 215 int size = size(); 216 for (int index = 0; index < size; index++) 217 { 218 if (((OrderByColumn) elementAt(index)).getResultColumn() != 219 (ResultColumn) sourceRCL.elementAt(index)) 220 { 221 return false; 222 } 223 } 224 return true; 225 } 226 227 233 void resetToSourceRCs() 234 { 235 int size = size(); 236 for (int index = 0; index < size; index++) 237 { 238 OrderByColumn obc = (OrderByColumn) elementAt(index); 239 obc.resetToSourceRC(); 240 } 241 } 242 243 251 ResultColumnList reorderRCL(ResultColumnList resultColumns) 252 throws StandardException 253 { 254 ResultColumnList newRCL = (ResultColumnList) getNodeFactory().getNode( 255 C_NodeTypes.RESULT_COLUMN_LIST, 256 getContextManager()); 257 258 259 int size = size(); 260 for (int index = 0; index < size; index++) 261 { 262 OrderByColumn obc = (OrderByColumn) elementAt(index); 263 newRCL.addElement(obc.getResultColumn()); 264 resultColumns.removeElement(obc.getResultColumn()); 265 } 266 267 268 newRCL.destructiveAppend(resultColumns); 269 newRCL.resetVirtualColumnIds(); 270 return newRCL; 271 } 272 273 279 void removeConstantColumns(PredicateList whereClause) 280 { 281 282 for (int loc = size() - 1; 283 loc >= 0; 284 loc--) 285 { 286 OrderByColumn obc = (OrderByColumn) elementAt(loc); 287 288 if (obc.constantColumn(whereClause)) 289 { 290 removeElementAt(loc); 291 } 292 } 293 } 294 295 301 void removeDupColumns() 302 { 303 304 for (int loc = size() - 1; loc > 0; loc--) 305 { 306 OrderByColumn obc = (OrderByColumn) elementAt(loc); 307 int colPosition = obc.getColumnPosition(); 308 309 for (int inner = 0; inner < loc; inner++) 310 { 311 OrderByColumn prev_obc = (OrderByColumn) elementAt(inner); 312 if (colPosition == prev_obc.getColumnPosition()) 313 { 314 removeElementAt(loc); 315 break; 316 } 317 } 318 } 319 } 320 321 329 public void generate(ActivationClassBuilder acb, 330 MethodBuilder mb, 331 ResultSetNode child) 332 throws StandardException 333 { 334 338 if ( ! sortNeeded) { 339 child.generate(acb, mb); 340 return; 341 } 342 343 353 CompilerContext cc = getCompilerContext(); 354 355 356 359 int orderItem = acb.addItem(acb.getColumnOrdering(this)); 360 361 362 375 376 acb.pushGetResultSetFactoryExpression(mb); 377 378 child.generate(acb, mb); 379 380 int resultSetNumber = cc.getNextResultSetNumber(); 381 382 mb.push(false); 384 385 mb.push(false); 387 388 mb.push(orderItem); 389 390 child.getResultColumns().generateHolder(acb, mb); 392 393 mb.push(child.getResultColumns().getTotalColumnSize()); 394 395 mb.push(resultSetNumber); 396 397 CostEstimate costEstimate = child.getFinalCostEstimate(); 400 401 mb.push(costEstimate.rowCount()); 402 mb.push(costEstimate.getEstimatedCost()); 403 404 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String ) null, "getSortResultSet", 405 ClassName.NoPutResultSet, 9); 406 407 } 408 409 410 411 416 public int sortRequired(RowOrdering rowOrdering) throws StandardException 417 { 418 return sortRequired(rowOrdering, (JBitSet) null); 419 } 420 421 426 public int sortRequired(RowOrdering rowOrdering, JBitSet tableMap) 427 throws StandardException 428 { 429 433 if (alwaysSort) 434 { 435 return RequiredRowOrdering.SORT_REQUIRED; 436 } 437 438 442 int position = 0; 443 int size = size(); 444 for (int loc = 0; loc < size; loc++) 445 { 446 OrderByColumn obc = getOrderByColumn(loc); 447 448 450 454 ValueNode expr = obc.getResultColumn().getExpression(); 456 457 if ( ! (expr instanceof ColumnReference)) 458 { 459 return RequiredRowOrdering.SORT_REQUIRED; 460 } 461 462 ColumnReference cr = (ColumnReference) expr; 463 464 472 if (tableMap != null) 473 { 474 if ( ! tableMap.get(cr.getTableNumber())) 475 { 476 477 for (int remainingPosition = loc + 1; 478 remainingPosition < size(); 479 remainingPosition++) 480 { 481 OrderByColumn remainingobc = getOrderByColumn(loc); 482 483 ResultColumn remainingrc = 484 remainingobc.getResultColumn(); 485 486 ValueNode remainingexpr = remainingrc.getExpression(); 487 488 if (remainingexpr instanceof ColumnReference) 489 { 490 ColumnReference remainingcr = 491 (ColumnReference) remainingexpr; 492 if (tableMap.get(remainingcr.getTableNumber())) 493 { 494 return RequiredRowOrdering.SORT_REQUIRED; 495 } 496 } 497 } 498 499 return RequiredRowOrdering.NOTHING_REQUIRED; 500 } 501 } 502 503 if ( ! rowOrdering.alwaysOrdered(cr.getTableNumber())) 504 { 505 509 if ( ! rowOrdering.orderedOnColumn( 510 obc.isAscending() ? 511 RowOrdering.ASCENDING : RowOrdering.DESCENDING, 512 position, 513 cr.getTableNumber(), 514 cr.getColumnNumber() 515 )) 516 { 517 return RequiredRowOrdering.SORT_REQUIRED; 518 } 519 520 525 position++; 526 } 527 } 528 529 return RequiredRowOrdering.NOTHING_REQUIRED; 530 } 531 532 537 public void estimateCost(double estimatedInputRows, 538 RowOrdering rowOrdering, 539 CostEstimate resultCost) 540 throws StandardException 541 { 542 547 if (scc == null) 548 { 549 scc = getCompilerContext().getSortCostController(); 550 551 resultRow = 552 resultToSort.getResultColumns().buildEmptyRow().getRowArray(); 553 columnOrdering = getColumnOrdering(); 554 estimatedRowSize = 555 resultToSort.getResultColumns().getTotalColumnSize(); 556 } 557 558 long inputRows = (long) estimatedInputRows; 559 long exportRows = inputRows; 560 double sortCost; 561 562 sortCost = scc.getSortCost( 563 (DataValueDescriptor[]) resultRow, 564 columnOrdering, 565 false, 566 inputRows, 567 exportRows, 568 estimatedRowSize 569 ); 570 571 resultCost.setCost(sortCost, estimatedInputRows, estimatedInputRows); 572 } 573 574 575 public void sortNeeded() 576 { 577 sortNeeded = true; 578 } 579 580 581 public void sortNotNeeded() 582 { 583 sortNeeded = false; 584 } 585 586 592 void remapColumnReferencesToExpressions() throws StandardException 593 { 594 } 595 596 601 public boolean getSortNeeded() 602 { 603 return sortNeeded; 604 } 605 } 606 | Popular Tags |