1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.monitor.Monitor; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 29 import org.apache.derby.iapi.services.stream.InfoStreams; 30 31 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 32 import org.apache.derby.iapi.sql.conn.StatementContext; 33 34 import org.apache.derby.iapi.sql.execute.CursorResultSet; 35 import org.apache.derby.iapi.sql.execute.ExecRow; 36 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 37 38 import org.apache.derby.iapi.types.DataValueDescriptor; 39 import org.apache.derby.iapi.sql.Activation; 40 import org.apache.derby.iapi.sql.ResultSet; 41 42 import org.apache.derby.iapi.services.loader.GeneratedMethod; 43 44 import org.apache.derby.iapi.error.StandardException; 45 46 import org.apache.derby.iapi.types.RowLocation; 47 48 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl; 49 50 51 57 class ProjectRestrictResultSet extends NoPutResultSetImpl 58 implements CursorResultSet 59 { 60 61 public long restrictionTime; 62 public long projectionTime; 63 64 public NoPutResultSet source; 67 public GeneratedMethod constantRestriction; 68 public GeneratedMethod restriction; 69 public boolean doesProjection; 70 private GeneratedMethod projection; 71 private int[] projectMapping; 72 private boolean runTimeStatsOn; 73 private ExecRow mappedResultRow; 74 public boolean reuseResult; 75 76 private boolean shortCircuitOpen; 77 78 private ExecRow projRow; 79 80 ProjectRestrictResultSet(NoPutResultSet s, 84 Activation a, 85 GeneratedMethod r, 86 GeneratedMethod p, 87 int resultSetNumber, 88 GeneratedMethod cr, 89 int mapRefItem, 90 boolean reuseResult, 91 boolean doesProjection, 92 double optimizerEstimatedRowCount, 93 double optimizerEstimatedCost) 94 throws StandardException 95 { 96 super(a, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost); 97 source = s; 98 if (SanityManager.DEBUG) 101 { 102 SanityManager.ASSERT(source != null, 103 "PRRS(), source expected to be non-null"); 104 } 105 restriction = r; 106 projection = p; 107 constantRestriction = cr; 108 projectMapping = ((ReferencedColumnsDescriptorImpl) a.getPreparedStatement().getSavedObject(mapRefItem)).getReferencedColumnPositions(); 109 this.reuseResult = reuseResult; 110 this.doesProjection = doesProjection; 111 112 if (projection == null) 114 { 115 mappedResultRow = activation.getExecutionFactory().getValueRow(projectMapping.length); 116 } 117 118 119 runTimeStatsOn = getLanguageConnectionContext().getRunTimeStatisticsMode(); 120 constructorTime += getElapsedMillis(beginTime); 121 } 122 123 127 134 public void openCore() throws StandardException 135 { 136 boolean constantEval = true; 137 138 beginTime = getCurrentTimeMillis(); 139 140 if (SanityManager.DEBUG) 143 { 144 SanityManager.ASSERT(source != null, 145 "PRRS().openCore(), source expected to be non-null"); 146 } 147 148 if (SanityManager.DEBUG) 152 SanityManager.ASSERT( ! isOpen, "ProjectRestrictResultSet already open"); 153 154 if (constantRestriction != null) 155 { 156 DataValueDescriptor restrictBoolean; 157 restrictBoolean = (DataValueDescriptor) 158 constantRestriction.invoke(activation); 159 160 constantEval = (restrictBoolean == null) || 163 ((! restrictBoolean.isNull()) && 164 restrictBoolean.getBoolean()); 165 } 166 167 if (constantEval) 168 { 169 source.openCore(); 170 } 171 else 172 { 173 shortCircuitOpen = true; 174 } 175 isOpen = true; 176 177 numOpens++; 178 179 openTime += getElapsedMillis(beginTime); 180 } 181 182 189 public void reopenCore() throws StandardException 190 { 191 boolean constantEval = true; 192 193 beginTime = getCurrentTimeMillis(); 194 195 if (SanityManager.DEBUG) 196 SanityManager.ASSERT(isOpen, "ProjectRestrictResultSet not open, cannot reopen"); 197 198 if (constantRestriction != null) 199 { 200 DataValueDescriptor restrictBoolean; 201 restrictBoolean = (DataValueDescriptor) 202 constantRestriction.invoke(activation); 203 204 constantEval = (restrictBoolean == null) || 207 ((! restrictBoolean.isNull()) && 208 restrictBoolean.getBoolean()); 209 } 210 211 if (constantEval) 212 { 213 source.reopenCore(); 214 } 215 else 216 { 217 shortCircuitOpen = true; 218 } 219 isOpen = true; 220 221 numOpens++; 222 223 openTime += getElapsedMillis(beginTime); 224 } 225 226 239 public ExecRow getNextRowCore() throws StandardException { 240 241 ExecRow candidateRow = null; 242 ExecRow result = null; 243 boolean restrict = false; 244 DataValueDescriptor restrictBoolean; 245 long beginRT = 0; 246 247 248 if (shortCircuitOpen) 249 { 250 return result; 251 } 252 253 beginTime = getCurrentTimeMillis(); 254 do 255 { 256 candidateRow = source.getNextRowCore(); 257 if (candidateRow != null) 258 { 259 beginRT = getCurrentTimeMillis(); 260 261 if (restriction == null) 262 { 263 restrict = true; 264 } 265 else 266 { 267 setCurrentRow(candidateRow); 268 restrictBoolean = (DataValueDescriptor) 269 restriction.invoke(activation); 270 restrictionTime += getElapsedMillis(beginRT); 271 272 restrict = ((! restrictBoolean.isNull()) && 275 restrictBoolean.getBoolean()); 276 if (! restrict) 277 { 278 rowsFiltered++; 279 } 280 } 281 282 283 rowsSeen++; 284 } 285 } while ( (candidateRow != null) && 286 (! restrict ) ); 287 288 if (candidateRow != null) 289 { 290 beginRT = getCurrentTimeMillis(); 291 292 result = doProjection(candidateRow); 293 294 projectionTime += getElapsedMillis(beginRT); 295 } 296 297 else 298 { 299 clearCurrentRow(); 300 } 301 302 303 currentRow = result; 304 305 if (runTimeStatsOn) 306 { 307 if (! isTopResultSet) 308 { 309 310 311 StatementContext sc = activation.getLanguageConnectionContext().getStatementContext(); 312 subqueryTrackingArray = sc.getSubqueryTrackingArray(); 313 } 314 nextTime += getElapsedMillis(beginTime); 315 } 316 return result; 317 } 318 319 327 public long getTimeSpent(int type) 328 { 329 long totTime = constructorTime + openTime + nextTime + closeTime; 330 331 if (type == CURRENT_RESULTSET_ONLY) 332 { 333 return totTime - source.getTimeSpent(ENTIRE_RESULTSET_TREE); 334 } 335 else 336 { 337 return totTime; 338 } 339 } 340 341 343 349 public void close() throws StandardException 350 { 351 352 if (shortCircuitOpen) 353 { 354 isOpen = false; 355 shortCircuitOpen = false; 356 return; 357 } 358 359 beginTime = getCurrentTimeMillis(); 360 if ( isOpen ) { 361 362 clearCurrentRow(); 367 368 source.close(); 369 370 super.close(); 371 } 372 else 373 if (SanityManager.DEBUG) 374 SanityManager.DEBUG("CloseRepeatInfo","Close of ProjectRestrictResultSet repeated"); 375 376 closeTime += getElapsedMillis(beginTime); 377 } 378 379 public void finish() throws StandardException 380 { 381 source.finish(); 382 finishAndRTS(); 383 } 384 385 389 399 public RowLocation getRowLocation() throws StandardException { 400 if (SanityManager.DEBUG) 401 SanityManager.ASSERT(source instanceof CursorResultSet, "source is not CursorResultSet"); 402 return ( (CursorResultSet)source ).getRowLocation(); 403 } 404 405 413 416 public ExecRow getCurrentRow() throws StandardException { 417 ExecRow candidateRow = null; 418 ExecRow result = null; 419 boolean restrict = false; 420 DataValueDescriptor restrictBoolean; 421 422 if (SanityManager.DEBUG) 423 SanityManager.ASSERT(isOpen, "PRRS is expected to be open"); 424 425 426 if (currentRow == null) 427 { 428 return null; 429 } 430 431 435 candidateRow = ((CursorResultSet) source).getCurrentRow(); 436 if (candidateRow != null) { 437 setCurrentRow(candidateRow); 438 439 restrictBoolean = (DataValueDescriptor) 440 ((restriction == null) ? null : restriction.invoke(activation)); 441 442 restrict = (restrictBoolean == null) || 445 ((! restrictBoolean.isNull()) && 446 restrictBoolean.getBoolean()); 447 } 448 449 if (candidateRow != null && restrict) 450 { 451 result = doProjection(candidateRow); 452 } 453 454 currentRow = result; 455 456 if (result == null) { 457 clearCurrentRow(); 458 } 459 460 return currentRow; 461 } 462 463 474 private ExecRow doProjection(ExecRow sourceRow) 475 throws StandardException 476 { 477 if (reuseResult && projRow != null) 479 { 480 return projRow; 481 } 482 483 ExecRow result; 484 485 if (projection != null) 487 { 488 result = (ExecRow) projection.invoke(activation); 489 } 490 else 491 { 492 result = mappedResultRow; 493 } 494 495 for (int index = 0; index < projectMapping.length; index++) 497 { 498 if (projectMapping[index] != -1) 499 { 500 result.setColumn(index + 1, sourceRow.getColumn(projectMapping[index])); 501 } 502 } 503 504 505 setCurrentRow(result); 506 507 508 if (reuseResult) 509 { 510 projRow = result; 511 } 512 return result; 513 } 514 515 526 public ExecRow doBaseRowProjection(ExecRow sourceRow) 527 throws StandardException 528 { 529 final ExecRow result; 530 if (source instanceof ProjectRestrictResultSet) { 531 ProjectRestrictResultSet prs = (ProjectRestrictResultSet) source; 532 result = prs.doBaseRowProjection(sourceRow); 533 } else { 534 result = sourceRow.getNewNullRow(); 535 result.setRowArray(sourceRow.getRowArray()); 536 } 537 return doProjection(result); 538 } 539 540 546 public int[] getBaseProjectMapping() 547 { 548 final int[] result; 549 if (source instanceof ProjectRestrictResultSet) { 550 result = new int[projectMapping.length]; 551 final ProjectRestrictResultSet prs = (ProjectRestrictResultSet) source; 552 final int[] sourceMap = prs.getBaseProjectMapping(); 553 for (int i=0; i<projectMapping.length; i++) { 554 if (projectMapping[i] > 0) { 555 result[i] = sourceMap[projectMapping[i] - 1]; 556 } 557 } 558 } else { 559 result = projectMapping; 560 } 561 return result; 562 } 563 564 569 public boolean isForUpdate() 570 { 571 return source.isForUpdate(); 572 } 573 574 577 public void updateRow (ExecRow row) throws StandardException { 578 source.updateRow(row); 579 } 580 581 584 public void markRowAsDeleted() throws StandardException { 585 source.markRowAsDeleted(); 586 } 587 588 } 589 590 591 592 593 | Popular Tags |