Search in sources :

Example 6 with RoutineAliasInfo

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

the class DDLConstantAction method adjustUDTDependencies.

/**
 * Add and drop dependencies of a routine on UDTs.
 *
 * @param lcc Interpreter's state variable for this session.
 * @param dd Metadata
 * @param ad Alias descriptor for the routine
 * @param adding True if we are adding dependencies, false if we're dropping them
 */
protected void adjustUDTDependencies(LanguageConnectionContext lcc, DataDictionary dd, AliasDescriptor ad, boolean adding) throws StandardException {
    RoutineAliasInfo routineInfo = null;
    AggregateAliasInfo aggInfo = null;
    // nothing to do if this is not a routine
    switch(ad.getAliasType()) {
        case AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR:
            aggInfo = (AggregateAliasInfo) ad.getAliasInfo();
            break;
        case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
        case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
            routineInfo = (RoutineAliasInfo) ad.getAliasInfo();
            break;
        default:
            return;
    }
    TransactionController tc = lcc.getTransactionExecute();
    HashMap<String, AliasDescriptor> addUdtMap = new HashMap<String, AliasDescriptor>();
    HashMap<String, AliasDescriptor> dropUdtMap = new HashMap<String, AliasDescriptor>();
    HashMap<String, AliasDescriptor> udtMap = adding ? addUdtMap : dropUdtMap;
    TypeDescriptor rawReturnType = aggInfo != null ? aggInfo.getReturnType() : routineInfo.getReturnType();
    if (rawReturnType != null) {
        AliasDescriptor returnTypeAD = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(rawReturnType));
        if (returnTypeAD != null) {
            udtMap.put(returnTypeAD.getObjectID().toString(), returnTypeAD);
        }
    }
    // table functions can have udt columns. track those dependencies.
    if ((rawReturnType != null) && rawReturnType.isRowMultiSet()) {
        TypeDescriptor[] columnTypes = rawReturnType.getRowTypes();
        int columnCount = columnTypes.length;
        for (int i = 0; i < columnCount; i++) {
            AliasDescriptor columnTypeAD = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(columnTypes[i]));
            if (columnTypeAD != null) {
                udtMap.put(columnTypeAD.getObjectID().toString(), columnTypeAD);
            }
        }
    }
    TypeDescriptor[] paramTypes = aggInfo != null ? new TypeDescriptor[] { aggInfo.getForType() } : routineInfo.getParameterTypes();
    if (paramTypes != null) {
        int paramCount = paramTypes.length;
        for (int i = 0; i < paramCount; i++) {
            AliasDescriptor paramType = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(paramTypes[i]));
            if (paramType != null) {
                udtMap.put(paramType.getObjectID().toString(), paramType);
            }
        }
    }
    adjustUDTDependencies(lcc, dd, ad, addUdtMap, dropUdtMap);
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) HashMap(java.util.HashMap) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) AggregateAliasInfo(org.apache.derby.catalog.types.AggregateAliasInfo) TransactionController(org.apache.derby.iapi.store.access.TransactionController)

Example 7 with RoutineAliasInfo

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

the class GeneratedColumnsTest method test_001_determinism_of_stored_system_routines.

/**
 * <p>
 * Test that the stored system procedures and functions are non-deterministic. If you want
 * a particular procedure/function to be deterministic, add some logic here.
 * </p>
 *
 * <p>
 * Also test that, by default, user-defined routines are created as NOT DETERMINISTIC.
 * </p>
 */
public void test_001_determinism_of_stored_system_routines() throws Exception {
    Connection conn = getConnection();
    // 
    // Create a user-defined function and procedure and verify
    // that they too are NOT DETERMINISTIC.
    // 
    PreparedStatement functionCreate = conn.prepareStatement("create function f1()\n" + "returns int\n" + "language java\n" + "parameter style java\n" + "no sql\n" + "external name 'foo.bar.wibble'\n");
    functionCreate.execute();
    functionCreate.close();
    PreparedStatement procedureCreate = conn.prepareStatement("create procedure p1()\n" + "language java\n" + "parameter style java\n" + "modifies sql data\n" + "external name 'foo.bar.wibble'\n");
    procedureCreate.execute();
    procedureCreate.close();
    // 
    // OK, now verify that all routines in the catalogs are NOT DETERMINISTIC
    // 
    PreparedStatement ps = conn.prepareStatement("select s.schemaname, a.alias, a.aliastype, a.systemalias, a.aliasinfo\n" + "from sys.sysschemas s, sys.sysaliases a\n" + "where s.schemaid = a.schemaid\n" + "order by s.schemaname, a.alias\n");
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
        String aliasName = rs.getString(2);
        boolean isSystemAlias = rs.getBoolean(4);
        RoutineAliasInfo rai = (RoutineAliasInfo) rs.getObject(5);
        if (isSystemAlias) {
            assertFalse(aliasName, rai.isDeterministic());
        }
    }
    rs.close();
    ps.close();
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement)

Example 8 with RoutineAliasInfo

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

the class Changes10_6 method testCLOBGETSUBSTRING.

/**
 * Make sure that SYSIBM.CLOBGETSUBSTRING has the correct return value.
 * See https://issues.apache.org/jira/browse/DERBY-4214
 */
public void testCLOBGETSUBSTRING() throws Exception {
    Version initialVersion = new Version(getOldMajor(), getOldMinor(), 0, 0);
    Version firstVersionHavingThisFunction = new Version(10, 3, 0, 0);
    Version firstVersionHavingCorrectReturnType = new Version(10, 5, 0, 0);
    int wrongLength = 32672;
    int correctLength = 10890;
    int actualJdbcType;
    int actualLength;
    Object returnType;
    boolean hasFunction = initialVersion.compareTo(firstVersionHavingThisFunction) >= 0;
    boolean hasCorrectReturnType = initialVersion.compareTo(firstVersionHavingCorrectReturnType) >= 0;
    Statement s = createStatement();
    ResultSet rs = s.executeQuery("select a.aliasinfo\n" + "from sys.sysschemas s, sys.sysaliases a\n" + "where s.schemaid = a.schemaid\n" + "and s.schemaname = 'SYSIBM'\n" + "and alias = 'CLOBGETSUBSTRING'\n");
    rs.next();
    switch(getPhase()) {
        case PH_CREATE:
        case PH_SOFT_UPGRADE:
        case PH_POST_SOFT_UPGRADE:
            if (!hasFunction) {
                break;
            }
            returnType = getTypeDescriptor(rs.getObject(1));
            actualJdbcType = getJDBCTypeId(returnType);
            actualLength = getMaximumWidth(returnType);
            int expectedLength = hasCorrectReturnType ? correctLength : wrongLength;
            assertEquals(java.sql.Types.VARCHAR, actualJdbcType);
            assertEquals(expectedLength, actualLength);
            break;
        case PH_HARD_UPGRADE:
            RoutineAliasInfo rai = (RoutineAliasInfo) rs.getObject(1);
            TypeDescriptor td = (TypeDescriptor) rai.getReturnType();
            assertEquals(java.sql.Types.VARCHAR, td.getJDBCTypeId());
            assertEquals(correctLength, td.getMaximumWidth());
            break;
    }
    rs.close();
    s.close();
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet)

Example 9 with RoutineAliasInfo

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

the class CreateAliasConstantAction method vetRoutine.

/**
 * Common checks to be performed for functions and procedures
 */
private void vetRoutine(DataDictionary dd, SchemaDescriptor sd, AliasDescriptor ads) throws StandardException {
    List<AliasDescriptor> list = dd.getRoutineList(sd.getUUID().toString(), aliasName, aliasType);
    for (int i = list.size() - 1; i >= 0; i--) {
        AliasDescriptor proc = list.get(i);
        RoutineAliasInfo procedureInfo = (RoutineAliasInfo) proc.getAliasInfo();
        int parameterCount = procedureInfo.getParameterCount();
        if (parameterCount != ((RoutineAliasInfo) aliasInfo).getParameterCount()) {
            continue;
        }
        // one procedure with a given number of parameters.
        throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
    }
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor)

Example 10 with RoutineAliasInfo

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

the class CreateAliasConstantAction method executeConstantAction.

// INTERFACE METHODS
/**
 *	This is the guts of the Execution-time logic for
 *  CREATE FUNCTION, PROCEDURE, SYNONYM, and TYPE.
 *  <P>
 *  A function, procedure, or udt is represented as:
 *  <UL>
 *  <LI> AliasDescriptor
 *  </UL>
 *  Routine dependencies are created as:
 *  <UL>
 *  <LI> None
 *  </UL>
 *
 *  <P>
 *  A synonym is represented as:
 *  <UL>
 *  <LI> AliasDescriptor
 *  <LI> TableDescriptor
 *  </UL>
 *  Synonym dependencies are created as:
 *  <UL>
 *  <LI> None
 *  </UL>
 *
 *  In both cases a SchemaDescriptor will be created if
 *  needed. No dependency is created on the SchemaDescriptor.
 *
 * @see ConstantAction#executeConstantAction
 * @see AliasDescriptor
 * @see TableDescriptor
 * @see SchemaDescriptor
 *
 * @exception StandardException		Thrown on failure
 */
public void executeConstantAction(Activation activation) throws StandardException {
    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    DataDictionary dd = lcc.getDataDictionary();
    TransactionController tc = lcc.getTransactionExecute();
    // For routines no validity checking is made
    // on the Java method, that is checked when the
    // routine is executed.
    /*
		** Inform the data dictionary that we are about to write to it.
		** There are several calls to data dictionary "get" methods here
		** that might be done in "read" mode in the data dictionary, but
		** it seemed safer to do this whole operation in "write" mode.
		**
		** We tell the data dictionary we're done writing at the end of
		** the transaction.
		*/
    dd.startWriting(lcc);
    SchemaDescriptor sd = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, schemaName);
    // 
    // Create a new alias descriptor with aliasID filled in.
    // 
    UUID aliasID = dd.getUUIDFactory().createUUID();
    AliasDescriptor ads = new AliasDescriptor(dd, aliasID, aliasName, sd.getUUID(), javaClassName, aliasType, nameSpace, false, aliasInfo, null);
    // perform duplicate rule checking
    switch(aliasType) {
        case AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR:
            AliasDescriptor duplicateAlias = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
            if (duplicateAlias != null) {
                throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
            }
            // also don't want to collide with 1-arg functions by the same name
            List<AliasDescriptor> funcList = dd.getRoutineList(sd.getUUID().toString(), aliasName, AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR);
            for (int i = 0; i < funcList.size(); i++) {
                AliasDescriptor func = funcList.get(i);
                RoutineAliasInfo funcInfo = (RoutineAliasInfo) func.getAliasInfo();
                if (funcInfo.getParameterCount() == 1) {
                    throw StandardException.newException(SQLState.LANG_BAD_UDA_OR_FUNCTION_NAME, schemaName, aliasName);
                }
            }
            break;
        case AliasInfo.ALIAS_TYPE_UDT_AS_CHAR:
            AliasDescriptor duplicateUDT = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
            if (duplicateUDT != null) {
                throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
            }
            break;
        case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
            vetRoutine(dd, sd, ads);
            break;
        case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
            vetRoutine(dd, sd, ads);
            // if this is a 1-arg function, make sure there isn't an aggregate
            // by the same qualified name
            int paramCount = ((RoutineAliasInfo) aliasInfo).getParameterCount();
            if (paramCount == 1) {
                AliasDescriptor aliasCollision = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR);
                if (aliasCollision != null) {
                    throw StandardException.newException(SQLState.LANG_BAD_UDA_OR_FUNCTION_NAME, schemaName, aliasName);
                }
            }
            break;
        case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
            // If target table/view exists already, error.
            TableDescriptor targetTD = dd.getTableDescriptor(aliasName, sd, tc);
            if (targetTD != null) {
                throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, targetTD.getDescriptorType(), targetTD.getDescriptorName());
            }
            // Detect synonym cycles, if present.
            String nextSynTable = ((SynonymAliasInfo) aliasInfo).getSynonymTable();
            String nextSynSchema = ((SynonymAliasInfo) aliasInfo).getSynonymSchema();
            SchemaDescriptor nextSD;
            for (; ; ) {
                nextSD = dd.getSchemaDescriptor(nextSynSchema, tc, false);
                if (nextSD == null)
                    break;
                AliasDescriptor nextAD = dd.getAliasDescriptor(nextSD.getUUID().toString(), nextSynTable, nameSpace);
                if (nextAD == null)
                    break;
                SynonymAliasInfo info = (SynonymAliasInfo) nextAD.getAliasInfo();
                nextSynTable = info.getSynonymTable();
                nextSynSchema = info.getSynonymSchema();
                if (aliasName.equals(nextSynTable) && schemaName.equals(nextSynSchema))
                    throw StandardException.newException(SQLState.LANG_SYNONYM_CIRCULAR, aliasName, ((SynonymAliasInfo) aliasInfo).getSynonymTable());
            }
            // If synonym final target is not present, raise a warning
            if (nextSD != null)
                targetTD = dd.getTableDescriptor(nextSynTable, nextSD, tc);
            if (nextSD == null || targetTD == null)
                activation.addWarning(StandardException.newWarning(SQLState.LANG_SYNONYM_UNDEFINED, aliasName, nextSynSchema + "." + nextSynTable));
            // To prevent any possible deadlocks with SYSTABLES, we insert a row into
            // SYSTABLES also for synonyms. This also ensures tables/views/synonyms share
            // same namespace
            TableDescriptor td;
            DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
            td = ddg.newTableDescriptor(aliasName, sd, TableDescriptor.SYNONYM_TYPE, TableDescriptor.DEFAULT_LOCK_GRANULARITY);
            dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM, false, tc);
            break;
        default:
            break;
    }
    dd.addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM, false, tc);
    adjustUDTDependencies(lcc, dd, ads, true);
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) DataDescriptorGenerator(org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) SynonymAliasInfo(org.apache.derby.catalog.types.SynonymAliasInfo) TransactionController(org.apache.derby.iapi.store.access.TransactionController) UUID(org.apache.derby.catalog.UUID)

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