1 21 22 package org.apache.derby.iapi.sql.dictionary; 23 24 import org.apache.derby.iapi.services.io.StoredFormatIds; 25 26 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 27 import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory; 28 import org.apache.derby.iapi.sql.conn.StatementContext; 29 30 import org.apache.derby.iapi.store.access.TransactionController; 31 32 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 33 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 34 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 35 36 import org.apache.derby.iapi.sql.execute.ConstantAction; 37 import org.apache.derby.iapi.sql.execute.ExecutionContext; 38 39 import org.apache.derby.iapi.sql.compile.CompilerContext; 40 41 import org.apache.derby.iapi.types.DataTypeDescriptor; 42 import org.apache.derby.iapi.sql.Statement; 43 import org.apache.derby.iapi.sql.StorablePreparedStatement; 44 45 import org.apache.derby.iapi.error.StandardException; 46 import org.apache.derby.iapi.reference.SQLState; 47 48 import org.apache.derby.iapi.services.context.ContextManager; 49 import org.apache.derby.iapi.services.loader.ClassFactory; 50 import org.apache.derby.iapi.services.context.ContextService; 51 import org.apache.derby.iapi.services.monitor.Monitor; 52 53 import org.apache.derby.iapi.sql.depend.DependencyManager; 54 import org.apache.derby.iapi.sql.depend.Dependent; 55 import org.apache.derby.iapi.sql.depend.Dependency; 56 import org.apache.derby.iapi.sql.depend.Provider; 57 import org.apache.derby.iapi.sql.depend.ProviderInfo; 58 59 import org.apache.derby.iapi.types.DataValueFactory; 60 61 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement; 62 63 import org.apache.derby.iapi.services.sanity.SanityManager; 64 import org.apache.derby.iapi.services.loader.GeneratedClass; 65 66 import org.apache.derby.catalog.UUID; 67 import org.apache.derby.catalog.Dependable; 68 import org.apache.derby.catalog.DependableFinder; 69 import org.apache.derby.iapi.services.uuid.UUIDFactory; 70 71 import java.util.Enumeration ; 72 import java.util.Vector ; 73 import java.sql.Timestamp ; 74 75 95 public class SPSDescriptor extends TupleDescriptor 96 implements UniqueSQLObjectDescriptor, Dependent, Provider 97 { 98 106 public static final char SPS_TYPE_TRIGGER = 'T'; 107 public static final char SPS_TYPE_REGULAR = 'S'; 108 public static final char SPS_TYPE_EXPLAIN = 'X'; 109 110 141 142 private static final int RECOMPILE = 1; 143 private static final int INVALIDATE = 0; 144 145 146 private SchemaDescriptor sd; 148 private String name; 149 private UUID uuid; 150 private UUID compSchemaId; 151 private char type; 152 private boolean valid; 153 private String text; 154 private String usingText; 155 private ExecPreparedStatement preparedStatement; 156 private DataTypeDescriptor params[]; 157 private Timestamp compileTime; 158 161 private Object paramDefaults[]; 162 private boolean initiallyCompilable; 163 private boolean lookedUpParams; 164 165 private UUIDFactory uuidFactory; 166 167 168 184 public SPSDescriptor 185 (DataDictionary dataDictionary, 186 String name, 187 UUID uuid, 188 UUID suuid, 189 UUID compSchemaUUID, 190 char type, 191 boolean valid, 192 String text, 193 boolean initiallyCompilable ) throws StandardException 194 { 195 this( dataDictionary, name, uuid, suuid, compSchemaUUID, 196 type, valid, text, (String ) null, null, null, initiallyCompilable ); 197 } 198 199 220 public SPSDescriptor 221 (DataDictionary dataDictionary, 222 String name, 223 UUID uuid, 224 UUID suuid, 225 UUID compSchemaUUID, 226 char type, 227 boolean valid, 228 String text, 229 String usingText, 230 Timestamp compileTime, 231 ExecPreparedStatement preparedStatement, 232 boolean initiallyCompilable ) throws StandardException 233 { 234 super( dataDictionary ); 235 236 this.name = name; 237 this.uuid = uuid; 238 this.type = type; 239 this.text = text; 240 this.usingText = usingText; 241 this.valid = valid; 242 this.compileTime = compileTime; 243 this.sd = dataDictionary.getSchemaDescriptor(suuid, null); 244 this.preparedStatement = preparedStatement; 245 this.compSchemaId = compSchemaUUID; 246 this.initiallyCompilable = initiallyCompilable; 247 } 248 249 267 public final synchronized void prepareAndRelease 268 ( 269 LanguageConnectionContext lcc, 270 TableDescriptor triggerTable, 271 TransactionController tc 272 ) throws StandardException 273 { 274 if (SanityManager.DEBUG) 275 { 276 if (triggerTable != null) 277 { 278 SanityManager.ASSERT(type == SPS_TYPE_TRIGGER, "only expect a table descriptor when we have a trigger"); 279 } 280 } 281 282 compileStatement(lcc, triggerTable, tc); 283 284 preparedStatement.makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc); 285 } 286 287 304 public final synchronized void prepareAndRelease 305 ( 306 LanguageConnectionContext lcc, 307 TableDescriptor triggerTable 308 ) throws StandardException 309 { 310 prepareAndRelease(lcc, triggerTable, (TransactionController)null); 311 } 312 313 326 public final synchronized void prepareAndRelease(LanguageConnectionContext lcc) throws StandardException 327 { 328 prepareAndRelease(lcc, (TableDescriptor)null, (TransactionController)null); 329 } 330 331 private void compileStatement 332 ( 333 LanguageConnectionContext lcc, 334 TableDescriptor triggerTable, 335 TransactionController tc 336 ) 337 throws StandardException 338 { 339 ContextManager cm = lcc.getContextManager(); 340 DependencyManager dm; 341 ProviderInfo[] providerInfo; 342 343 LanguageConnectionFactory lcf = lcc.getLanguageConnectionFactory(); 344 345 DataDictionary dd = getDataDictionary(); 346 347 348 356 if (type == SPS_TYPE_TRIGGER && triggerTable == null) 357 { 358 String uuidStr = name.substring(49); 359 triggerTable = dd.getTableDescriptor(recreateUUID(uuidStr)); 360 if (SanityManager.DEBUG) 361 { 362 if (triggerTable == null) 363 { 364 SanityManager.THROWASSERT("couldn't find trigger table for trigger sps "+name); 365 } 366 } 367 } 368 369 if (triggerTable != null) 370 { 371 lcc.pushTriggerTable(triggerTable); 372 } 373 374 Statement stmt = lcf.getStatement(dd.getSchemaDescriptor(compSchemaId, null), text, true); 376 377 try 378 { 379 preparedStatement = (ExecPreparedStatement) stmt.prepareStorable( 380 lcc, 381 preparedStatement, 382 getParameterDefaults(), 383 getSchemaDescriptor(), 384 type == SPS_TYPE_TRIGGER); 385 } 386 finally 387 { 388 if (triggerTable != null) 389 { 390 lcc.popTriggerTable(triggerTable); 391 } 392 } 393 394 if (preparedStatement.referencesSessionSchema()) 400 throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES); 401 402 setCompileTime(); 403 setParams(preparedStatement.getParameterTypes()); 404 405 if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade) { 406 407 412 dd.startWriting(lcc); 413 414 dm = dd.getDependencyManager(); 415 420 dm.clearDependencies(lcc, this, tc); 421 422 425 dm.copyDependencies(preparedStatement, this, false, cm, 429 tc); 430 } 431 432 valid = true; 434 } 435 436 441 public final String getName() 442 { 443 return name; 444 } 445 446 451 public final String getQualifiedName() 452 { 453 return sd.getSchemaName() + "." + name; 454 } 455 456 461 public final SchemaDescriptor getSchemaDescriptor() 462 { 463 return sd; 464 } 465 466 474 public final char getType() 475 { 476 return type; 477 } 478 479 485 public final String getTypeAsString() 486 { 487 char[] charArray = new char[1]; 488 charArray[0] = type; 489 return new String (charArray); 490 } 491 492 498 public boolean initiallyCompilable() { return initiallyCompilable; } 499 500 508 public final static boolean validType(char type) 509 { 510 return (type == SPSDescriptor.SPS_TYPE_REGULAR) || 511 (type == SPSDescriptor.SPS_TYPE_TRIGGER); 512 } 513 514 519 public final synchronized Timestamp getCompileTime() 520 { 521 return compileTime; 522 } 523 524 528 public final synchronized void setCompileTime() 529 { 530 compileTime = new Timestamp (System.currentTimeMillis()); 531 } 532 533 539 public final String getText() 540 { 541 return text; 542 } 543 544 550 public final synchronized String getUsingText() 551 { 552 return usingText; 553 } 554 555 560 public final synchronized void setUUID(UUID uuid) 561 { 562 this.uuid = uuid; 563 } 564 565 570 public final UUID getUUID() 571 { 572 return uuid; 573 } 574 575 586 public final synchronized DataTypeDescriptor[] getParams() 587 throws StandardException 588 { 589 if (params == null && !lookedUpParams) 590 { 591 Vector v = new Vector (); 592 params = getDataDictionary().getSPSParams(this, v); 593 paramDefaults = new Object [v.size()]; 594 Enumeration iterator = v.elements(); 595 for (int i = 0; iterator.hasMoreElements(); i++) 596 { 597 paramDefaults[i] = iterator.nextElement(); 598 } 599 600 lookedUpParams = true; 601 } 602 603 return params; 604 } 605 606 611 public final synchronized void setParams(DataTypeDescriptor params[]) 612 { 613 this.params = params; 614 } 615 616 626 public final synchronized Object [] getParameterDefaults() 627 throws StandardException 628 { 629 if (paramDefaults == null) 630 getParams(); 631 632 return paramDefaults; 633 } 634 635 640 public final synchronized void setParameterDefaults(Object [] values) 641 { 642 this.paramDefaults = values; 643 } 644 645 650 655 664 public final ExecPreparedStatement getPreparedStatement() 665 throws StandardException 666 { 667 return getPreparedStatement(true); 668 } 669 670 685 public final synchronized ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid) 686 throws StandardException 687 { 688 694 if (recompIfInvalid && 695 (!valid || 696 (preparedStatement == null))) 697 { 698 ContextManager cm = ContextService.getFactory().getCurrentContextManager(); 699 700 704 LanguageConnectionContext lcc = (LanguageConnectionContext) 705 cm.getContext(LanguageConnectionContext.CONTEXT_ID); 706 707 708 709 if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) (lcc.getDataDictionary())).readOnlyUpgrade) { 710 711 TransactionController nestedTC; 717 try 718 { 719 nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false); 720 } 721 catch (StandardException se) 722 { 723 nestedTC = null; 726 } 727 728 try 729 { 730 prepareAndRelease(lcc, null, nestedTC); 731 updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC); 732 } 733 catch (StandardException se) 734 { 735 if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT)) 736 { 737 if (nestedTC != null) 738 { 739 nestedTC.commit(); 740 nestedTC.destroy(); 741 nestedTC = null; 742 } 743 prepareAndRelease(lcc, null, null); 746 updateSYSSTATEMENTS(lcc, RECOMPILE, null); 747 } 748 else throw se; 749 } 750 finally 751 { 752 if (nestedTC != null) 756 { 757 nestedTC.commit(); 758 nestedTC.destroy(); 759 } 760 } 761 } 762 } 763 764 return preparedStatement; 765 } 766 767 773 public final UUID getCompSchemaId() 774 { 775 return compSchemaId; 776 } 777 778 783 public final String toString() 784 { 785 if (SanityManager.DEBUG) 786 { 787 return "SPSDescriptor:\n"+ 788 "\tname: "+sd.getSchemaName()+"."+name+"\n"+ 789 "\tuuid: "+uuid+"\n"+ 790 "\ttext: "+text+"\n"+ 791 "\tvalid: "+((valid) ? "TRUE" : "FALSE")+"\n" + 792 "\tpreparedStatement: "+preparedStatement+"\n"; 793 } 794 else 795 { 796 return ""; 797 } 798 } 799 800 806 811 public final DependableFinder getDependableFinder() 812 { 813 return getDependableFinder(StoredFormatIds.SPS_DESCRIPTOR_FINDER_V01_ID); 814 } 815 816 821 public final String getObjectName() 822 { 823 return name; 824 } 825 826 831 public final UUID getObjectID() 832 { 833 return uuid; 834 } 835 836 841 public final String getClassType() 842 { 843 return Dependable.STORED_PREPARED_STATEMENT; 844 } 845 846 856 public final synchronized boolean isValid() 857 { 858 return valid; 859 } 860 861 870 public final synchronized void prepareToInvalidate( 871 Provider p, int action, 872 LanguageConnectionContext lcc) 873 throws StandardException 874 { 875 switch (action) 876 { 877 880 case DependencyManager.CREATE_VIEW: 881 882 886 case DependencyManager.CREATE_INDEX: 887 case DependencyManager.CREATE_CONSTRAINT: 888 case DependencyManager.DROP_CONSTRAINT: 889 case DependencyManager.DROP_INDEX: 890 case DependencyManager.DROP_TABLE: 891 case DependencyManager.DROP_VIEW: 892 case DependencyManager.DROP_METHOD_ALIAS: 893 case DependencyManager.DROP_SYNONYM: 894 case DependencyManager.ALTER_TABLE: 895 case DependencyManager.RENAME: 896 case DependencyManager.RENAME_INDEX: 897 case DependencyManager.PREPARED_STATEMENT_RELEASE: 898 case DependencyManager.USER_RECOMPILE_REQUEST: 899 case DependencyManager.CHANGED_CURSOR: 900 case DependencyManager.BULK_INSERT: 901 case DependencyManager.COMPRESS_TABLE: 902 case DependencyManager.SET_CONSTRAINTS_ENABLE: 903 case DependencyManager.SET_CONSTRAINTS_DISABLE: 904 case DependencyManager.SET_TRIGGERS_ENABLE: 905 case DependencyManager.SET_TRIGGERS_DISABLE: 906 case DependencyManager.ROLLBACK: 907 case DependencyManager.INTERNAL_RECOMPILE_REQUEST: 908 case DependencyManager.CREATE_TRIGGER: 909 case DependencyManager.DROP_TRIGGER: 910 case DependencyManager.DROP_COLUMN: 911 case DependencyManager.UPDATE_STATISTICS: 912 case DependencyManager.DROP_STATISTICS: 913 case DependencyManager.TRUNCATE_TABLE: 914 break; 915 916 919 default: 920 921 DependencyManager dm; 922 923 dm = getDataDictionary().getDependencyManager(); 924 throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_S_P_S, 925 dm.getActionString(action), 926 p.getObjectName(), name); 927 928 } 929 } 930 931 939 public final synchronized void makeInvalid(int action, 940 LanguageConnectionContext lcc) 941 throws StandardException 942 { 943 DependencyManager dm; 944 945 dm = getDataDictionary().getDependencyManager(); 946 947 switch (action) 948 { 949 953 case DependencyManager.PREPARED_STATEMENT_RELEASE: 954 case DependencyManager.CREATE_VIEW: 955 break; 956 957 961 case DependencyManager.CREATE_INDEX: 962 case DependencyManager.CREATE_CONSTRAINT: 963 case DependencyManager.DROP_CONSTRAINT: 964 case DependencyManager.DROP_TABLE: 965 case DependencyManager.DROP_INDEX: 966 case DependencyManager.DROP_VIEW: 967 case DependencyManager.DROP_METHOD_ALIAS: 968 case DependencyManager.DROP_SYNONYM: 969 case DependencyManager.ALTER_TABLE: 970 case DependencyManager.RENAME: 971 case DependencyManager.RENAME_INDEX: 972 case DependencyManager.USER_RECOMPILE_REQUEST: 973 case DependencyManager.CHANGED_CURSOR: 974 case DependencyManager.BULK_INSERT: 975 case DependencyManager.COMPRESS_TABLE: 976 case DependencyManager.SET_CONSTRAINTS_ENABLE: 977 case DependencyManager.SET_CONSTRAINTS_DISABLE: 978 case DependencyManager.SET_TRIGGERS_ENABLE: 979 case DependencyManager.SET_TRIGGERS_DISABLE: 980 case DependencyManager.ROLLBACK: 981 case DependencyManager.INTERNAL_RECOMPILE_REQUEST: 982 case DependencyManager.CREATE_TRIGGER: 983 case DependencyManager.DROP_TRIGGER: 984 case DependencyManager.DROP_COLUMN: 985 case DependencyManager.UPDATE_STATISTICS: 986 case DependencyManager.DROP_STATISTICS: 987 case DependencyManager.TRUNCATE_TABLE: 988 993 if (valid == true) 994 { 995 valid = false; 996 updateSYSSTATEMENTS(lcc, INVALIDATE, null); 997 } 998 dm.invalidateFor(this, dm.USER_RECOMPILE_REQUEST, lcc); 999 break; 1000 case DependencyManager.DROP_SPS: 1001 dm.clearDependencies(lcc, this); 1003 break; 1004 1005 default: 1006 1007 1010 if (SanityManager.DEBUG) 1011 { 1012 SanityManager.THROWASSERT("makeInvalid("+ 1013 dm.getActionString(action)+ 1014 ") not expected to get called; should have failed in "+ 1015 "prepareToInvalidate()"); 1016 } 1017 break; 1018 1019 } 1020 1021 } 1022 1023 1032 public final synchronized void makeValid(LanguageConnectionContext lcc) 1033 throws StandardException 1034 { 1035 if (valid) 1036 { 1037 return; 1038 } 1039 prepareAndRelease(lcc); 1040 1041 updateSYSSTATEMENTS(lcc, RECOMPILE, null); 1042 1043 } 1044 1045 1052 public final synchronized void revalidate(LanguageConnectionContext lcc) 1053 throws StandardException 1054 { 1055 1059 valid = false; 1060 makeInvalid(DependencyManager.USER_RECOMPILE_REQUEST, lcc); 1061 prepareAndRelease(lcc); 1062 updateSYSSTATEMENTS(lcc, RECOMPILE, null); 1063 } 1064 1065 1073 public void loadGeneratedClass() throws StandardException 1074 { 1075 1079 if (preparedStatement != null) 1080 { 1081 ((StorablePreparedStatement)preparedStatement).loadGeneratedClass(); 1082 } 1083 } 1084 1085 1102 private void updateSYSSTATEMENTS(LanguageConnectionContext lcc, int mode, TransactionController tc) 1103 throws StandardException 1104 { 1105 int[] colsToUpdate; 1106 boolean updateSYSCOLUMNS, recompile; 1107 boolean wait = false; 1109 boolean firstCompilation = false; 1110 if (mode == RECOMPILE) 1111 { 1112 recompile = true; 1113 updateSYSCOLUMNS = true; 1114 if(!initiallyCompilable) 1115 { 1116 firstCompilation = true; 1117 initiallyCompilable = true; 1118 } 1119 } 1120 else 1121 { 1122 recompile = false; 1123 updateSYSCOLUMNS = false; 1124 } 1125 1126 DataDictionary dd = getDataDictionary(); 1127 1128 if (((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade) 1129 return; 1130 1131 1132 1135 dd.startWriting(lcc); 1136 1137 if (tc == null) { tc = lcc.getTransactionExecute(); 1139 wait = true; 1140 } 1141 1142 dd.updateSPS(this, 1143 tc, 1144 recompile, 1145 updateSYSCOLUMNS, 1146 wait, 1147 firstCompilation); 1148 } 1149 1150 1157 private UUID recreateUUID(String idString) 1158 { 1159 if (uuidFactory == null) 1160 { 1161 uuidFactory = Monitor.getMonitor().getUUIDFactory(); 1162 } 1163 return uuidFactory.recreateUUID(idString); 1164 } 1165 1166 1167 public String getDescriptorType() { return "Statement"; } 1168 1169 1170 public String getDescriptorName() { return name; } 1174 1175} 1176 1177 | Popular Tags |