Search in sources :

Example 11 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class GeneratedColumnsHelper method assertDeterministic.

/**
 * <p>
 * Assert whether a routine is expected to be DETERMINISTIC.
 * </p>
 */
public void assertDeterministic(Connection conn, String routineName, boolean isDeterministic) throws Exception {
    PreparedStatement ps = conn.prepareStatement("select a.aliasinfo\n" + "from sys.sysaliases a\n" + "where alias =  ?");
    ps.setString(1, routineName);
    ResultSet rs = ps.executeQuery();
    rs.next();
    RoutineAliasInfo rai = (RoutineAliasInfo) rs.getObject(1);
    assertEquals(isDeterministic, rai.isDeterministic());
    rs.close();
    ps.close();
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement)

Example 12 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class StaticMethodCallNode method resolveRoutine.

/**
 * Resolve a routine. Obtain a list of routines from the data dictionary
 * of the correct type (functions or procedures) and name.
 * Pick the best routine from the list. Currently only a single routine
 * with a given type and name is allowed, thus if changes are made to
 * support overloaded routines, careful code inspection and testing will
 * be required.
 */
private void resolveRoutine(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates, SchemaDescriptor sd, boolean noSchema) throws StandardException {
    if (sd.getUUID() != null) {
        List<AliasDescriptor> list = getDataDictionary().getRoutineList(sd.getUUID().toString(), methodName, forCallStatement ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR);
        for (int i = list.size() - 1; i >= 0; i--) {
            AliasDescriptor proc = list.get(i);
            RoutineAliasInfo rai = (RoutineAliasInfo) proc.getAliasInfo();
            int parameterCount = rai.getParameterCount();
            boolean hasVarargs = rai.hasVarargs();
            if (hasVarargs) {
                // for the trailing varargs argument
                if (methodParms.length < (parameterCount - 1)) {
                    continue;
                }
            } else if (parameterCount != methodParms.length) {
                continue;
            }
            // pre-form the method signature. If it is a dynamic result set procedure
            // then we need to add in the ResultSet array
            TypeDescriptor[] parameterTypes = rai.getParameterTypes();
            int sigParameterCount = parameterCount;
            if (rai.getMaxDynamicResultSets() > 0) {
                sigParameterCount++;
            }
            signature = new JSQLType[sigParameterCount];
            for (int p = 0; p < parameterCount; p++) {
                // find the declared type.
                TypeDescriptor td = parameterTypes[p];
                TypeId typeId = TypeId.getTypeId(td);
                TypeId parameterTypeId = typeId;
                // if it's an OUT or INOUT parameter we need an array.
                int parameterMode = rai.getParameterModes()[getRoutineArgIdx(rai, p)];
                if (parameterMode != (ParameterMetaData.parameterModeIn)) {
                    String arrayType;
                    switch(typeId.getJDBCTypeId()) {
                        case java.sql.Types.BOOLEAN:
                        case java.sql.Types.SMALLINT:
                        case java.sql.Types.INTEGER:
                        case java.sql.Types.BIGINT:
                        case java.sql.Types.REAL:
                        case java.sql.Types.DOUBLE:
                            arrayType = getTypeCompiler(typeId).getCorrespondingPrimitiveTypeName().concat("[]");
                            break;
                        default:
                            arrayType = typeId.getCorrespondingJavaTypeName().concat("[]");
                            break;
                    }
                    typeId = TypeId.getUserDefinedTypeId(arrayType);
                }
                // this is the type descriptor of the require method parameter
                DataTypeDescriptor methoddtd = new DataTypeDescriptor(typeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
                signature[p] = new JSQLType(methoddtd);
                // this is the SQL type of the procedure parameter.
                DataTypeDescriptor paramdtd = new DataTypeDescriptor(parameterTypeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
                // if this is the last argument of a varargs routine...
                if (hasVarargs && (p == parameterCount - 1)) {
                    // 
                    for (int idx = p; idx < methodParms.length; idx++) {
                        coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, idx);
                    }
                } else // NOT the last argument of a varargs routine
                {
                    coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, p);
                }
            }
            if (sigParameterCount != parameterCount) {
                DataTypeDescriptor dtd = new DataTypeDescriptor(TypeId.getUserDefinedTypeId("java.sql.ResultSet[]"), 0, 0, false, -1);
                signature[parameterCount] = new JSQLType(dtd);
            }
            this.routineInfo = rai;
            ad = proc;
            // SQL, note that we are in system code.
            if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL) {
                isSystemCode = true;
            }
            routineDefiner = sd.getAuthorizationId();
            break;
        }
    }
    if ((ad == null) && (methodParms.length == 1)) {
        ad = AggregateNode.resolveAggregate(getDataDictionary(), sd, methodName, noSchema);
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) JSQLType(org.apache.derby.iapi.types.JSQLType) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor)

Example 13 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class FromVTI method bindVTITables.

// end of getVTIName
/**
 * Bind this VTI that appears in the FROM list.
 *
 * @param fromListParam		FromList to use/append to.
 *
 * @return	ResultSetNode		The bound FromVTI.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ResultSetNode bindVTITables(FromList fromListParam) throws StandardException {
    ResultColumnList derivedRCL = getResultColumns();
    LanguageConnectionContext lcc = getLanguageConnectionContext();
    /* NOTE - setting of table number moved to FromList.bindTables()
		 * in order to avoid an ordering problem with join columns in
		 * parameters.
		 */
    /* Bind the constructor or static method - does basic error checking.
		 * Correlated subqueries are not allowed as parameters to
		 * a VTI, so pass an empty FromList.
		 */
    ArrayList<AggregateNode> aggregates = new ArrayList<AggregateNode>();
    methodCall.bindExpression(fromListParam, subqueryList, aggregates);
    // Is the parameter list to the constructor valid for a VTI?
    methodParms = methodCall.getMethodParms();
    RoutineAliasInfo routineInfo = methodCall.getRoutineInfo();
    if ((routineInfo != null) && routineInfo.getReturnType().isRowMultiSet() && (routineInfo.getParameterStyle() == RoutineAliasInfo.PS_DERBY_JDBC_RESULT_SET)) {
        isDerbyStyleTableFunction = true;
    }
    if (isDerbyStyleTableFunction) {
        Method boundMethod = (Method) methodCall.getResolvedMethod();
        isRestrictedTableFunction = RestrictedVTI.class.isAssignableFrom(boundMethod.getReturnType());
    }
    if (isConstructor()) {
        NewInvocationNode constructor = (NewInvocationNode) methodCall;
        if (!constructor.assignableTo("java.sql.PreparedStatement")) {
            if (version2) {
                throw StandardException.newException(SQLState.LANG_DOES_NOT_IMPLEMENT, getVTIName(), "java.sql.PreparedStatement");
            } else if (!constructor.assignableTo("java.sql.ResultSet")) {
                throw StandardException.newException(SQLState.LANG_DOES_NOT_IMPLEMENT, getVTIName(), "java.sql.ResultSet");
            }
        } else {
            version2 = true;
        }
        /* If this is a version 2 VTI */
        if (version2) {
            // Does it support predicates
            implementsPushable = constructor.assignableTo("org.apache.derby.vti.IQualifyable");
        }
        // Remember whether or not the VTI implements the VTICosting interface
        implementsVTICosting = constructor.assignableTo(ClassName.VTICosting);
    }
    if (isDerbyStyleTableFunction) {
        implementsVTICosting = implementsDerbyStyleVTICosting(methodCall.getJavaClassName());
    }
    /* Build the RCL for this VTI.  We instantiate an object in order
		 * to get the ResultSetMetaData.
		 * 
		 * If we have a special trigger vti, then we branch off and get
		 * its rcl from the trigger table that is waiting for us in
		 * the compiler context.
		 */
    UUID triggerTableId;
    if ((isConstructor()) && ((triggerTableId = getSpecialTriggerVTITableName(lcc, methodCall.getJavaClassName())) != null)) {
        TableDescriptor td = getDataDictionary().getTableDescriptor(triggerTableId);
        setResultColumns(genResultColList(td));
        // costing info
        vtiCosted = true;
        estimatedCost = 50d;
        estimatedRowCount = 5d;
        supportsMultipleInstantiations = true;
    } else {
        setResultColumns(new ResultColumnList((getContextManager())));
        if (isDerbyStyleTableFunction) {
            createResultColumnsForTableFunction(routineInfo.getReturnType());
        } else {
            ResultSetMetaData rsmd = getResultSetMetaData();
            /* Wouldn't it be nice if we knew that the class/object would never
			     * return a null ResultSetMetaData.
			     */
            if (rsmd == null) {
                throw StandardException.newException(SQLState.LANG_NULL_RESULT_SET_META_DATA, getVTIName());
            }
            // Remember how many columns VTI returns for partial row calculation
            try {
                numVTICols = rsmd.getColumnCount();
            } catch (SQLException sqle) {
                numVTICols = 0;
            }
            getResultColumns().createListFromResultSetMetaData(rsmd, exposedName, getVTIName());
        }
    }
    numVTICols = getResultColumns().size();
    /* Propagate the name info from the derived column list */
    if (derivedRCL != null) {
        getResultColumns().propagateDCLInfo(derivedRCL, correlationName);
    }
    return this;
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) RestrictedVTI(org.apache.derby.vti.RestrictedVTI) ResultSetMetaData(java.sql.ResultSetMetaData) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) UUID(org.apache.derby.catalog.UUID)

Example 14 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class DataDictionaryImpl method upgradeCLOBGETSUBSTRING_10_6.

/**
 * 10.6 upgrade logic to update the return type of SYSIBM.CLOBGETSUBSTRING. The length of the
 * return type was changed in 10.5 but old versions of the metadata were not
 * upgraded at that time. See DERBY-4214.
 */
void upgradeCLOBGETSUBSTRING_10_6(TransactionController tc) throws StandardException {
    TabInfoImpl ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
    ExecIndexRow keyRow = exFactory.getIndexableRow(3);
    DataValueDescriptor aliasNameOrderable = new SQLVarchar("CLOBGETSUBSTRING");
    DataValueDescriptor nameSpaceOrderable = new SQLChar(new String(new char[] { AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR }));
    keyRow.setColumn(1, new SQLChar(SchemaDescriptor.SYSIBM_SCHEMA_UUID));
    keyRow.setColumn(2, aliasNameOrderable);
    keyRow.setColumn(3, nameSpaceOrderable);
    AliasDescriptor oldAD = getDescriptorViaIndex(SYSALIASESRowFactory.SYSALIASES_INDEX1_ID, keyRow, (ScanQualifier[][]) null, ti, (TupleDescriptor) null, (List<TupleDescriptor>) null, AliasDescriptor.class, true, TransactionController.ISOLATION_REPEATABLE_READ, tc);
    RoutineAliasInfo oldRai = (RoutineAliasInfo) oldAD.getAliasInfo();
    TypeDescriptor newReturnType = DataTypeDescriptor.getCatalogType(Types.VARCHAR, Limits.MAX_CLOB_RETURN_LEN);
    RoutineAliasInfo newRai = new RoutineAliasInfo(oldRai.getMethodName(), oldRai.getParameterCount(), oldRai.getParameterNames(), oldRai.getParameterTypes(), oldRai.getParameterModes(), oldRai.getMaxDynamicResultSets(), oldRai.getParameterStyle(), oldRai.getSQLAllowed(), oldRai.isDeterministic(), oldRai.hasVarargs(), oldRai.hasDefinersRights(), oldRai.calledOnNullInput(), newReturnType);
    AliasDescriptor newAD = new AliasDescriptor(this, oldAD.getUUID(), oldAD.getObjectName(), oldAD.getSchemaUUID(), oldAD.getJavaClassName(), oldAD.getAliasType(), oldAD.getNameSpace(), oldAD.getSystemAlias(), newRai, oldAD.getSpecificName());
    ExecRow newRow = ti.getCatalogRowFactory().makeRow(newAD, null);
    ti.updateRow(keyRow, newRow, SYSALIASESRowFactory.SYSALIASES_INDEX1_ID, new boolean[] { false, false, false }, (int[]) null, tc);
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) TupleDescriptor(org.apache.derby.iapi.sql.dictionary.TupleDescriptor) SQLChar(org.apache.derby.iapi.types.SQLChar) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) SQLVarchar(org.apache.derby.iapi.types.SQLVarchar) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow)

Aggregations

RoutineAliasInfo (org.apache.derby.catalog.types.RoutineAliasInfo)14 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)9 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)6 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)4 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)4 ResultSet (java.sql.ResultSet)3 UUID (org.apache.derby.catalog.UUID)3 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)3 PreparedStatement (java.sql.PreparedStatement)2 ArrayList (java.util.ArrayList)2 AggregateAliasInfo (org.apache.derby.catalog.types.AggregateAliasInfo)2 SynonymAliasInfo (org.apache.derby.catalog.types.SynonymAliasInfo)2 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)2 TransactionController (org.apache.derby.iapi.store.access.TransactionController)2 SQLLongint (org.apache.derby.iapi.types.SQLLongint)2 TypeId (org.apache.derby.iapi.types.TypeId)2 Method (java.lang.reflect.Method)1 Connection (java.sql.Connection)1 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1