1 21 22 package org.apache.derby.impl.sql.conn; 23 24 import org.apache.derby.iapi.services.context.Context; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.services.monitor.Monitor; 29 30 import org.apache.derby.iapi.services.timer.TimerFactory; 31 32 import org.apache.derby.iapi.error.StandardException; 33 34 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 35 import org.apache.derby.iapi.sql.conn.StatementContext; 36 37 import org.apache.derby.iapi.sql.depend.Dependency; 38 import org.apache.derby.iapi.sql.depend.DependencyManager; 39 40 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 41 42 import org.apache.derby.iapi.sql.ResultSet; 43 import org.apache.derby.iapi.sql.ParameterValueSet; 44 45 import org.apache.derby.iapi.store.access.TransactionController; 46 47 import org.apache.derby.iapi.services.context.ContextImpl; 48 49 import org.apache.derby.iapi.error.ExceptionSeverity; 50 import org.apache.derby.iapi.reference.SQLState; 51 import java.util.ArrayList ; 52 import java.util.Iterator ; 53 import java.util.Timer ; 54 import java.util.TimerTask ; 55 import java.sql.SQLException ; 56 57 64 final class GenericStatementContext 65 extends ContextImpl implements StatementContext 66 { 67 private final TransactionController tc; 68 69 private boolean setSavePoint; 70 private String internalSavePointName; 71 private ResultSet topResultSet; 72 private ArrayList dependencies; 73 private NoPutResultSet[] subqueryTrackingArray; 74 private NoPutResultSet[] materializedSubqueries; 75 private final LanguageConnectionContext lcc; 76 private boolean inUse = true; 77 78 private volatile boolean cancellationFlag = false; 84 85 private CancelQueryTask cancelTask = null; 88 89 private boolean parentInTrigger; private boolean isForReadOnly = false; 91 private boolean isAtomic; 92 private boolean isSystemCode; 93 private boolean rollbackParentContext; 94 private String stmtText; 95 private ParameterValueSet pvs; 96 97 100 private short sqlAllowed = -1; 101 102 106 GenericStatementContext(LanguageConnectionContext lcc, TransactionController tc) 107 { 108 super(lcc.getContextManager(), org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT); 109 this.lcc = lcc; 110 this.tc = tc; 111 112 internalSavePointName = "ISSP" + hashCode(); 113 114 if (SanityManager.DEBUG) 115 { 116 SanityManager.ASSERT((lcc != null), 117 "Failed to get language connection context"); 118 } 119 120 } 121 122 134 private static class CancelQueryTask 135 extends 136 TimerTask 137 { 138 142 private StatementContext statementContext; 143 144 150 public CancelQueryTask(StatementContext ctx) 151 { 152 statementContext = ctx; 153 } 154 155 162 public void run() 163 { 164 synchronized (this) { 165 if (statementContext != null) { 166 statementContext.cancel(); 167 } 168 } 169 } 170 171 178 public void forgetContext() { 179 boolean mayStillRun = !cancel(); 180 if (mayStillRun) { 181 synchronized (this) { 182 statementContext = null; 183 } 184 } 185 } 186 } 187 188 190 public void setInUse 191 ( 192 boolean parentInTrigger, 193 boolean isAtomic, 194 boolean isForReadOnly, 195 String stmtText, 196 ParameterValueSet pvs, 197 long timeoutMillis 198 ) 199 { 200 inUse = true; 201 202 this.parentInTrigger = parentInTrigger; 203 this.isForReadOnly = isForReadOnly; 204 this.isAtomic = isAtomic; 205 this.stmtText = stmtText; 206 this.pvs = pvs; 207 rollbackParentContext = false; 208 if (timeoutMillis > 0) { 209 TimerFactory factory = Monitor.getMonitor().getTimerFactory(); 210 Timer timer = factory.getCancellationTimer(); 211 cancelTask = new CancelQueryTask(this); 212 timer.schedule(cancelTask, timeoutMillis); 213 } 214 } 215 216 public void clearInUse() { 217 220 stuffTopResultSet( null, null ); 221 inUse = false; 222 223 parentInTrigger = false; 224 isAtomic = false; 225 isForReadOnly = false; 226 this.stmtText = null; 227 sqlAllowed = -1; 228 isSystemCode = false; 229 rollbackParentContext = false; 230 231 if (cancelTask != null) { 232 cancelTask.forgetContext(); 233 cancelTask = null; 234 } 235 cancellationFlag = false; 236 } 237 238 242 public void setSavePoint() throws StandardException { 243 244 if (SanityManager.DEBUG) 245 { 246 if (SanityManager.DEBUG_ON("traceSavepoints")) 247 { 248 SanityManager.DEBUG_PRINT( 249 "GenericStatementContext.setSavePoint()", 250 internalSavePointName); 251 } 252 } 253 254 pleaseBeOnStack(); 255 256 257 if ( tc != null ) { tc.setSavePoint(internalSavePointName, null); } 259 setSavePoint = true; 260 } 261 262 270 public void resetSavePoint() throws StandardException { 271 if (SanityManager.DEBUG) 272 { 273 if (SanityManager.DEBUG_ON("traceSavepoints")) 274 { 275 SanityManager.DEBUG_PRINT( 276 "GenericStatementContext.resetSavePoint()", 277 internalSavePointName); 278 } 279 } 280 281 if (inUse && setSavePoint) 282 { 283 if ( tc != null ) { tc.setSavePoint(internalSavePointName, null); } 285 } 287 } 288 289 293 public void clearSavePoint() throws StandardException { 294 295 if (SanityManager.DEBUG) 296 { 297 if (SanityManager.DEBUG_ON("traceSavepoints")) 298 { 299 SanityManager.DEBUG_PRINT("GenericStatementContext.clearSavePoint()", 300 internalSavePointName); 301 } 302 } 303 304 pleaseBeOnStack(); 305 306 if (SanityManager.DEBUG) 307 { 308 SanityManager.ASSERT(setSavePoint, "setSavePoint is expected to be true"); 309 } 310 311 if ( tc != null ) { tc.releaseSavePoint(internalSavePointName, null); } 313 setSavePoint = false; 314 } 315 316 322 public void setTopResultSet(ResultSet topResultSet, 323 NoPutResultSet[] subqueryTrackingArray) 324 throws StandardException 325 { 326 pleaseBeOnStack(); 327 328 333 if (materializedSubqueries != null) 334 { 335 if (subqueryTrackingArray != null) 337 { 338 if (SanityManager.DEBUG) 339 { 340 if (this.materializedSubqueries.length != subqueryTrackingArray.length) 341 { 342 SanityManager.THROWASSERT( 343 "this.ms.length (" + this.materializedSubqueries.length + 344 ") expected to = sta.length(" + subqueryTrackingArray.length + 345 ")"); 346 } 347 } 348 for (int index = 0; index < subqueryTrackingArray.length; index++) 349 { 350 if (this.subqueryTrackingArray[index] != null) 351 { 352 subqueryTrackingArray[index] = this.materializedSubqueries[index]; 353 } 354 } 355 } 356 else 357 { 358 subqueryTrackingArray = this.materializedSubqueries; 359 } 360 materializedSubqueries = null; 361 } 362 363 stuffTopResultSet( topResultSet, subqueryTrackingArray ); 364 } 365 366 372 private void stuffTopResultSet(ResultSet topResultSet, 373 NoPutResultSet[] subqueryTrackingArray) 374 { 375 this.topResultSet = topResultSet; 376 this.subqueryTrackingArray = subqueryTrackingArray; 377 dependencies = null; 378 } 379 380 381 392 public void setSubqueryResultSet(int subqueryNumber, 393 NoPutResultSet subqueryResultSet, 394 int numSubqueries) 395 throws StandardException 396 { 397 pleaseBeOnStack(); 398 399 409 if (subqueryTrackingArray == null) 410 { 411 if (topResultSet == null) 412 { 413 subqueryTrackingArray = new NoPutResultSet[numSubqueries]; 414 materializedSubqueries = new NoPutResultSet[numSubqueries]; 415 } 416 else 417 { 418 subqueryTrackingArray = 419 topResultSet.getSubqueryTrackingArray(numSubqueries); 420 } 421 } 422 subqueryTrackingArray[subqueryNumber] = subqueryResultSet; 423 if (materializedSubqueries != null) 424 { 425 materializedSubqueries[subqueryNumber] = subqueryResultSet; 426 } 427 } 428 429 436 public NoPutResultSet[] getSubqueryTrackingArray() 437 throws StandardException 438 { 439 pleaseBeOnStack(); 440 441 return subqueryTrackingArray; 442 } 443 444 453 public void addDependency(Dependency dy) 454 throws StandardException 455 { 456 pleaseBeOnStack(); 457 458 if (dependencies == null) 459 { 460 dependencies = new ArrayList (); 461 } 462 dependencies.add(dy); 463 } 464 465 471 public boolean inTrigger() 472 { 473 return parentInTrigger; 474 } 475 476 486 public void cleanupOnError(Throwable error) throws StandardException 487 { 488 489 if (SanityManager.DEBUG) 490 { 491 if (SanityManager.DEBUG_ON("traceSavepoints")) 492 { 493 SanityManager.DEBUG_PRINT( 494 "GenericStatementContext.cleanupOnError()", 495 String.valueOf( hashCode() ) ); 496 } 497 } 498 499 508 int severity = (error instanceof StandardException) ? 509 ((StandardException) error).getSeverity() : 510 ExceptionSeverity.SESSION_SEVERITY; 511 512 513 519 if (! inUse) 520 { 521 return; 522 } 523 524 525 if (topResultSet != null) 526 { 527 topResultSet.cleanUp(); 528 } 529 530 531 if (subqueryTrackingArray != null) 532 { 533 for (int index = 0; index < subqueryTrackingArray.length; index++) 534 { 535 538 if (subqueryTrackingArray[index] != null) 539 { 540 subqueryTrackingArray[index].cleanUp(); 541 } 542 } 543 } 544 545 546 if (dependencies != null) 547 { 548 DependencyManager dmgr = lcc.getDataDictionary().getDependencyManager(); 549 550 for (Iterator iterator = dependencies.iterator(); iterator.hasNext(); ) 551 { 552 Dependency dy = (Dependency) iterator.next(); 553 dmgr.clearInMemoryDependency(dy); 554 } 555 556 dependencies = null; 557 } 558 559 if (severity <= ExceptionSeverity.STATEMENT_SEVERITY 560 && setSavePoint) 561 { 562 if (SanityManager.DEBUG) 563 { 564 if (SanityManager.DEBUG_ON("traceSavepoints")) 565 { 566 SanityManager.DEBUG_PRINT( 567 "GenericStatementContext.cleanupOnError", 568 "rolling back to: " + internalSavePointName); 569 } 570 } 571 572 lcc.internalRollbackToSavepoint( internalSavePointName, false, null); 573 574 clearSavePoint(); 575 } 576 577 if (severity >= ExceptionSeverity.TRANSACTION_SEVERITY ) 578 { 579 581 587 setSavePoint = false; 588 } 589 590 591 lcc.popStatementContext(this, error); 592 } 593 594 597 public boolean isLastHandler(int severity) 598 { 599 return inUse && !rollbackParentContext && 606 ( severity == ExceptionSeverity.STATEMENT_SEVERITY ); 607 } 608 609 614 public boolean onStack() { return inUse; } 615 616 623 public boolean isAtomic() 624 { 625 return isAtomic; 626 } 627 628 637 public String getStatementText() 638 { 639 return stmtText; 640 } 641 642 646 652 private void pleaseBeOnStack() throws StandardException 653 { 654 if ( !inUse ) { throw StandardException.newException(SQLState.LANG_DEAD_STATEMENT); } 655 } 656 657 public boolean inUse() 658 { 659 return inUse; 660 } 661 public boolean isForReadOnly() 662 { 663 return isForReadOnly; 664 } 665 666 675 public boolean isCancelled() 676 { 677 return cancellationFlag; 678 } 679 680 686 public void cancel() 687 { 688 cancellationFlag = true; 689 } 690 691 public void setSQLAllowed(short allow, boolean force) { 692 693 if (force || (allow > sqlAllowed)) 698 sqlAllowed = allow; 699 700 } 701 public short getSQLAllowed() { 702 if (!inUse) 703 return org.apache.derby.catalog.types.RoutineAliasInfo.NO_SQL; 704 705 return sqlAllowed; 706 } 707 708 715 public void setParentRollback() { 716 rollbackParentContext = true; 717 } 718 719 723 public void setSystemCode() { 724 isSystemCode = true; 725 } 726 727 730 public boolean getSystemCode() { 731 return isSystemCode; 732 } 733 734 public StringBuffer appendErrorInfo() { 735 736 StringBuffer sb = ((ContextImpl) lcc).appendErrorInfo(); 737 if (sb != null) { 738 739 sb.append("Failed Statement is: "); 740 741 sb.append(getStatementText()); 742 743 if (lcc.getLogStatementText() && (pvs != null) && pvs.getParameterCount() > 0) 744 { 745 String pvsString = " with " + pvs.getParameterCount() + 746 " parameters " + pvs.toString(); 747 sb.append(pvsString); 748 } 749 } 750 return sb; 751 752 } 753 } 754 | Popular Tags |