Search in sources :

Example 41 with MethodBuilder

use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.

the class DeleteNode method generate.

/**
 * Code generation for delete.
 * The generated code will contain:
 *		o  A static member for the (xxx)ResultSet with the RowLocations
 *		o  The static member will be assigned the appropriate ResultSet within
 *		   the nested calls to get the ResultSets.  (The appropriate cast to the
 *		   (xxx)ResultSet will be generated.)
 *		o  The CurrentRowLocation() in SelectNode's select list will generate
 *		   a new method for returning the RowLocation as well as a call to
 *		   that method which will be stuffed in the call to the
 *		    ProjectRestrictResultSet.
 *      o In case of referential actions, this function generate an
 *        array of resultsets on its dependent tables.
 *
 * @param acb	The ActivationClassBuilder for the class being built
 * @param mb	The execute() method to be built
 *
 * @exception StandardException		Thrown on error
 */
@Override
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. After
    // DERBY-827 this must be done in execute() since
    // createResultSet() will only be called once.
    generateCodeForTemporaryTable(acb);
    /* generate the parameters */
    if (!isDependentTable)
        generateParameterValueSet(acb);
    acb.pushGetResultSetFactoryExpression(mb);
    acb.newRowLocationScanResultSetName();
    // arg 1
    if (inMatchingClause()) {
        matchingClause.generateResultSetField(acb, mb);
    } else {
        resultSet.generate(acb, mb);
    }
    String resultSetGetter;
    int argCount;
    String parentResultSetId;
    // Base table
    if (targetTableDescriptor != null) {
        /* Create the declaration for the scan ResultSet which generates the
			 * RowLocations to be deleted.
	 		 * Note that the field cannot be static because there
			 * can be multiple activations of the same activation class,
			 * and they can't share this field.  Only exprN fields can
			 * be shared (or, more generally, read-only fields).
			 * RESOLVE - Need to deal with the type of the field.
			 */
        acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.CursorResultSet, acb.getRowLocationScanResultSetName());
        if (cascadeDelete || isDependentTable) {
            resultSetGetter = "getDeleteCascadeResultSet";
            argCount = 4;
        } else {
            resultSetGetter = "getDeleteResultSet";
            argCount = 1;
        }
    } else {
        argCount = 1;
        resultSetGetter = "getDeleteVTIResultSet";
    }
    if (isDependentTable) {
        mb.push(acb.addItem(makeConstantAction()));
    } else {
        if (cascadeDelete) {
            // root table.
            mb.push(-1);
        }
    }
    String resultSetArrayType = ClassName.ResultSet + "[]";
    if (cascadeDelete) {
        parentResultSetId = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
        // Generate the code to build the array
        LocalField arrayField = acb.newFieldDeclaration(Modifier.PRIVATE, resultSetArrayType);
        // new ResultSet[size]
        mb.pushNewArray(ClassName.ResultSet, dependentNodes.length);
        mb.setField(arrayField);
        for (int index = 0; index < dependentNodes.length; index++) {
            dependentNodes[index].setRefActionInfo(fkIndexConglomNumbers[index], fkColArrays[index], parentResultSetId, true);
            // first arg (resultset array reference)
            mb.getField(arrayField);
            /*beetle:5360 : if too many statements are added  to a  method, 
				 *size of method can hit  65k limit, which will
				 *lead to the class format errors at load time.
				 *To avoid this problem, when number of statements added 
				 *to a method is > 2048, remaing statements are added to  a new function
				 *and called from the function which created the function.
				 *See Beetle 5135 or 4293 for further details on this type of problem.
				*/
            if (mb.statementNumHitLimit(10)) {
                MethodBuilder dmb = acb.newGeneratedFun(ClassName.ResultSet, Modifier.PRIVATE);
                // generates the resultset expression
                dependentNodes[index].generate(acb, dmb);
                dmb.methodReturn();
                dmb.complete();
                /* Generate the call to the new method */
                mb.pushThis();
                // second arg will be generated by this call
                mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, dmb.getName(), ClassName.ResultSet, 0);
            } else {
                // generates the resultset expression
                dependentNodes[index].generate(acb, mb);
            }
            mb.setArrayElement(index);
        }
        // fourth argument - array reference
        mb.getField(arrayField);
    } else {
        if (isDependentTable) {
            // No dependent tables for this table
            mb.pushNull(resultSetArrayType);
        }
    }
    if (cascadeDelete || isDependentTable) {
        parentResultSetId = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
        mb.push(parentResultSetId);
    }
    mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSetGetter, ClassName.ResultSet, argCount);
    if (!isDependentTable && cascadeDelete) {
        int numResultSets = acb.getRowCount();
        if (numResultSets > 0) {
            // generate activation.raParentResultSets = new NoPutResultSet[size]
            MethodBuilder constructor = acb.getConstructor();
            constructor.pushThis();
            constructor.pushNewArray(ClassName.CursorResultSet, numResultSets);
            constructor.putField(ClassName.BaseActivation, "raParentResultSets", ClassName.CursorResultSet + "[]");
            constructor.endStatement();
        }
    }
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 42 with MethodBuilder

use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.

the class JoinNode method getJoinArguments.

/**
 * Get the arguments to the join result set.
 *
 * @param acb	The ActivationClassBuilder for the class we're building.
 * @param mb the method the generated code is going into
 * @param joinClause	The join clause, if any
 *
 * @return	The array of arguments to the join result set
 *
 * @exception StandardException		Thrown on error
 */
private int getJoinArguments(ActivationClassBuilder acb, MethodBuilder mb, ValueNode joinClause) throws StandardException {
    int numArgs = getNumJoinArguments();
    // arg 1
    leftResultSet.generate(acb, mb);
    // arg 2
    mb.push(leftResultSet.getResultColumns().size());
    // arg 3
    rightResultSet.generate(acb, mb);
    // arg 4
    mb.push(rightResultSet.getResultColumns().size());
    // Get our final cost estimate based on child estimates.
    setCostEstimate(getFinalCostEstimate());
    // if there is no join clause, we just pass a null Expression.
    if (joinClause == null) {
        // arg 5
        mb.pushNull(ClassName.GeneratedMethod);
    } else {
        // this sets up the method and the static field.
        // generates:
        // Object userExprFun { }
        MethodBuilder userExprFun = acb.newUserExprFun();
        // join clause knows it is returning its value;
        /* generates:
			 *    return <joinClause.generate(acb)>;
			 * and adds it to userExprFun
			 */
        joinClause.generate(acb, userExprFun);
        userExprFun.methodReturn();
        // we are done modifying userExprFun, complete it.
        userExprFun.complete();
        // join clause is used in the final result set as an access of the new static
        // field holding a reference to this new method.
        // generates:
        // ActivationClass.userExprFun
        // which is the static field that "points" to the userExprFun
        // that evaluates the where clause.
        // arg 5
        acb.pushMethodReference(mb, userExprFun);
    }
    // arg 6
    mb.push(getResultSetNumber());
    addOuterJoinArguments(acb, mb);
    // Does right side return a single row
    oneRowRightSide(acb, mb);
    // estimated row count
    mb.push(getCostEstimate().rowCount());
    // estimated cost
    mb.push(getCostEstimate().getEstimatedCost());
    // run time statistics.
    if (joinOrderStrategyProperties != null)
        mb.push(PropertyUtil.sortProperties(joinOrderStrategyProperties));
    else
        mb.pushNull("java.lang.String");
    return numArgs;
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 43 with MethodBuilder

use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.

the class MatchingClauseNode method generateInsertUpdateRow.

/**
 * <p>
 * Generate a method to build a row for the temporary table for INSERT/UPDATE actions.
 * The method stuffs each column in the row with the result of the corresponding
 * expression built out of columns in the current row of the driving left join.
 * The method returns the stuffed row.
 * </p>
 */
private void generateInsertUpdateRow(ActivationClassBuilder acb, ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn) throws StandardException {
    // point expressions in the temporary row at the columns in the
    // result column list of the driving left join.
    adjustThenColumns(selectList, generatedScan, hojn);
    _rowMakingMethodName = "mergeRowMakingMethod_" + _clauseNumber;
    MethodBuilder mb = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, ClassName.ExecRow, _rowMakingMethodName);
    mb.addThrownException(ClassName.StandardException);
    _thenColumns.generateEvaluatedRow(acb, mb, false, true);
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 44 with MethodBuilder

use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.

the class MatchingClauseNode method makeConstantAction.

// /////////////////////////////////////////////////////////////////////////////////
// 
// generate() BEHAVIOR
// 
// /////////////////////////////////////////////////////////////////////////////////
ConstantAction makeConstantAction(ActivationClassBuilder acb) throws StandardException {
    // generate the clause-specific refinement
    String refinementName = null;
    if (_matchingRefinement != null) {
        MethodBuilder userExprFun = acb.newUserExprFun();
        _matchingRefinement.generateExpression(acb, userExprFun);
        userExprFun.methodReturn();
        // we are done modifying userExprFun, complete it.
        userExprFun.complete();
        refinementName = userExprFun.getName();
    }
    return getGenericConstantActionFactory().getMatchingClauseConstantAction(getClauseType(), refinementName, buildThenColumnSignature(), _rowMakingMethodName, _resultSetFieldName, _actionMethodName, _dml.makeConstantAction());
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 45 with MethodBuilder

use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.

the class OperatorNode method pushSqlXmlUtil.

/**
 * <p>
 * Generate code that pushes an SqlXmlUtil instance onto the stack. The
 * instance will be created and cached in the activation's constructor, so
 * that we don't need to create a new instance for every row.
 * </p>
 *
 * <p>
 * If the {@code xmlQuery} parameter is non-null, there will also be code
 * that compiles the query when the SqlXmlUtil instance is created.
 * </p>
 *
 * @param acb builder for the class in which the generated code lives
 * @param mb builder for the method that implements this operator
 * @param xmlQuery the XML query to be executed by the operator, or
 * {@code null} if this isn't an XMLEXISTS or XMLQUERY operator
 * @param xmlOpName the name of the operator (ignored if {@code xmlQuery}
 * is {@code null})
 */
static void pushSqlXmlUtil(ExpressionClassBuilder acb, MethodBuilder mb, String xmlQuery, String xmlOpName) {
    // Create a field in which the instance can be cached.
    LocalField sqlXmlUtil = acb.newFieldDeclaration(Modifier.PRIVATE | Modifier.FINAL, SqlXmlUtil.class.getName());
    // Add code that creates the SqlXmlUtil instance in the constructor.
    MethodBuilder constructor = acb.getConstructor();
    constructor.pushNewStart(SqlXmlUtil.class.getName());
    constructor.pushNewComplete(0);
    constructor.putField(sqlXmlUtil);
    // Compile the query, if one is specified.
    if (xmlQuery == null) {
        // No query. The SqlXmlUtil instance is still on the stack. Pop it
        // to restore the initial state of the stack.
        constructor.pop();
    } else {
        // Compile the query. This will consume the SqlXmlUtil instance
        // and leave the stack in its initial state.
        constructor.push(xmlQuery);
        constructor.push(xmlOpName);
        constructor.callMethod(VMOpcode.INVOKEVIRTUAL, SqlXmlUtil.class.getName(), "compileXQExpr", "void", 2);
    }
    // Read the cached value and push it onto the stack in the method
    // generated for the operator.
    mb.getField(sqlXmlUtil);
}
Also used : SqlXmlUtil(org.apache.derby.iapi.types.SqlXmlUtil) LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Aggregations

MethodBuilder (org.apache.derby.iapi.services.compiler.MethodBuilder)48 LocalField (org.apache.derby.iapi.services.compiler.LocalField)18 ReferencedColumnsDescriptorImpl (org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl)3 OptimizablePredicate (org.apache.derby.iapi.sql.compile.OptimizablePredicate)3 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 FormatableArrayHolder (org.apache.derby.iapi.services.io.FormatableArrayHolder)1 FormatableIntHolder (org.apache.derby.iapi.services.io.FormatableIntHolder)1 GeneratedClass (org.apache.derby.iapi.services.loader.GeneratedClass)1 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)1 CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)1 StaticCompiledOpenConglomInfo (org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo)1 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)1 SqlXmlUtil (org.apache.derby.iapi.types.SqlXmlUtil)1 StandardException (org.apache.derby.shared.common.error.StandardException)1