📄 insertnode.java
字号:
if (resultSet instanceof UnionNode) { // If we are inserting a number of rows in VALUES clause, we need to // examine each row for 'autoincrement'. resultColumnList.checkAutoincrementUnion(resultSet); } else resultColumnList.checkAutoincrement(resultSet.getResultColumns()); resultColumnList.checkStorableExpressions(resultSet.getResultColumns()); /* Insert a NormalizeResultSetNode above the source if the source * and target column types and lengths do not match. */ if (! resultColumnList.columnTypesAndLengthsMatch( resultSet.getResultColumns())) { resultSet = resultSet.genNormalizeResultSetNode(resultSet, false); resultColumnList.copyTypesAndLengthsToSource(resultSet.getResultColumns()); } if (targetTableDescriptor != null) { /* Get and bind all constraints on the table */ ResultColumnList sourceRCL = resultSet.getResultColumns(); sourceRCL.copyResultColumnNames(resultColumnList); checkConstraints = bindConstraints(dataDictionary, getNodeFactory(), targetTableDescriptor, null, sourceRCL, (int[]) null, (FormatableBitSet) null, false, true); /* we always include * triggers in core language */ /* Do we need to do a deferred mode insert */ /* ** Deferred if: ** If the target table is also a source table ** Self-referencing foreign key constraint ** trigger */ if (resultSet.referencesTarget( targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) { deferred = true; /* Disallow bulk insert replace when target table * is also a source table. */ if (bulkInsertReplace && resultSet.referencesTarget( targetTableDescriptor.getName(), true)) { throw StandardException.newException(SQLState.LANG_INVALID_BULK_INSERT_REPLACE, targetTableDescriptor.getQualifiedName()); } } /* Get the list of indexes on the table being inserted into */ getAffectedIndexes(targetTableDescriptor); TransactionController tc = getLanguageConnectionContext().getTransactionCompile(); autoincRowLocation = dd.computeAutoincRowLocations(tc, targetTableDescriptor); } else { deferred = VTIDeferModPolicy.deferIt( DeferModification.INSERT_STATEMENT, targetVTI, null, resultSet); } return this; } /** * Return true if the node references SESSION schema tables (temporary or permanent) * * @return true if references SESSION schema tables, else false * * @exception StandardException Thrown on error */ public boolean referencesSessionSchema() throws StandardException { boolean returnValue = false; //If this node references a SESSION schema table, then return true. if (targetTableDescriptor != null) returnValue = isSessionSchema(targetTableDescriptor.getSchemaDescriptor()); if (returnValue == false) returnValue = resultSet.referencesSessionSchema(); return returnValue; } /** * Verify that the target properties that we are interested in * all hold valid values. * NOTE: Any target property which is valid but cannot be supported * due to a target database, etc. will be turned off quietly. * * @param dd The DataDictionary * * @return Nothing. * * @exception StandardException Thrown on error */ private void verifyTargetProperties(DataDictionary dd) throws StandardException { // The only property that we're currently interested in is insertMode String insertMode = targetProperties.getProperty("insertMode"); if (insertMode != null) { String upperValue = StringUtil.SQLToUpperCase(insertMode); if (! upperValue.equals("BULKINSERT") && ! upperValue.equals("REPLACE")) { throw StandardException.newException(SQLState.LANG_INVALID_INSERT_MODE, insertMode, targetTableName); } else { /* Turn off bulkInsert if it is on and we can't support it. */ if (! verifyBulkInsert(dd, upperValue)) { targetProperties.remove("insertMode"); } else { /* Now we know we're doing bulk insert */ bulkInsert = true; if (upperValue.equals("REPLACE")) { bulkInsertReplace = true; } // Validate the bulkFetch property if specified String bulkFetchStr = targetProperties.getProperty("bulkFetch"); if (bulkFetchStr != null) { int bulkFetch = getIntProperty(bulkFetchStr, "bulkFetch"); // verify that the specified value is valid if (bulkFetch <= 0) { throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_VALUE, String.valueOf(bulkFetch)); } } } } } } /** * Do the bind time checks to see if bulkInsert is allowed on * this table. bulkInsert is disallowed at bind time for: * o target databases * o (tables with triggers?) * (It is disallowed at execution time if the table has at * least 1 row in it or if it is a deferred mode insert.) * * @param dd The DataDictionary * @param mode The insert mode * * @return Whether or not bulkInsert is allowed. * * @exception StandardException Thrown on error */ private boolean verifyBulkInsert(DataDictionary dd, String mode) throws StandardException { return true; } /** * Compile constants that Execution will use * * @exception StandardException Thrown on failure */ public ConstantAction makeConstantAction() throws StandardException { /* Different constant actions for base tables and updatable VTIs */ if (targetTableDescriptor != null) { // Base table long heapConglomId = targetTableDescriptor.getHeapConglomerateId(); TransactionController tc = getLanguageConnectionContext().getTransactionCompile(); int numIndexes = (targetTableDescriptor != null) ? indexConglomerateNumbers.length : 0; StaticCompiledOpenConglomInfo[] indexSCOCIs = new StaticCompiledOpenConglomInfo[numIndexes]; for (int index = 0; index < numIndexes; index++) { indexSCOCIs[index] = tc.getStaticCompiledConglomInfo(indexConglomerateNumbers[index]); } /* ** If we're doing bulk insert, do table locking regardless of ** what the optimizer decided. This is because bulk insert is ** generally done with a large number of rows into an empty table. ** We also do table locking if the table's lock granularity is ** set to table. */ if (bulkInsert || targetTableDescriptor.getLockGranularity() == TableDescriptor.TABLE_LOCK_GRANULARITY) { lockMode = TransactionController.MODE_TABLE; } return getGenericConstantActionFactory().getInsertConstantAction ( targetTableDescriptor, heapConglomId, tc.getStaticCompiledConglomInfo(heapConglomId), indicesToMaintain, indexConglomerateNumbers, indexSCOCIs, indexNames, deferred, false, targetTableDescriptor.getUUID(), lockMode, null, null, targetProperties, getFKInfo(), getTriggerInfo(), resultColumnList.getStreamStorableColIds(targetTableDescriptor.getNumberOfColumns()), getIndexedCols(), (UUID) null, null, null, resultSet.isOneRowResultSet(), autoincRowLocation ); } else { /* Return constant action for VTI * NOTE: ConstantAction responsible for preserving instantiated * VTIs for in-memory queries and for only preserving VTIs * that implement Serializable for SPSs. */ return getGenericConstantActionFactory().getUpdatableVTIConstantAction( DeferModification.INSERT_STATEMENT, deferred); } } /** * Create a boolean[] to track the (0-based) columns which are indexed. * * @return A boolean[] to track the (0-based) columns which are indexed. * * @exception StandardException Thrown on failure */ public boolean[] getIndexedCols() throws StandardException { /* Create a boolean[] to track the (0-based) columns which are indexed */ boolean[] indexedCols = new boolean[targetTableDescriptor.getNumberOfColumns()]; for (int index = 0; index < indicesToMaintain.length; index++) { int[] colIds = indicesToMaintain[index].getIndexDescriptor().baseColumnPositions(); for (int index2 = 0; index2 < colIds.length; index2++) { indexedCols[colIds[index2] - 1] = true; } } return indexedCols; } /** * Code generation for insert * creates an expression for: * ResultSetFactory.getInsertResultSet(resultSet.generate(ps), this ) * * @param acb The ActivationClassBuilder for the class being built * @param mb the method for the execute() method to be built * * @return A compiled Expression returning an InsertResultSet * * @exception StandardException Thrown on error */ public void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException { //If the DML is on the temporary table, generate the code to mark temporary table as modified in the current UOW generateCodeForTemporaryTable(acb, mb); /* generate the parameters */ generateParameterValueSet(acb); // Base table if (targetTableDescriptor != null) { /* ** Generate the insert result set, giving it either the original ** source or the normalize result set, the constant action, ** and "this". */ acb.pushGetResultSetFactoryExpression(mb); // arg 1 resultSet.generate(acb, mb); // arg 2 generate code to evaluate CHECK CONSTRAINTS generateCheckConstraints( checkConstraints, acb, mb ); acb.pushThisAsActivation(mb); // arg 3 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getInsertResultSet", ClassName.ResultSet, 3); } else { /* Generate code for the VTI * NOTE: we need to create a dummy cost estimate for the * targetVTI since we never optimized it. * RESOLVEVTI - we will have to optimize it in order to * push predicates into the VTI. */ targetVTI.assignCostEstimate(resultSet.getNewCostEstimate()); /* ** Generate the insert VTI result set, giving it either the original ** source or the normalize result set, the constant action, ** and "this". */ acb.pushGetResultSetFactoryExpression(mb); // arg 1 resultSet.generate(acb, mb); // arg 2 targetVTI.generate(acb, mb); acb.pushThisAsActivation(mb); // arg 3 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getInsertVTIResultSet", ClassName.ResultSet, 3); } /* ** ensure all parameters have been generated */ generateParameterHolders(acb); } /** * Return the type of statement, something from * StatementType. * * @return the type of statement */ protected final int getStatementType() { return StatementType.INSERT; } /** * Return the statement type, where it is dependent on * the targetProperties. (insertMode = replace causes * statement type to be BULK_INSERT_REPLACE. * * @return the type of statement */ static final int getStatementType(Properties targetProperties) { int retval = StatementType.INSERT; // The only property that we're currently interested in is insertMode String insertMode = (targetProperties == null) ? null : targetProperties.getProperty("insertMode"); if (insertMode != null) { String upperValue = StringUtil.SQLToUpperCase(insertMode); if (upperValue.equals("REPLACE")) { retval = StatementType.BULK_INSERT_REPLACE; } } return retval; } /** * Get the list of indexes on the table being inserted into. This * is used by INSERT. This is an optimized version of what * UPDATE and DELETE use. * * @param td TableDescriptor for the table being inserted into * or deleted from * * @return Nothing * * @exception StandardException Thrown on error */ private void getAffectedIndexes ( TableDescriptor td ) throws StandardException { IndexLister indexLister = td.getIndexLister( ); indicesToMaintain = indexLister.getDistinctIndexRowGenerators(); indexConglomerateNumbers = indexLister.getDistinctIndexConglomerateNumbers(); indexNames = indexLister.getDistinctIndexNames(); /* Add dependencies on all indexes in the list */ ConglomerateDescriptor[] cds = td.getConglomerateDescriptors(); CompilerContext cc = getCompilerContext(); for (int index = 0; index < cds.length; index++) { cc.createDependency(cds[index]); } }} // end of class InsertNode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -