Search in sources :

Example 51 with TypeId

use of org.apache.derby.iapi.types.TypeId in project derby by apache.

the class MethodCallNode method getPrimitiveSignature.

String[] getPrimitiveSignature(boolean castToPrimitiveAsNecessary) throws StandardException {
    int count = signature.length;
    String[] primParmTypeNames = new String[count];
    JSQLType jsqlTyp;
    for (int i = 0; i < count; i++) {
        jsqlTyp = signature[i];
        if (jsqlTyp == null) {
            primParmTypeNames[i] = "";
        } else {
            switch(jsqlTyp.getCategory()) {
                case JSQLType.SQLTYPE:
                    if ((procedurePrimitiveArrayType != null) && (i < procedurePrimitiveArrayType.length) && (procedurePrimitiveArrayType[i] != null)) {
                        primParmTypeNames[i] = procedurePrimitiveArrayType[i];
                    } else {
                        TypeId ctid = mapToTypeID(jsqlTyp);
                        if ((ctid.isNumericTypeId() && !ctid.isDecimalTypeId()) || ctid.isBooleanTypeId()) {
                            TypeCompiler tc = getTypeCompiler(ctid);
                            primParmTypeNames[i] = tc.getCorrespondingPrimitiveTypeName();
                            if (castToPrimitiveAsNecessary) {
                                methodParms[i].castToPrimitive(true);
                            }
                        } else {
                            primParmTypeNames[i] = ctid.getCorrespondingJavaTypeName();
                        }
                    }
                    break;
                case JSQLType.JAVA_CLASS:
                    primParmTypeNames[i] = jsqlTyp.getJavaClassName();
                    break;
                case JSQLType.JAVA_PRIMITIVE:
                    primParmTypeNames[i] = JSQLType.getPrimitiveName(jsqlTyp.getPrimitiveKind());
                    if (castToPrimitiveAsNecessary) {
                        methodParms[i].castToPrimitive(true);
                    }
                    break;
                default:
                    if (SanityManager.DEBUG) {
                        SanityManager.THROWASSERT("Unknown JSQLType: " + jsqlTyp);
                    }
            }
        // end switch
        }
    // end if
    }
    return primParmTypeNames;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) JSQLType(org.apache.derby.iapi.types.JSQLType) TypeCompiler(org.apache.derby.iapi.sql.compile.TypeCompiler)

Example 52 with TypeId

use of org.apache.derby.iapi.types.TypeId in project derby by apache.

the class JavaToSQLValueNode method generateExpression.

/**
 * Do code generation for this conversion of a value from the Java to
 * the SQL domain.
 *
 * @param acb	The ExpressionClassBuilder for the class we're generating
 * @param mb the method  the expression will go into
 *
 * @exception StandardException		Thrown on error
 */
@Override
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    TypeId resultType;
    String resultTypeName;
    /*
		** Tell the Java node that it's value is being returned to the
		** SQL domain.  This way, it knows whether the checking for a null
		** receiver is to be done at the Java level or the SQL level.
		*/
    javaNode.returnValueToSQLDomain();
    /* Generate the receiver, if any. */
    boolean hasReceiver = javaNode.generateReceiver(acb, mb);
    /*
		** If the java expression has a receiver, we want to check whether
		** it's null before evaluating the whole expression (to avoid
		** a NullPointerException.
		*/
    if (hasReceiver) {
        /*
			** There is a receiver.  Generate a null SQL value to return
			** in case the receiver is null.  First, create a field to hold
			** the null SQL value.
			*/
        String nullValueClass = getTypeCompiler().interfaceName();
        LocalField nullValueField = acb.newFieldDeclaration(Modifier.PRIVATE, nullValueClass);
        /*
			** There is a receiver.  Generate the following to test
			** for null:
			**
			**		(receiverExpression == null) ? 
			*/
        mb.conditionalIfNull();
        mb.getField(nullValueField);
        acb.generateNullWithExpress(mb, getTypeCompiler(), getTypeServices().getCollationType());
        /*
			** We have now generated the expression to test, and the
			** "true" side of the ?: operator.  Finish the "true" side
			** so we can generate the "false" side.
			*/
        mb.startElseCode();
    }
    resultType = getTypeId();
    TypeCompiler tc = getTypeCompiler();
    resultTypeName = tc.interfaceName();
    /* Allocate an object for re-use to hold the result of the conversion */
    LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
    /* Generate the expression for the Java value under us */
    javaNode.generateExpression(acb, mb);
    /* Generate the SQL value, which is always nullable */
    acb.generateDataValue(mb, tc, getTypeServices().getCollationType(), field);
    /*
		** If there was a receiver, the return value will be the result
		** of the ?: operator.
		*/
    if (hasReceiver) {
        mb.completeConditional();
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) TypeCompiler(org.apache.derby.iapi.sql.compile.TypeCompiler) LocalField(org.apache.derby.iapi.services.compiler.LocalField)

Example 53 with TypeId

use of org.apache.derby.iapi.types.TypeId in project derby by apache.

the class DataDictionaryImpl method genColumnReferenceSQL.

/*
	** Make sure the given column name is found in the trigger
	** target table.  Generate the appropriate SQL to get it.
	**
	** @return a string that is used to get the column using
	** getObject() on the desired result set and CAST it back
	** to the proper type in the SQL domain. 
	**
	** @exception StandardException on invalid column name
	*/
private String genColumnReferenceSQL(TableDescriptor td, String colName, String tabName, boolean isOldTable, int colPositionInRuntimeResultSet) throws StandardException {
    ColumnDescriptor colDesc = null;
    if ((colDesc = td.getColumnDescriptor(colName)) == null) {
        throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND, tabName + "." + colName);
    }
    /*
		** Generate something like this:
		**
		** 		CAST (org.apache.derby.iapi.db.Factory::
		**			getTriggerExecutionContext().getNewRow().
		**				getObject(<colPosition>) AS DECIMAL(6,2))
	    **
	    ** Column position is used to avoid the wrong column being
	    ** selected problem (DERBY-1258) caused by the case insensitive
	    ** JDBC rules for fetching a column by name.
		**
		** The cast back to the SQL Domain may seem redundant
		** but we need it to make the column reference appear
		** EXACTLY like a regular column reference, so we need
		** the object in the SQL Domain and we need to have the
		** type information.  Thus a user should be able to do 
		** something like
		**
		**		CREATE TRIGGER ... INSERT INTO T length(Column), ...
	    **
	    */
    DataTypeDescriptor dts = colDesc.getType();
    TypeId typeId = dts.getTypeId();
    if (!typeId.isXMLTypeId()) {
        StringBuffer methodCall = new StringBuffer();
        methodCall.append("CAST (org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().");
        methodCall.append(isOldTable ? "getOldRow()" : "getNewRow()");
        methodCall.append(".getObject(");
        methodCall.append(colPositionInRuntimeResultSet);
        methodCall.append(") AS ");
        /*
	        ** getSQLString() returns <typeName> 
	        ** for user types, so call getSQLTypeName in that
	        ** case.
	        */
        methodCall.append((typeId.userType() ? typeId.getSQLTypeName() : dts.getSQLstring()));
        methodCall.append(") ");
        return methodCall.toString();
    } else {
        /*  DERBY-2350
	        **
	        **  Triggers currently use jdbc 1.2 to access columns.  The default
	        **  uses getObject() which is not supported for an XML type until
	        **  jdbc 4.  In the meantime use getString() and then call 
	        **  XMLPARSE() on the string to get the type.  See Derby issue and
	        **  http://wiki.apache.org/db-derby/TriggerImplementation , for
	        **  better long term solutions.  Long term I think changing the
	        **  trigger architecture to not rely on jdbc, but instead on an
	        **  internal direct access interface to execution nodes would be
	        **  best future direction, but believe such a change appropriate
	        **  for a major release, not a bug fix.
	        **
	        **  Rather than the above described code generation, use the 
	        **  following for XML types to generate an XML column from the
	        **  old or new row.
	        ** 
	        **          XMLPARSE(DOCUMENT
	        **              CAST (org.apache.derby.iapi.db.Factory::
	        **                  getTriggerExecutionContext().getNewRow().
	        **                      getString(<colPosition>) AS CLOB)  
	        **                        PRESERVE WHITESPACE)
	        */
        StringBuffer methodCall = new StringBuffer();
        methodCall.append("XMLPARSE(DOCUMENT CAST( ");
        methodCall.append("org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().");
        methodCall.append(isOldTable ? "getOldRow()" : "getNewRow()");
        methodCall.append(".getString(");
        methodCall.append(colPositionInRuntimeResultSet);
        methodCall.append(") AS CLOB) PRESERVE WHITESPACE ) ");
        return methodCall.toString();
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)

Aggregations

TypeId (org.apache.derby.iapi.types.TypeId)53 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)32 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)8 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)6 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)4 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)3 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)3 StandardException (org.apache.derby.shared.common.error.StandardException)3 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)2 DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)2 RoutineAliasInfo (org.apache.derby.catalog.types.RoutineAliasInfo)2 ClassInspector (org.apache.derby.iapi.services.loader.ClassInspector)2 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)2 ProviderList (org.apache.derby.iapi.sql.depend.ProviderList)2 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)2 JSQLType (org.apache.derby.iapi.types.JSQLType)2 ResultSet (java.sql.ResultSet)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Properties (java.util.Properties)1