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);
}
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();
}
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();
}
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);
}
}
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);
}
Aggregations