1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.loader.GeneratedMethod; 25 26 import org.apache.derby.iapi.services.context.ContextManager; 27 28 import org.apache.derby.iapi.services.compiler.JavaFactory; 29 import org.apache.derby.iapi.services.compiler.MethodBuilder; 30 31 import org.apache.derby.iapi.services.sanity.SanityManager; 32 33 import org.apache.derby.iapi.sql.depend.Dependent; 34 35 import org.apache.derby.iapi.sql.compile.CompilerContext; 36 import org.apache.derby.iapi.sql.compile.Parser; 37 import org.apache.derby.iapi.sql.compile.CostEstimate; 38 import org.apache.derby.iapi.sql.compile.OptimizerFactory; 39 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 40 import org.apache.derby.iapi.sql.compile.NodeFactory; 41 42 import org.apache.derby.iapi.sql.conn.Authorizer; 43 44 import org.apache.derby.iapi.reference.ClassName; 45 import org.apache.derby.iapi.reference.SQLState; 46 47 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 48 49 import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor; 50 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; 51 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor; 52 import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList; 53 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor; 54 import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor; 55 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 56 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList; 57 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 58 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 59 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; 60 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 61 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 62 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor; 63 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 64 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList; 65 66 import org.apache.derby.iapi.sql.StatementType; 67 68 import org.apache.derby.iapi.store.access.TransactionController; 69 70 import org.apache.derby.impl.sql.compile.ActivationClassBuilder; 71 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 72 73 import org.apache.derby.iapi.error.StandardException; 74 75 import org.apache.derby.impl.sql.execute.FKInfo; 76 import org.apache.derby.impl.sql.execute.TriggerInfo; 77 78 import org.apache.derby.iapi.types.RowLocation; 79 80 import org.apache.derby.catalog.UUID; 81 import java.util.Properties ; 82 import java.util.Vector ; 83 import java.util.Enumeration ; 84 import java.util.Hashtable ; 85 import org.apache.derby.iapi.services.io.FormatableBitSet; 86 import org.apache.derby.iapi.services.classfile.VMOpcode; 87 88 94 95 abstract class DMLModStatementNode extends DMLStatementNode 96 { 97 protected FromVTI targetVTI; 99 protected TableName targetTableName; 100 protected ResultColumnList resultColumnList; 101 protected int lockMode; 103 protected FKInfo[] fkInfo; protected TriggerInfo triggerInfo; public TableDescriptor targetTableDescriptor; 107 108 109 110 public IndexRowGenerator[] indicesToMaintain; 111 public long[] indexConglomerateNumbers; 112 public String [] indexNames; 113 protected ConstraintDescriptorList relevantCdl; 114 protected GenericDescriptorList relevantTriggers; 115 116 private boolean requiresDeferredProcessing; 118 private int statementType; 119 private boolean bound; 120 private ValueNode checkConstraints; 121 122 123 protected String [] fkTableNames; protected int[] fkRefActions; protected ColumnDescriptorList[] fkColDescriptors; 126 protected long[] fkIndexConglomNumbers; protected boolean isDependentTable; 128 protected int[][] fkColArrays; 129 protected Hashtable graphHashTable; 130 protected TableName synonymTableName; 132 133 139 public void init(Object resultSet) 140 { 141 super.init(resultSet); 142 statementType = getStatementType(); 143 } 144 145 153 public void init(Object resultSet, Object statementType) 154 { 155 super.init(resultSet); 156 this.statementType = ((Integer ) statementType).intValue(); 157 } 158 159 void setTarget(QueryTreeNode targetName) 160 { 161 if (targetName instanceof TableName) 162 { 163 this.targetTableName = (TableName) targetName; 164 } 165 else 166 { 167 if (SanityManager.DEBUG) 168 { 169 if (! (targetName instanceof FromVTI)) 170 { 171 SanityManager.THROWASSERT( 172 "targetName expected to be FromVTI, not " + 173 targetName.getClass().getName()); 174 } 175 } 176 this.targetVTI = (FromVTI) targetName; 177 targetVTI.setTarget(); 178 } 179 } 180 181 191 protected void generateCodeForTemporaryTable(ActivationClassBuilder acb, MethodBuilder mb) 192 throws StandardException 193 { 194 if (targetTableDescriptor != null && targetTableDescriptor.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE && 195 targetTableDescriptor.isOnRollbackDeleteRows() == true) 196 { 197 mb.pushThis(); 198 mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Activation, 199 "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0); 200 mb.push(targetTableDescriptor.getName()); 201 mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "markTempTableAsModifiedInUnitOfWork", 202 "void", 1); 203 mb.endStatement(); 204 } 205 } 206 207 213 void verifyTargetTable() 214 throws StandardException 215 { 216 DataDictionary dataDictionary = getDataDictionary(); 217 if (targetTableName != null) 218 { 219 222 SchemaDescriptor sdtc = getSchemaDescriptor(targetTableName.getSchemaName()); 223 224 targetTableDescriptor = getTableDescriptor( 225 targetTableName.getTableName(), sdtc); 226 227 if (targetTableDescriptor == null) 228 { 229 TableName synonymTab = resolveTableToSynonym(targetTableName); 231 if (synonymTab == null) 232 throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName); 233 synonymTableName = targetTableName; 234 targetTableName = synonymTab; 235 sdtc = getSchemaDescriptor(targetTableName.getSchemaName()); 236 237 targetTableDescriptor = getTableDescriptor(synonymTab.getTableName(), sdtc); 238 if (targetTableDescriptor == null) 239 throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName); 240 } 241 242 switch (targetTableDescriptor.getTableType()) 243 { 244 case TableDescriptor.VIEW_TYPE: 245 throw StandardException.newException(SQLState.LANG_VIEW_NOT_UPDATEABLE, 247 targetTableName); 248 249 case TableDescriptor.VTI_TYPE: 250 case TableDescriptor.SYSTEM_TABLE_TYPE: 252 throw StandardException.newException(SQLState.LANG_UPDATE_SYSTEM_TABLE_ATTEMPTED, 254 targetTableName); 255 default: 256 break; 257 258 } 259 260 267 targetTableDescriptor = lockTableForCompilation(targetTableDescriptor); 268 269 getCompilerContext().createDependency(targetTableDescriptor); 270 } 271 else 272 { 273 278 FromList dummyFromList = new FromList(); 279 targetVTI = (FromVTI) targetVTI.bindNonVTITables(dataDictionary, dummyFromList); 280 targetVTI = (FromVTI) targetVTI.bindVTITables(dummyFromList); 281 } 282 } 283 284 290 public boolean isAtomic() 291 { 292 return true; 293 } 294 295 304 public SchemaDescriptor getSchemaDescriptor() throws StandardException 305 { 306 SchemaDescriptor sd; 307 308 sd = getSchemaDescriptor(targetTableName.getSchemaName()); 309 310 return sd; 311 } 312 313 329 public static int[] getReadColMap(int column_map_length,FormatableBitSet readColsBitSet) 330 { 331 if (readColsBitSet == null) return null; 332 333 int partial_col_cnt = 0; 334 int column_map[] = new int[column_map_length]; 335 int readColsBitSetSize = readColsBitSet.size(); 336 337 for (int base_index = 0; base_index < column_map.length; base_index++) 338 { 339 if (readColsBitSetSize > base_index && readColsBitSet.get(base_index+1)) 340 column_map[base_index] = partial_col_cnt++; 341 else 342 column_map[base_index] = -1; 344 } 345 346 return(column_map); 347 } 348 349 355 protected void getResultColumnList() 356 throws StandardException 357 { 358 if (targetVTI == null) 359 { 360 getResultColumnList((ResultColumnList) null); 361 } 362 else 363 { 364 367 resultColumnList = targetVTI.getResultColumns(); 368 } 369 } 370 371 377 protected FromBaseTable getResultColumnList(ResultColumnList inputRcl) 378 throws StandardException 379 { 380 381 FromBaseTable fbt = 382 (FromBaseTable) 383 (getNodeFactory().getNode( 384 C_NodeTypes.FROM_BASE_TABLE, 385 targetTableName, 386 null, 387 null, 388 null, 389 getContextManager()) 390 ); 391 392 fbt.bindNonVTITables( 393 getDataDictionary(), 394 (FromList) getNodeFactory().getNode( 395 C_NodeTypes.FROM_LIST, 396 getNodeFactory().doJoinOrderOptimization(), 397 getContextManager())); 398 399 getResultColumnList( 400 fbt, 401 inputRcl 402 ); 403 return fbt; 404 } 405 406 412 private void getResultColumnList(FromBaseTable fromBaseTable, 413 ResultColumnList inputRcl) 414 throws StandardException 415 { 416 if (inputRcl == null) 417 { 418 resultColumnList = fromBaseTable.getAllResultColumns(null); 419 resultColumnList.bindResultColumnsByPosition(targetTableDescriptor); 420 } 421 else 422 { 423 resultColumnList = fromBaseTable.getResultColumnsForList(null, inputRcl, 424 fromBaseTable.getTableNameField()); 425 426 resultColumnList.bindResultColumnsByName(targetTableDescriptor, 427 (DMLStatementNode) this); 428 } 429 } 430 431 463 public ValueNode bindConstraints 464 ( 465 DataDictionary dataDictionary, 466 NodeFactory nodeFactory, 467 TableDescriptor targetTableDescriptor, 468 Dependent dependent, 469 ResultColumnList sourceRCL, 470 int[] changedColumnIds, 471 FormatableBitSet readColsBitSet, 472 boolean skipCheckConstraints, 473 boolean includeTriggers 474 ) 475 throws StandardException 476 { 477 bound = true; 478 479 480 if (targetVTI != null) 481 { 482 return null; 483 } 484 485 getCompilerContext().pushCurrentPrivType( Authorizer.NULL_PRIV); 487 try { 488 getAllRelevantConstraints(dataDictionary, 489 targetTableDescriptor, 490 skipCheckConstraints, 491 changedColumnIds); 492 createConstraintDependencies(dataDictionary, relevantCdl, dependent); 493 generateFKInfo(relevantCdl, dataDictionary, targetTableDescriptor, readColsBitSet); 494 495 getAllRelevantTriggers(dataDictionary, targetTableDescriptor, 496 changedColumnIds, includeTriggers); 497 createTriggerDependencies(relevantTriggers, dependent); 498 generateTriggerInfo(relevantTriggers, targetTableDescriptor, changedColumnIds); 499 500 if (skipCheckConstraints) 501 { 502 return null; 503 } 504 505 checkConstraints = generateCheckTree(relevantCdl, 506 targetTableDescriptor); 507 508 if (checkConstraints != null) 509 { 510 bindCheckConstraint(nodeFactory, 511 targetTableDescriptor, 512 sourceRCL, 513 checkConstraints); 514 } 515 } 516 finally 517 { 518 getCompilerContext().popCurrentPrivType(); 519 } 520 521 return checkConstraints; 522 } 523 524 534 public void bindCheckConstraint 535 ( 536 NodeFactory nodeFactory, 537 TableDescriptor targetTableDescriptor, 538 ResultColumnList sourceRCL, 539 ValueNode checkConstraint 540 ) 541 throws StandardException 542 { 543 544 TableName targetTableName = 545 makeTableName(targetTableDescriptor.getSchemaName(), 546 targetTableDescriptor.getName()); 547 548 549 567 FromList fakeFromList = 568 (FromList) nodeFactory.getNode( 569 C_NodeTypes.FROM_LIST, 570 nodeFactory.doJoinOrderOptimization(), 571 getContextManager()); 572 FromBaseTable table = (FromBaseTable) 573 nodeFactory.getNode( 574 C_NodeTypes.FROM_BASE_TABLE, 575 targetTableName, 576 null, 577 sourceRCL, 578 null, 579 getContextManager()); 580 table.setTableNumber(0); 581 fakeFromList.addFromTable(table); 582 583 checkConstraint = checkConstraint.bindExpression( 585 fakeFromList, 586 (SubqueryList) null, 587 (Vector ) null); 588 } 589 590 601 protected boolean hasCheckConstraints(DataDictionary dd, 602 TableDescriptor td) 603 throws StandardException 604 { 605 ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td); 606 if (cdl == null) 607 return false; 608 ConstraintDescriptorList ccCDL = cdl.getSubList(DataDictionary.CHECK_CONSTRAINT); 609 610 return (ccCDL.size() > 0); 611 } 612 613 614 626 private ValueNode generateCheckTree 627 ( 628 ConstraintDescriptorList cdl, 629 TableDescriptor td 630 ) 631 throws StandardException 632 { 633 ConstraintDescriptorList ccCDL = cdl.getSubList(DataDictionary.CHECK_CONSTRAINT); 634 int ccCDLSize = ccCDL.size(); 635 ValueNode checkTree = null; 636 637 for (int index = 0; index < ccCDLSize; index++) 639 { 640 ConstraintDescriptor cd = ccCDL.elementAt(index); 641 642 String constraintText = cd.getConstraintText(); 643 644 ValueNode oneConstraint = 646 parseCheckConstraint(constraintText, td); 647 648 TestConstraintNode tcn = 650 (TestConstraintNode) getNodeFactory().getNode( 651 C_NodeTypes.TEST_CONSTRAINT_NODE, 652 oneConstraint, 653 SQLState.LANG_CHECK_CONSTRAINT_VIOLATED, 654 td.getQualifiedName(), 655 cd.getConstraintName(), 656 getContextManager()); 657 658 if (checkTree == null) 660 { 661 checkTree = tcn; 662 } 663 else 664 { 665 checkTree = (ValueNode) getNodeFactory().getNode( 666 C_NodeTypes.AND_NODE, 667 tcn, 668 checkTree, 669 getContextManager()); 670 } 671 } 672 673 return checkTree; 674 } 675 676 689 private void generateFKInfo 690 ( 691 ConstraintDescriptorList cdl, 692 DataDictionary dd, 693 TableDescriptor td, 694 FormatableBitSet readColsBitSet 695 ) 696 throws StandardException 697 { 698 Vector fkVector = new Vector (10); 699 int type; 700 UUID[] uuids = null; 701 long[] conglomNumbers = null; 702 String [] fkNames = null; 703 ConstraintDescriptorList fkcdl; 704 ReferencedKeyConstraintDescriptor refcd; 705 boolean[] isSelfReferencingFK; 706 ConstraintDescriptorList activeList = dd.getActiveConstraintDescriptors(cdl); 707 int[] rowMap = getRowMap(readColsBitSet, td); 708 int[] raRules = null; 709 Vector refTableNames = new Vector (1); 710 Vector refIndexConglomNum = new Vector (1); 711 Vector refActions = new Vector (1); 712 Vector refColDescriptors = new Vector (1); 713 Vector fkColMap = new Vector (1); 714 int activeSize = activeList.size(); 715 for (int index = 0; index < activeSize; index++) 716 { 717 ConstraintDescriptor cd = activeList.elementAt(index); 718 719 if (cd instanceof ForeignKeyConstraintDescriptor) 720 { 721 726 type = FKInfo.FOREIGN_KEY; 727 refcd = ((ForeignKeyConstraintDescriptor)cd).getReferencedConstraint(); 728 uuids = new UUID[1]; 729 conglomNumbers = new long[1]; 730 fkNames = new String [1]; 731 isSelfReferencingFK = new boolean[1]; 732 raRules = new int[1]; 733 fkSetupArrays(dd, (ForeignKeyConstraintDescriptor)cd, 734 0, uuids, conglomNumbers, 735 fkNames, isSelfReferencingFK, raRules); 736 737 fkNames[0] = cd.getConstraintName(); 740 } 741 else if (cd instanceof ReferencedKeyConstraintDescriptor) 742 { 743 refcd = (ReferencedKeyConstraintDescriptor)cd; 744 745 750 type = FKInfo.REFERENCED_KEY; 751 fkcdl = dd.getActiveConstraintDescriptors 752 ( ((ReferencedKeyConstraintDescriptor)cd).getForeignKeyConstraints(ConstraintDescriptor.ENABLED) ); 753 754 int size = fkcdl.size(); 755 if (size == 0) 756 { 757 continue; 758 } 759 760 uuids = new UUID[size]; 761 fkNames = new String [size]; 762 conglomNumbers = new long[size]; 763 isSelfReferencingFK = new boolean[size]; 764 raRules = new int[size]; 765 ForeignKeyConstraintDescriptor fkcd = null; 766 TableDescriptor fktd; 767 ColumnDescriptorList coldl; 768 int[] refColumns; 769 ColumnDescriptor cold; 770 int[] colArray = remapReferencedColumns(cd, rowMap); 771 for (int inner = 0; inner < size; inner++) 772 { 773 fkcd = (ForeignKeyConstraintDescriptor) fkcdl.elementAt(inner); 774 fkSetupArrays(dd, fkcd, 775 inner, uuids, conglomNumbers, fkNames, 776 isSelfReferencingFK, raRules); 777 if((raRules[inner] == StatementType.RA_CASCADE) || 778 (raRules[inner] ==StatementType.RA_SETNULL)) 779 { 780 fktd = fkcd.getTableDescriptor(); 782 refTableNames.addElement(fktd.getSchemaName() + "." + fktd.getName()); 783 refActions.addElement(new Integer (raRules[inner])); 784 refColumns = fkcd.getReferencedColumns(); 786 coldl = fktd.getColumnDescriptorList(); 787 ColumnDescriptorList releventColDes = new ColumnDescriptorList(); 788 for(int i = 0 ; i < refColumns.length; i++) 789 { 790 cold =(ColumnDescriptor)coldl.elementAt(refColumns[i]-1); 791 releventColDes.add(cold); 792 } 793 refColDescriptors.addElement(releventColDes); 794 refIndexConglomNum.addElement(new Long (conglomNumbers[inner])); 795 fkColMap.addElement(colArray); 796 } 797 } 798 } 799 else 800 { 801 continue; 802 } 803 804 TableDescriptor pktd = refcd.getTableDescriptor(); 805 UUID pkuuid = refcd.getIndexId(); 806 ConglomerateDescriptor pkIndexConglom = pktd.getConglomerateDescriptor(pkuuid); 807 808 TableDescriptor refTd = cd.getTableDescriptor(); 809 fkVector.addElement(new FKInfo( 810 fkNames, refTd.getName(), statementType, type, pkuuid, pkIndexConglom.getConglomerateNumber(), uuids, conglomNumbers, isSelfReferencingFK, remapReferencedColumns(cd, rowMap), dd.getRowLocationTemplate(getLanguageConnectionContext(), refTd), 821 raRules)); 824 } 825 826 829 int size = fkVector.size(); 830 if (size > 0) 831 { 832 fkInfo = new FKInfo[size]; 833 for (int i = 0; i < size; i++) 834 { 835 fkInfo[i] = (FKInfo)fkVector.elementAt(i); 836 } 837 } 838 839 size = refActions.size(); 841 if (size > 0) 842 { 843 fkTableNames = new String [size]; 844 fkRefActions = new int[size]; 845 fkColDescriptors = new ColumnDescriptorList[size]; 846 fkIndexConglomNumbers = new long[size]; 847 fkColArrays = new int[size][]; 848 for (int i = 0; i < size; i++) 849 { 850 fkTableNames[i] = (String )refTableNames.elementAt(i); 851 fkRefActions[i] = ((Integer ) refActions.elementAt(i)).intValue(); 852 fkColDescriptors[i] = 853 (ColumnDescriptorList)refColDescriptors.elementAt(i); 854 fkIndexConglomNumbers[i] = 855 ((Long )refIndexConglomNum.elementAt(i)).longValue(); 856 fkColArrays[i] = ((int[])fkColMap.elementAt(i)); 857 } 858 } 859 860 } 861 862 865 private void fkSetupArrays 866 ( 867 DataDictionary dd, 868 ForeignKeyConstraintDescriptor fkcd, 869 int index, 870 UUID[] uuids, 871 long[] conglomNumbers, 872 String [] fkNames, 873 boolean[] isSelfReferencingFK, 874 int[] raRules 875 ) 876 throws StandardException 877 { 878 fkNames[index] = fkcd.getConstraintName(); 879 uuids[index] = fkcd.getIndexId(); 880 conglomNumbers[index] = fkcd.getIndexConglomerateDescriptor(dd).getConglomerateNumber(); 881 isSelfReferencingFK[index] = fkcd.isSelfReferencingFK(); 882 if(statementType == StatementType.DELETE) 883 raRules[index] = fkcd.getRaDeleteRule(); 884 else if(statementType == StatementType.UPDATE) 885 raRules[index] = fkcd.getRaUpdateRule(); 886 } 887 888 897 private void generateTriggerInfo 898 ( 899 GenericDescriptorList triggerList, 900 TableDescriptor td, 901 int[] changedCols 902 ) 903 throws StandardException 904 { 905 if ((triggerList != null) && (triggerList.size() > 0)) 906 { 907 triggerInfo = new TriggerInfo(td, changedCols, triggerList); 908 } 909 } 910 911 918 public FKInfo[] getFKInfo() 919 { 920 if (SanityManager.DEBUG) 921 { 922 SanityManager.ASSERT(bound, "attempt to access FKInfo "+ 923 "before binding"); 924 } 925 return fkInfo; 926 } 927 928 935 public TriggerInfo getTriggerInfo() 936 { 937 if (SanityManager.DEBUG) 938 { 939 SanityManager.ASSERT(bound, "attempt to access TriggerInfo "+ 940 "before binding"); 941 } 942 return triggerInfo; 943 } 944 945 950 public ValueNode getCheckConstraints() 951 { 952 if (SanityManager.DEBUG) 953 { 954 SanityManager.ASSERT(bound, "attempt to access FKInfo "+ 955 "before binding"); 956 } 957 return checkConstraints; 958 } 959 960 970 private void createTriggerDependencies 971 ( 972 GenericDescriptorList tdl, 973 Dependent dependent 974 ) 975 throws StandardException 976 { 977 CompilerContext compilerContext = getCompilerContext(); 978 979 Enumeration descs = tdl.elements(); 980 981 while (descs.hasMoreElements()) 982 { 983 TriggerDescriptor td = (TriggerDescriptor)descs.nextElement(); 984 985 990 if (dependent == null) 991 { 992 compilerContext.createDependency(td); 993 } 994 else 995 { 996 compilerContext.createDependency(dependent, td); 997 } 998 } 999 } 1000 1001 1015 protected GenericDescriptorList getAllRelevantTriggers 1016 ( 1017 DataDictionary dd, 1018 TableDescriptor td, 1019 int[] changedColumnIds, 1020 boolean includeTriggers 1021 ) 1022 throws StandardException 1023 { 1024 if ( relevantTriggers != null ) { return relevantTriggers; } 1025 1026 relevantTriggers = new GenericDescriptorList(); 1027 1028 if(!includeTriggers) 1029 return relevantTriggers; 1030 1031 td.getAllRelevantTriggers( statementType, changedColumnIds, relevantTriggers ); 1032 adjustDeferredFlag( relevantTriggers.size() > 0 ); 1033 return relevantTriggers; 1034 } 1035 1036 protected void adjustDeferredFlag( boolean adjustment ) 1037 { 1038 if( !requiresDeferredProcessing ) { requiresDeferredProcessing = adjustment; } 1039 } 1040 1041 1054 private void createConstraintDependencies 1055 ( 1056 DataDictionary dd, 1057 ConstraintDescriptorList cdl, 1058 Dependent dependent 1059 ) 1060 throws StandardException 1061 { 1062 CompilerContext compilerContext = getCompilerContext(); 1063 1064 int cdlSize = cdl.size(); 1065 for (int index = 0; index < cdlSize; index++) 1066 { 1067 ConstraintDescriptor cd = cdl.elementAt(index); 1068 1069 1074 if (dependent == null) 1075 { 1076 compilerContext.createDependency(cd); 1077 } 1078 else 1079 { 1080 compilerContext.createDependency(dependent, cd); 1081 } 1082 1083 1091 if (cd instanceof ReferencedKeyConstraintDescriptor) 1092 { 1093 ConstraintDescriptorList fkcdl = dd.getActiveConstraintDescriptors 1094 ( ((ReferencedKeyConstraintDescriptor)cd).getForeignKeyConstraints(ConstraintDescriptor.ENABLED) ); 1095 1096 int fklSize = fkcdl.size(); 1097 for (int inner = 0; inner < fklSize; inner++) 1098 { 1099 ConstraintDescriptor fkcd = fkcdl.elementAt(inner); 1100 if (dependent == null) 1101 { 1102 compilerContext.createDependency(fkcd); 1103 compilerContext.createDependency(fkcd.getTableDescriptor()); 1104 } 1105 else 1106 { 1107 compilerContext.createDependency(dependent, fkcd); 1108 compilerContext.createDependency(dependent, fkcd.getTableDescriptor()); 1109 } 1110 } 1111 } 1112 else if (cd instanceof ForeignKeyConstraintDescriptor) 1113 { 1114 ForeignKeyConstraintDescriptor fkcd = (ForeignKeyConstraintDescriptor) cd; 1115 if (dependent == null) 1116 { 1117 compilerContext.createDependency(fkcd.getReferencedConstraint().getTableDescriptor()); 1118 } 1119 else 1120 { 1121 compilerContext.createDependency(dependent, 1122 fkcd.getReferencedConstraint().getTableDescriptor()); 1123 } 1124 } 1125 } 1126 } 1127 1128 1141 protected ConstraintDescriptorList getAllRelevantConstraints 1142 ( 1143 DataDictionary dd, 1144 TableDescriptor td, 1145 boolean skipCheckConstraints, 1146 int[] changedColumnIds 1147 ) 1148 throws StandardException 1149 { 1150 if ( relevantCdl != null ) { return relevantCdl; } 1151 1152 boolean[] needsDeferredProcessing = new boolean[1]; 1153 relevantCdl = new ConstraintDescriptorList(); 1154 1155 needsDeferredProcessing[0] = requiresDeferredProcessing; 1156 td.getAllRelevantConstraints 1157 ( statementType, skipCheckConstraints, changedColumnIds, 1158 needsDeferredProcessing, relevantCdl ); 1159 1160 adjustDeferredFlag( needsDeferredProcessing[0] ); 1161 1162 return relevantCdl; 1163 } 1164 1165 1172 public boolean requiresDeferredProcessing() 1173 { 1174 return requiresDeferredProcessing; 1175 } 1176 1177 1188 public ValueNode parseCheckConstraint 1189 ( 1190 String checkConstraintText, 1191 TableDescriptor td 1192 ) 1193 throws StandardException 1194 { 1195 Parser p; 1196 ValueNode checkTree; 1197 LanguageConnectionContext lcc = getLanguageConnectionContext(); 1198 CompilerContext compilerContext = getCompilerContext(); 1199 1200 1201 1202 1206 String select = "SELECT * FROM " + 1207 td.getQualifiedName() + 1208 " WHERE " + 1209 checkConstraintText; 1210 1211 1216 CompilerContext newCC = lcc.pushCompilerContext(); 1217 1218 p = newCC.getParser(); 1219 1220 1221 QueryTreeNode qt = p.parseStatement(select); 1224 if (SanityManager.DEBUG) 1225 { 1226 if (! (qt instanceof CursorNode)) 1227 { 1228 SanityManager.THROWASSERT( 1229 "qt expected to be instanceof CursorNode, not " + 1230 qt.getClass().getName()); 1231 } 1232 CursorNode cn = (CursorNode) qt; 1233 if (! (cn.getResultSetNode() instanceof SelectNode)) 1234 { 1235 SanityManager.THROWASSERT( 1236 "cn.getResultSetNode() expected to be instanceof SelectNode, not " + 1237 cn.getResultSetNode().getClass().getName()); 1238 } 1239 } 1240 1241 checkTree = ((SelectNode) ((CursorNode) qt).getResultSetNode()).getWhereClause(); 1242 1243 lcc.popCompilerContext(newCC); 1244 1245 return checkTree; 1246 } 1247 1248 1249 1259 public void generateCheckConstraints 1260 ( 1261 ValueNode checkConstraints, 1262 ExpressionClassBuilder ecb, 1263 MethodBuilder mb 1264 ) 1265 throws StandardException 1266 { 1267 1273 1281 if (checkConstraints == null) 1283 { 1284 mb.pushNull(ClassName.GeneratedMethod); 1285 } 1286 else 1287 { 1288 MethodBuilder userExprFun = generateCheckConstraints(checkConstraints, ecb); 1289 1290 ecb.pushMethodReference(mb, userExprFun); 1294 } 1295 } 1296 1297 1307 public MethodBuilder generateCheckConstraints 1308 ( 1309 ValueNode checkConstraints, 1310 ExpressionClassBuilder ecb 1311 ) 1312 throws StandardException 1313 { 1314 MethodBuilder userExprFun = ecb.newUserExprFun(); 1318 1319 1321 1325 1326 checkConstraints.generateExpression(ecb, userExprFun); 1327 userExprFun.methodReturn(); 1328 1329 userExprFun.complete(); 1331 1332 return userExprFun; 1333 } 1334 1335 1350 public QueryTreeNode optimize() throws StandardException 1351 { 1352 ResultSetNode originalRSNode = getResultSetNode(); 1353 1354 1355 QueryTreeNode retval = super.optimize(); 1356 1357 1362 lockMode = TransactionController.MODE_RECORD; 1363 1364 return retval; 1365 } 1366 1367 1377 protected void getAffectedIndexes 1378 ( 1379 TableDescriptor td, 1380 ResultColumnList updatedColumns, 1381 FormatableBitSet colBitSet 1382 ) 1383 throws StandardException 1384 { 1385 Vector conglomVector = new Vector (); 1386 1387 DMLModStatementNode.getXAffectedIndexes(td, updatedColumns, colBitSet, conglomVector ); 1388 1389 markAffectedIndexes( conglomVector ); 1390 } 1391 1408 static void getXAffectedIndexes 1409 ( 1410 TableDescriptor baseTable, 1411 ResultColumnList updatedColumns, 1412 FormatableBitSet colBitSet, 1413 Vector conglomVector 1414 ) 1415 throws StandardException 1416 { 1417 ConglomerateDescriptor[] cds = baseTable.getConglomerateDescriptors(); 1418 1419 1422 long[] distinctConglomNums = new long[cds.length - 1]; 1423 int distinctCount = 0; 1424 1425 for (int index = 0; index < cds.length; index++) 1426 { 1427 ConglomerateDescriptor cd = cds[index]; 1428 1429 if (!cd.isIndex()) { continue; } 1430 1431 1435 if ((updatedColumns != null) && 1436 (!updatedColumns.updateOverlaps( 1437 cd.getIndexDescriptor().baseColumnPositions()))) 1438 { continue; } 1439 1440 if ( conglomVector != null ) 1441 { 1442 int i; 1443 for (i = 0; i < distinctCount; i++) 1444 { 1445 if (distinctConglomNums[i] == cd.getConglomerateNumber()) 1446 break; 1447 } 1448 if (i == distinctCount) { 1450 distinctConglomNums[distinctCount++] = cd.getConglomerateNumber(); 1451 conglomVector.addElement( cd ); 1452 } 1453 } 1454 1455 IndexRowGenerator ixd = cd.getIndexDescriptor(); 1456 int[] cols = ixd.baseColumnPositions(); 1457 1458 if (colBitSet != null) 1459 { 1460 for (int i = 0; i < cols.length; i++) 1461 { 1462 colBitSet.set(cols[i]); 1463 } 1464 } } 1467 } 1468 1469 protected void markAffectedIndexes 1470 ( 1471 Vector affectedConglomerates 1472 ) 1473 throws StandardException 1474 { 1475 ConglomerateDescriptor cd; 1476 int indexCount = affectedConglomerates.size(); 1477 CompilerContext cc = getCompilerContext(); 1478 1479 indicesToMaintain = new IndexRowGenerator[ indexCount ]; 1480 indexConglomerateNumbers = new long[ indexCount ]; 1481 indexNames = new String [indexCount]; 1482 1483 for ( int ictr = 0; ictr < indexCount; ictr++ ) 1484 { 1485 cd = (ConglomerateDescriptor) affectedConglomerates.elementAt( ictr ); 1486 1487 indicesToMaintain[ ictr ] = cd.getIndexDescriptor(); 1488 indexConglomerateNumbers[ ictr ] = cd.getConglomerateNumber(); 1489 indexNames[ictr] = 1490 ((cd.isConstraint()) ? null : cd.getConglomerateName()); 1491 1492 cc.createDependency(cd); 1493 } 1494 1495 } 1496 1497 1498 public String statementToString() 1499 { 1500 return "DML MOD"; 1501 } 1502 1503 1510 private int[] remapReferencedColumns(ConstraintDescriptor cd, int[] rowMap) 1511 { 1512 int[] oldCols = cd.getReferencedColumns(); 1513 if (rowMap == null) 1514 { 1515 return oldCols; 1516 } 1517 1518 int[] newCols = new int[oldCols.length]; 1519 for (int i = 0; i<oldCols.length; i++) 1520 { 1521 newCols[i] = rowMap[oldCols[i]]; 1522 if (SanityManager.DEBUG) 1523 { 1524 SanityManager.ASSERT(newCols[i] != 0, "attempt to map a column "+ 1525 oldCols[i]+" which is not in our new column map. Something is "+ 1526 "wrong with the logic to do partial reads for an update stmt"); 1527 } 1528 } 1529 return newCols; 1530 } 1531 1532 1539 private int[] getRowMap(FormatableBitSet bitSet, TableDescriptor td) 1540 throws StandardException 1541 { 1542 if (bitSet == null) 1543 { 1544 return (int[])null; 1545 } 1546 1547 int size = td.getMaxColumnID(); 1548 int[] iArray = new int[size+1]; 1549 int j = 1; 1550 for (int i = 1; i <= size; i++) 1551 { 1552 if (bitSet.get(i)) 1553 { 1554 iArray[i] = j++; 1555 } 1556 } 1557 return iArray; 1558 } 1559 1560 1561 public void setRefActionInfo(long fkIndexConglomId, 1562 int[]fkColArray, 1563 String parentResultSetId, 1564 boolean dependentScan) 1565 { 1566 resultSet.setRefActionInfo(fkIndexConglomId, 1567 fkColArray, 1568 parentResultSetId, 1569 dependentScan); 1570 } 1571 1572 1580 public void normalizeSynonymColumns( 1581 ResultColumnList rcl, 1582 TableName targetTableName) 1583 throws StandardException 1584 { 1585 if (synonymTableName == null) 1586 return; 1587 1588 String synTableName = synonymTableName.getTableName(); 1589 1590 int count = rcl.size(); 1591 for (int i = 0; i < count; i++) 1592 { 1593 ResultColumn column = (ResultColumn) rcl.elementAt(i); 1594 ColumnReference reference = column.getReference(); 1595 1596 if ( reference != null ) 1597 { 1598 String crTableName = reference.getTableName(); 1599 if ( crTableName != null ) 1600 { 1601 if ( synTableName.equals( crTableName ) ) 1602 { 1603 reference.setTableNameNode( targetTableName ); 1604 } 1605 else 1606 { 1607 throw StandardException.newException( 1608 SQLState.LANG_TABLE_NAME_MISMATCH, 1609 synTableName, 1610 crTableName); 1611 } 1612 } 1613 } 1614 } 1615 } 1616} 1617 1618 1619 | Popular Tags |