use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.
the class UnaryOperatorNode method addXmlOpMethodParams.
/**
* Add some additional arguments to our method call for
* XML related operations like XMLPARSE and XMLSERIALIZE.
*
* @param acb the builder for the class in which the method lives
* @param mb The MethodBuilder that will make the call.
* @param resultField the field that contains the previous result
* @return Number of parameters added.
*/
int addXmlOpMethodParams(ExpressionClassBuilder acb, MethodBuilder mb, LocalField resultField) throws StandardException {
if ((kind != K_XMLPARSE) && (kind != K_XMLSERIALIZE)) {
// nothing to do.
return 0;
}
if (kind == K_XMLSERIALIZE) {
// We push the target type's JDBC type id as well as
// the maximum width, since both are required when
// we actually perform the operation, and both are
// primitive types. Note: we don't have to save
// any objects for XMLSERIALIZE because it doesn't
// require any XML-specific objects: it just returns
// the serialized version of the XML value, which we
// already found when the XML value was created (ex.
// as part of the XMLPARSE work).
// We also need to pass the collation type of the current
// compilation schema. If the JDBC type id is of type
// StringDataValue, then we should use the collation to
// decide whether we need to generate collation sensitive
// StringDataValue.
mb.push(targetType.getJDBCTypeId());
mb.push(targetType.getMaximumWidth());
mb.push(getSchemaDescriptor(null, false).getCollationType());
return 3;
}
/* Else we're here for XMLPARSE. */
// XMLPARSE is different from other unary operators in that the method
// must be called on the result object (the XML value) and not on the
// operand (the string value). We must therefore make sure the result
// object is not null.
MethodBuilder constructor = acb.getConstructor();
acb.generateNull(constructor, getTypeCompiler(), getTypeServices().getCollationType());
constructor.setField(resultField);
// Swap operand and result object so that the method will be called
// on the result object.
mb.swap();
// Push whether or not we want to preserve whitespace.
mb.push(preserveWhitespace);
// Push the SqlXmlUtil instance as the next argument.
pushSqlXmlUtil(acb, mb, null, null);
return 2;
}
use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.
the class CurrentOfNode method generate.
/**
* Generation on a CurrentOfNode creates a scan on the
* cursor, CurrentOfResultSet.
* <p>
* This routine will generate and return a call of the form:
* <pre><verbatim>
* ResultSetFactory.getCurrentOfResultSet(cursorName)
* </verbatim></pre>
*
* @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 (SanityManager.DEBUG)
SanityManager.ASSERT(!isStatementResultSet(), "CurrentOfNode not expected to be statement node");
/* Get the next ResultSet #, so that we can number this ResultSetNode, its
* ResultColumnList and ResultSet.
*/
assignResultSetNumber();
// for the putField
mb.pushThis();
// The generated java returned by this method is the expression:
// ResultSetFactory.getCurrentOfResultSet(
// #cursorName(), this, resultSetNumber)
acb.pushGetResultSetFactoryExpression(mb);
mb.push(cursorName);
acb.pushThisAsActivation(mb);
mb.push(getResultSetNumber());
mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getCurrentOfResultSet", ClassName.NoPutResultSet, 3);
mb.cast(ClassName.CursorResultSet);
// the current of scan generator is what we return
/* This table is the target of an update or a delete, so we must
* wrap the Expression up in an assignment expression before
* returning. Delete or update use the field that is set
* to calculate the CurrentRowLocation value.
* NOTE - scanExpress is a ResultSet. We will need to cast it to the
* appropriate subclass.
* For example, for a DELETE, instead of returning a call to the
* ResultSetFactory, we will generate and return:
* this.SCANRESULTSET = (cast to appropriate ResultSet type)
* The outer cast back to ResultSet is needed so that
* we invoke the appropriate method in the call to the ResultSetFactory
*/
mb.putField((String) null, acb.getRowLocationScanResultSetName(), ClassName.CursorResultSet);
mb.cast(ClassName.NoPutResultSet);
// add a check at activation reset time to see if the cursor has
// changed underneath us. Doing it in the constructor allows the
// compilation to happen
MethodBuilder rmb = acb.startResetMethod();
rmb.pushThis();
rmb.push(cursorName);
rmb.push(preStmt.getObjectName());
rmb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "checkPositionedStatement", "void", 2);
rmb.methodReturn();
rmb.complete();
}
use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.
the class CurrentRowLocationNode method generateExpression.
/**
* CurrentRowLocationNode is used in updates and deletes. See generate() in
* UpdateNode and DeleteNode to get the full overview of generate(). This
* class is responsible for generating the method that will return the RowLocation
* for the next row to be updated or deleted.
*
* This routine will generate a method of the form:
*
* private SQLRef fieldx;
*
* ...
*
* protected DataValueDescriptor exprx()
* throws StandardException
* {
* return fieldx = <SQLRefConstructor>(
* "result set member".getRowLocation(),
* fieldx);
* }
* and return the generated code:
* exprx()
*
* ("result set member" is a member of the generated class added by UpdateNode or
* DeleteNode.)
* This exprx function is used within another exprx function,
* and so doesn't need a static field or to be public; but
* at present, it has both.
*
* fieldx is a generated field that is initialized to null when the
* activation is constructed. getSQLRef will re-use fieldx on calls
* after the first call, rather than allocate a new SQLRef for each call.
*
* @param acb The ExpressionClassBuilder for the class being built
*
* @exception StandardException Thrown on error
*/
@Override
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mbex) throws StandardException {
/* Generate a new method */
/* only used within the other exprFuns, so can be private */
MethodBuilder mb = acb.newGeneratedFun(ClassName.DataValueDescriptor, Modifier.PROTECTED);
/* Allocate an object for re-use to hold the result of the operator */
LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.RefDataValue);
/* Fill in the body of the method
* generates:
* return TypeFactory.getSQLRef(this.ROWLOCATIONSCANRESULTSET.getRowLocation());
* and adds it to exprFun
*/
mb.pushThis();
mb.getField((String) null, acb.getRowLocationScanResultSetName(), ClassName.CursorResultSet);
mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getRowLocation", ClassName.RowLocation, 0);
acb.generateDataValue(mb, getTypeCompiler(), getTypeServices().getCollationType(), field);
/*
** Store the result of the method call in the field, so we can re-use
** the object.
*/
mb.putField(field);
/* Stuff the full expression into a return statement and add that to the
* body of the new method.
*/
mb.methodReturn();
// complete the method
mb.complete();
/* Generate the call to the new method */
mbex.pushThis();
mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), ClassName.DataValueDescriptor, 0);
}
use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.
the class ActivationClassBuilder method startResetMethod.
// /////////////////////////////////////////////////////////////////////
//
// EXECUTE METHODS
//
// /////////////////////////////////////////////////////////////////////
MethodBuilder startResetMethod() {
MethodBuilder mb = cb.newMethodBuilder(Modifier.PUBLIC, "void", "reset");
mb.addThrownException(ClassName.StandardException);
mb.pushThis();
mb.callMethod(VMOpcode.INVOKESPECIAL, ClassName.BaseActivation, "reset", "void", 0);
return mb;
}
use of org.apache.derby.iapi.services.compiler.MethodBuilder in project derby by apache.
the class ActivationClassBuilder method addCursorPositionCode.
// /////////////////////////////////////////////////////////////////////
//
// CURSOR SUPPORT
//
// /////////////////////////////////////////////////////////////////////
/**
* Updatable cursors
* need to add a getter method for use in BaseActivation to access
* the result set that identifies target rows for a positioned
* update or delete.
* <p>
* The code that is generated is:
* <pre><verbatim>
* public CursorResultSet getTargetResultSet() {
* return targetResultSet;
* }
*
* public CursorResultSet getCursorResultSet() {
* return cursorResultSet;
* }
* </verbatim></pre>
*/
void addCursorPositionCode() {
// the getter
// This method is an implementation of the interface method
// CursorActivation - CursorResultSet getTargetResultSet()
MethodBuilder getter = cb.newMethodBuilder(Modifier.PUBLIC, ClassName.CursorResultSet, "getTargetResultSet");
getter.getField(targetResultSetField);
getter.methodReturn();
getter.complete();
// This method is an implementation of the interface method
// CursorActivation - CursorResultSet getCursorResultSet()
getter = cb.newMethodBuilder(Modifier.PUBLIC, ClassName.CursorResultSet, "getCursorResultSet");
getter.getField(cursorResultSetField);
getter.methodReturn();
getter.complete();
}
Aggregations