Search in sources :

Example 11 with CompilerContext

use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.

the class RenameNode method bindStatement.

// We inherit the generate() method from DDLStatementNode.
/**
 * Bind this node.  This means doing any static error checking that
 * can be done before actually renaming the table/column/index.
 *
 * For a table rename: looking up the from table, verifying it exists
 * verifying it's not a system table, verifying it's not view
 * and looking up to table, verifying it doesn't exist.
 *
 * For a column rename: looking up the table, verifying it exists,
 * verifying it's not a system table, verifying it's not view, verifying
 * the from column exists, verifying the to column doesn't exist.
 *
 * For a index rename: looking up the table, verifying it exists,
 * verifying it's not a system table, verifying it's not view, verifying
 * the from index exists, verifying the to index doesn't exist.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    CompilerContext cc = getCompilerContext();
    DataDictionary dd = getDataDictionary();
    ConglomerateDescriptor cd;
    SchemaDescriptor sd;
    /* in case of rename index, the only thing we get from parser is
		 * current and new index names with no information about the
		 * table it belongs to. This is because index names are unique
		 * within a schema and hence then is no need to qualify an index
		 * name with a table name which we have to do for rename column.
		 * But from the index name, using the data dictionary, you can
		 * find the table it belongs to. Since most of the checking
		 * in bind is done using table descriptor, in the following if
		 * statement, we are trying to get the table information from the
		 * index name so it is available for the rest of he bind code.
		 */
    TableName baseTable;
    if (renamingWhat == StatementType.RENAME_INDEX) {
        sd = getSchemaDescriptor((String) null);
        ConglomerateDescriptor indexDescriptor = dd.getConglomerateDescriptor(oldObjectName, sd, false);
        if (indexDescriptor == null)
            throw StandardException.newException(SQLState.LANG_INDEX_NOT_FOUND, oldObjectName);
        /* Get the table descriptor */
        td = dd.getTableDescriptor(indexDescriptor.getTableID());
        initAndCheck(makeTableName(td.getSchemaName(), td.getName()));
    } else
        sd = getSchemaDescriptor();
    td = getTableDescriptor();
    // throw an exception if user is attempting a rename on temporary table
    if (td.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
        throw StandardException.newException(SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE);
    }
    switch(this.renamingWhat) {
        case StatementType.RENAME_TABLE:
            /* Verify that new table name does not exist in the database */
            TableDescriptor tabDesc = getTableDescriptor(newObjectName, sd);
            if (tabDesc != null)
                throw descriptorExistsException(tabDesc, sd);
            renameTableBind(dd);
            break;
        case StatementType.RENAME_COLUMN:
            renameColumnBind(dd);
            break;
        case StatementType.RENAME_INDEX:
            ConglomerateDescriptor conglomDesc = dd.getConglomerateDescriptor(newObjectName, sd, false);
            if (conglomDesc != null)
                throw descriptorExistsException(conglomDesc, sd);
            break;
        default:
            if (SanityManager.DEBUG)
                SanityManager.THROWASSERT("Unexpected rename action in RenameNode");
            break;
    }
    conglomerateNumber = td.getHeapConglomerateId();
    /* Get the base conglomerate descriptor */
    cd = td.getConglomerateDescriptor(conglomerateNumber);
    /* Statement is dependent on the TableDescriptor and ConglomerateDescriptor */
    cc.createDependency(td);
    cc.createDependency(cd);
}
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) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Example 12 with CompilerContext

use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.

the class FromBaseTable method genProjectRestrict.

/**
 * Put a ProjectRestrictNode on top of each FromTable in the FromList.
 * ColumnReferences must continue to point to the same ResultColumn, so
 * that ResultColumn must percolate up to the new PRN.  However,
 * that ResultColumn will point to a new expression, a VirtualColumnNode,
 * which points to the FromTable and the ResultColumn that is the source for
 * the ColumnReference.
 * (The new PRN will have the original of the ResultColumnList and
 * the ResultColumns from that list.  The FromTable will get shallow copies
 * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
 * will remain at the FromTable, with the PRN getting a new
 * VirtualColumnNode for each ResultColumn.expression.)
 * We then project out the non-referenced columns.  If there are no referenced
 * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
 * whose expression is 1.
 *
 * @param numTables			Number of tables in the DML Statement
 *
 * @return The generated ProjectRestrictNode atop the original FromTable.
 *
 * @exception StandardException		Thrown on error
 */
@Override
protected ResultSetNode genProjectRestrict(int numTables) throws StandardException {
    /* We get a shallow copy of the ResultColumnList and its 
		 * ResultColumns.  (Copy maintains ResultColumn.expression for now.)
		 */
    ResultColumnList prRCList = getResultColumns();
    setResultColumns(getResultColumns().copyListAndObjects());
    getResultColumns().setIndexRow(baseConglomerateDescriptor.getConglomerateNumber(), forUpdate());
    /* Replace ResultColumn.expression with new VirtualColumnNodes
		 * in the ProjectRestrictNode's ResultColumnList.  (VirtualColumnNodes include
		 * pointers to source ResultSetNode, this, and source ResultColumn.)
		 * NOTE: We don't want to mark the underlying RCs as referenced, otherwise
		 * we won't be able to project out any of them.
		 */
    prRCList.genVirtualColumnNodes(this, getResultColumns(), false);
    /* Project out any unreferenced columns.  If there are no referenced 
		 * columns, generate and bind a single ResultColumn whose expression is 1.
		 */
    prRCList.doProjection();
    /* Finally, we create the new ProjectRestrictNode */
    ProjectRestrictNode result = new ProjectRestrictNode(this, prRCList, null, /* Restriction */
    null, /* Restriction as PredicateList */
    null, /* Project subquery list */
    null, /* Restrict subquery list */
    null, getContextManager());
    if (isValidatingCheckConstraint()) {
        CompilerContext cc = getCompilerContext();
        if ((cc.getReliability() & // Internal feature: throw if used on app level
        CompilerContext.INTERNAL_SQL_ILLEGAL) != 0) {
            throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "validateCheckConstraint");
        }
        result.setValidatingCheckConstraints(targetTableUUIDString);
    }
    return result;
}
Also used : CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext)

Example 13 with CompilerContext

use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.

the class FromBaseTable method bindNonVTITables.

/**
 * Bind the table in this FromBaseTable.
 * This is where view resolution occurs
 *
 * @param dataDictionary	The DataDictionary to use for binding
 * @param fromListParam		FromList to use/append to.
 *
 * @return	ResultSetNode	The FromTable for the table or resolved view.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ResultSetNode bindNonVTITables(DataDictionary dataDictionary, FromList fromListParam) throws StandardException {
    tableName.bind();
    TableDescriptor tabDescr = bindTableDescriptor();
    if (tabDescr.getTableType() == TableDescriptor.VTI_TYPE) {
        ResultSetNode vtiNode = mapTableAsVTI(tabDescr, getCorrelationName(), getResultColumns(), getProperties(), getContextManager());
        return vtiNode.bindNonVTITables(dataDictionary, fromListParam);
    }
    ResultColumnList derivedRCL = getResultColumns();
    // make sure there's a restriction list
    restrictionList = new PredicateList(getContextManager());
    baseTableRestrictionList = new PredicateList(getContextManager());
    CompilerContext compilerContext = getCompilerContext();
    /* Generate the ResultColumnList */
    setResultColumns(genResultColList());
    templateColumns = getResultColumns();
    /* Resolve the view, if this is a view */
    if (tabDescr.getTableType() == TableDescriptor.VIEW_TYPE) {
        FromSubquery fsq;
        ResultSetNode rsn;
        ViewDescriptor vd;
        CreateViewNode cvn;
        SchemaDescriptor compSchema;
        /* Get the associated ViewDescriptor so that we can get 
			 * the view definition text.
			 */
        vd = dataDictionary.getViewDescriptor(tabDescr);
        /*
			** Set the default compilation schema to be whatever
			** this schema this view was originally compiled against.
			** That way we pick up the same tables no matter what
			** schema we are running against.
			*/
        compSchema = dataDictionary.getSchemaDescriptor(vd.getCompSchemaId(), null);
        compilerContext.pushCompilationSchema(compSchema);
        try {
            /* This represents a view - query is dependent on the ViewDescriptor */
            compilerContext.createDependency(vd);
            cvn = (CreateViewNode) parseStatement(vd.getViewText(), false);
            rsn = cvn.getParsedQueryExpression();
            /* If the view contains a '*' then we mark the views derived column list
				 * so that the view will still work, and return the expected results,
				 * if any of the tables referenced in the view have columns added to
				 * them via ALTER TABLE.  The expected results means that the view
				 * will always return the same # of columns.
				 */
            if (rsn.getResultColumns().containsAllResultColumn()) {
                getResultColumns().setCountMismatchAllowed(true);
            }
            // checking.
            for (ResultColumn rc : getResultColumns()) {
                if (isPrivilegeCollectionRequired()) {
                    compilerContext.addRequiredColumnPriv(rc.getTableColumnDescriptor());
                }
            }
            fsq = new FromSubquery(rsn, cvn.getOrderByList(), cvn.getOffset(), cvn.getFetchFirst(), cvn.hasJDBClimitClause(), (correlationName != null) ? correlationName : getOrigTableName().getTableName(), getResultColumns(), tableProperties, getContextManager());
            // Transfer the nesting level to the new FromSubquery
            fsq.setLevel(level);
            // We are getting ready to bind the query underneath the view. Since
            // that query is going to run with definer's privileges, we do not
            // need to collect any privilege requirement for that query.
            // Following call is marking the query to run with definer
            // privileges. This marking will make sure that we do not collect
            // any privilege requirement for it.
            CollectNodesVisitor<QueryTreeNode> cnv = new CollectNodesVisitor<QueryTreeNode>(QueryTreeNode.class);
            fsq.accept(cnv);
            for (QueryTreeNode node : cnv.getList()) {
                node.disablePrivilegeCollection();
            }
            fsq.setOrigTableName(this.getOrigTableName());
            // since we reset the compilation schema when we return, we
            // need to save it for use when we bind expressions:
            fsq.setOrigCompilationSchema(compSchema);
            ResultSetNode fsqBound = fsq.bindNonVTITables(dataDictionary, fromListParam);
            /* Do error checking on derived column list and update "exposed"
				 * column names if valid.
				 */
            if (derivedRCL != null) {
                fsqBound.getResultColumns().propagateDCLInfo(derivedRCL, origTableName.getFullTableName());
            }
            return fsqBound;
        } finally {
            compilerContext.popCompilationSchema();
        }
    } else {
        /* This represents a table - query is dependent on the TableDescriptor */
        compilerContext.createDependency(tabDescr);
        /* Get the base conglomerate descriptor */
        baseConglomerateDescriptor = tabDescr.getConglomerateDescriptor(tabDescr.getHeapConglomerateId());
        // probably doesn't exist anymore.
        if (baseConglomerateDescriptor == null) {
            throw StandardException.newException(SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, Long.valueOf(tabDescr.getHeapConglomerateId()));
        }
        /* Build the 0-based array of base column names. */
        columnNames = getResultColumns().getColumnNames();
        /* Do error checking on derived column list and update "exposed"
			 * column names if valid.
			 */
        if (derivedRCL != null) {
            getResultColumns().propagateDCLInfo(derivedRCL, origTableName.getFullTableName());
        }
        /* Assign the tableNumber */
        if (// allow re-bind, in which case use old number
        tableNumber == -1)
            tableNumber = compilerContext.getNextTableNumber();
    }
    // 
    // Only the DBO can select from SYS.SYSUSERS.
    // 
    authorizeSYSUSERS = dataDictionary.usesSqlAuthorization() && tabDescr.getUUID().toString().equals(SYSUSERSRowFactory.SYSUSERS_UUID);
    if (authorizeSYSUSERS) {
        String databaseOwner = dataDictionary.getAuthorizationDatabaseOwner();
        String currentUser = getLanguageConnectionContext().getStatementContext().getSQLSessionContext().getCurrentUser();
        if (!databaseOwner.equals(currentUser)) {
            throw StandardException.newException(SQLState.DBO_ONLY);
        }
    }
    return this;
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) ViewDescriptor(org.apache.derby.iapi.sql.dictionary.ViewDescriptor) OptimizablePredicateList(org.apache.derby.iapi.sql.compile.OptimizablePredicateList)

Example 14 with CompilerContext

use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.

the class ColumnDefinitionNode method validateDefault.

/**
 * Check the validity of the default for this node.
 *
 * @param td		The TableDescriptor.
 *
 * @exception StandardException		Thrown on error
 */
void validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException {
    if (defaultNode == null)
        return;
    // Examin whether default value is autoincrement.
    if (isAutoincrement) {
        defaultInfo = createDefaultInfoOfAutoInc();
        return;
    }
    // Judged as default value is constant value.
    CompilerContext cc = getCompilerContext();
    ValueNode defaultTree = defaultNode.getDefaultTree();
    /* bind the default.
		 * Verify that it does not contain any ColumnReferences or subqueries
		 * and that it is type compatable with the column.
		 */
    final int previousReliability = cc.getReliability();
    try {
        /*
				Defaults cannot have dependencies as they
				should just be constants. Code used to exist
				to handle dependencies in defaults, now this
				is under sanity to ensure no dependencies exist.
			 */
        ProviderList apl = null;
        ProviderList prevAPL = null;
        if (SanityManager.DEBUG) {
            apl = new ProviderList();
            prevAPL = cc.getCurrentAuxiliaryProviderList();
            cc.setCurrentAuxiliaryProviderList(apl);
        }
        // Tell the compiler context to only allow deterministic nodes
        cc.setReliability(CompilerContext.DEFAULT_RESTRICTION);
        defaultTree = defaultTree.bindExpression(new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), (SubqueryList) null, (List<AggregateNode>) null);
        TypeId columnTypeId = getType().getTypeId();
        TypeId defaultTypeId = defaultTree.getTypeId();
        // before checking for 'not storable' errors (42821).
        if (!defaultTypeIsValid(columnTypeId, getType(), defaultTypeId, defaultTree, defaultNode.getDefaultText())) {
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_DEFAULT_VALUE, this.name);
        }
        // Now check 'not storable' errors.
        if (!getTypeCompiler(columnTypeId).storable(defaultTypeId, getClassFactory())) {
            throw StandardException.newException(SQLState.LANG_NOT_STORABLE, columnTypeId.getSQLTypeName(), defaultTypeId.getSQLTypeName());
        }
        // Save off the default text
        // RESOLVEDEFAULT - Convert to constant if possible
        defaultInfo = new DefaultInfoImpl(false, defaultNode.getDefaultText(), defaultValue);
        if (SanityManager.DEBUG) {
            /* Save the APL off in the constraint node */
            if (apl.size() > 0) {
                SanityManager.THROWASSERT("DEFAULT clause has unexpected dependencies");
            }
            // Restore the previous AuxiliaryProviderList
            cc.setCurrentAuxiliaryProviderList(prevAPL);
        }
    } finally {
        cc.setReliability(previousReliability);
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) List(java.util.List) ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 15 with CompilerContext

use of org.apache.derby.iapi.sql.compile.CompilerContext in project derby by apache.

the class ConditionalNode 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.
 * @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 {
    CompilerContext cc = getCompilerContext();
    int previousReliability = orReliability(CompilerContext.CONDITIONAL_RESTRICTION);
    ValueNodeList caseOperandParameters = bindCaseOperand(cc, fromList, subqueryList, aggregates);
    testConditions.bindExpression(fromList, subqueryList, aggregates);
    // parameter), find out which type best describes it.
    if (caseOperandParameters != null) {
        // when testConditions was bound.
        for (ValueNode vn : caseOperandParameters) {
            // Check that this parameter is comparable to all the other
            // parameters in the list. This indirectly checks whether
            // all when operands have compatible types.
            caseOperandParameters.comparable(vn);
            // Replace the dummy parameter node with the actual case
            // operand.
            testConditions.accept(new ReplaceNodeVisitor(vn, caseOperand));
        }
        // Finally, after we have determined that all the when operands
        // are compatible, and we have reinserted the case operand into
        // the tree, set the type of the case operand to the dominant
        // type of all the when operands.
        caseOperand.setType(caseOperandParameters.getDominantTypeServices());
    }
    thenElseList.bindExpression(fromList, subqueryList, aggregates);
    // Find the type of the first typed value in thenElseList and cast
    // all untyped NULL values to that type. We don't need to find the
    // dominant type here, since a top-level cast to that type will be
    // added later, if necessary.
    DataTypeDescriptor nullType = thenElseList.getTypeServices();
    if (nullType == null) {
        // an error.
        throw StandardException.newException(SQLState.LANG_ALL_RESULT_EXPRESSIONS_UNTYPED);
    } else {
        recastNullNodes(nullType, fromList, subqueryList, aggregates);
    }
    // Set the result type of this conditional to be the dominant type
    // of the result expressions.
    setType(thenElseList.getDominantTypeServices());
    /* testCondition must be a boolean expression.
		 * If it is a ? parameter on the left, then set type to boolean,
		 * otherwise verify that the result type is boolean.
		 */
    testConditions.setParameterDescriptor(new DataTypeDescriptor(TypeId.BOOLEAN_ID, true));
    for (ValueNode testCondition : testConditions) {
        if (!testCondition.getTypeServices().getTypeId().equals(TypeId.BOOLEAN_ID)) {
            throw StandardException.newException(SQLState.LANG_CONDITIONAL_NON_BOOLEAN);
        }
    }
    // Set the type of the parameters.
    thenElseList.setParameterDescriptor(getTypeServices());
    /* The then and else expressions must be type compatible */
    ClassInspector cu = getClassFactory().getClassInspector();
    /*
		** If it is comparable, then we are ok.  Note that we
		** could in fact allow any expressions that are convertible()
		** since we are going to generate a cast node, but that might
		** be confusing to users...
		*/
    for (ValueNode expr : thenElseList) {
        DataTypeDescriptor dtd = expr.getTypeServices();
        String javaTypeName = dtd.getTypeId().getCorrespondingJavaTypeName();
        String resultJavaTypeName = getTypeId().getCorrespondingJavaTypeName();
        if (!dtd.comparable(getTypeServices(), false, getClassFactory()) && !cu.assignableTo(javaTypeName, resultJavaTypeName) && !cu.assignableTo(resultJavaTypeName, javaTypeName)) {
            throw StandardException.newException(SQLState.LANG_NOT_TYPE_COMPATIBLE, dtd.getTypeId().getSQLTypeName(), getTypeId().getSQLTypeName());
        }
    }
    // The result is nullable if and only if at least one of the result
    // expressions is nullable (DERBY-6567).
    setNullability(thenElseList.isNullable());
    /*
		** Generate a CastNode if necessary and
		** stick it over the original expression
		*/
    TypeId condTypeId = getTypeId();
    for (int i = 0; i < thenElseList.size(); i++) {
        ValueNode expr = thenElseList.elementAt(i);
        if (expr.getTypeId().typePrecedence() != condTypeId.typePrecedence()) {
            // Cast to dominant type.
            ValueNode cast = new CastNode(expr, getTypeServices(), getContextManager());
            cast = cast.bindExpression(fromList, subqueryList, aggregates);
            thenElseList.setElementAt(cast, i);
        }
    }
    cc.setReliability(previousReliability);
    return this;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ClassInspector(org.apache.derby.iapi.services.loader.ClassInspector) 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