use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.
the class DropTriggerNode method bindStatement.
/**
* Bind this DropTriggerNode. This means looking up the trigger,
* verifying it exists and getting its table uuid.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
CompilerContext cc = getCompilerContext();
DataDictionary dd = getDataDictionary();
SchemaDescriptor sd = getSchemaDescriptor();
TriggerDescriptor triggerDescriptor = null;
if (sd.getUUID() != null)
triggerDescriptor = dd.getTriggerDescriptor(getRelativeName(), sd);
if (triggerDescriptor == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "TRIGGER", getFullName());
}
/* Get the table descriptor */
td = triggerDescriptor.getTableDescriptor();
cc.createDependency(td);
cc.createDependency(triggerDescriptor);
}
use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.
the class DropViewNode method bindStatement.
/**
* Bind the drop view node
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
DataDictionary dd = getDataDictionary();
CompilerContext cc = getCompilerContext();
TableDescriptor td = dd.getTableDescriptor(getRelativeName(), getSchemaDescriptor(), getLanguageConnectionContext().getTransactionCompile());
/*
* Statement is dependent on the TableDescriptor
* If td is null, let execution throw the error like
* it is before.
*/
if (td != null) {
cc.createDependency(td);
}
}
use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.
the class GenericLanguageConnectionContext method pushCompilerContext.
/**
* Push a CompilerContext on the context stack with
* the passed in schema sd as the default schema
* we compile against.
*
* @param sd the default schema
*
* @return the compiler context
*
* For the parameter sd, there are 3 possible values(of interest) that can
* get passed into this method:
*
* a) A null SchemaDescriptor which indicates to the system to use the
* CURRENT SCHEMA as the compilation schema.
*
* b) A SchemaDescriptor with its UUID == null, this indicates that either
* the schema has not been physically created yet or that the LCC's
* getDefaultSchema() is not yet up-to-date with its actual UUID.
* The system will use the CURRENT SCHEMA as the compilation schema.
*
* c) A SchemaDescriptor with its UUID != null, this means that the schema
* has been physically created. The system will use this schema as the
* compilation schema (e.g.: for trigger or view recompilation cases,
* etc.).
*
* The compiler context's compilation schema will be set accordingly based
* on the given input above.
*/
public CompilerContext pushCompilerContext(SchemaDescriptor sd) {
CompilerContext cc;
boolean firstCompilerContext = false;
// DEBUG END
cc = (CompilerContext) (getContextManager().getContext(CompilerContext.CONTEXT_ID));
/*
** If there is no compiler context, this is the first one on the
** stack, so don't pop it when we're done (saves time).
*/
if (cc == null) {
firstCompilerContext = true;
}
if (cc == null || cc.getInUse()) {
cc = new CompilerContextImpl(getContextManager(), this, tcf);
if (firstCompilerContext) {
cc.firstOnStack();
}
} else {
/* Reset the next column,table, subquery and ResultSet numbers at
* the beginning of each statement
*/
cc.resetContext();
}
cc.setInUse(true);
StatementContext sc = getStatementContext();
if (sc.getSystemCode())
cc.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
/*
* Set the compilation schema when its UUID is available.
* i.e.: Schema may not have been physically created yet, so
* its UUID will be null.
*
* o For trigger SPS recompilation, the system must use its
* compilation schema to recompile the statement.
*
* o For view recompilation, we set the compilation schema
* for this compiler context if its UUID is available.
* Otherwise, the compilation schema will be determined
* at execution time of view creation.
*/
if (sd != null && sd.getUUID() != null) {
cc.setCompilationSchema(sd);
}
return cc;
}
use of org.apache.derby.iapi.sql.compile.CompilerContext 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.compile.CompilerContext in project derby by apache.
the class SubqueryNode method bindExpression.
/**
* Bind this expression. This means binding the sub-expressions,
* as well as figuring out what the return type is for this expression.
*
* @param fromList The FROM list for the query this
* expression is in, for binding columns.
* NOTE: fromList will be null if the subquery appears
* in a VALUES clause.
* @param subqueryList The subquery list being built as we find SubqueryNodes
* @param aggregates The aggregate list being built as we find AggregateNodes
*
* @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 {
ResultColumnList resultColumns;
// check if subquery is allowed in expression tree
checkReliability(CompilerContext.SUBQUERY_ILLEGAL, SQLState.LANG_SUBQUERY);
resultColumns = resultSet.getResultColumns();
/* The parser does not enforce the fact that a subquery (except in the
* case of EXISTS; NOT EXISTS does not appear prior to preprocessing)
* can only return a single column, so we must check here.
*/
if (subqueryType != EXISTS_SUBQUERY && resultColumns.visibleSize() != 1) {
throw StandardException.newException(SQLState.LANG_NON_SINGLE_COLUMN_SUBQUERY);
}
/* Verify the usage of "*" in the select list:
* o Only valid in EXISTS subqueries
* o If the AllResultColumn is qualified, then we have to verify
* that the qualification is a valid exposed name.
* NOTE: The exposed name can come from an outer query block.
*/
resultSet.verifySelectStarSubquery(fromList, subqueryType);
/* For an EXISTS subquery:
* o If the SELECT list is a "*", then we convert it to a true.
* (We need to do the conversion since we don't want the "*" to
* get expanded.)
* o We then must bind the expression under the SELECT list to
* verify that it is a valid expression. (We must do this as a
* separate step because we need to validate the expression and
* we need to handle EXISTS (select * ... union all select 1 ...)
* without getting a type compatability error.)
* o Finally, we convert the expression to a SELECT true.
*/
if (subqueryType == EXISTS_SUBQUERY) {
/* Transform the * into true (EXISTS). */
resultSet = resultSet.setResultToBooleanTrueNode(true);
}
/* We need to bind the tables before we can bind the target list
* (for exists subqueries). However, we need to wait until after
* any *'s have been replaced, so that they don't get expanded.
*/
CompilerContext cc = getCompilerContext();
/* DERBY-4191
* We should make sure that we require select privileges
* on the tables in the underlying subquery and not the
* parent sql's privilege. eg
* update t1 set c1=(select c2 from t2)
* For the query above, when working with the subquery, we should
* require select privilege on t2.c2 rather than update privilege.
* Prior to fix for DERBY-4191, we were collecting update privilege
* requirement for t2.c2 rather than select privilege
*/
cc.pushCurrentPrivType(Authorizer.SELECT_PRIV);
resultSet = resultSet.bindNonVTITables(getDataDictionary(), fromList);
resultSet = resultSet.bindVTITables(fromList);
/* Set the subquery # for this SubqueryNode */
if (subqueryNumber == -1)
subqueryNumber = cc.getNextSubqueryNumber();
/* reject ? parameters in the select list of subqueries */
resultSet.rejectParameters();
if (subqueryType == EXISTS_SUBQUERY) {
/* Bind the expression in the SELECT list */
resultSet.bindTargetExpressions(fromList);
/*
* reject any untyped nulls in the EXISTS subquery before
* SELECT TRUE transformation.
*/
resultSet.bindUntypedNullsToResultColumns(null);
/* Transform the ResultColumn into true.
* NOTE: This may be a 2nd instance of the same transformation for
* an EXISTS (select * ...), since we had to transform the
* AllResultColumn above, but we have to also handle
* EXISTS (select r from s ...)
*/
resultSet = resultSet.setResultToBooleanTrueNode(false);
}
/* bind the left operand, if there is one */
if (leftOperand != null) {
leftOperand = leftOperand.bindExpression(fromList, subqueryList, aggregates);
}
if (orderByList != null) {
orderByList.pullUpOrderByColumns(resultSet);
}
/* bind the expressions in the underlying subquery */
resultSet.bindExpressions(fromList);
resultSet.bindResultColumns(fromList);
if (orderByList != null) {
orderByList.bindOrderByColumns(resultSet);
}
bindOffsetFetch(offset, fetchFirst);
/* reject any untyped nulls in the subquery */
resultSet.bindUntypedNullsToResultColumns(null);
/* We need to reset resultColumns since the underlying resultSet may
* be a UNION (and UnionNode.bindResultColumns() regens a new RCL).
*/
resultColumns = resultSet.getResultColumns();
/*
* A ? parameter to the left of this subquery gets type of the
* subquery's sole column.
*/
if (leftOperand != null && leftOperand.requiresTypeFromContext()) {
leftOperand.setType(resultColumns.elementAt(0).getTypeServices());
}
// Set the DataTypeServices
setDataTypeServices(resultColumns);
/* Add this subquery to the subquery list */
subqueryList.addSubqueryNode(this);
cc.popCurrentPrivType();
return this;
}
Aggregations