Search in sources :

Example 51 with DataTypeDescriptor

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

the class DMLWriteResultSet method normalizeRow.

/**
 * <p>
 * Normalize a row as part of the INSERT/UPDATE action of a MERGE statement.
 * This applies logic usually found in a NormalizeResultSet, which is missing for
 * the MERGE statement.
 * </p>
 * @param sourceResultSet        the result set for which this action is
 *                               to be performed
 * @param row                    the row to be normalized
 * @return                       the normalized row
 * @throws StandardException     Standard error policy
 */
protected ExecRow normalizeRow(NoPutResultSet sourceResultSet, ExecRow row) throws StandardException {
    // 
    // Make sure that the evaluated expressions fit in the base table row.
    // 
    int count = resultDescription.getColumnCount();
    if (cachedDestinations == null) {
        cachedDestinations = new DataValueDescriptor[count];
        for (int i = 0; i < count; i++) {
            int position = i + 1;
            ResultColumnDescriptor colDesc = resultDescription.getColumnDescriptor(position);
            cachedDestinations[i] = colDesc.getType().getNull();
        }
    }
    for (int i = 0; i < count; i++) {
        int position = i + 1;
        DataTypeDescriptor dtd = resultDescription.getColumnDescriptor(position).getType();
        if (row.getColumn(position) == null) {
            row.setColumn(position, dtd.getNull());
        }
        row.setColumn(position, NormalizeResultSet.normalizeColumn(dtd, row, position, cachedDestinations[i], resultDescription));
    }
    // put the row where expressions in constraints can access it
    activation.setCurrentRow(row, sourceResultSet.resultSetNumber());
    return row;
}
Also used : ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 52 with DataTypeDescriptor

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

the class DataFileVTI method getTypeSignature.

private DataTypeDescriptor[] getTypeSignature(Connection conn, String tableSignature) throws Exception {
    String createTable = "create table " + DUMMY_TABLE_NAME + tableSignature;
    String dropTable = "drop table " + DUMMY_TABLE_NAME;
    try {
        conn.prepareStatement(createTable).execute();
    } catch (SQLException se) {
        throw new Exception("Illegal table signature: " + tableSignature, se);
    }
    String select = "select c.columndatatype, c.columnnumber\n" + "from sys.syscolumns c, sys.systables t\n" + "where c.referenceid = t.tableid\n" + "and t.tablename = ?\n" + "order by c.columnnumber";
    PreparedStatement ps = conn.prepareStatement(select);
    ps.setString(1, DUMMY_TABLE_NAME.toUpperCase());
    ResultSet rs = ps.executeQuery();
    ArrayList<DataTypeDescriptor> list = new ArrayList<DataTypeDescriptor>();
    while (rs.next()) {
        list.add(DataTypeDescriptor.getType((TypeDescriptor) rs.getObject(1)));
    }
    rs.close();
    ps.close();
    DataTypeDescriptor[] result = new DataTypeDescriptor[list.size()];
    list.toArray(result);
    conn.prepareStatement(dropTable).execute();
    return result;
}
Also used : TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) SQLException(java.sql.SQLException) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) EOFException(java.io.EOFException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 53 with DataTypeDescriptor

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

the class QueryTreeNode method bindUserCatalogType.

/**
 * Bind user defined types as necessary
 */
public TypeDescriptor bindUserCatalogType(TypeDescriptor td) throws StandardException {
    // if this is a user defined type, resolve the Java class name
    if (!td.isUserDefinedType()) {
        return td;
    } else {
        DataTypeDescriptor dtd = DataTypeDescriptor.getType(td);
        dtd = bindUserType(dtd);
        return dtd.getCatalogType();
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 54 with DataTypeDescriptor

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

the class SpecialFunctionNode method bindExpression.

/**
 * Binding this special function means setting the result DataTypeServices.
 * In this case, the result type is based on the operation requested.
 *
 * @param fromList			The FROM list for the statement.  This parameter
 *							is not used in this case.
 * @param subqueryList		The subquery list being built as we find
 *							SubqueryNodes. Not used in this case.
 * @param aggregates        The aggregate list being built as we find
 *							AggregateNodes. Not used in this case.
 *
 * @return	The new top of the expression tree.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
    DataTypeDescriptor dtd;
    switch(kind) {
        case K_USER:
        case K_CURRENT_USER:
        case K_SYSTEM_USER:
            switch(kind) {
                case K_USER:
                    sqlName = "USER";
                    break;
                case K_CURRENT_USER:
                    sqlName = "CURRENT_USER";
                    break;
                case K_SYSTEM_USER:
                    sqlName = "SYSTEM_USER";
                    break;
            }
            methodName = "getCurrentUserId";
            methodType = "java.lang.String";
            // SQL spec Section 6.4 Syntax Rule 4 says that the collation type
            // of these functions will be the collation of character set
            // SQL_IDENTIFIER. In Derby's case, that will mean, the collation of
            // these functions will be UCS_BASIC. The collation derivation will
            // be implicit.
            dtd = DataDictionary.TYPE_SYSTEM_IDENTIFIER;
            break;
        case K_SESSION_USER:
            methodName = "getSessionUserId";
            methodType = "java.lang.String";
            sqlName = "SESSION_USER";
            dtd = DataDictionary.TYPE_SYSTEM_IDENTIFIER;
            break;
        case K_CURRENT_SCHEMA:
            sqlName = "CURRENT SCHEMA";
            methodName = "getCurrentSchemaName";
            methodType = "java.lang.String";
            // This is a Derby specific function but its collation type will
            // be based on the same rules as for SESSION_USER/CURRENT_USER etc.
            // ie there collation type will be UCS_BASIC. The collation
            // derivation will be implicit.
            dtd = DataDictionary.TYPE_SYSTEM_IDENTIFIER;
            break;
        case K_CURRENT_ROLE:
            sqlName = "CURRENT_ROLE";
            methodName = "getCurrentRoleIdDelimited";
            methodType = "java.lang.String";
            dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(// escapes
            Types.VARCHAR, true, 2 + (2 * 128));
            // be implicit. (set by default)
            break;
        case K_IDENTITY_VAL:
            sqlName = "IDENTITY_VAL_LOCAL";
            methodName = "getIdentityValue";
            methodType = "java.lang.Long";
            dtd = DataTypeDescriptor.getSQLDataTypeDescriptor("java.math.BigDecimal", 31, 0, true, 31);
            break;
        case K_CURRENT_ISOLATION:
            sqlName = "CURRENT ISOLATION";
            methodName = "getCurrentIsolationLevelStr";
            methodType = "java.lang.String";
            dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 2);
            // derivation will be implicit. (set by default).
            break;
        default:
            if (SanityManager.DEBUG) {
                SanityManager.THROWASSERT("Invalid type for SpecialFunctionNode " + kind);
            }
            dtd = null;
            break;
    }
    checkReliability(sqlName, CompilerContext.USER_ILLEGAL);
    setType(dtd);
    return this;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 55 with DataTypeDescriptor

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

the class StaticMethodCallNode method generateExpression.

/**
 * Do code generation for this method call
 *
 * @param acb	The ExpressionClassBuilder for the class we're generating
 * @param mb	The method the expression will go into
 *
 * @exception StandardException		Thrown on error
 */
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    if (routineInfo != null) {
        if (!routineInfo.calledOnNullInput() && routineInfo.getParameterCount() != 0)
            returnsNullOnNullState = acb.newFieldDeclaration(Modifier.PRIVATE, "boolean");
    }
    // reset the parameters are null indicator.
    if (returnsNullOnNullState != null) {
        mb.push(false);
        mb.setField(returnsNullOnNullState);
        // for the call to the generated method below.
        mb.pushThis();
    }
    int nargs = generateParameters(acb, mb);
    LocalField functionEntrySQLAllowed = null;
    if (routineInfo != null) {
        short sqlAllowed = routineInfo.getSQLAllowed();
        if (sqlAllowed != RoutineAliasInfo.NO_SQL) {
            int sqlOperation;
            if (sqlAllowed == RoutineAliasInfo.READS_SQL_DATA)
                sqlOperation = Authorizer.SQL_SELECT_OP;
            else if (sqlAllowed == RoutineAliasInfo.MODIFIES_SQL_DATA)
                sqlOperation = Authorizer.SQL_WRITE_OP;
            else
                sqlOperation = Authorizer.SQL_ARBITARY_OP;
            generateAuthorizeCheck((ActivationClassBuilder) acb, mb, sqlOperation);
        }
        int statmentContextReferences = isSystemCode ? 2 : 1;
        boolean isFunction = routineInfo.getReturnType() != null;
        if (isFunction)
            statmentContextReferences++;
        if (statmentContextReferences != 0) {
            acb.pushThisAsActivation(mb);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
            for (int scc = 1; scc < statmentContextReferences; scc++) mb.dup();
        }
        /**
         *				Set the statement context to reflect we are running
         *				System procedures, so that we can execute non-standard SQL.
         */
        if (isSystemCode) {
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setSystemCode", "void", 0);
        }
        // context.
        if (sqlAllowed != RoutineAliasInfo.NO_SQL) {
            generatePushNestedSessionContext((ActivationClassBuilder) acb, mb, routineInfo.hasDefinersRights(), routineDefiner);
        }
        // 
        if (isFunction) {
            functionEntrySQLAllowed = acb.newFieldDeclaration(Modifier.PRIVATE, "short");
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getSQLAllowed", "short", 0);
            mb.setField(functionEntrySQLAllowed);
        }
        // Set up the statement context to reflect the
        // restricted SQL execution allowed by this routine.
        mb.push(sqlAllowed);
        mb.push(false);
        mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setSQLAllowed", "void", 2);
    }
    // a routine may make use of both varargs and dynamic ResultSets.
    if (routineInfo != null && !hasVarargs()) {
        int compiledResultSets = methodParameterTypes.length - methodParms.length;
        if (compiledResultSets != 0) {
            // Add a method that indicates the maxium number of dynamic result sets.
            int maxDynamicResults = routineInfo.getMaxDynamicResultSets();
            if (maxDynamicResults > 0) {
                MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "int", "getMaxDynamicResults");
                gdr.push(maxDynamicResults);
                gdr.methodReturn();
                gdr.complete();
            }
            // add a method to return all the dynamic result sets (unordered)
            MethodBuilder gdr = acb.getClassBuilder().newMethodBuilder(Modifier.PUBLIC, "java.sql.ResultSet[][]", "getDynamicResults");
            MethodBuilder cons = acb.getConstructor();
            // if (procDef.getParameterStyle() == RoutineAliasInfo.PS_JAVA)
            {
                // PARAMETER STYLE JAVA
                LocalField procedureResultSetsHolder = acb.newFieldDeclaration(Modifier.PRIVATE, "java.sql.ResultSet[][]");
                // getDynamicResults body
                gdr.getField(procedureResultSetsHolder);
                // create the holder of all the ResultSet arrays, new java.sql.ResultSet[][compiledResultSets]
                cons.pushNewArray("java.sql.ResultSet[]", compiledResultSets);
                cons.setField(procedureResultSetsHolder);
                // arguments for the dynamic result sets
                for (int i = 0; i < compiledResultSets; i++) {
                    mb.pushNewArray("java.sql.ResultSet", 1);
                    mb.dup();
                    mb.getField(procedureResultSetsHolder);
                    mb.swap();
                    mb.setArrayElement(i);
                }
            }
            // complete the method that returns the ResultSet[][] to the
            gdr.methodReturn();
            gdr.complete();
            nargs += compiledResultSets;
        }
    }
    String javaReturnType = getJavaTypeName();
    MethodBuilder mbnc = null;
    MethodBuilder mbcm = mb;
    // do not call the method, just return null.
    if (returnsNullOnNullState != null) {
        mbnc = acb.newGeneratedFun(javaReturnType, Modifier.PRIVATE, methodParameterTypes);
        // add the throws clause for the public static method we are going to call.
        Class[] throwsSet = ((java.lang.reflect.Method) method).getExceptionTypes();
        for (int te = 0; te < throwsSet.length; te++) {
            mbnc.addThrownException(throwsSet[te].getName());
        }
        mbnc.getField(returnsNullOnNullState);
        mbnc.conditionalIf();
        // set up for a null!!
        // for objects is easy.
        mbnc.pushNull(javaReturnType);
        mbnc.startElseCode();
        if (!actualMethodReturnType.equals(javaReturnType))
            mbnc.pushNewStart(javaReturnType);
        // fetch all the arguments
        for (int pa = 0; pa < nargs; pa++) {
            mbnc.getParameter(pa);
        }
        mbcm = mbnc;
    }
    mbcm.callMethod(VMOpcode.INVOKESTATIC, method.getDeclaringClass().getName(), methodName, actualMethodReturnType, nargs);
    if (returnsNullOnNullState != null) {
        // compatible with their function return types.
        if (!actualMethodReturnType.equals(javaReturnType)) {
            if (actualMethodReturnType.equals("short") && javaReturnType.equals("java.lang.Integer"))
                mbnc.upCast("int");
            mbnc.pushNewComplete(1);
        }
        mbnc.completeConditional();
        mbnc.methodReturn();
        mbnc.complete();
        // now call the wrapper method
        mb.callMethod(VMOpcode.INVOKEVIRTUAL, acb.getClassBuilder().getFullName(), mbnc.getName(), javaReturnType, nargs);
        mbnc = null;
    }
    if (routineInfo != null) {
        // entry to the method.
        if (functionEntrySQLAllowed != null) {
            acb.pushThisAsActivation(mb);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext", 0);
            mb.getField(functionEntrySQLAllowed);
            // override as we are ending the control set by this function all.
            mb.push(true);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setSQLAllowed", "void", 2);
        }
        if (outParamArrays != null) {
            MethodBuilder constructor = acb.getConstructor();
            // constructor  - setting up correct parameter type info
            acb.pushThisAsActivation(constructor);
            constructor.callMethod(VMOpcode.INVOKEINTERFACE, null, "getParameterValueSet", ClassName.ParameterValueSet, 0);
            // execute  - passing out parameters back.
            acb.pushThisAsActivation(mb);
            mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getParameterValueSet", ClassName.ParameterValueSet, 0);
            int[] parameterModes = routineInfo.getParameterModes();
            for (int i = 0; i < outParamArrays.length; i++) {
                int parameterMode = parameterModes[getRoutineArgIdx(i)];
                if (parameterMode != (ParameterMetaData.parameterModeIn)) {
                    // must be a parameter if it is INOUT or OUT.
                    ValueNode sqlParamNode = ((SQLToJavaValueNode) methodParms[i]).getSQLValueNode();
                    int applicationParameterNumber = applicationParameterNumbers[i];
                    // Set the correct parameter nodes in the ParameterValueSet at constructor time.
                    constructor.dup();
                    constructor.push(applicationParameterNumber);
                    constructor.push(parameterMode);
                    constructor.callMethod(VMOpcode.INVOKEINTERFACE, null, "setParameterMode", "void", 2);
                    // Pass the value of the outparameters back to the calling code
                    LocalField lf = outParamArrays[i];
                    mb.dup();
                    mb.push(applicationParameterNumber);
                    mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getParameter", ClassName.DataValueDescriptor, 1);
                    // see if we need to set the desired length/scale/precision of the type
                    DataTypeDescriptor paramdtd = sqlParamNode.getTypeServices();
                    boolean isNumericType = paramdtd.getTypeId().isNumericTypeId();
                    boolean isAnsiUDT = paramdtd.getTypeId().getBaseTypeId().isAnsiUDT();
                    // is the underlying type for the OUT/INOUT parameter primitive.
                    // if this is a varargs arg then we have to strip off another array level
                    Class<?> cellType = ((Method) method).getParameterTypes()[getRoutineArgIdx(i)].getComponentType();
                    if (isVararg(i)) {
                        cellType = cellType.getComponentType();
                    }
                    boolean isPrimitive = cellType.isPrimitive();
                    if (isNumericType) {
                        if (!isPrimitive)
                            mb.cast(ClassName.NumberDataValue);
                    } else if (paramdtd.getTypeId().isBooleanTypeId()) {
                        // need to cast as the setValue(Boolean) method only exists on BooleanDataValue
                        if (!isPrimitive)
                            mb.cast(ClassName.BooleanDataValue);
                    }
                    if (paramdtd.getTypeId().variableLength()) {
                        // need another DVD reference for the set width below.
                        mb.dup();
                    }
                    // pvs, dvd, array
                    mb.getField(lf);
                    // pvs, dvd, value
                    mb.getArrayElement(0);
                    // The value needs to be set thorugh the setValue(Number) method.
                    if (isNumericType && !isPrimitive) {
                        mb.upCast("java.lang.Number");
                    }
                    // The value needs to be set thorugh the setValue(Object) method.
                    if (isAnsiUDT) {
                        mb.upCast("java.lang.Object");
                    }
                    mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "setValue", "void", 1);
                    if (paramdtd.getTypeId().variableLength()) {
                        mb.push(isNumericType ? paramdtd.getPrecision() : paramdtd.getMaximumWidth());
                        mb.push(paramdtd.getScale());
                        mb.push(isNumericType);
                        mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", "void", 3);
                    // mb.endStatement();
                    }
                }
            }
            constructor.endStatement();
            mb.endStatement();
        }
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) Method(java.lang.reflect.Method) LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Aggregations

DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)99 TypeId (org.apache.derby.iapi.types.TypeId)32 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)14 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)14 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)9 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)8 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)8 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)7 UUID (org.apache.derby.catalog.UUID)5 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)5 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)5 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)5 StandardException (org.apache.derby.shared.common.error.StandardException)5 Properties (java.util.Properties)4 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)4 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)4 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)3 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)3 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)3 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)3