Source Code Cross Referenced for DMLModStatementNode.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » compile » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.sql.compile 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.sql.compile.DMLModStatementNode
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.sql.compile;
0023:
0024:        import org.apache.derby.iapi.services.loader.GeneratedMethod;
0025:
0026:        import org.apache.derby.iapi.services.context.ContextManager;
0027:
0028:        import org.apache.derby.iapi.services.compiler.JavaFactory;
0029:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
0030:
0031:        import org.apache.derby.iapi.services.sanity.SanityManager;
0032:
0033:        import org.apache.derby.iapi.sql.depend.Dependent;
0034:
0035:        import org.apache.derby.iapi.sql.compile.CompilerContext;
0036:        import org.apache.derby.iapi.sql.compile.Parser;
0037:        import org.apache.derby.iapi.sql.compile.CostEstimate;
0038:        import org.apache.derby.iapi.sql.compile.OptimizerFactory;
0039:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0040:        import org.apache.derby.iapi.sql.compile.NodeFactory;
0041:
0042:        import org.apache.derby.iapi.sql.conn.Authorizer;
0043:
0044:        import org.apache.derby.iapi.reference.ClassName;
0045:        import org.apache.derby.iapi.reference.SQLState;
0046:
0047:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0048:
0049:        import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
0050:        import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
0051:        import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
0052:        import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
0053:        import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
0054:        import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
0055:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
0056:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
0057:        import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
0058:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0059:        import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
0060:        import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
0061:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0062:        import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
0063:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
0064:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
0065:
0066:        import org.apache.derby.iapi.sql.StatementType;
0067:
0068:        import org.apache.derby.iapi.store.access.TransactionController;
0069:
0070:        import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0071:        import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
0072:
0073:        import org.apache.derby.iapi.error.StandardException;
0074:
0075:        import org.apache.derby.impl.sql.execute.FKInfo;
0076:        import org.apache.derby.impl.sql.execute.TriggerInfo;
0077:
0078:        import org.apache.derby.iapi.types.RowLocation;
0079:
0080:        import org.apache.derby.catalog.UUID;
0081:        import java.util.Properties;
0082:        import java.util.Vector;
0083:        import java.util.Enumeration;
0084:        import java.util.Hashtable;
0085:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0086:        import org.apache.derby.iapi.services.classfile.VMOpcode;
0087:
0088:        /**
0089:         * A DMLStatement for a table modification: to wit, INSERT
0090:         * UPDATE or DELETE.
0091:         *
0092:         * @author Jamie
0093:         */
0094:
0095:        abstract class DMLModStatementNode extends DMLStatementNode {
0096:            //	protected DataDictionary	dataDictionary;
0097:            protected FromVTI targetVTI;
0098:            protected TableName targetTableName;
0099:            protected ResultColumnList resultColumnList;
0100:            protected int lockMode; // lock mode for the target table
0101:
0102:            protected FKInfo[] fkInfo; // array of FKInfo structures
0103:            // generated during bind
0104:            protected TriggerInfo triggerInfo; // generated during bind
0105:            public TableDescriptor targetTableDescriptor;
0106:
0107:            /* The indexes that could be affected by this statement */
0108:            public IndexRowGenerator[] indicesToMaintain;
0109:            public long[] indexConglomerateNumbers;
0110:            public String[] indexNames;
0111:            protected ConstraintDescriptorList relevantCdl;
0112:            protected GenericDescriptorList relevantTriggers;
0113:
0114:            // PRIVATE
0115:            private boolean requiresDeferredProcessing;
0116:            private int statementType;
0117:            private boolean bound;
0118:            private ValueNode checkConstraints;
0119:
0120:            /* Info required to perform referential actions */
0121:            protected String[] fkTableNames; // referencing table names.
0122:            protected int[] fkRefActions; //type of referential actions 
0123:            protected ColumnDescriptorList[] fkColDescriptors;
0124:            protected long[] fkIndexConglomNumbers; //conglomerate number of the backing index
0125:            protected boolean isDependentTable;
0126:            protected int[][] fkColArrays;
0127:            protected Hashtable graphHashTable;
0128:            // Hash Table which maitains the querytreenode graph 
0129:            protected TableName synonymTableName;
0130:
0131:            /**
0132:             * Initializer for a DMLModStatementNode -- delegate to DMLStatementNode
0133:             *
0134:             * @param resultSet	A ResultSetNode for the result set of the
0135:             *			DML statement
0136:             */
0137:            public void init(Object resultSet) {
0138:                super .init(resultSet);
0139:                statementType = getStatementType();
0140:            }
0141:
0142:            /**
0143:             * Initializer for a DMLModStatementNode -- delegate to DMLStatementNode
0144:             *
0145:             * @param resultSet	A ResultSetNode for the result set of the
0146:             *			DML statement
0147:             * @param statementType used by nodes that allocate a DMLMod directly
0148:             *			(rather than inheriting it).
0149:             */
0150:            public void init(Object resultSet, Object statementType) {
0151:                super .init(resultSet);
0152:                this .statementType = ((Integer) statementType).intValue();
0153:            }
0154:
0155:            void setTarget(QueryTreeNode targetName) {
0156:                if (targetName instanceof  TableName) {
0157:                    this .targetTableName = (TableName) targetName;
0158:                } else {
0159:                    if (SanityManager.DEBUG) {
0160:                        if (!(targetName instanceof  FromVTI)) {
0161:                            SanityManager
0162:                                    .THROWASSERT("targetName expected to be FromVTI, not "
0163:                                            + targetName.getClass().getName());
0164:                        }
0165:                    }
0166:                    this .targetVTI = (FromVTI) targetName;
0167:                    targetVTI.setTarget();
0168:                }
0169:            }
0170:
0171:            /**
0172:             * If the DML is on a temporary table, generate the code to mark temporary table as modified in the current UOW.
0173:             * At rollback transaction (or savepoint), we will check if the temporary table was modified in that UOW.
0174:             * If yes, we will remove all the data from the temporary table
0175:             *
0176:             * @param acb	The ActivationClassBuilder for the class being built
0177:             * @param mb	The execute() method to be built
0178:             *
0179:             * @exception StandardException		Thrown on error
0180:             */
0181:            protected void generateCodeForTemporaryTable(
0182:                    ActivationClassBuilder acb, MethodBuilder mb)
0183:                    throws StandardException {
0184:                if (targetTableDescriptor != null
0185:                        && targetTableDescriptor.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE
0186:                        && targetTableDescriptor.isOnRollbackDeleteRows() == true) {
0187:                    mb.pushThis();
0188:                    mb.callMethod(VMOpcode.INVOKEINTERFACE,
0189:                            ClassName.Activation,
0190:                            "getLanguageConnectionContext",
0191:                            ClassName.LanguageConnectionContext, 0);
0192:                    mb.push(targetTableDescriptor.getName());
0193:                    mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
0194:                            "markTempTableAsModifiedInUnitOfWork", "void", 1);
0195:                    mb.endStatement();
0196:                }
0197:            }
0198:
0199:            /**
0200:             * Verify the target table.  Get the TableDescriptor
0201:             * if the target table is not a VTI.
0202:             *
0203:             * @exception StandardException		Thrown on error
0204:             */
0205:            void verifyTargetTable() throws StandardException {
0206:                DataDictionary dataDictionary = getDataDictionary();
0207:                if (targetTableName != null) {
0208:                    /*
0209:                     ** Get the TableDescriptor for the table we are inserting into
0210:                     */
0211:                    SchemaDescriptor sdtc = getSchemaDescriptor(targetTableName
0212:                            .getSchemaName());
0213:
0214:                    targetTableDescriptor = getTableDescriptor(targetTableName
0215:                            .getTableName(), sdtc);
0216:
0217:                    if (targetTableDescriptor == null) {
0218:                        // Check if the reference is for a synonym.
0219:                        TableName synonymTab = resolveTableToSynonym(targetTableName);
0220:                        if (synonymTab == null)
0221:                            throw StandardException.newException(
0222:                                    SQLState.LANG_TABLE_NOT_FOUND,
0223:                                    targetTableName);
0224:                        synonymTableName = targetTableName;
0225:                        targetTableName = synonymTab;
0226:                        sdtc = getSchemaDescriptor(targetTableName
0227:                                .getSchemaName());
0228:
0229:                        targetTableDescriptor = getTableDescriptor(synonymTab
0230:                                .getTableName(), sdtc);
0231:                        if (targetTableDescriptor == null)
0232:                            throw StandardException.newException(
0233:                                    SQLState.LANG_TABLE_NOT_FOUND,
0234:                                    targetTableName);
0235:                    }
0236:
0237:                    switch (targetTableDescriptor.getTableType()) {
0238:                    case TableDescriptor.VIEW_TYPE:
0239:                        // Views are currently not updatable
0240:                        throw StandardException.newException(
0241:                                SQLState.LANG_VIEW_NOT_UPDATEABLE,
0242:                                targetTableName);
0243:
0244:                    case TableDescriptor.VTI_TYPE:
0245:                        // fall through - currently all vti tables are system tables.
0246:                    case TableDescriptor.SYSTEM_TABLE_TYPE:
0247:                        // System tables are not updatable
0248:                        throw StandardException.newException(
0249:                                SQLState.LANG_UPDATE_SYSTEM_TABLE_ATTEMPTED,
0250:                                targetTableName);
0251:                    default:
0252:                        break;
0253:
0254:                    }
0255:
0256:                    /* We need to get some kind of table lock (IX here), to prevent
0257:                     * another thread from adding a new index while we are binding,
0258:                     * if we are a reader in DDL mode.  Just a row lock on system table
0259:                     * SYSCONGLOMERATE is not enough: that wouldn't prevent another
0260:                     * thread from adding a new entry.  Part of the fix for Beetle 3976.
0261:                     * Same lock as in exec, compatible with row lock, for concurrency.
0262:                     */
0263:                    targetTableDescriptor = lockTableForCompilation(targetTableDescriptor);
0264:
0265:                    getCompilerContext()
0266:                            .createDependency(targetTableDescriptor);
0267:                } else {
0268:                    /* VTI - VTIs in DML Mod are version 2 VTIs - They
0269:                     * must implement java.sql.PreparedStatement and have
0270:                     * the JDBC2.0 getMetaData() and getResultSetConcurrency()
0271:                     * methods and return an updatable ResultSet.
0272:                     */
0273:                    FromList dummyFromList = new FromList();
0274:                    targetVTI = (FromVTI) targetVTI.bindNonVTITables(
0275:                            dataDictionary, dummyFromList);
0276:                    targetVTI = (FromVTI) targetVTI
0277:                            .bindVTITables(dummyFromList);
0278:                }
0279:            }
0280:
0281:            /**
0282:             *
0283:             * INSERT/UPDATE/DELETE are always atomic.
0284:             *
0285:             * @return true 
0286:             */
0287:            public boolean isAtomic() {
0288:                return true;
0289:            }
0290:
0291:            /**
0292:             * Get a schema descriptor for the given table.
0293:             * Uses this.targetTableName.
0294:             *
0295:             * @return Schema Descriptor
0296:             *
0297:             * @exception	StandardException	throws on schema name
0298:             *						that doesn't exist	
0299:             */
0300:            public SchemaDescriptor getSchemaDescriptor()
0301:                    throws StandardException {
0302:                SchemaDescriptor sd;
0303:
0304:                sd = getSchemaDescriptor(targetTableName.getSchemaName());
0305:
0306:                return sd;
0307:            }
0308:
0309:            /**
0310:              Get a map to efficiently find heap columns from a compressed set of
0311:              read columns. The returns a map such that
0312:
0313:              <PRE>
0314:              map[heapColId (0 based)] -> readCol id (0 based)
0315:              </PRE>
0316:
0317:              @param column_map_length The number of columns(ints) in the map.
0318:              @param readColsBitSet A language style (1 based) bit set with bits for
0319:              read heap columns set.
0320:
0321:              RESOLVE: Replace this with a call to RowUtil when the store and
0322:              the language both use 0 base or 1 base offsets for columns. Today
0323:              we can't use the store function because we have a 1 based FormatableBitSet.
0324:             */
0325:            public static int[] getReadColMap(int column_map_length,
0326:                    FormatableBitSet readColsBitSet) {
0327:                if (readColsBitSet == null)
0328:                    return null;
0329:
0330:                int partial_col_cnt = 0;
0331:                int column_map[] = new int[column_map_length];
0332:                int readColsBitSetSize = readColsBitSet.size();
0333:
0334:                for (int base_index = 0; base_index < column_map.length; base_index++) {
0335:                    if (readColsBitSetSize > base_index
0336:                            && readColsBitSet.get(base_index + 1))
0337:                        column_map[base_index] = partial_col_cnt++;
0338:                    else
0339:                        // this column map offset entry should never be referenced.
0340:                        column_map[base_index] = -1;
0341:                }
0342:
0343:                return (column_map);
0344:            }
0345:
0346:            /**
0347:             * Get and bind the ResultColumnList representing the columns in the
0348:             * target table, given the table's name.
0349:             *
0350:             * @exception StandardException		Thrown on error
0351:             */
0352:            protected void getResultColumnList() throws StandardException {
0353:                if (targetVTI == null) {
0354:                    getResultColumnList((ResultColumnList) null);
0355:                } else {
0356:                    /* binding VTI - just point to VTI's RCL,
0357:                     * which was already bound.
0358:                     */
0359:                    resultColumnList = targetVTI.getResultColumns();
0360:                }
0361:            }
0362:
0363:            /**
0364:             * Get and bind the ResultColumnList representing the columns in the
0365:             * target table, given the table's name.
0366:             *
0367:             * @exception StandardException		Thrown on error
0368:             */
0369:            protected FromBaseTable getResultColumnList(
0370:                    ResultColumnList inputRcl) throws StandardException {
0371:                /* Get a ResultColumnList representing all the columns in the target */
0372:                FromBaseTable fbt = (FromBaseTable) (getNodeFactory().getNode(
0373:                        C_NodeTypes.FROM_BASE_TABLE, targetTableName, null,
0374:                        null, null, getContextManager()));
0375:
0376:                fbt.bindNonVTITables(getDataDictionary(),
0377:                        (FromList) getNodeFactory().getNode(
0378:                                C_NodeTypes.FROM_LIST,
0379:                                getNodeFactory().doJoinOrderOptimization(),
0380:                                getContextManager()));
0381:
0382:                getResultColumnList(fbt, inputRcl);
0383:                return fbt;
0384:            }
0385:
0386:            /**
0387:             * Get and bind the ResultColumnList representing the columns in the
0388:             * target table, given a FromTable for the target table.
0389:             *
0390:             * @exception StandardException		Thrown on error
0391:             */
0392:            private void getResultColumnList(FromBaseTable fromBaseTable,
0393:                    ResultColumnList inputRcl) throws StandardException {
0394:                if (inputRcl == null) {
0395:                    resultColumnList = fromBaseTable.getAllResultColumns(null);
0396:                    resultColumnList
0397:                            .bindResultColumnsByPosition(targetTableDescriptor);
0398:                } else {
0399:                    resultColumnList = fromBaseTable.getResultColumnsForList(
0400:                            null, inputRcl, fromBaseTable.getTableNameField());
0401:
0402:                    resultColumnList.bindResultColumnsByName(
0403:                            targetTableDescriptor, (DMLStatementNode) this );
0404:                }
0405:            }
0406:
0407:            /**
0408:             * Gets and binds all the constraints for an INSERT/UPDATE/DELETE.
0409:             * First finds the constraints that are relevant to this node.
0410:             * This is done by calling getAllRelevantConstriants().  If
0411:             * getAllRelevantConstraints() has already been called, then
0412:             * this list is used.  Then it creates appropriate 
0413:             * dependencies. Then binds check constraints.  It also 
0414:             * generates the array of FKInfo items that are used in
0415:             * code generation.
0416:
0417:             * Note: we have a new flag here to see if defer processing is enabled or
0418:             *       not, the only scenario that is disabled is when we reapply the
0419:             *		 reply message we get from the source
0420:             *
0421:             *
0422:             * @param dataDictionary		The DataDictionary
0423:             * @param nodeFactory			Where to get query tree nodes.
0424:             * @param targetTableDescriptor	The TableDescriptor
0425:             * @param dependent			Parent object that will depend on all the constraints
0426:             *							that we look up. If this argument is null, then we
0427:             *							use the default dependent (the statement being compiled).
0428:             * @param sourceRCL				RCL of the table being changed
0429:             * @param changedColumnIds		If null, all columns being changed, otherwise array
0430:             *								of 1-based column ids for columns being changed
0431:             * @param readColsBitSet		bit set for the read scan
0432:             * @param skipCheckConstraints 	whether to skip check constraints or not
0433:             * @param includeTriggers		whether triggers are included in the processing
0434:             *
0435:             * @return	The bound, ANDed check constraints as a query tree.
0436:             *
0437:             * @exception StandardException		Thrown on failure
0438:             */
0439:            public ValueNode bindConstraints(DataDictionary dataDictionary,
0440:                    NodeFactory nodeFactory,
0441:                    TableDescriptor targetTableDescriptor, Dependent dependent,
0442:                    ResultColumnList sourceRCL, int[] changedColumnIds,
0443:                    FormatableBitSet readColsBitSet,
0444:                    boolean skipCheckConstraints, boolean includeTriggers)
0445:                    throws StandardException {
0446:                bound = true;
0447:
0448:                /* Nothing to do if updatable VTI */
0449:                if (targetVTI != null) {
0450:                    return null;
0451:                }
0452:
0453:                // Donot need privileges to execute constraints
0454:                getCompilerContext().pushCurrentPrivType(Authorizer.NULL_PRIV);
0455:                try {
0456:                    getAllRelevantConstraints(dataDictionary,
0457:                            targetTableDescriptor, skipCheckConstraints,
0458:                            changedColumnIds);
0459:                    createConstraintDependencies(dataDictionary, relevantCdl,
0460:                            dependent);
0461:                    generateFKInfo(relevantCdl, dataDictionary,
0462:                            targetTableDescriptor, readColsBitSet);
0463:
0464:                    getAllRelevantTriggers(dataDictionary,
0465:                            targetTableDescriptor, changedColumnIds,
0466:                            includeTriggers);
0467:                    createTriggerDependencies(relevantTriggers, dependent);
0468:                    generateTriggerInfo(relevantTriggers,
0469:                            targetTableDescriptor, changedColumnIds);
0470:
0471:                    if (skipCheckConstraints) {
0472:                        return null;
0473:                    }
0474:
0475:                    checkConstraints = generateCheckTree(relevantCdl,
0476:                            targetTableDescriptor);
0477:
0478:                    if (checkConstraints != null) {
0479:                        bindCheckConstraint(nodeFactory, targetTableDescriptor,
0480:                                sourceRCL, checkConstraints);
0481:                    }
0482:                } finally {
0483:                    getCompilerContext().popCurrentPrivType();
0484:                }
0485:
0486:                return checkConstraints;
0487:            }
0488:
0489:            /**
0490:             * Binds an already parsed check constraint
0491:             *
0492:             * @param nodeFactory			Where to get query tree nodes.
0493:             * @param targetTableDescriptor	The TableDescriptor for the constrained table.
0494:             * @param sourceRCL		Result columns.
0495:             * @param checkConstraint		Parsed query tree for check constraint
0496:             *
0497:             * @exception StandardException		Thrown on failure
0498:             */
0499:            public void bindCheckConstraint(NodeFactory nodeFactory,
0500:                    TableDescriptor targetTableDescriptor,
0501:                    ResultColumnList sourceRCL, ValueNode checkConstraint)
0502:                    throws StandardException {
0503:
0504:                TableName targetTableName = makeTableName(targetTableDescriptor
0505:                        .getSchemaName(), targetTableDescriptor.getName());
0506:
0507:                /* We now have the check constraints as a query tree.  Now, we prepare
0508:                 * to bind that query tree to the source's RCL.  That way, the
0509:                 * generated code for the check constraints will be evaluated against the
0510:                 * source row to be inserted into the target table or
0511:                 * against the after portion of the source row for the update
0512:                 * into the target table.
0513:                 *		o  Goober up a new FromList which has a single table,
0514:                 *		   a goobered up FromBaseTable for the target table
0515:                 *		   which has the source's RCL as it RCL.
0516:                 *		   (This allows the ColumnReferences in the check constraint
0517:                 *		   tree to be bound to the right RCs.)
0518:                 *
0519:                 * Note that in some circumstances we may not actually verify
0520:                 * the constraint against the source RCL but against a temp
0521:                 * row source used for deferred processing because of a trigger.
0522:                 * In this case, the caller of bindConstraints (UpdateNode)
0523:                 * has chosen to pass in the correct RCL to bind against.
0524:                 */
0525:                FromList fakeFromList = (FromList) nodeFactory
0526:                        .getNode(C_NodeTypes.FROM_LIST, nodeFactory
0527:                                .doJoinOrderOptimization(), getContextManager());
0528:                FromBaseTable table = (FromBaseTable) nodeFactory.getNode(
0529:                        C_NodeTypes.FROM_BASE_TABLE, targetTableName, null,
0530:                        sourceRCL, null, getContextManager());
0531:                table.setTableNumber(0);
0532:                fakeFromList.addFromTable(table);
0533:
0534:                // Now we can do the bind.
0535:                checkConstraint = checkConstraint.bindExpression(fakeFromList,
0536:                        (SubqueryList) null, (Vector) null);
0537:            }
0538:
0539:            /**
0540:             * Determine whether or not there are check constraints on the
0541:             * specified table.
0542:             *
0543:             * @param dd	The DataDictionary to use
0544:             * @param td	The TableDescriptor for the table
0545:             *
0546:             * @return Whether or not there are check constraints on the specified table.
0547:             *
0548:             * @exception StandardException		Thrown on failure
0549:             */
0550:            protected boolean hasCheckConstraints(DataDictionary dd,
0551:                    TableDescriptor td) throws StandardException {
0552:                ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
0553:                if (cdl == null)
0554:                    return false;
0555:                ConstraintDescriptorList ccCDL = cdl
0556:                        .getSubList(DataDictionary.CHECK_CONSTRAINT);
0557:
0558:                return (ccCDL.size() > 0);
0559:            }
0560:
0561:            /**
0562:             * Get the ANDing of all appropriate check constraints as 1 giant query tree.
0563:             *
0564:             * Makes the calling object (usually a Statement) dependent on all the constraints.
0565:             *
0566:             * @param cdl				The constriant descriptor list
0567:             * @param td				The TableDescriptor
0568:             *
0569:             * @return	The ANDing of all appropriate check constraints as a query tree.
0570:             *
0571:             * @exception StandardException		Thrown on failure
0572:             */
0573:            private ValueNode generateCheckTree(ConstraintDescriptorList cdl,
0574:                    TableDescriptor td) throws StandardException {
0575:                ConstraintDescriptorList ccCDL = cdl
0576:                        .getSubList(DataDictionary.CHECK_CONSTRAINT);
0577:                int ccCDLSize = ccCDL.size();
0578:                ValueNode checkTree = null;
0579:
0580:                // Get the text of all the check constraints
0581:                for (int index = 0; index < ccCDLSize; index++) {
0582:                    ConstraintDescriptor cd = ccCDL.elementAt(index);
0583:
0584:                    String constraintText = cd.getConstraintText();
0585:
0586:                    // Get the query tree for this constraint
0587:                    ValueNode oneConstraint = parseCheckConstraint(
0588:                            constraintText, td);
0589:
0590:                    // Put a TestConstraintNode above the constraint tree
0591:                    TestConstraintNode tcn = (TestConstraintNode) getNodeFactory()
0592:                            .getNode(C_NodeTypes.TEST_CONSTRAINT_NODE,
0593:                                    oneConstraint,
0594:                                    SQLState.LANG_CHECK_CONSTRAINT_VIOLATED,
0595:                                    td.getQualifiedName(),
0596:                                    cd.getConstraintName(), getContextManager());
0597:
0598:                    // Link consecutive TestConstraintNodes with AND nodes
0599:                    if (checkTree == null) {
0600:                        checkTree = tcn;
0601:                    } else {
0602:                        checkTree = (ValueNode) getNodeFactory().getNode(
0603:                                C_NodeTypes.AND_NODE, tcn, checkTree,
0604:                                getContextManager());
0605:                    }
0606:                }
0607:
0608:                return checkTree;
0609:            }
0610:
0611:            /**
0612:             * Generate the FKInfo structures used during code generation.
0613:             * For each constraint that isn't a check constraint, add another
0614:             * one of these FKInfo structures and then package them up into
0615:             * a single array.
0616:             *
0617:             * @param cdl				The constriant descriptor list
0618:             * @param dd				The DataDictionary
0619:             * @param td				The TableDescriptor
0620:             * @param readColsBitSet 	columns read
0621:             *
0622:             * @exception StandardException		Thrown on failure
0623:             */
0624:            private void generateFKInfo(ConstraintDescriptorList cdl,
0625:                    DataDictionary dd, TableDescriptor td,
0626:                    FormatableBitSet readColsBitSet) throws StandardException {
0627:                Vector fkVector = new Vector(10);
0628:                int type;
0629:                UUID[] uuids = null;
0630:                long[] conglomNumbers = null;
0631:                String[] fkNames = null;
0632:                ConstraintDescriptorList fkcdl;
0633:                ReferencedKeyConstraintDescriptor refcd;
0634:                boolean[] isSelfReferencingFK;
0635:                ConstraintDescriptorList activeList = dd
0636:                        .getActiveConstraintDescriptors(cdl);
0637:                int[] rowMap = getRowMap(readColsBitSet, td);
0638:                int[] raRules = null;
0639:                Vector refTableNames = new Vector(1);
0640:                Vector refIndexConglomNum = new Vector(1);
0641:                Vector refActions = new Vector(1);
0642:                Vector refColDescriptors = new Vector(1);
0643:                Vector fkColMap = new Vector(1);
0644:                int activeSize = activeList.size();
0645:                for (int index = 0; index < activeSize; index++) {
0646:                    ConstraintDescriptor cd = activeList.elementAt(index);
0647:
0648:                    if (cd instanceof  ForeignKeyConstraintDescriptor) {
0649:                        /*
0650:                         ** We are saving information for checking the
0651:                         ** primary/unique key that is referenced by this
0652:                         ** foreign key, so type is FOREIGN KEY.
0653:                         */
0654:                        type = FKInfo.FOREIGN_KEY;
0655:                        refcd = ((ForeignKeyConstraintDescriptor) cd)
0656:                                .getReferencedConstraint();
0657:                        uuids = new UUID[1];
0658:                        conglomNumbers = new long[1];
0659:                        fkNames = new String[1];
0660:                        isSelfReferencingFK = new boolean[1];
0661:                        raRules = new int[1];
0662:                        fkSetupArrays(dd, (ForeignKeyConstraintDescriptor) cd,
0663:                                0, uuids, conglomNumbers, fkNames,
0664:                                isSelfReferencingFK, raRules);
0665:
0666:                        // oops, get the right constraint name -- for error
0667:                        // handling we want the FK name, not refcd name
0668:                        fkNames[0] = cd.getConstraintName();
0669:                    } else if (cd instanceof  ReferencedKeyConstraintDescriptor) {
0670:                        refcd = (ReferencedKeyConstraintDescriptor) cd;
0671:
0672:                        /*
0673:                         ** We are saving information for checking the
0674:                         ** foreign key(s) that is dependent on this referenced
0675:                         ** key, so type is REFERENCED KEY.
0676:                         */
0677:                        type = FKInfo.REFERENCED_KEY;
0678:                        fkcdl = dd
0679:                                .getActiveConstraintDescriptors(((ReferencedKeyConstraintDescriptor) cd)
0680:                                        .getForeignKeyConstraints(ConstraintDescriptor.ENABLED));
0681:
0682:                        int size = fkcdl.size();
0683:                        if (size == 0) {
0684:                            continue;
0685:                        }
0686:
0687:                        uuids = new UUID[size];
0688:                        fkNames = new String[size];
0689:                        conglomNumbers = new long[size];
0690:                        isSelfReferencingFK = new boolean[size];
0691:                        raRules = new int[size];
0692:                        ForeignKeyConstraintDescriptor fkcd = null;
0693:                        TableDescriptor fktd;
0694:                        ColumnDescriptorList coldl;
0695:                        int[] refColumns;
0696:                        ColumnDescriptor cold;
0697:                        int[] colArray = remapReferencedColumns(cd, rowMap);
0698:                        for (int inner = 0; inner < size; inner++) {
0699:                            fkcd = (ForeignKeyConstraintDescriptor) fkcdl
0700:                                    .elementAt(inner);
0701:                            fkSetupArrays(dd, fkcd, inner, uuids,
0702:                                    conglomNumbers, fkNames,
0703:                                    isSelfReferencingFK, raRules);
0704:                            if ((raRules[inner] == StatementType.RA_CASCADE)
0705:                                    || (raRules[inner] == StatementType.RA_SETNULL)) {
0706:                                //find  the referencing  table Name
0707:                                fktd = fkcd.getTableDescriptor();
0708:                                refTableNames.addElement(fktd.getSchemaName()
0709:                                        + "." + fktd.getName());
0710:                                refActions.addElement(new Integer(
0711:                                        raRules[inner]));
0712:                                //find the referencing column name required for update null.
0713:                                refColumns = fkcd.getReferencedColumns();
0714:                                coldl = fktd.getColumnDescriptorList();
0715:                                ColumnDescriptorList releventColDes = new ColumnDescriptorList();
0716:                                for (int i = 0; i < refColumns.length; i++) {
0717:                                    cold = (ColumnDescriptor) coldl
0718:                                            .elementAt(refColumns[i] - 1);
0719:                                    releventColDes.add(cold);
0720:                                }
0721:                                refColDescriptors.addElement(releventColDes);
0722:                                refIndexConglomNum.addElement(new Long(
0723:                                        conglomNumbers[inner]));
0724:                                fkColMap.addElement(colArray);
0725:                            }
0726:                        }
0727:                    } else {
0728:                        continue;
0729:                    }
0730:
0731:                    TableDescriptor pktd = refcd.getTableDescriptor();
0732:                    UUID pkuuid = refcd.getIndexId();
0733:                    ConglomerateDescriptor pkIndexConglom = pktd
0734:                            .getConglomerateDescriptor(pkuuid);
0735:
0736:                    TableDescriptor refTd = cd.getTableDescriptor();
0737:                    fkVector.addElement(new FKInfo(fkNames, // foreign key names
0738:                            refTd.getName(), // table being modified
0739:                            statementType, // INSERT|UPDATE|DELETE
0740:                            type, // FOREIGN_KEY|REFERENCED_KEY
0741:                            pkuuid, // referenced backing index uuid
0742:                            pkIndexConglom.getConglomerateNumber(), // referened backing index conglom
0743:                            uuids, // fk backing index uuids
0744:                            conglomNumbers, // fk backing index congloms
0745:                            isSelfReferencingFK, // is self ref array of bool
0746:                            remapReferencedColumns(cd, rowMap), // column referened by key
0747:                            dd.getRowLocationTemplate(
0748:                                    getLanguageConnectionContext(), refTd),
0749:                            // row location template  for table being modified 
0750:                            raRules)); // referential action rules
0751:
0752:                }
0753:
0754:                /*
0755:                 ** Now convert the vector into an array.
0756:                 */
0757:                int size = fkVector.size();
0758:                if (size > 0) {
0759:                    fkInfo = new FKInfo[size];
0760:                    for (int i = 0; i < size; i++) {
0761:                        fkInfo[i] = (FKInfo) fkVector.elementAt(i);
0762:                    }
0763:                }
0764:
0765:                //convert the ref action info vectors to  to arrays
0766:                size = refActions.size();
0767:                if (size > 0) {
0768:                    fkTableNames = new String[size];
0769:                    fkRefActions = new int[size];
0770:                    fkColDescriptors = new ColumnDescriptorList[size];
0771:                    fkIndexConglomNumbers = new long[size];
0772:                    fkColArrays = new int[size][];
0773:                    for (int i = 0; i < size; i++) {
0774:                        fkTableNames[i] = (String) refTableNames.elementAt(i);
0775:                        fkRefActions[i] = ((Integer) refActions.elementAt(i))
0776:                                .intValue();
0777:                        fkColDescriptors[i] = (ColumnDescriptorList) refColDescriptors
0778:                                .elementAt(i);
0779:                        fkIndexConglomNumbers[i] = ((Long) refIndexConglomNum
0780:                                .elementAt(i)).longValue();
0781:                        fkColArrays[i] = ((int[]) fkColMap.elementAt(i));
0782:                    }
0783:                }
0784:
0785:            }
0786:
0787:            /*
0788:             ** Simple little helper method
0789:             */
0790:            private void fkSetupArrays(DataDictionary dd,
0791:                    ForeignKeyConstraintDescriptor fkcd, int index,
0792:                    UUID[] uuids, long[] conglomNumbers, String[] fkNames,
0793:                    boolean[] isSelfReferencingFK, int[] raRules)
0794:                    throws StandardException {
0795:                fkNames[index] = fkcd.getConstraintName();
0796:                uuids[index] = fkcd.getIndexId();
0797:                conglomNumbers[index] = fkcd.getIndexConglomerateDescriptor(dd)
0798:                        .getConglomerateNumber();
0799:                isSelfReferencingFK[index] = fkcd.isSelfReferencingFK();
0800:                if (statementType == StatementType.DELETE)
0801:                    raRules[index] = fkcd.getRaDeleteRule();
0802:                else if (statementType == StatementType.UPDATE)
0803:                    raRules[index] = fkcd.getRaUpdateRule();
0804:            }
0805:
0806:            /**
0807:             * Generate the TriggerInfo structures used during code generation.
0808:             *
0809:             * @param triggerList				The trigger descriptor list
0810:             * @param td				The TableDescriptor
0811:             * @param changedCols		The columns that are being modified
0812:             *
0813:             * @exception StandardException		Thrown on failure
0814:             */
0815:            private void generateTriggerInfo(GenericDescriptorList triggerList,
0816:                    TableDescriptor td, int[] changedCols)
0817:                    throws StandardException {
0818:                if ((triggerList != null) && (triggerList.size() > 0)) {
0819:                    triggerInfo = new TriggerInfo(td, changedCols, triggerList);
0820:                }
0821:            }
0822:
0823:            /**
0824:             * Return the FKInfo structure.  Just  a little wrapper
0825:             * to make sure we don't try to access it until after
0826:             * binding.
0827:             *
0828:             * @return the array of fkinfos
0829:             */
0830:            public FKInfo[] getFKInfo() {
0831:                if (SanityManager.DEBUG) {
0832:                    SanityManager.ASSERT(bound, "attempt to access FKInfo "
0833:                            + "before binding");
0834:                }
0835:                return fkInfo;
0836:            }
0837:
0838:            /**
0839:             * Return the TriggerInfo structure.  Just  a little wrapper
0840:             * to make sure we don't try to access it until after
0841:             * binding.
0842:             *
0843:             * @return the trigger info
0844:             */
0845:            public TriggerInfo getTriggerInfo() {
0846:                if (SanityManager.DEBUG) {
0847:                    SanityManager
0848:                            .ASSERT(bound, "attempt to access TriggerInfo "
0849:                                    + "before binding");
0850:                }
0851:                return triggerInfo;
0852:            }
0853:
0854:            /**
0855:             * Get the check constraints for this node
0856:             *
0857:             * @return the check constraints, may be null
0858:             */
0859:            public ValueNode getCheckConstraints() {
0860:                if (SanityManager.DEBUG) {
0861:                    SanityManager.ASSERT(bound, "attempt to access FKInfo "
0862:                            + "before binding");
0863:                }
0864:                return checkConstraints;
0865:            }
0866:
0867:            /**
0868:             * Makes the calling object (usually a Statement) dependent on all the constraints.
0869:             *
0870:             * @param tdl				The trigger descriptor list
0871:             * @param dependent			Parent object that will depend on all the constraints
0872:             *							that we look up. If this argument is null, then we
0873:             *							use the default dependent (the statement being compiled).
0874:             *
0875:             * @exception StandardException		Thrown on failure
0876:             */
0877:            private void createTriggerDependencies(GenericDescriptorList tdl,
0878:                    Dependent dependent) throws StandardException {
0879:                CompilerContext compilerContext = getCompilerContext();
0880:
0881:                Enumeration descs = tdl.elements();
0882:
0883:                while (descs.hasMoreElements()) {
0884:                    TriggerDescriptor td = (TriggerDescriptor) descs
0885:                            .nextElement();
0886:
0887:                    /*
0888:                     ** The dependent now depends on this trigger. 
0889:                     ** the default dependent is the statement 
0890:                     ** being compiled.
0891:                     */
0892:                    if (dependent == null) {
0893:                        compilerContext.createDependency(td);
0894:                    } else {
0895:                        compilerContext.createDependency(dependent, td);
0896:                    }
0897:                }
0898:            }
0899:
0900:            /**
0901:             * Get all the triggers relevant to this DML operation
0902:             *
0903:             * @param dd				The data dictionary
0904:             * @param td				The TableDescriptor
0905:             * @param changedColumnIds	If null, all columns being changed, otherwise array
0906:             *							of 1-based column ids for columns being changed
0907:             * @param includeTriggers	whether we allow trigger processing or not for
0908:             * 							this table
0909:             *
0910:             * @return	the constraint descriptor list
0911:             *
0912:             * @exception StandardException		Thrown on failure
0913:             */
0914:            protected GenericDescriptorList getAllRelevantTriggers(
0915:                    DataDictionary dd, TableDescriptor td,
0916:                    int[] changedColumnIds, boolean includeTriggers)
0917:                    throws StandardException {
0918:                if (relevantTriggers != null) {
0919:                    return relevantTriggers;
0920:                }
0921:
0922:                relevantTriggers = new GenericDescriptorList();
0923:
0924:                if (!includeTriggers)
0925:                    return relevantTriggers;
0926:
0927:                td.getAllRelevantTriggers(statementType, changedColumnIds,
0928:                        relevantTriggers);
0929:                adjustDeferredFlag(relevantTriggers.size() > 0);
0930:                return relevantTriggers;
0931:            }
0932:
0933:            protected void adjustDeferredFlag(boolean adjustment) {
0934:                if (!requiresDeferredProcessing) {
0935:                    requiresDeferredProcessing = adjustment;
0936:                }
0937:            }
0938:
0939:            /**
0940:             * Get all of our dependents due to a constraint.
0941:             *
0942:             * Makes the calling object (usually a Statement) dependent on all the constraints.
0943:             *
0944:             * @param dd				The data dictionary
0945:             * @param cdl				The constraint descriptor list
0946:             * @param dependent			Parent object that will depend on all the constraints
0947:             *							that we look up. If this argument is null, then we
0948:             *							use the default dependent (the statement being compiled).
0949:             *
0950:             * @exception StandardException		Thrown on failure
0951:             */
0952:            private void createConstraintDependencies(DataDictionary dd,
0953:                    ConstraintDescriptorList cdl, Dependent dependent)
0954:                    throws StandardException {
0955:                CompilerContext compilerContext = getCompilerContext();
0956:
0957:                int cdlSize = cdl.size();
0958:                for (int index = 0; index < cdlSize; index++) {
0959:                    ConstraintDescriptor cd = cdl.elementAt(index);
0960:
0961:                    /*
0962:                     ** The dependent now depends on this constraint. 
0963:                     ** the default dependent is the statement 
0964:                     ** being compiled.
0965:                     */
0966:                    if (dependent == null) {
0967:                        compilerContext.createDependency(cd);
0968:                    } else {
0969:                        compilerContext.createDependency(dependent, cd);
0970:                    }
0971:
0972:                    /*
0973:                     ** We are also dependent on all referencing keys --
0974:                     ** if one of them is deleted, we'll have to recompile.
0975:                     ** Also, if there is a BULK_INSERT on the table
0976:                     ** we are going to scan to validate the constraint,
0977:                     ** the index number will change, so we'll add a
0978:                     ** dependency on all tables we will scan.
0979:                     */
0980:                    if (cd instanceof  ReferencedKeyConstraintDescriptor) {
0981:                        ConstraintDescriptorList fkcdl = dd
0982:                                .getActiveConstraintDescriptors(((ReferencedKeyConstraintDescriptor) cd)
0983:                                        .getForeignKeyConstraints(ConstraintDescriptor.ENABLED));
0984:
0985:                        int fklSize = fkcdl.size();
0986:                        for (int inner = 0; inner < fklSize; inner++) {
0987:                            ConstraintDescriptor fkcd = fkcdl.elementAt(inner);
0988:                            if (dependent == null) {
0989:                                compilerContext.createDependency(fkcd);
0990:                                compilerContext.createDependency(fkcd
0991:                                        .getTableDescriptor());
0992:                            } else {
0993:                                compilerContext.createDependency(dependent,
0994:                                        fkcd);
0995:                                compilerContext.createDependency(dependent,
0996:                                        fkcd.getTableDescriptor());
0997:                            }
0998:                        }
0999:                    } else if (cd instanceof  ForeignKeyConstraintDescriptor) {
1000:                        ForeignKeyConstraintDescriptor fkcd = (ForeignKeyConstraintDescriptor) cd;
1001:                        if (dependent == null) {
1002:                            compilerContext.createDependency(fkcd
1003:                                    .getReferencedConstraint()
1004:                                    .getTableDescriptor());
1005:                        } else {
1006:                            compilerContext.createDependency(dependent, fkcd
1007:                                    .getReferencedConstraint()
1008:                                    .getTableDescriptor());
1009:                        }
1010:                    }
1011:                }
1012:            }
1013:
1014:            /**
1015:             * Get all the constraints relevant to this DML operation
1016:             *
1017:             * @param dd				The DataDictionary
1018:             * @param td				The TableDescriptor
1019:             * @param skipCheckConstraints Skip check constraints
1020:             * @param changedColumnIds	If null, all columns being changed, otherwise array
1021:             *							of 1-based column ids for columns being changed
1022:             *
1023:             * @return	the constraint descriptor list
1024:             *
1025:             * @exception StandardException		Thrown on failure
1026:             */
1027:            protected ConstraintDescriptorList getAllRelevantConstraints(
1028:                    DataDictionary dd, TableDescriptor td,
1029:                    boolean skipCheckConstraints, int[] changedColumnIds)
1030:                    throws StandardException {
1031:                if (relevantCdl != null) {
1032:                    return relevantCdl;
1033:                }
1034:
1035:                boolean[] needsDeferredProcessing = new boolean[1];
1036:                relevantCdl = new ConstraintDescriptorList();
1037:
1038:                needsDeferredProcessing[0] = requiresDeferredProcessing;
1039:                td.getAllRelevantConstraints(statementType,
1040:                        skipCheckConstraints, changedColumnIds,
1041:                        needsDeferredProcessing, relevantCdl);
1042:
1043:                adjustDeferredFlag(needsDeferredProcessing[0]);
1044:
1045:                return relevantCdl;
1046:            }
1047:
1048:            /**
1049:             * Does this DML Node require deferred processing?
1050:             * Set to true if we have triggers or referential
1051:             * constraints that need deferred processing.
1052:             *
1053:             * @return true/false 
1054:             */
1055:            public boolean requiresDeferredProcessing() {
1056:                return requiresDeferredProcessing;
1057:            }
1058:
1059:            /**
1060:             *	Parse a check constraint and turn it into a query tree.
1061:             *
1062:             *	@param	checkConstraintText	Text of CHECK CONSTRAINT.
1063:             * @param	td					The TableDescriptor for the table the the constraint is on.
1064:             *
1065:             *
1066:             * @return	The parsed check constraint as a query tree.
1067:             *
1068:             * @exception StandardException		Thrown on failure
1069:             */
1070:            public ValueNode parseCheckConstraint(String checkConstraintText,
1071:                    TableDescriptor td) throws StandardException {
1072:                Parser p;
1073:                ValueNode checkTree;
1074:                LanguageConnectionContext lcc = getLanguageConnectionContext();
1075:                CompilerContext compilerContext = getCompilerContext();
1076:
1077:                /* Get a Statement to pass to the parser */
1078:
1079:                /* We're all set up to parse. We have to build a compile SQL statement
1080:                 * before we can parse - we just have a WHERE clause right now.
1081:                 * So, we goober up a SELECT * FROM table WHERE checkDefs.
1082:                 */
1083:                String select = "SELECT * FROM " + td.getQualifiedName()
1084:                        + " WHERE " + checkConstraintText;
1085:
1086:                /*
1087:                 ** Get a new compiler context, so the parsing of the select statement
1088:                 ** doesn't mess up anything in the current context (it could clobber
1089:                 ** the ParameterValueSet, for example).
1090:                 */
1091:                CompilerContext newCC = lcc.pushCompilerContext();
1092:
1093:                p = newCC.getParser();
1094:
1095:                /* Finally, we can call the parser */
1096:                // Since this is always nested inside another SQL statement, so topLevel flag
1097:                // should be false
1098:                QueryTreeNode qt = p.parseStatement(select);
1099:                if (SanityManager.DEBUG) {
1100:                    if (!(qt instanceof  CursorNode)) {
1101:                        SanityManager
1102:                                .THROWASSERT("qt expected to be instanceof CursorNode, not "
1103:                                        + qt.getClass().getName());
1104:                    }
1105:                    CursorNode cn = (CursorNode) qt;
1106:                    if (!(cn.getResultSetNode() instanceof  SelectNode)) {
1107:                        SanityManager
1108:                                .THROWASSERT("cn.getResultSetNode() expected to be instanceof SelectNode, not "
1109:                                        + cn.getResultSetNode().getClass()
1110:                                                .getName());
1111:                    }
1112:                }
1113:
1114:                checkTree = ((SelectNode) ((CursorNode) qt).getResultSetNode())
1115:                        .getWhereClause();
1116:
1117:                lcc.popCompilerContext(newCC);
1118:
1119:                return checkTree;
1120:            }
1121:
1122:            /**
1123:             *	Generate the code to evaluate a tree of CHECK CONSTRAINTS.
1124:             *
1125:             *	@param	checkConstraints	Bound query tree of ANDed check constraints.
1126:             *	@param	ecb					Expression Class Builder
1127:             *
1128:             *
1129:             *
1130:             * @exception StandardException		Thrown on error
1131:             */
1132:            public void generateCheckConstraints(ValueNode checkConstraints,
1133:                    ExpressionClassBuilder ecb, MethodBuilder mb)
1134:                    throws StandardException {
1135:                // for the check constraints, we generate an exprFun
1136:                // that evaluates the expression of the clause
1137:                // against the current row of the child's result.
1138:                // if there are no check constraints, simply pass null
1139:                // to optimize for run time performance.
1140:
1141:                // generate the function and initializer:
1142:                // Note: Boolean lets us return nulls (boolean would not)
1143:                // private Boolean exprN()
1144:                // {
1145:                //   return <<checkConstraints.generate(ps)>>;
1146:                // }
1147:                // static Method exprN = method pointer to exprN;
1148:
1149:                // if there is no check constraint, we just want to pass null.
1150:                if (checkConstraints == null) {
1151:                    mb.pushNull(ClassName.GeneratedMethod);
1152:                } else {
1153:                    MethodBuilder userExprFun = generateCheckConstraints(
1154:                            checkConstraints, ecb);
1155:
1156:                    // check constraint is used in the final result set 
1157:                    // as an access of the new static
1158:                    // field holding a reference to this new method.
1159:                    ecb.pushMethodReference(mb, userExprFun);
1160:                }
1161:            }
1162:
1163:            /**
1164:             *	Generate a method to evaluate a tree of CHECK CONSTRAINTS.
1165:             *
1166:             *	@param	checkConstraints	Bound query tree of ANDed check constraints.
1167:             *	@param	ecb					Expression Class Builder
1168:             *
1169:             *
1170:             *
1171:             * @exception StandardException		Thrown on error
1172:             */
1173:            public MethodBuilder generateCheckConstraints(
1174:                    ValueNode checkConstraints, ExpressionClassBuilder ecb)
1175:                    throws StandardException {
1176:                // this sets up the method and the static field.
1177:                // generates:
1178:                // 	java.lang.Object userExprFun { }
1179:                MethodBuilder userExprFun = ecb.newUserExprFun();
1180:
1181:                // check constraint knows it is returning its value;
1182:
1183:                /* generates:
1184:                 *    return <checkExpress.generate(ecb)>;
1185:                 * and adds it to userExprFun
1186:                 */
1187:
1188:                checkConstraints.generateExpression(ecb, userExprFun);
1189:                userExprFun.methodReturn();
1190:
1191:                // we are done modifying userExprFun, complete it.
1192:                userExprFun.complete();
1193:
1194:                return userExprFun;
1195:            }
1196:
1197:            /**
1198:             * Generate an optimized QueryTree from a bound QueryTree.  Actually,
1199:             * it can annotate the tree in place rather than generate a new tree,
1200:             * but this interface allows the root node of the optimized QueryTree
1201:             * to be different from the root node of the bound QueryTree.
1202:             *
1203:             * For non-optimizable statements, this method is a no-op.
1204:             *
1205:             * Throws an exception if the tree is not bound, or if the binding
1206:             * is out of date.
1207:             *
1208:             * @return      An optimized QueryTree
1209:             *
1210:             * @exception StandardException         Thrown on failure
1211:             */
1212:            public QueryTreeNode optimize() throws StandardException {
1213:                ResultSetNode originalRSNode = getResultSetNode();
1214:
1215:                /* First optimize the query */
1216:                QueryTreeNode retval = super .optimize();
1217:
1218:                /* In language we always set it to row lock, it's up to store to
1219:                 * upgrade it to table lock.  This makes sense for the default read
1220:                 * committed isolation level and update lock.  For more detail, see
1221:                 * Beetle 4133.
1222:                 */
1223:                lockMode = TransactionController.MODE_RECORD;
1224:
1225:                return retval;
1226:            }
1227:
1228:            /**
1229:             * Get the list of indexes that must be updated by this DML statement.
1230:             * WARNING: As a side effect, it creates dependencies on those indexes.
1231:             *
1232:             * @param td	The table descriptor for the table being updated
1233:             * @param updatedColumns	The updated column list.  If not update, null
1234:             * @param colBitSet			a 1 based bit set of the columns in the list
1235:             *
1236:             * @exception StandardException		Thrown on error
1237:             */
1238:            protected void getAffectedIndexes(TableDescriptor td,
1239:                    ResultColumnList updatedColumns, FormatableBitSet colBitSet)
1240:                    throws StandardException {
1241:                Vector conglomVector = new Vector();
1242:
1243:                DMLModStatementNode.getXAffectedIndexes(td, updatedColumns,
1244:                        colBitSet, conglomVector);
1245:
1246:                markAffectedIndexes(conglomVector);
1247:            }
1248:
1249:            /**
1250:             *	Marks which indexes are affected by an UPDATE of the
1251:             *	desired shape.
1252:             *
1253:             *	Is passed a list of updated columns. Does the following:
1254:             *
1255:             *	1)	finds all indices which overlap the updated columns
1256:             *	2)	adds the index columns to a bitmap of affected columns
1257:             *	3)	adds the index descriptors to a list of conglomerate
1258:             *		descriptors.
1259:             *
1260:             *	@param	updatedColumns	a list of updated columns
1261:             *	@param	colBitSet		OUT: evolving bitmap of affected columns
1262:             *	@param	conglomVector	OUT: vector of affected indices
1263:             *
1264:             * @exception StandardException		Thrown on error
1265:             */
1266:            static void getXAffectedIndexes(TableDescriptor baseTable,
1267:                    ResultColumnList updatedColumns,
1268:                    FormatableBitSet colBitSet, Vector conglomVector)
1269:                    throws StandardException {
1270:                ConglomerateDescriptor[] cds = baseTable
1271:                        .getConglomerateDescriptors();
1272:
1273:                /* we only get distinct conglomerate numbers.  If duplicate indexes
1274:                 * share one conglomerate, we only return one number.
1275:                 */
1276:                long[] distinctConglomNums = new long[cds.length - 1];
1277:                int distinctCount = 0;
1278:
1279:                for (int index = 0; index < cds.length; index++) {
1280:                    ConglomerateDescriptor cd = cds[index];
1281:
1282:                    if (!cd.isIndex()) {
1283:                        continue;
1284:                    }
1285:
1286:                    /*
1287:                     ** If this index doesn't contain any updated
1288:                     ** columns, then we can skip it.
1289:                     */
1290:                    if ((updatedColumns != null)
1291:                            && (!updatedColumns
1292:                                    .updateOverlaps(cd.getIndexDescriptor()
1293:                                            .baseColumnPositions()))) {
1294:                        continue;
1295:                    }
1296:
1297:                    if (conglomVector != null) {
1298:                        int i;
1299:                        for (i = 0; i < distinctCount; i++) {
1300:                            if (distinctConglomNums[i] == cd
1301:                                    .getConglomerateNumber())
1302:                                break;
1303:                        }
1304:                        if (i == distinctCount) // first appearence
1305:                        {
1306:                            distinctConglomNums[distinctCount++] = cd
1307:                                    .getConglomerateNumber();
1308:                            conglomVector.addElement(cd);
1309:                        }
1310:                    }
1311:
1312:                    IndexRowGenerator ixd = cd.getIndexDescriptor();
1313:                    int[] cols = ixd.baseColumnPositions();
1314:
1315:                    if (colBitSet != null) {
1316:                        for (int i = 0; i < cols.length; i++) {
1317:                            colBitSet.set(cols[i]);
1318:                        }
1319:                    } // end IF
1320:                } // end loop through conglomerates
1321:
1322:            }
1323:
1324:            protected void markAffectedIndexes(Vector affectedConglomerates)
1325:                    throws StandardException {
1326:                ConglomerateDescriptor cd;
1327:                int indexCount = affectedConglomerates.size();
1328:                CompilerContext cc = getCompilerContext();
1329:
1330:                indicesToMaintain = new IndexRowGenerator[indexCount];
1331:                indexConglomerateNumbers = new long[indexCount];
1332:                indexNames = new String[indexCount];
1333:
1334:                for (int ictr = 0; ictr < indexCount; ictr++) {
1335:                    cd = (ConglomerateDescriptor) affectedConglomerates
1336:                            .elementAt(ictr);
1337:
1338:                    indicesToMaintain[ictr] = cd.getIndexDescriptor();
1339:                    indexConglomerateNumbers[ictr] = cd.getConglomerateNumber();
1340:                    indexNames[ictr] = ((cd.isConstraint()) ? null : cd
1341:                            .getConglomerateName());
1342:
1343:                    cc.createDependency(cd);
1344:                }
1345:
1346:            }
1347:
1348:            public String statementToString() {
1349:                return "DML MOD";
1350:            }
1351:
1352:            /**
1353:             * Remap referenced columns in the cd to reflect the
1354:             * passed in row map.
1355:             *
1356:             * @param cd 		constraint descriptor
1357:             * @param rowMap	1 based row map 
1358:             */
1359:            private int[] remapReferencedColumns(ConstraintDescriptor cd,
1360:                    int[] rowMap) {
1361:                int[] oldCols = cd.getReferencedColumns();
1362:                if (rowMap == null) {
1363:                    return oldCols;
1364:                }
1365:
1366:                int[] newCols = new int[oldCols.length];
1367:                for (int i = 0; i < oldCols.length; i++) {
1368:                    newCols[i] = rowMap[oldCols[i]];
1369:                    if (SanityManager.DEBUG) {
1370:                        SanityManager
1371:                                .ASSERT(
1372:                                        newCols[i] != 0,
1373:                                        "attempt to map a column "
1374:                                                + oldCols[i]
1375:                                                + " which is not in our new column map.  Something is "
1376:                                                + "wrong with the logic to do partial reads for an update stmt");
1377:                    }
1378:                }
1379:                return newCols;
1380:            }
1381:
1382:            /**
1383:             * Get a integer based row map from a bit set.
1384:             * 
1385:             * @param bitSet
1386:             * @param td 
1387:             * 
1388:             */
1389:            private int[] getRowMap(FormatableBitSet bitSet, TableDescriptor td)
1390:                    throws StandardException {
1391:                if (bitSet == null) {
1392:                    return (int[]) null;
1393:                }
1394:
1395:                int size = td.getMaxColumnID();
1396:                int[] iArray = new int[size + 1];
1397:                int j = 1;
1398:                for (int i = 1; i <= size; i++) {
1399:                    if (bitSet.get(i)) {
1400:                        iArray[i] = j++;
1401:                    }
1402:                }
1403:                return iArray;
1404:            }
1405:
1406:            public void setRefActionInfo(long fkIndexConglomId,
1407:                    int[] fkColArray, String parentResultSetId,
1408:                    boolean dependentScan) {
1409:                resultSet.setRefActionInfo(fkIndexConglomId, fkColArray,
1410:                        parentResultSetId, dependentScan);
1411:            }
1412:
1413:            /**
1414:             * Normalize synonym column references to have the name of the base table. 
1415:             *
1416:             * @param rcl	           The result column list of the target table
1417:             * @param targetTableName  The target tablename
1418:             *
1419:             * @exception StandardException		Thrown on error
1420:             */
1421:            public void normalizeSynonymColumns(ResultColumnList rcl,
1422:                    TableName targetTableName) throws StandardException {
1423:                if (synonymTableName == null)
1424:                    return;
1425:
1426:                String synTableName = synonymTableName.getTableName();
1427:
1428:                int count = rcl.size();
1429:                for (int i = 0; i < count; i++) {
1430:                    ResultColumn column = (ResultColumn) rcl.elementAt(i);
1431:                    ColumnReference reference = column.getReference();
1432:
1433:                    if (reference != null) {
1434:                        String crTableName = reference.getTableName();
1435:                        if (crTableName != null) {
1436:                            if (synTableName.equals(crTableName)) {
1437:                                reference.setTableNameNode(targetTableName);
1438:                            } else {
1439:                                throw StandardException.newException(
1440:                                        SQLState.LANG_TABLE_NAME_MISMATCH,
1441:                                        synTableName, crTableName);
1442:                            }
1443:                        }
1444:                    }
1445:                }
1446:            }
1447:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.