1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.loader.ClassFactory; 25 import org.apache.derby.iapi.services.loader.ClassInspector; 26 27 import org.apache.derby.iapi.services.monitor.Monitor; 28 29 import org.apache.derby.iapi.services.sanity.SanityManager; 30 31 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 32 import org.apache.derby.iapi.services.stream.InfoStreams; 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.sql.Activation; 39 import org.apache.derby.iapi.sql.ResultDescription; 40 import org.apache.derby.iapi.types.DataValueDescriptor; 41 import org.apache.derby.iapi.sql.execute.ExecutionContext; 42 43 import org.apache.derby.iapi.store.access.Qualifier; 44 45 import org.apache.derby.iapi.error.StandardException; 46 47 import org.apache.derby.iapi.services.loader.GeneratedMethod; 48 49 import org.apache.derby.iapi.types.RowLocation; 50 import org.apache.derby.iapi.reference.SQLState; 51 52 import org.apache.derby.iapi.services.io.FormatableBitSet; 53 import org.apache.derby.iapi.services.io.FormatableHashtable; 54 55 import org.apache.derby.vti.DeferModification; 56 import org.apache.derby.vti.IFastPath; 57 import org.apache.derby.vti.VTIEnvironment; 58 59 import java.sql.PreparedStatement ; 60 import java.sql.ResultSet ; 61 import java.sql.SQLException ; 62 import java.sql.ResultSetMetaData ; 63 64 65 67 class VTIResultSet extends NoPutResultSetImpl 68 implements CursorResultSet, VTIEnvironment { 69 70 71 public int rowsReturned; 72 public String javaClassName; 73 74 private boolean next; 75 private ClassInspector classInspector; 76 private GeneratedMethod row; 77 private GeneratedMethod constructor; 78 private PreparedStatement userPS; 79 private ResultSet userVTI; 80 private ExecRow allocatedRow; 81 private FormatableBitSet referencedColumns; 82 private boolean version2; 83 private boolean reuseablePs; 84 private boolean isTarget; 85 private FormatableHashtable compileTimeConstants; 86 private int ctcNumber; 87 88 private boolean pushedProjection; 89 private IFastPath fastPath; 90 91 private Qualifier[][] pushedQualifiers; 92 93 private boolean[] runtimeNullableColumn; 94 95 99 private int scanIsolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL; 100 101 VTIResultSet(Activation activation, GeneratedMethod row, int resultSetNumber, 105 GeneratedMethod constructor, 106 String javaClassName, 107 Qualifier[][] pushedQualifiers, 108 int erdNumber, 109 boolean version2, boolean reuseablePs, 110 int ctcNumber, 111 boolean isTarget, 112 int scanIsolationLevel, 113 double optimizerEstimatedRowCount, 114 double optimizerEstimatedCost) 115 throws StandardException 116 { 117 super(activation, resultSetNumber, 118 optimizerEstimatedRowCount, optimizerEstimatedCost); 119 this.row = row; 120 this.constructor = constructor; 121 this.javaClassName = javaClassName; 122 this.version2 = version2; 123 this.reuseablePs = reuseablePs; 124 this.isTarget = isTarget; 125 this.pushedQualifiers = pushedQualifiers; 126 this.scanIsolationLevel = scanIsolationLevel; 127 128 if (erdNumber != -1) 129 { 130 this.referencedColumns = (FormatableBitSet)(activation.getPreparedStatement(). 131 getSavedObject(erdNumber)); 132 } 133 134 this.ctcNumber = ctcNumber; 135 compileTimeConstants = (FormatableHashtable) (activation.getPreparedStatement(). 136 getSavedObject(ctcNumber)); 137 138 constructorTime += getElapsedMillis(beginTime); 139 } 140 141 145 146 151 public void openCore() throws StandardException 152 { 153 beginTime = getCurrentTimeMillis(); 154 if (SanityManager.DEBUG) 155 SanityManager.ASSERT( ! isOpen, "VTIResultSet already open"); 156 157 isOpen = true; 158 numOpens++; 159 160 165 try { 166 if (version2) 167 { 168 userPS = (PreparedStatement ) constructor.invoke(activation); 169 170 if (userPS instanceof org.apache.derby.vti.Pushable) { 171 org.apache.derby.vti.Pushable p = (org.apache.derby.vti.Pushable) userPS; 172 if (referencedColumns != null) { 173 pushedProjection = p.pushProjection(this, getProjectedColList()); 174 } 175 } 176 177 if (userPS instanceof org.apache.derby.vti.IQualifyable) { 178 org.apache.derby.vti.IQualifyable q = (org.apache.derby.vti.IQualifyable) userPS; 179 180 q.setQualifiers(this, pushedQualifiers); 181 } 182 fastPath = userPS instanceof IFastPath ? (IFastPath) userPS : null; 183 184 if( isTarget 185 && userPS instanceof DeferModification 186 && activation.getConstantAction() instanceof UpdatableVTIConstantAction) 187 { 188 UpdatableVTIConstantAction constants = (UpdatableVTIConstantAction) activation.getConstantAction(); 189 ((DeferModification) userPS).modificationNotify( constants.statementType, constants.deferred); 190 } 191 192 if ((fastPath != null) && fastPath.executeAsFastPath()) 193 ; 194 else 195 userVTI = userPS.executeQuery(); 196 197 198 if (isTarget) 199 { 200 activation.setTargetVTI(userVTI); 201 } 202 203 } 204 else 205 { 206 userVTI = (ResultSet) constructor.invoke(activation); 207 } 208 209 setNullableColumnList(); 211 } 212 catch (Throwable t) 213 { 214 throw StandardException.unexpectedUserException(t); 215 } 216 217 218 openTime += getElapsedMillis(beginTime); 219 } 220 221 private boolean[] setNullableColumnList() throws SQLException { 222 223 if (runtimeNullableColumn != null) 224 return runtimeNullableColumn; 225 226 if (userVTI == null) 227 return null; 228 229 ResultSetMetaData rsmd = userVTI.getMetaData(); 230 boolean[] nullableColumn = new boolean[rsmd.getColumnCount() + 1]; 231 for (int i = 1; i < nullableColumn.length; i++) { 232 nullableColumn[i] = rsmd.isNullable(i) != ResultSetMetaData.columnNoNulls; 233 } 234 235 return runtimeNullableColumn = nullableColumn; 236 } 237 238 248 public void reopenCore() throws StandardException 249 { 250 if (reuseablePs) 251 { 252 254 if (userVTI != null) 255 { 256 try 257 { 258 userVTI.close(); 259 userVTI = userPS.executeQuery(); 260 261 262 if (isTarget) 263 { 264 activation.setTargetVTI(userVTI); 265 } 266 } catch (SQLException se) 267 { 268 throw StandardException.unexpectedUserException(se); 269 } 270 } 271 } 272 else 273 { 274 close(); 275 openCore(); 276 } 277 } 278 279 285 public ExecRow getNextRowCore() throws StandardException 286 { 287 ExecRow result = null; 288 289 beginTime = getCurrentTimeMillis(); 290 291 if ( isOpen ) 292 { 293 try 294 { 295 if ((userVTI == null) && (fastPath != null)) { 296 result = getAllocatedRow(); 297 int action = fastPath.nextRow(result.getRowArray()); 298 if (action == IFastPath.GOT_ROW) 299 ; 300 else if (action == IFastPath.SCAN_COMPLETED) 301 result = null; 302 else if (action == IFastPath.NEED_RS) { 303 userVTI = userPS.executeQuery(); 304 } 305 } 306 if ((userVTI != null)) 307 { 308 if( ! userVTI.next()) 309 { 310 if( null != fastPath) 311 fastPath.rowsDone(); 312 result = null; 313 } 314 else 315 { 316 result = getAllocatedRow(); 318 populateFromResultSet(result); 319 if (fastPath != null) 320 fastPath.currentRow(userVTI, result.getRowArray()); 321 } 322 } 323 } 324 catch (Throwable t) 325 { 326 throw StandardException.unexpectedUserException(t); 327 } 328 329 } 330 331 setCurrentRow(result); 332 if (result != null) 333 { 334 rowsReturned++; 335 rowsSeen++; 336 } 337 338 nextTime += getElapsedMillis(beginTime); 339 return result; 340 } 341 342 343 344 349 public void close() throws StandardException 350 { 351 beginTime = getCurrentTimeMillis(); 352 if (isOpen) { 353 354 clearCurrentRow(); 359 next = false; 360 361 364 if (userVTI != null) 365 { 366 try 367 { 368 userVTI.close(); 369 } catch (SQLException se) 370 { 371 throw StandardException.unexpectedUserException(se); 372 } 373 finally { 374 userVTI = null; 375 } 376 } 377 if ((userPS != null) && !reuseablePs) 378 { 379 try 380 { 381 userPS.close(); 382 } catch (SQLException se) 383 { 384 throw StandardException.unexpectedUserException(se); 385 } 386 finally { 387 userPS = null; 388 } 389 } 390 super.close(); 391 } 392 else 393 if (SanityManager.DEBUG) 394 SanityManager.DEBUG("CloseRepeatInfo","Close of VTIResultSet repeated"); 395 396 closeTime += getElapsedMillis(beginTime); 397 } 398 399 public void finish() throws StandardException { 400 401 if ((userPS != null) && !reuseablePs) 404 { 405 try 406 { 407 userPS.close(); 408 userPS = null; 409 } catch (SQLException se) 410 { 411 throw StandardException.unexpectedUserException(se); 412 } 413 } 414 415 finishAndRTS(); 416 417 } 418 419 427 public long getTimeSpent(int type) 428 { 429 long totTime = constructorTime + openTime + nextTime + closeTime; 430 return totTime; 431 } 432 433 437 445 public RowLocation getRowLocation() { 446 if (SanityManager.DEBUG) 447 SanityManager.THROWASSERT("RowResultSet used in positioned update/delete"); 448 return null; 449 } 450 451 459 public ExecRow getCurrentRow() { 460 if (SanityManager.DEBUG) 461 SanityManager.THROWASSERT("RowResultSet used in positioned update/delete"); 462 return null; 463 } 464 465 467 472 GeneratedMethod getVTIConstructor() 473 { 474 return constructor; 475 } 476 477 boolean isReuseablePs() { 478 return reuseablePs; 479 } 480 481 482 489 private ExecRow getAllocatedRow() 490 throws StandardException 491 { 492 if (allocatedRow == null) 493 { 494 allocatedRow = (ExecRow) row.invoke(activation); 495 } 496 497 return allocatedRow; 498 } 499 500 private int[] getProjectedColList() { 501 502 FormatableBitSet refs = referencedColumns; 503 int size = refs.size(); 504 int arrayLen = 0; 505 for (int i = 0; i < size; i++) { 506 if (refs.isSet(i)) 507 arrayLen++; 508 } 509 510 int[] colList = new int[arrayLen]; 511 int offset = 0; 512 for (int i = 0; i < size; i++) { 513 if (refs.isSet(i)) 514 colList[offset++] = i + 1; 515 } 516 517 return colList; 518 } 519 522 public void populateFromResultSet(ExecRow row) 523 throws StandardException 524 { 525 try 526 { 527 boolean[] nullableColumn = setNullableColumnList(); 528 DataValueDescriptor[] columns = row.getRowArray(); 529 int rsColNumber = 1; 531 for (int index = 0; index < columns.length; index++) 532 { 533 if (referencedColumns != null && (! referencedColumns.get(index))) 535 { 536 if (!pushedProjection) 537 rsColNumber++; 538 539 continue; 540 } 541 542 columns[index].setValueFromResultSet( 543 userVTI, rsColNumber, 544 547 nullableColumn[rsColNumber]); 548 rsColNumber++; 549 } 550 551 } catch (StandardException se) { 552 throw se; 553 } 554 catch (Throwable t) 555 { 556 throw StandardException.unexpectedUserException(t); 557 } 558 } 559 560 public final int getScanIsolationLevel() { 561 return scanIsolationLevel; 562 } 563 564 567 public final boolean isCompileTime() { 568 return false; 569 } 570 571 public final String getOriginalSQL() { 572 return activation.getPreparedStatement().getSource(); 573 } 574 575 public final int getStatementIsolationLevel() { 576 return ExecutionContext.CS_TO_JDBC_ISOLATION_LEVEL_MAP[getScanIsolationLevel()]; 577 } 578 579 580 public final void setSharedState(String key, java.io.Serializable value) { 581 if (key == null) 582 return; 583 584 if (compileTimeConstants == null) { 585 586 Object [] savedObjects = activation.getPreparedStatement().getSavedObjects(); 587 588 synchronized (savedObjects) { 589 590 compileTimeConstants = (FormatableHashtable) savedObjects[ctcNumber]; 591 if (compileTimeConstants == null) { 592 compileTimeConstants = new FormatableHashtable(); 593 savedObjects[ctcNumber] = compileTimeConstants; 594 } 595 } 596 } 597 598 if (value == null) 599 compileTimeConstants.remove(key); 600 else 601 compileTimeConstants.put(key, value); 602 603 604 } 605 606 public Object getSharedState(String key) { 607 if ((key == null) || (compileTimeConstants == null)) 608 return null; 609 610 return compileTimeConstants.get(key); 611 } 612 } 613 | Popular Tags |