1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.context.ContextService; 25 import org.apache.derby.iapi.services.monitor.Monitor; 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 28 import org.apache.derby.iapi.services.stream.InfoStreams; 29 import org.apache.derby.iapi.error.StandardException; 30 import org.apache.derby.iapi.services.i18n.MessageService; 31 32 import org.apache.derby.iapi.store.access.TransactionController; 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.reference.SQLState; 38 39 import org.apache.derby.iapi.sql.execute.ExecRow; 40 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 41 import org.apache.derby.iapi.sql.execute.ExecutionFactory; 42 import org.apache.derby.iapi.sql.Activation; 43 44 45 import org.apache.derby.iapi.sql.ResultDescription; 46 import org.apache.derby.iapi.sql.ResultSet; 47 import org.apache.derby.iapi.sql.Row; 48 49 import org.apache.derby.iapi.types.DataValueDescriptor; 50 51 import org.apache.derby.iapi.services.io.FormatableBitSet; 52 53 import java.sql.Timestamp ; 54 import java.sql.SQLWarning ; 55 56 69 abstract class BasicNoPutResultSetImpl 70 implements NoPutResultSet 71 { 72 73 protected boolean isOpen; 74 protected boolean finished; 75 protected ExecRow currentRow; 76 protected boolean isTopResultSet; 77 protected LanguageConnectionContext lcc; 78 private SQLWarning warnings; 79 80 81 public int numOpens; 82 public int rowsSeen; 83 public int rowsFiltered; 84 protected long startExecutionTime; 85 protected long endExecutionTime; 86 public long beginTime; 87 public long constructorTime; 88 public long openTime; 89 public long nextTime; 90 public long closeTime; 91 92 public double optimizerEstimatedRowCount; 93 public double optimizerEstimatedCost; 94 95 private StatementContext statementContext; 97 public NoPutResultSet[] subqueryTrackingArray; 98 ExecRow compactRow; 99 100 protected Activation activation; 102 private boolean statisticsTimingOn; 103 104 ResultDescription resultDescription; 105 106 private transient ExecutionFactory exFactory; 107 private transient TransactionController tc; 108 109 private int[] baseColumnMap; 110 111 124 BasicNoPutResultSetImpl(ResultDescription resultDescription, 125 Activation activation, 126 double optimizerEstimatedRowCount, 127 double optimizerEstimatedCost) 128 { 129 this.activation = activation; 130 statisticsTimingOn = (activation != null && getLanguageConnectionContext().getStatisticsTiming()); 131 beginTime = startExecutionTime = getCurrentTimeMillis(); 132 this.resultDescription = resultDescription; 133 this.optimizerEstimatedRowCount = optimizerEstimatedRowCount; 134 this.optimizerEstimatedCost = optimizerEstimatedCost; 135 } 136 137 public final Activation getActivation() 138 { 139 return activation; 140 } 141 142 144 148 public abstract void openCore() throws StandardException; 149 150 162 public void reopenCore() throws StandardException 163 { 164 close(); 165 openCore(); 166 } 167 168 172 public abstract ExecRow getNextRowCore() throws StandardException; 173 174 177 public int getPointOfAttachment() 178 { 179 if (SanityManager.DEBUG) 180 { 181 SanityManager.THROWASSERT( 182 "getPointOfAttachment() not expected to be called for " + 183 getClass().getName()); 184 } 185 return -1; 186 } 187 188 192 public void markAsTopResultSet() 193 { 194 isTopResultSet = true; 195 } 196 197 200 public int getScanIsolationLevel() 201 { 202 if (SanityManager.DEBUG) 203 { 204 SanityManager.THROWASSERT( 205 "getScanIsolationLevel() not expected to be called for " + 206 getClass().getName()); 207 } 208 return 0; 209 } 210 211 212 public double getEstimatedRowCount() 213 { 214 return optimizerEstimatedRowCount; 215 } 216 217 220 public boolean requiresRelocking() 221 { 222 if (SanityManager.DEBUG) 223 { 224 SanityManager.THROWASSERT( 225 "requiresRelocking() not expected to be called for " + 226 getClass().getName()); 227 } 228 return false; 229 } 230 231 233 245 public final void open() throws StandardException 246 { 247 if (SanityManager.DEBUG) 248 { 249 if (!isTopResultSet) 250 SanityManager.THROWASSERT( 251 this + "expected to be the top ResultSet"); 252 } 253 254 finished = false; 255 256 attachStatementContext(); 257 258 try { 259 260 openCore(); 261 262 } catch (StandardException se) { 263 activation.checkStatementValidity(); 264 throw se; 265 } 266 267 activation.checkStatementValidity(); 268 } 269 270 285 public ExecRow getAbsoluteRow(int row) throws StandardException 286 { 287 if ( ! isOpen ) 288 { 289 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, ABSOLUTE); 290 } 291 292 attachStatementContext(); 293 294 if (SanityManager.DEBUG) 295 { 296 if (!isTopResultSet) 297 { 298 SanityManager.THROWASSERT( 299 this + "expected to be the top ResultSet"); 300 } 301 302 SanityManager.THROWASSERT( 303 "getAbsoluteRow() not expected to be called for " + getClass().getName()); 304 } 305 306 return null; 307 } 308 309 326 public ExecRow getRelativeRow(int row) throws StandardException 327 { 328 if ( ! isOpen ) 329 { 330 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, RELATIVE); 331 } 332 333 attachStatementContext(); 334 335 if (SanityManager.DEBUG) 336 { 337 if (!isTopResultSet) 338 { 339 SanityManager.THROWASSERT( 340 this + "expected to be the top ResultSet"); 341 } 342 343 SanityManager.THROWASSERT( 344 "getRelativeRow() not expected to be called for " + getClass().getName()); 345 } 346 347 return null; 348 } 349 350 359 public ExecRow setBeforeFirstRow() 360 throws StandardException 361 { 362 if ( ! isOpen ) 363 { 364 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, FIRST); 365 } 366 367 if (SanityManager.DEBUG) 368 { 369 if (!isTopResultSet) 370 { 371 SanityManager.THROWASSERT( 372 this + "expected to be the top ResultSet"); 373 } 374 375 SanityManager.THROWASSERT( 376 "setBeforeFirstRow() not expected to be called for " + getClass().getName()); 377 } 378 379 return null; 380 } 381 382 389 public boolean checkRowPosition(int isType) throws StandardException 390 { 391 return false; 392 } 393 394 403 public int getRowNumber() 404 { 405 return 0; 406 } 407 408 417 public ExecRow getFirstRow() 418 throws StandardException 419 { 420 if ( ! isOpen ) 421 { 422 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, FIRST); 423 } 424 425 attachStatementContext(); 426 427 if (SanityManager.DEBUG) 428 { 429 if (!isTopResultSet) 430 { 431 SanityManager.THROWASSERT( 432 this + "expected to be the top ResultSet"); 433 } 434 435 SanityManager.THROWASSERT( 436 "getFirstRow() not expected to be called for " + getClass().getName()); 437 } 438 439 return null; 440 } 441 442 460 public final ExecRow getNextRow() throws StandardException 461 { 462 if ( ! isOpen ) { 463 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, NEXT); 464 } 465 466 if (SanityManager.DEBUG) 467 { 468 if (!isTopResultSet) 469 SanityManager.THROWASSERT( 470 this + "expected to be the top ResultSet"); 471 } 472 473 attachStatementContext(); 474 475 return getNextRowCore(); 476 } 477 478 487 public ExecRow getPreviousRow() 488 throws StandardException 489 { 490 if ( ! isOpen ) 491 { 492 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, PREVIOUS); 493 } 494 495 attachStatementContext(); 496 497 if (SanityManager.DEBUG) 498 { 499 if (!isTopResultSet) 500 { 501 SanityManager.THROWASSERT( 502 this + "expected to be the top ResultSet"); 503 } 504 505 SanityManager.THROWASSERT( 506 "getPreviousRow() not expected to be called."); 507 } 508 509 return null; 510 } 511 512 521 public ExecRow getLastRow() 522 throws StandardException 523 { 524 if ( ! isOpen ) 525 { 526 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, LAST); 527 } 528 529 attachStatementContext(); 530 531 if (SanityManager.DEBUG) 532 { 533 if (!isTopResultSet) 534 { 535 SanityManager.THROWASSERT( 536 this + "expected to be the top ResultSet"); 537 } 538 539 SanityManager.THROWASSERT( 540 "getLastRow() not expected to be called."); 541 } 542 543 return null; 544 } 545 546 555 public ExecRow setAfterLastRow() 556 throws StandardException 557 { 558 if ( ! isOpen ) 559 { 560 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, LAST); 561 } 562 563 if (SanityManager.DEBUG) 564 { 565 if (!isTopResultSet) 566 { 567 SanityManager.THROWASSERT( 568 this + "expected to be the top ResultSet"); 569 } 570 571 SanityManager.THROWASSERT( 572 "setAfterLastRow() not expected to be called."); 573 } 574 575 return null; 576 } 577 578 579 582 public boolean returnsRows() { return true; } 583 584 public final int modifiedRowCount() { return 0; } 585 586 591 public void cleanUp() throws StandardException 592 { 593 if (isOpen) { 594 close(); 595 } 596 } 597 598 601 public boolean isClosed() { 602 return ( ! isOpen ); 603 } 604 605 public void finish() throws StandardException 606 { 607 finishAndRTS(); 608 } 609 610 613 protected final void finishAndRTS() throws StandardException 614 { 615 616 if (!finished) { 617 621 if (isTopResultSet) { 622 623 LanguageConnectionContext lcc = getLanguageConnectionContext(); 624 if (lcc.getRunTimeStatisticsMode()) 625 { 626 endExecutionTime = getCurrentTimeMillis(); 627 628 lcc.setRunTimeStatisticsObject( 629 lcc.getExecutionContext().getResultSetStatisticsFactory().getRunTimeStatistics(activation, this, subqueryTrackingArray)); 630 631 HeaderPrintWriter istream = lcc.getLogQueryPlan() ? Monitor.getStream() : null; 632 if (istream != null) 633 { 634 istream.printlnWithHeader(LanguageConnectionContext.xidStr + 635 lcc.getTransactionExecute().getTransactionIdString() + 636 "), " + 637 LanguageConnectionContext.lccStr + 638 lcc.getInstanceNumber() + 639 "), " + 640 lcc.getRunTimeStatisticsObject().getStatementText() + " ******* " + 641 lcc.getRunTimeStatisticsObject().getStatementExecutionPlanText()); 642 } 643 } 644 645 } 646 647 if (!isClosed()) 648 close(); 649 650 finished = true; 651 652 if (isTopResultSet && activation.isSingleExecution()) 653 activation.close(); 654 } 655 } 656 657 660 661 664 public ResultDescription getResultDescription() { 665 return resultDescription; 666 } 667 668 673 public long getExecuteTime() 674 { 675 return getTimeSpent(ResultSet.ENTIRE_RESULTSET_TREE); 676 } 677 678 683 public Timestamp getBeginExecutionTimestamp() 684 { 685 if (startExecutionTime == 0) 686 { 687 return null; 688 } 689 else 690 { 691 return new Timestamp (startExecutionTime); 692 } 693 } 694 695 700 public Timestamp getEndExecutionTimestamp() 701 { 702 if (endExecutionTime == 0) 703 { 704 return null; 705 } 706 else 707 { 708 return new Timestamp (endExecutionTime); 709 } 710 } 711 712 715 public final NoPutResultSet[] getSubqueryTrackingArray(int numSubqueries) 716 { 717 if (subqueryTrackingArray == null) 718 { 719 subqueryTrackingArray = new NoPutResultSet[numSubqueries]; 720 } 721 722 return subqueryTrackingArray; 723 } 724 725 731 protected final long getCurrentTimeMillis() 732 { 733 if (statisticsTimingOn) 734 { 735 return System.currentTimeMillis(); 736 } 737 else 738 { 739 return 0; 740 } 741 } 742 743 746 public ResultSet getAutoGeneratedKeysResultset() 747 { 748 return (ResultSet)null; 750 } 751 752 759 760 protected final long getElapsedMillis(long beginTime) 761 { 762 if (statisticsTimingOn) 763 { 764 return (System.currentTimeMillis() - beginTime); 765 } 766 else 767 { 768 return 0; 769 } 770 } 771 772 777 protected final String dumpTimeStats(String indent, String subIndent) 778 { 779 return 780 indent + 781 MessageService.getTextMessage(SQLState.LANG_TIME_SPENT_THIS) + 782 " " + getTimeSpent(ResultSet.CURRENT_RESULTSET_ONLY) + "\n" + 783 indent + 784 MessageService.getTextMessage( 785 SQLState.LANG_TIME_SPENT_THIS_AND_BELOW) + 786 " " + getTimeSpent(NoPutResultSet.ENTIRE_RESULTSET_TREE) + "\n" + 787 indent + 788 MessageService.getTextMessage( 789 SQLState.LANG_TOTAL_TIME_BREAKDOWN) + "\n" + 790 subIndent + 791 MessageService.getTextMessage(SQLState.LANG_CONSTRUCTOR_TIME) + 792 " " + constructorTime + "\n" + 793 subIndent + 794 MessageService.getTextMessage(SQLState.LANG_OPEN_TIME) + 795 " " + openTime + "\n" + 796 subIndent + 797 MessageService.getTextMessage(SQLState.LANG_NEXT_TIME) + 798 " " + nextTime + "\n" + 799 subIndent + 800 MessageService.getTextMessage(SQLState.LANG_CLOSE_TIME) + 801 " " + closeTime; 802 } 803 804 805 822 protected void attachStatementContext() throws StandardException 823 { 824 if (isTopResultSet) 825 { 826 if (statementContext == null || !statementContext.onStack() ) 827 { 828 statementContext = getLanguageConnectionContext().getStatementContext(); 829 } 830 statementContext.setTopResultSet(this, subqueryTrackingArray); 831 if (subqueryTrackingArray == null) 833 { 834 subqueryTrackingArray = statementContext.getSubqueryTrackingArray(); 835 } 836 } 837 838 } 839 840 845 protected final LanguageConnectionContext getLanguageConnectionContext() 846 { 847 if ( lcc == null ) 848 { 849 852 if (activation != null) 853 { 854 lcc = activation.getLanguageConnectionContext(); 855 } 856 else 857 { 858 lcc = (LanguageConnectionContext) ContextService.getContext(LanguageConnectionContext.CONTEXT_ID); 859 } 860 } 861 862 return lcc; 863 } 864 865 866 public int resultSetNumber() { 867 if (SanityManager.DEBUG) { 868 SanityManager.THROWASSERT( 869 "resultSetNumber() should not be called on a " + 870 this.getClass().getName() 871 ); 872 } 873 874 return 0; 875 } 876 877 883 888 final ExecutionFactory getExecutionFactory() 889 { 890 if (exFactory == null) { 891 exFactory = activation.getExecutionFactory(); 892 } 893 if (SanityManager.DEBUG) 894 SanityManager.ASSERT(exFactory!=null,"unable to get execution factory"); 895 return exFactory; 896 } 897 898 902 final TransactionController getTransactionController() 903 { 904 if (tc == null) 905 { 906 tc = getLanguageConnectionContext().getTransactionExecute(); 907 } 908 return tc; 909 } 910 911 935 protected ExecRow getCompactRow(ExecRow candidate, 936 FormatableBitSet accessedCols, 937 FormatableBitSet otherCols, 938 boolean isKeyed) 939 throws StandardException 940 { 941 int numCandidateCols = candidate.nColumns(); 942 943 if (accessedCols == null) 944 { 945 compactRow = candidate; 946 baseColumnMap = new int[numCandidateCols]; 947 for (int i = 0; i < baseColumnMap.length; i++) 948 baseColumnMap[i] = i; 949 } 950 else 951 { 952 FormatableBitSet allCols; 953 954 if (otherCols == null) 955 { 956 allCols = accessedCols; 957 } 958 else 959 { 960 allCols = new FormatableBitSet(accessedCols); 961 allCols.or(otherCols); 962 } 963 964 int numCols = allCols.getNumBitsSet(); 965 baseColumnMap = new int[numCols]; 966 967 if (compactRow == null) 968 { 969 ExecutionFactory ex = lcc.getExecutionContext().getExecutionFactory(); 970 971 if (isKeyed) 972 { 973 compactRow = ex.getIndexableRow(numCols); 974 } 975 else 976 { 977 compactRow = ex.getValueRow(numCols); 978 } 979 } 980 981 int position = 0; 982 for (int i = allCols.anySetBit(); 983 i != -1; 984 i = allCols.anySetBit(i)) 985 { 986 if (i >= numCandidateCols) 990 break; 991 992 DataValueDescriptor sc = candidate.getColumn(i+1); 993 if (sc != null) 994 { 995 compactRow.setColumn( 996 position + 1, 997 sc 998 ); 999 } 1000 baseColumnMap[position] = i; 1001 position++; 1002 } 1003 } 1004 1005 return compactRow; 1006 } 1007 1008 1020 protected ExecRow setCompactRow(ExecRow candidateRow, ExecRow compactRow) 1021 { 1022 ExecRow retval; 1023 1024 if (baseColumnMap == null) 1026 { 1027 retval = candidateRow; 1028 } 1029 else 1030 { 1031 retval = compactRow; 1032 1033 setCompatRow(compactRow, candidateRow.getRowArray()); 1034 } 1035 1036 return retval; 1037 } 1038 1039 1040 protected final void setCompatRow(ExecRow compactRow, Object [] sourceRow) { 1041 1042 Object [] destRow = compactRow.getRowArray(); 1043 int[] lbcm = baseColumnMap; 1044 1045 for (int i = 0; i < lbcm.length; i++) 1046 { 1047 1048 destRow[i] = sourceRow[lbcm[i]]; 1049 1050 } 1051 } 1052 1053 1059 public boolean isForUpdate() 1060 { 1061 return false; 1062 } 1063 1064 1071 public void checkCancellationFlag() 1072 throws 1073 StandardException 1074 { 1075 StatementContext localStatementContext = getLanguageConnectionContext().getStatementContext(); 1076 if (localStatementContext == null) { 1077 return; 1078 } 1079 1080 if (localStatementContext.isCancelled()) { 1081 throw StandardException.newException(SQLState.LANG_STATEMENT_CANCELLED_OR_TIMED_OUT); 1082 } 1083 } 1084 1085 protected final void addWarning(SQLWarning w) { 1086 1087 if (isTopResultSet) { 1088 if (warnings == null) 1089 warnings = w; 1090 else 1091 warnings.setNextWarning(w); 1092 return; 1093 } 1094 1095 if (activation != null) { 1096 1097 ResultSet rs = activation.getResultSet(); 1098 if (rs instanceof BasicNoPutResultSetImpl) { 1099 ((BasicNoPutResultSetImpl) rs).addWarning(w); 1100 } 1101 1102 } 1103 } 1104 1105 public final SQLWarning getWarnings() { 1106 SQLWarning w = warnings; 1107 warnings = null; 1108 return w; 1109 } 1110} 1111 | Popular Tags |