1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.monitor.Monitor; 25 import org.apache.derby.iapi.services.sanity.SanityManager; 26 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 27 import org.apache.derby.iapi.services.stream.InfoStreams; 28 import org.apache.derby.iapi.error.StandardException; 29 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 30 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; 31 import org.apache.derby.iapi.sql.execute.ConstantAction; 32 import org.apache.derby.iapi.sql.execute.CursorResultSet; 33 import org.apache.derby.iapi.sql.execute.ExecRow; 34 import org.apache.derby.iapi.sql.execute.ExecutionContext; 35 import org.apache.derby.iapi.sql.execute.RowChanger; 36 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 37 import org.apache.derby.iapi.sql.Activation; 38 import org.apache.derby.iapi.sql.ResultDescription; 39 import org.apache.derby.iapi.sql.ResultSet; 40 import org.apache.derby.iapi.types.DataValueDescriptor; 41 42 import org.apache.derby.iapi.store.access.ConglomerateController; 43 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 44 import org.apache.derby.iapi.store.access.ScanController; 45 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 46 import org.apache.derby.iapi.store.access.TransactionController; 47 48 import org.apache.derby.iapi.types.RowLocation; 49 50 import org.apache.derby.iapi.reference.SQLState; 51 52 import org.apache.derby.iapi.db.TriggerExecutionContext; 53 import org.apache.derby.iapi.services.io.FormatableBitSet; 54 import java.util.Properties ; 55 56 import org.apache.derby.iapi.types.RowLocation; 57 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 58 59 65 class DeleteResultSet extends DMLWriteResultSet 66 { 67 private TransactionController tc; 68 DeleteConstantAction constants; 69 protected ResultDescription resultDescription; 70 protected NoPutResultSet source; 71 NoPutResultSet savedSource; 72 int numIndexes; 73 protected RowChanger rc; 74 private ExecRow row; 75 76 protected ConglomerateController deferredBaseCC; 77 78 protected TemporaryRowHolderImpl rowHolder; 79 80 private int numOpens; private boolean firstExecute; 82 83 private FormatableBitSet baseRowReadList; 85 private int rlColumnNumber; 86 protected FKInfo[] fkInfoArray; 87 private TriggerInfo triggerInfo; 88 private RISetChecker fkChecker; 89 private TriggerEventActivator triggerActivator; 90 private boolean noTriggersOrFks; 91 92 ExecRow deferredSparseRow; 93 ExecRow deferredBaseRow; 94 int lockMode; 95 protected boolean cascadeDelete; 96 ExecRow deferredRLRow = null; 97 int numberOfBaseColumns = 0; 98 99 103 public ResultDescription getResultDescription() 104 { 105 return resultDescription; 106 } 107 108 112 DeleteResultSet 113 ( 114 NoPutResultSet source, 115 Activation activation 116 ) 117 throws StandardException 118 { 119 this(source, activation.getConstantAction(), activation); 120 } 121 130 DeleteResultSet 131 ( 132 NoPutResultSet source, 133 ConstantAction passedInConstantAction, 134 Activation activation 135 ) 136 throws StandardException 137 { 138 super(activation, passedInConstantAction); 139 this.source = source; 140 141 tc = activation.getTransactionController(); 142 constants = (DeleteConstantAction) constantAction; 143 fkInfoArray = constants.getFKInfo( lcc.getExecutionContext() ); 144 triggerInfo = constants.getTriggerInfo(lcc.getExecutionContext()); 145 noTriggersOrFks = ((fkInfoArray == null) && (triggerInfo == null)); 146 baseRowReadList = constants.getBaseRowReadList(); 147 if(source != null) 148 resultDescription = source.getResultDescription(); 149 else 150 resultDescription = constants.resultDescription; 151 152 } 153 154 157 public void open() throws StandardException 158 { 159 160 setup(); 161 boolean rowsFound = collectAffectedRows(); if (! rowsFound) 163 { 164 activation.addWarning( 165 StandardException.newWarning( 166 SQLState.LANG_NO_ROW_FOUND)); 167 } 168 169 174 if (constants.deferred) 175 { 176 runFkChecker(true); fireBeforeTriggers(); 178 deleteDeferredRows(); 179 runFkChecker(false); rc.finish(); 182 fireAfterTriggers(); 183 } 184 185 186 187 if (lcc.getRunTimeStatisticsMode()) 188 { 189 190 savedSource = source; 191 } 192 193 cleanUp(); 194 endTime = getCurrentTimeMillis(); 195 196 } 197 198 199 void setup() throws StandardException 201 { 202 203 firstExecute = (rc == null); 205 206 try { 207 208 if (numOpens++ == 0) 210 { 211 source.openCore(); 212 } 213 else 214 { 215 source.reopenCore(); 216 } 217 } catch (StandardException se) { 218 activation.checkStatementValidity(); 219 throw se; 220 221 } 222 223 activation.checkStatementValidity(); 224 225 230 if (firstExecute) 231 { 232 rc = lcc.getLanguageConnectionFactory().getExecutionFactory(). 233 getRowChanger( 234 constants.conglomId, 235 constants.heapSCOCI, 236 heapDCOCI, 237 constants.irgs, 238 constants.indexCIDS, 239 constants.indexSCOCIs, 240 indexDCOCIs, 241 constants.numColumns, 242 tc, 243 (int[])null, 244 baseRowReadList, 245 constants.getBaseRowReadMap(), 246 constants.getStreamStorableHeapColIds(), 247 activation); 248 } 249 else 250 { 251 lcc.getStatementContext().setTopResultSet(this, subqueryTrackingArray); 252 } 253 254 lockMode = UpdateResultSet.decodeLockMode(lcc, constants.lockMode); 255 256 260 rc.open(lockMode); 261 262 268 if (constants.deferred || cascadeDelete) 269 { 270 activation.clearIndexScanInfo(); 271 } 272 273 rowCount = 0; 274 if(!cascadeDelete) 275 row = getNextRowCore(source); 276 277 282 if (resultDescription == null) 283 { 284 if (SanityManager.DEBUG) 285 { 286 293 SanityManager.ASSERT(triggerInfo == null, "result description is needed to supply to trigger result sets"); 294 } 295 numberOfBaseColumns = (row == null) ? 0 : row.nColumns(); 296 } 297 else 298 { 299 numberOfBaseColumns = resultDescription.getColumnCount(); 300 } 301 302 numIndexes = constants.irgs.length; 303 304 if (constants.deferred || cascadeDelete) 305 { 306 Properties properties = new Properties (); 307 308 rc.getHeapConglomerateController().getInternalTablePropertySet(properties); 310 311 318 deferredRLRow = RowUtil.getEmptyValueRow(1, lcc); 319 rlColumnNumber = noTriggersOrFks ? 1: numberOfBaseColumns; 320 if(cascadeDelete) 321 { 322 rowHolder = new TemporaryRowHolderImpl(activation, properties, 323 (resultDescription != null) ? 324 resultDescription.truncateColumns(rlColumnNumber) : 325 null, false); 326 327 328 }else 329 { 330 331 rowHolder = new TemporaryRowHolderImpl(activation, properties, 332 (resultDescription != null) ? 333 resultDescription.truncateColumns(rlColumnNumber) : 334 null); 335 336 } 337 338 rc.setRowHolder(rowHolder); 339 } 340 341 if (fkInfoArray != null) 342 { 343 if (fkChecker == null) 344 { 345 fkChecker = new RISetChecker(tc, fkInfoArray); 346 } 347 else 348 { 349 fkChecker.reopen(); 350 } 351 } 352 } 353 354 355 boolean collectAffectedRows() throws StandardException 356 { 357 358 DataValueDescriptor rlColumn; 359 RowLocation baseRowLocation; 360 boolean rowsFound = false; 361 362 if(cascadeDelete) 363 row = getNextRowCore(source); 364 365 while ( row != null ) 366 { 367 373 374 rowsFound = true; 375 376 rlColumn = row.getColumn( row.nColumns() ); 377 378 if (constants.deferred || cascadeDelete) 379 { 380 381 386 if (noTriggersOrFks) 387 { 388 deferredRLRow.setColumn(1, rlColumn); 389 rowHolder.insert(deferredRLRow); 390 } 391 else 392 { 393 rowHolder.insert(row); 394 } 395 396 406 if (deferredBaseRow == null) 407 { 408 deferredBaseRow = RowUtil.getEmptyValueRow(numberOfBaseColumns - 1, lcc); 409 410 RowUtil.copyCloneColumns(deferredBaseRow, row, 411 numberOfBaseColumns - 1); 412 deferredSparseRow = makeDeferredSparseRow(deferredBaseRow, 413 baseRowReadList, 414 lcc); 415 } 416 } 417 else 418 { 419 if (fkChecker != null) 420 { 421 fkChecker.doPKCheck(row, false); 422 } 423 424 baseRowLocation = 425 (RowLocation) (rlColumn).getObject(); 426 427 if (SanityManager.DEBUG) 428 { 429 SanityManager.ASSERT(baseRowLocation != null, 430 "baseRowLocation is null"); 431 } 432 433 rc.deleteRow(row,baseRowLocation); 434 source.markRowAsDeleted(); 435 } 436 437 rowCount++; 438 439 if (constants.singleRowSource) 441 { 442 row = null; 443 } 444 else 445 { 446 row = getNextRowCore(source); 447 } 448 } 449 450 return rowsFound; 451 } 452 453 454 void fireBeforeTriggers() throws StandardException 456 { 457 458 if (triggerInfo != null) 459 { 460 if (triggerActivator == null) 461 { 462 triggerActivator = new TriggerEventActivator(lcc, 463 tc, 464 constants.targetUUID, 465 triggerInfo, 466 TriggerExecutionContext.DELETE_EVENT, 467 activation, null 468 ); 469 } 470 else 471 { 472 triggerActivator.reopen(); 473 } 474 475 triggerActivator.notifyEvent(TriggerEvents.BEFORE_DELETE, 477 rowHolder.getResultSet(), 478 (CursorResultSet)null); 479 triggerActivator.cleanup(); 480 481 } 482 483 } 484 485 void fireAfterTriggers() throws StandardException 487 { 488 489 if (triggerActivator != null) 491 { 492 triggerActivator.reopen(); 493 triggerActivator.notifyEvent(TriggerEvents.AFTER_DELETE, 494 rowHolder.getResultSet(), 495 (CursorResultSet)null); 496 triggerActivator.cleanup(); 497 } 498 499 } 500 501 502 void deleteDeferredRows() throws StandardException 505 { 506 507 DataValueDescriptor rlColumn; 508 RowLocation baseRowLocation; 509 ExecRow deferredRLRow = null; 510 511 deferredBaseCC = tc.openCompiledConglomerate(false, 512 tc.OPENMODE_FORUPDATE|tc.OPENMODE_SECONDARY_LOCKED, 513 lockMode, 514 TransactionController.ISOLATION_SERIALIZABLE, 515 constants.heapSCOCI, 516 heapDCOCI); 517 518 CursorResultSet rs = rowHolder.getResultSet(); 519 try 520 { 521 527 FormatableBitSet readBitSet = RowUtil.shift(baseRowReadList, 1); 528 529 rs.open(); 530 while ((deferredRLRow = rs.getNextRow()) != null) 531 { 532 rlColumn = deferredRLRow.getColumn(rlColumnNumber); 533 baseRowLocation = 534 (RowLocation) (rlColumn).getObject(); 535 536 537 boolean row_exists = 538 deferredBaseCC.fetch( 539 baseRowLocation, deferredSparseRow.getRowArray(), 540 readBitSet); 541 542 if(cascadeDelete && !row_exists) 545 continue; 546 547 if (SanityManager.DEBUG) 548 { 549 if (!row_exists) 550 { 551 SanityManager.THROWASSERT("could not find row "+baseRowLocation); 552 } 553 } 554 555 rc.deleteRow(deferredBaseRow, baseRowLocation); 556 source.markRowAsDeleted(); 557 } 558 } finally 559 { 560 rs.close(); 561 } 562 } 563 564 565 void runFkChecker(boolean restrictCheckOnly) throws StandardException 567 { 568 569 ExecRow deferredRLRow = null; 570 if (fkChecker != null) 571 { 572 578 CursorResultSet rs = rowHolder.getResultSet(); 579 try 580 { 581 rs.open(); 582 while ((deferredRLRow = rs.getNextRow()) != null) 583 { 584 fkChecker.doPKCheck(deferredRLRow, restrictCheckOnly); 585 } 586 } finally 587 { 588 rs.close(); 589 } 590 } 591 } 592 593 600 NoPutResultSet createDependentSource(RowChanger rc) 601 throws StandardException 602 { 603 return null; 604 } 605 606 607 612 public void cleanUp() throws StandardException 613 { 614 numOpens = 0; 615 616 617 if (source != null) 618 { 619 source.close(); 620 } 622 if (rc != null) 623 { 624 rc.close(); 625 } 627 628 if (rowHolder != null) 629 { 630 rowHolder.close(); 631 } 633 634 if (fkChecker != null) 635 { 636 fkChecker.close(); 637 } 639 640 if (deferredBaseCC != null) 641 deferredBaseCC.close(); 642 deferredBaseCC = null; 643 644 super.close(); 645 } 646 647 public void finish() throws StandardException { 648 if (source != null) 649 source.finish(); 650 super.finish(); 651 } 652 653 } 654 655 656 657 658 659 660 661 662 663 664 665 666 | Popular Tags |