1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 26 import org.apache.derby.iapi.sql.compile.CompilerContext; 27 import org.apache.derby.iapi.sql.compile.OptimizablePredicateList; 28 import org.apache.derby.iapi.sql.compile.Optimizer; 29 import org.apache.derby.iapi.sql.compile.CostEstimate; 30 import org.apache.derby.iapi.sql.compile.OptimizableList; 31 import org.apache.derby.iapi.sql.compile.Optimizable; 32 import org.apache.derby.iapi.sql.compile.RequiredRowOrdering; 33 import org.apache.derby.iapi.sql.compile.RowOrdering; 34 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 35 36 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 37 38 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 39 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 40 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList; 41 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 42 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 43 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 44 45 import org.apache.derby.iapi.types.TypeId; 46 47 import org.apache.derby.iapi.sql.execute.ExecCursorTableReference; 48 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement; 49 50 import org.apache.derby.iapi.types.DataValueDescriptor; 51 import org.apache.derby.iapi.sql.ResultSet; 52 import org.apache.derby.iapi.sql.Activation; 53 54 import org.apache.derby.iapi.reference.SQLState; 55 56 import org.apache.derby.iapi.sql.execute.CursorResultSet; 57 58 import org.apache.derby.iapi.types.RowLocation; 59 60 import org.apache.derby.iapi.store.access.TransactionController; 61 import org.apache.derby.iapi.reference.ClassName; 62 63 import org.apache.derby.iapi.error.StandardException; 64 65 import org.apache.derby.iapi.services.compiler.MethodBuilder; 66 67 import org.apache.derby.iapi.services.sanity.SanityManager; 68 69 import org.apache.derby.impl.sql.compile.ActivationClassBuilder; 70 71 import org.apache.derby.iapi.util.JBitSet; 72 import org.apache.derby.iapi.services.classfile.VMOpcode; 73 74 import java.util.Properties ; 75 76 91 public final class CurrentOfNode extends FromTable { 92 93 private String cursorName; 94 private ExecPreparedStatement preStmt; 95 private TableName exposedTableName; 96 private TableName baseTableName; 97 private CostEstimate singleScanCostEstimate; 98 99 public void init( Object correlationName, Object cursor, Object tableProperties) 103 { 104 super.init(correlationName, tableProperties); 105 cursorName = (String ) cursor; 106 } 107 108 111 112 117 public CostEstimate estimateCost(OptimizablePredicateList predList, 118 ConglomerateDescriptor cd, 119 CostEstimate outerCost, 120 Optimizer optimizer, 121 RowOrdering rowOrdering) 122 throws StandardException 123 { 124 133 if (singleScanCostEstimate == null) 134 { 135 singleScanCostEstimate = optimizer.newCostEstimate(); 136 } 137 138 singleScanCostEstimate.setCost(0.0d, 1.0d, 1.0d); 139 getBestAccessPath().setCostEstimate(singleScanCostEstimate); 140 getBestSortAvoidancePath().setCostEstimate(singleScanCostEstimate); 141 142 return singleScanCostEstimate; 143 } 144 145 149 164 public ResultSetNode bindNonVTITables(DataDictionary dataDictionary, 165 FromList fromListParam) 166 throws StandardException { 167 168 171 preStmt = getCursorStatement(); 172 if ((preStmt!=null) && (! preStmt.upToDate())) { 173 preStmt.makeValid(getLanguageConnectionContext()); if (! preStmt.isValid()) preStmt = null; 176 } 177 178 if (preStmt == null) { 179 throw StandardException.newException(SQLState.LANG_CURSOR_NOT_FOUND, 180 cursorName); 181 } 182 183 184 if (preStmt.getUpdateMode() != CursorNode.UPDATE) 187 { 188 String printableString = (cursorName == null) ? "" : cursorName; 189 throw StandardException.newException(SQLState.LANG_CURSOR_NOT_UPDATABLE, printableString); 190 } 191 192 getCompilerContext().createDependency(preStmt); 193 194 ExecCursorTableReference refTab = preStmt.getTargetTable(); 195 String schemaName = refTab.getSchemaName(); 196 exposedTableName = makeTableName(null, refTab.getExposedName()); 197 baseTableName = makeTableName(schemaName, 198 refTab.getBaseName()); 199 SchemaDescriptor tableSchema = null; 200 tableSchema = getSchemaDescriptor(refTab.getSchemaName()); 201 202 206 if (tableSchema == null) 207 { 208 throw StandardException.newException(SQLState.LANG_SCHEMA_DOES_NOT_EXIST, refTab.getSchemaName()); 209 } 210 211 215 TableDescriptor td = getTableDescriptor(refTab.getBaseName(), tableSchema); 216 217 if (td == null) 218 { 219 throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, refTab.getBaseName()); 220 } 221 222 223 235 resultColumns = (ResultColumnList) getNodeFactory().getNode( 236 C_NodeTypes.RESULT_COLUMN_LIST, 237 getContextManager()); 238 ColumnDescriptorList cdl = td.getColumnDescriptorList(); 239 int cdlSize = cdl.size(); 240 241 for (int index = 0; index < cdlSize; index++) 242 { 243 244 ColumnDescriptor colDesc = (ColumnDescriptor) cdl.elementAt(index); 245 246 BaseColumnNode bcn = (BaseColumnNode) getNodeFactory().getNode( 247 C_NodeTypes.BASE_COLUMN_NODE, 248 colDesc.getColumnName(), 249 exposedTableName, 250 colDesc.getType(), 251 getContextManager()); 252 ResultColumn rc = (ResultColumn) getNodeFactory().getNode( 253 C_NodeTypes.RESULT_COLUMN, 254 colDesc, 255 bcn, 256 getContextManager()); 257 258 259 resultColumns.addResultColumn(rc); 260 } 261 262 263 if (tableNumber == -1) tableNumber = getCompilerContext().getNextTableNumber(); 265 266 return this; 267 } 268 269 276 public void bindExpressions(FromList fromListParam) 277 { 278 282 } 283 284 297 298 public ResultColumn getMatchingColumn(ColumnReference columnReference) 299 throws StandardException { 300 301 ResultColumn resultColumn = null; 302 TableName columnsTableName; 303 304 columnsTableName = columnReference.getTableNameNode(); 305 306 if(columnsTableName != null) 307 if(columnsTableName.getSchemaName() == null && correlationName == null) 308 columnsTableName.bind(this.getDataDictionary()); 309 310 if (SanityManager.DEBUG) 311 { 312 SanityManager.ASSERT(preStmt!=null, "must have prepared statement"); 313 } 314 315 324 if (SanityManager.DEBUG) 325 { 326 SanityManager.ASSERT(baseTableName!=null,"no name on target table"); 327 } 328 329 if(baseTableName != null) 330 if(baseTableName.getSchemaName() == null && correlationName == null) 331 baseTableName.bind(this.getDataDictionary()); 332 333 338 if ( 339 (columnsTableName == null) || 340 (columnsTableName.getFullTableName().equals(baseTableName.getFullTableName())) || 341 ((correlationName != null) && correlationName.equals( columnsTableName.getTableName())) 342 ) 343 { 344 boolean notfound = false; 345 346 resultColumn = 347 resultColumns.getResultColumn(columnReference.getColumnName()); 348 349 if (resultColumn != null) 350 { 351 columnReference.setTableNumber( tableNumber ); 360 361 notfound = 364 (resultColumn.updatableByCursor() && 365 !foundString( 366 preStmt.getUpdateColumns(), 367 columnReference.getColumnName())); 368 } 369 else 370 { 371 notfound = true; 372 } 373 374 if (notfound) 375 { 376 String printableString = (cursorName == null) ? "" : cursorName; 377 throw StandardException.newException(SQLState.LANG_COLUMN_NOT_UPDATABLE_IN_CURSOR, 378 columnReference.getColumnName(), printableString); 379 } 380 } 381 382 return resultColumn; 383 } 384 385 398 399 public ResultSetNode preprocess(int numTables, 400 GroupByList gbl, 401 FromList fromList) 402 throws StandardException 403 { 404 405 referencedTableMap = new JBitSet(numTables); 406 return this; 407 } 408 409 422 public ResultSetNode optimize(DataDictionary dataDictionary, 423 PredicateList predicateList, 424 double outerRows) 425 throws StandardException { 426 427 Optimizer optimizer = getOptimizer( 428 (FromList) getNodeFactory().getNode( 429 C_NodeTypes.FROM_LIST, 430 getNodeFactory().doJoinOrderOptimization(), 431 this, 432 getContextManager()), 433 predicateList, 434 dataDictionary, 435 (RequiredRowOrdering) null); 436 437 438 bestCostEstimate = optimizer.newCostEstimate(); 439 bestCostEstimate.setCost(0.0d, outerRows, outerRows); 440 441 return this; 442 } 443 444 458 public void generate(ActivationClassBuilder acb, 459 MethodBuilder mb) 460 throws StandardException { 461 462 if (SanityManager.DEBUG) 463 SanityManager.ASSERT(!statementResultSet, 464 "CurrentOfNode not expected to be statement node"); 465 466 469 assignResultSetNumber(); 470 471 mb.pushThis(); 473 477 acb.pushGetResultSetFactoryExpression(mb); 478 479 mb.push(cursorName); 480 acb.pushThisAsActivation(mb); 481 mb.push(resultSetNumber); 482 mb.push(preStmt.getObjectName()); 483 484 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String ) null, "getCurrentOfResultSet", 485 ClassName.NoPutResultSet, 4); 486 487 mb.cast(ClassName.CursorResultSet); 488 489 502 503 mb.putField((String ) null, acb.getRowLocationScanResultSetName(), ClassName.CursorResultSet); 504 mb.cast(ClassName.NoPutResultSet); 505 506 MethodBuilder rmb = acb.startResetMethod(); 510 511 rmb.pushThis(); 512 rmb.push(cursorName); 513 rmb.push(preStmt.getObjectName()); 514 rmb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "checkPositionedStatement", 515 "void", 2); 516 517 rmb.methodReturn(); 518 rmb.complete(); 519 } 520 521 527 public void printSubNodes(int depth) { 528 if (SanityManager.DEBUG) { 529 super.printSubNodes(depth); 530 531 printLabel(depth, "cursor: "); 532 } 533 } 534 535 541 public String toString() { 542 if (SanityManager.DEBUG) { 543 return "preparedStatement: " + 544 (preStmt == null? "no prepared statement yet\n" : 545 preStmt.toString() + "\n")+ 546 cursorName + "\n" + 547 super.toString(); 548 } else { 549 return ""; 550 } 551 } 552 553 557 public String getExposedName() 558 { 559 return exposedTableName.getFullTableName(); 560 } 561 public TableName getExposedTableName() 562 { 563 return exposedTableName; 564 } 565 566 public TableName getBaseCursorTargetTableName() 567 { 568 return baseTableName; 569 } 570 571 public String getCursorName() 572 { 573 return cursorName; 574 } 575 576 582 ExecPreparedStatement getCursorStatement() 583 { 584 Activation activation = getLanguageConnectionContext().lookupCursorActivation(cursorName); 585 586 if (activation == null) 587 return null; 588 589 return activation.getPreparedStatement(); 590 } 591 592 601 public int updateTargetLockMode() 602 { 603 604 return TransactionController.MODE_RECORD; 605 } 606 } 607 | Popular Tags |