Search in sources :

Example 21 with CompilerContext

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);
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) TriggerDescriptor(org.apache.derby.iapi.sql.dictionary.TriggerDescriptor)

Example 22 with CompilerContext

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);
    }
}
Also used : CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Example 23 with CompilerContext

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;
}
Also used : CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) CompilerContextImpl(org.apache.derby.impl.sql.compile.CompilerContextImpl) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 24 with CompilerContext

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;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor)

Example 25 with CompilerContext

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;
}
Also used : CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext)

Aggregations

CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)53 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)12 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)10 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)9 Parser (org.apache.derby.iapi.sql.compile.Parser)8 Visitable (org.apache.derby.iapi.sql.compile.Visitable)6 TypeId (org.apache.derby.iapi.types.TypeId)6 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)5 ProviderList (org.apache.derby.iapi.sql.depend.ProviderList)5 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)5 ArrayList (java.util.ArrayList)4 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)4 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)4 ContextManager (org.apache.derby.iapi.services.context.ContextManager)3 StandardException (org.apache.derby.shared.common.error.StandardException)3 UUID (org.apache.derby.catalog.UUID)2 DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)2 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)2 CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)2 TypeCompilerFactory (org.apache.derby.iapi.sql.compile.TypeCompilerFactory)2