use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class ExecSPSNode method bindStatement.
/**
* Bind this ExecSPSNode. This means doing any static error
* checking that can be done before actually creating the table.
* For example, verifying that the ResultColumnList does not
* contain any duplicate column names.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
/*
** Grab the compiler context each time we bind just
** to make sure we have the write one (even though
** we are caching it).
*/
DataDictionary dd = getDataDictionary();
String schemaName = name.getSchemaName();
SchemaDescriptor sd = getSchemaDescriptor(name.getSchemaName());
if (schemaName == null)
name.setSchemaName(sd.getSchemaName());
if (sd.getUUID() != null)
spsd = dd.getSPSDescriptor(name.getTableName(), sd);
if (spsd == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "STATEMENT", name);
}
if (spsd.getType() == SPSDescriptor.SPS_TYPE_TRIGGER) {
throw StandardException.newException(SQLState.LANG_TRIGGER_SPS_CANNOT_BE_EXECED, name);
}
/*
** This execute statement is dependent on the
** stored prepared statement. If for any reason
** the underlying statement is invalidated by
** the time we get to execution, the 'execute statement'
** will get invalidated when the underlying statement
** is invalidated.
*/
getCompilerContext().createDependency(spsd);
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class CreateAliasNode method bindStatement.
// We inherit the generate() method from DDLStatementNode.
/**
* Bind this CreateAliasNode. This means doing any static error
* checking that can be done before actually creating the table.
* For example, verifying that the column name list does not
* contain any duplicate column names.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
// Are we dealing with user defined function or procedure?
if (aliasType == AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR || aliasType == AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR) {
RoutineAliasInfo rai = (RoutineAliasInfo) aliasInfo;
// Set the collation for all string types in parameters
// and return types including row multi-sets to be that of
// the schema the routine is being defined in.
rai.setCollationTypeForAllStringTypes(getSchemaDescriptor().getCollationType());
bindParameterTypes((RoutineAliasInfo) aliasInfo);
if (rai.hasVarargs()) {
switch(rai.getParameterStyle()) {
case RoutineAliasInfo.PS_DERBY_JDBC_RESULT_SET:
case RoutineAliasInfo.PS_DERBY:
break;
default:
throw StandardException.newException(SQLState.LANG_VARARGS_PARAMETER_STYLE);
}
if (rai.getMaxDynamicResultSets() > 0) {
throw StandardException.newException(SQLState.LANG_VARARGS_RETURN_RESULT_SETS);
}
}
if ((rai.getParameterStyle() == RoutineAliasInfo.PS_DERBY) && !rai.hasVarargs()) {
throw StandardException.newException(SQLState.LANG_DERBY_PARAMETER_STYLE);
}
}
// validity checking for UDTs
if (aliasType == AliasInfo.ALIAS_TYPE_UDT_AS_CHAR) {
//
// Make sure that the java class name is not the name of a builtin
// type. This skirts problems caused by logic across the system
// which assumes a tight association between the builtin SQL types
// and the Java classes which implement them.
//
// For security reasons we do not allow the user to bind a UDT
// to a Derby class.
//
TypeId[] allSystemTypeIds = TypeId.getAllBuiltinTypeIds();
int systemTypeCount = allSystemTypeIds.length;
boolean foundConflict = javaClassName.startsWith("org.apache.derby.");
if (!foundConflict) {
for (int i = 0; i < systemTypeCount; i++) {
TypeId systemType = allSystemTypeIds[i];
String systemTypeName = systemType.getCorrespondingJavaTypeName();
if (systemTypeName.equals(javaClassName)) {
foundConflict = true;
break;
}
}
}
if (foundConflict) {
throw StandardException.newException(SQLState.LANG_UDT_BUILTIN_CONFLICT, javaClassName);
}
return;
}
// validity checking for aggregates
if (aliasType == AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR) {
bindAggregate();
}
// runtime execution. Synonyms do need some validity checks.
if (aliasType != AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR)
return;
// a temporary table is created later with same name.
if (isSessionSchema(getSchemaDescriptor().getSchemaName()))
throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
String targetSchema = ((SynonymAliasInfo) aliasInfo).getSynonymSchema();
String targetTable = ((SynonymAliasInfo) aliasInfo).getSynonymTable();
if (this.getObjectName().equals(targetSchema, targetTable))
throw StandardException.newException(SQLState.LANG_SYNONYM_CIRCULAR, this.getFullName(), targetSchema + "." + targetTable);
SchemaDescriptor targetSD = getSchemaDescriptor(targetSchema, false);
if ((targetSD != null) && isSessionSchema(targetSD))
throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class CreateAliasNode method bindAggregate.
/**
* Extra logic for binding user-defined aggregate definitions
*/
private void bindAggregate() throws StandardException {
String unqualifiedName = getRelativeName();
//
// A user-defined aggregate cannot have the name of a builtin function which takes 1 argument.
//
SchemaDescriptor sysfun = getSchemaDescriptor("SYSFUN", true);
List<AliasDescriptor> systemFunctions = getDataDictionary().getRoutineList(sysfun.getUUID().toString(), unqualifiedName, AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR);
for (int i = 0; i < systemFunctions.size(); i++) {
AliasDescriptor function = systemFunctions.get(i);
RoutineAliasInfo routineInfo = (RoutineAliasInfo) function.getAliasInfo();
int parameterCount = routineInfo.getParameterCount();
if (parameterCount == 1) {
throw illegalAggregate();
}
}
//
for (int i = 0; i < NON_RESERVED_FUNCTION_NAMES.length; i++) {
if (NON_RESERVED_FUNCTION_NAMES[i].equals(unqualifiedName)) {
throw illegalAggregate();
}
}
//
for (int i = 0; i < NON_RESERVED_AGGREGATES.length; i++) {
if (NON_RESERVED_AGGREGATES[i].equals(unqualifiedName)) {
throw illegalAggregate();
}
}
// now bind the input and return types
AggregateAliasInfo aai = (AggregateAliasInfo) aliasInfo;
aai.setCollationTypeForAllStringTypes(getSchemaDescriptor().getCollationType());
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class StaticMethodCallNode method bindExpressionMinion.
private JavaValueNode bindExpressionMinion(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
bindParameters(fromList, subqueryList, aggregates);
/* If javaClassName is null then we assume that the current methodName
* is an alias and we must go to sysmethods to
* get the real method and java class names for this alias.
*/
if (javaClassName == null) {
CompilerContext cc = getCompilerContext();
// look for a routine
String schemaName = procedureName.getSchemaName();
boolean noSchema = schemaName == null;
SchemaDescriptor sd = getSchemaDescriptor(schemaName, schemaName != null);
// The field methodName is used by resolveRoutine and
// is set to the name of the routine (procedureName.getTableName()).
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
if ((ad != null) && (ad.getAliasType() == AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR)) {
resolvedAggregate = new AggregateNode(((SQLToJavaValueNode) methodParms[0]).getSQLValueNode(), new UserAggregateDefinition(ad), procedureName, false, ad.getJavaClassName(), getContextManager());
// Propagate tags used to flag nodes which need privilege checks. See DERBY-6429.
resolvedAggregate.copyTagsFrom(this);
// GROUP BY clause. That is not allowed.
if (appearsInGroupBy) {
throw StandardException.newException(SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST);
}
return this;
}
SchemaDescriptor savedSd = sd;
if (ad == null && noSchema && !forCallStatement) {
// Resolve to a built-in SYSFUN function but only
// if this is a function call and the call
// was not qualified. E.g. COS(angle). The
// SYSFUN functions are not in SYSALIASES but
// an in-memory table, set up in DataDictioanryImpl.
sd = getSchemaDescriptor("SYSFUN", true);
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
}
if (ad == null) {
// DERBY-2927. Check if a procedure is being used as a
// function, or vice versa.
sd = savedSd;
if (!forCallStatement) {
// Procedure as function. We have JDBC escape syntax which
// may entice users to try that:
// "{? = CALL <proc>}"
//
// but we don't currently support it (it's not std SQL
// either). By resolving it as a procedure we can give a
// better error message.
//
// Note that with the above escape syntax one *can* CALL a
// function, though:
// "{? = CALL <func>}"
//
// but such cases have already been resolved above.
// temporarily: resolve
forCallStatement = true;
// as procedure
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
// restore it
forCallStatement = false;
if (ad != null) {
throw StandardException.newException(SQLState.LANG_PROC_USED_AS_FUNCTION, procedureName);
}
} else {
// Maybe a function is being CALLed ?
// temporarily: resolve
forCallStatement = false;
// as function
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
// restore it
forCallStatement = true;
if (ad != null) {
throw StandardException.newException(SQLState.LANG_FUNCTION_USED_AS_PROC, procedureName);
}
}
}
/* Throw exception if no routine found */
if (ad == null) {
throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, procedureName);
}
if (noSchema) {
// If no schema was specified, register where we found the
// routine.
procedureName.setSchemaName(sd.getSchemaName());
}
if (!routineInfo.isDeterministic()) {
checkReliability(getMethodName(), CompilerContext.NON_DETERMINISTIC_ILLEGAL);
}
if (permitsSQL(routineInfo)) {
checkReliability(getMethodName(), CompilerContext.SQL_IN_ROUTINES_ILLEGAL);
}
/* Query is dependent on the AliasDescriptor */
cc.createDependency(ad);
methodName = ad.getAliasInfo().getMethodName();
javaClassName = ad.getJavaClassName();
// A special exception is made for the optional tools methods.
if (javaClassName.startsWith("org.apache.derby.") && !javaClassName.startsWith("org.apache.derby.impl.tools.optional.") && !javaClassName.startsWith("org.apache.derby.optional.lucene.") && !javaClassName.startsWith("org.apache.derby.optional.json.") && !javaClassName.startsWith("org.apache.derby.optional.api.") && !javaClassName.startsWith("org.apache.derby.optional.dump.") && !javaClassName.startsWith("org.apache.derby.vti.")) {
if (!sd.isSystemSchema())
throw StandardException.newException(SQLState.LANG_TYPE_DOESNT_EXIST2, (Throwable) null, javaClassName);
}
}
verifyClassExist(javaClassName);
/* Resolve the method call */
resolveMethodCall(javaClassName, true);
if (isPrivilegeCollectionRequired())
getCompilerContext().addRequiredRoutinePriv(ad);
// return type, then we need to push a CAST node.
if (routineInfo != null) {
if (methodParms != null)
optimizeDomainValueConversion();
TypeDescriptor returnType = routineInfo.getReturnType();
// create type dependency if return type is an ANSI UDT
if (returnType != null) {
createTypeDependency(DataTypeDescriptor.getType(returnType));
}
if (returnType != null && !returnType.isRowMultiSet() && !returnType.isUserDefinedType()) {
TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
if (returnTypeId.variableLength()) {
// Cast the return using a cast node, but have to go
// into the SQL domain, and back to the Java domain.
DataTypeDescriptor returnValueDtd = new DataTypeDescriptor(returnTypeId, returnType.getPrecision(), returnType.getScale(), returnType.isNullable(), returnType.getMaximumWidth());
ValueNode returnValueToSQL = new JavaToSQLValueNode(this, getContextManager());
ValueNode returnValueCastNode = new CastNode(returnValueToSQL, returnValueDtd, getContextManager());
// DERBY-2972 Match the collation of the RoutineAliasInfo
returnValueCastNode.setCollationInfo(returnType.getCollationType(), StringDataValue.COLLATION_DERIVATION_IMPLICIT);
JavaValueNode returnValueToJava = new SQLToJavaValueNode(returnValueCastNode, getContextManager());
returnValueToJava.setCollationType(returnType.getCollationType());
return returnValueToJava.bindExpression(fromList, subqueryList, aggregates);
}
}
}
return this;
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class TableElementList method validate.
/**
* Validate this TableElementList. This includes checking for
* duplicate columns names, and checking that user types really exist.
*
* @param ddlStmt DDLStatementNode which contains this list
* @param dd DataDictionary to use
* @param td TableDescriptor for table, if existing table.
*
* @exception StandardException Thrown on error
*/
void validate(DDLStatementNode ddlStmt, DataDictionary dd, TableDescriptor td) throws StandardException {
this.td = td;
int numAutoCols = 0;
int size = size();
HashSet<String> columnNames = new HashSet<String>(size + 2, 0.999f);
HashSet<String> constraintNames = new HashSet<String>(size + 2, 0.999f);
// all the primary key/unique key constraints for this table
ArrayList<Object> constraints = new ArrayList<Object>();
// special case for alter table (td is not null in case of alter table)
if (td != null) {
// In case of alter table, get the already existing primary key and unique
// key constraints for this table. And then we will compare them with new
// primary key/unique key constraint column lists.
ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
ConstraintDescriptor cd;
if (// table does have some pre-existing constraints defined on it
cdl != null) {
for (int i = 0; i < cdl.size(); i++) {
cd = cdl.elementAt(i);
// if the constraint type is not primary key or unique key, ignore it.
if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT || cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
constraints.add(cd);
}
}
}
}
int tableType = TableDescriptor.BASE_TABLE_TYPE;
if (ddlStmt instanceof CreateTableNode)
tableType = ((CreateTableNode) ddlStmt).tableType;
for (TableElementNode tableElement : this) {
if (tableElement instanceof ColumnDefinitionNode) {
ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;
if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE && (cdn.getType().getTypeId().isLongConcatableTypeId() || cdn.getType().getTypeId().isUserDefinedTypeId())) {
throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED, cdn.getColumnName());
}
checkForDuplicateColumns(ddlStmt, columnNames, cdn.getColumnName());
cdn.checkUserType(td);
cdn.bindAndValidateDefault(dd, td);
cdn.validateAutoincrement(dd, td, tableType);
if (tableElement instanceof ModifyColumnNode) {
ModifyColumnNode mcdn = (ModifyColumnNode) cdn;
mcdn.checkExistingConstraints(td);
mcdn.useExistingCollation(td);
} else if (cdn.isAutoincrementColumn()) {
numAutoCols++;
}
} else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN) {
String colName = tableElement.getName();
if (td.getColumnDescriptor(colName) == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, colName, td.getQualifiedName());
}
break;
}
/* The rest of this method deals with validating constraints */
if (!(tableElement.hasConstraint())) {
continue;
}
ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;
cdn.bind(ddlStmt, dd);
// If constraint is primary key or unique key, add it to the list.
if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT || cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
/* In case of create table, the list can have only ConstraintDefinitionNode
* elements. In case of alter table, it can have both ConstraintDefinitionNode
* (for new constraints) and ConstraintDescriptor(for pre-existing constraints).
*/
Object destConstraint;
String destName = null;
String[] destColumnNames = null;
for (int i = 0; i < constraints.size(); i++) {
destConstraint = constraints.get(i);
if (destConstraint instanceof ConstraintDefinitionNode) {
ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode) destConstraint;
destName = destCDN.getConstraintMoniker();
destColumnNames = destCDN.getColumnList().getColumnNames();
} else if (destConstraint instanceof ConstraintDescriptor) {
// will come here only for pre-existing constraints in case of alter table
ConstraintDescriptor destCD = (ConstraintDescriptor) destConstraint;
destName = destCD.getConstraintName();
destColumnNames = destCD.getColumnDescriptors().getColumnNames();
}
// check if there are multiple constraints with same set of columns
if (columnsMatch(cdn.getColumnList().getColumnNames(), destColumnNames))
throw StandardException.newException(SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS, cdn.getConstraintMoniker(), destName);
}
constraints.add(cdn);
}
/* Make sure that there are no duplicate constraint names in the list */
checkForDuplicateConstraintNames(ddlStmt, constraintNames, cdn.getConstraintMoniker());
/* Make sure that the constraint we are trying to drop exists */
if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT || cdn.getConstraintType() == DataDictionary.MODIFY_CONSTRAINT) {
/*
** If no schema descriptor, then must be an invalid
** schema name.
*/
String dropConstraintName = cdn.getConstraintMoniker();
if (dropConstraintName != null) {
String dropSchemaName = cdn.getDropSchemaName();
SchemaDescriptor sd = dropSchemaName == null ? td.getSchemaDescriptor() : getSchemaDescriptor(dropSchemaName);
ConstraintDescriptor cd = dd.getConstraintDescriptorByName(td, sd, dropConstraintName, false);
if (cd == null) {
throw StandardException.newException(SQLState.LANG_DROP_OR_ALTER_NON_EXISTING_CONSTRAINT, (sd.getSchemaName() + "." + dropConstraintName), td.getQualifiedName());
}
/* Statement is dependendent on the ConstraintDescriptor */
getCompilerContext().createDependency(cd);
}
}
// validation of primary key nullability moved to validatePrimaryKeyNullability().
if (cdn.hasPrimaryKeyConstraint()) {
// for PRIMARY KEY, check that columns are unique
verifyUniqueColumnList(ddlStmt, cdn);
} else if (cdn.hasUniqueKeyConstraint()) {
// for UNIQUE, check that columns are unique
verifyUniqueColumnList(ddlStmt, cdn);
// disallow until database hard upgraded at least to 10.4.
if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null)) {
checkForNullColumns(cdn, td);
}
} else if (cdn.hasForeignKeyConstraint()) {
// for FOREIGN KEY, check that columns are unique
verifyUniqueColumnList(ddlStmt, cdn);
}
}
// with ALTER TABLE ADD COLUMN.
if (numAutoCols > 1 || (numAutoCols > 0 && td != null && td.tableHasAutoincrement())) {
throw StandardException.newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);
}
}
Aggregations