Search in sources :

Example 56 with TupleValueExpression

use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.

the class AbstractScanPlanNode method resolveColumnIndexes.

@Override
public void resolveColumnIndexes() {
    // The following applies to both seq and index scan.  Index scan has
    // some additional expressions that need to be handled as well
    // predicate expression
    List<TupleValueExpression> predicate_tves = ExpressionUtil.getTupleValueExpressions(m_predicate);
    for (TupleValueExpression tve : predicate_tves) {
        tve.setColumnIndexUsingSchema(m_tableSchema);
    }
    // inline projection and insert
    InsertPlanNode ins = (InsertPlanNode) getInlinePlanNode(PlanNodeType.INSERT);
    ProjectionPlanNode proj = (ProjectionPlanNode) getInlinePlanNode(PlanNodeType.PROJECTION);
    // Resolve the inline projection and insert if there are any.
    if (proj != null) {
        proj.resolveColumnIndexesUsingSchema(m_tableSchema);
    }
    if (ins != null) {
        ins.resolveColumnIndexes();
    }
    // if there are any, in that order.
    if (ins != null) {
        m_outputSchema = ins.getOutputSchema().clone();
    } else if (proj != null) {
        m_outputSchema = proj.getOutputSchema().clone();
    } else {
        m_outputSchema = m_preAggOutputSchema;
        // and sort them by table schema index order.
        for (SchemaColumn col : m_outputSchema.getColumns()) {
            AbstractExpression colExpr = col.getExpression();
            // At this point, they'd better all be TVEs.
            assert (colExpr instanceof TupleValueExpression);
            TupleValueExpression tve = (TupleValueExpression) colExpr;
            tve.setColumnIndexUsingSchema(m_tableSchema);
        }
        m_outputSchema.sortByTveIndex();
    }
    // The outputschema of an inline limit node is completely irrelevant to the EE except that
    // serialization will complain if it contains expressions of unresolved columns.
    // Logically, the limited scan output has the same schema as the pre-limit scan.
    // It's at least as easy to just re-use the known-good output schema of the scan
    // than it would be to carefully resolve the limit node's current output schema.
    // And this simply works regardless of whether the limit was originally applied or inlined
    // before or after the (possibly inline) projection.
    // There's no need to be concerned about re-adjusting the irrelevant outputschema
    // based on the different schema of the original raw scan and the projection.
    LimitPlanNode limit = (LimitPlanNode) getInlinePlanNode(PlanNodeType.LIMIT);
    if (limit != null) {
        limit.m_outputSchema = m_outputSchema.clone();
        // It's just another cheap knock-off
        limit.m_hasSignificantOutputSchema = false;
    }
    // Resolve subquery expression indexes
    resolveSubqueryColumnIndexes();
    AggregatePlanNode aggNode = AggregatePlanNode.getInlineAggregationNode(this);
    if (aggNode != null) {
        aggNode.resolveColumnIndexesUsingSchema(m_outputSchema);
        m_outputSchema = aggNode.getOutputSchema().copyAndReplaceWithTVE();
        // Aggregate plan node change its output schema, and
        // EE does not have special code to get output schema from inlined aggregate node.
        m_hasSignificantOutputSchema = true;
    }
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression)

Example 57 with TupleValueExpression

use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.

the class AggregatePlanNode method isTableCountNonDistinctNullableColumn.

public boolean isTableCountNonDistinctNullableColumn() {
    if (!isTableNonDistinctCount()) {
        return false;
    }
    // Is the expression a column?
    AbstractExpression aggArgument = m_aggregateExpressions.get(0);
    if (!aggArgument.getExpressionType().equals(ExpressionType.VALUE_TUPLE)) {
        return false;
    }
    // If the query is a join query then the child will be something like nested loop.
    assert (m_children.size() == 1);
    if (!(m_children.get(0) instanceof AbstractScanPlanNode)) {
        return false;
    }
    AbstractScanPlanNode asp = (AbstractScanPlanNode) m_children.get(0);
    if (!(asp.getTableScan() instanceof StmtTargetTableScan)) {
        return false;
    }
    StmtTargetTableScan sttscan = (StmtTargetTableScan) asp.getTableScan();
    Table tbl = sttscan.getTargetTable();
    TupleValueExpression tve = (TupleValueExpression) aggArgument;
    String columnName = tve.getColumnName();
    Column col = tbl.getColumns().get(columnName);
    // Is the column nullable?
    if (col.getNullable()) {
        return false;
    }
    return true;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) Table(org.voltdb.catalog.Table) AbstractExpression(org.voltdb.expressions.AbstractExpression) Column(org.voltdb.catalog.Column) StmtTargetTableScan(org.voltdb.planner.parseinfo.StmtTargetTableScan)

Example 58 with TupleValueExpression

use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.

the class AbstractScanPlanNode method initPreAggOutputSchema.

// Until the scan has an implicit projection rather than an explicitly
// inlined one, the output schema generation is going to be a bit odd.
// It will depend on three bits of state: whether any scan columns were
// specified for this table, whether or not there is an inlined
// projection and whether or not there is an inlined insert node.
// Note that only a seqscan node can have an inlined insert node,
// though support for index scan is expected.
//
// If there is an inlined insert or projection, then we'll just steal that
// output schema as our own, preferring insert to projection.
// If there is no inlined insert or projection, then, if there are no scan columns
// specified, use the entire table's schema as the output schema.
// Otherwise add an inline projection that projects the scan columns
// and then take that output schema as our own.
// These have the effect of repeatably generating the correct output
// schema if called again and again, but also allowing the planner
// to overwrite the inline projection and still have the right thing
// happen.
//
// Note that when an index scan is inlined into a join node (as with
// nested loop index joins), then there will be a project node inlined into
// the index scan node that determines which columns from the inner table
// are used as an output of the join, but that predicates evaluated against
// this table should use the complete schema of the table being scanned.
// See also the comments in NestLoopIndexPlanNode.resolveColumnIndexes.
// Related tickets: ENG-9389, ENG-9533.
private void initPreAggOutputSchema() {
    InsertPlanNode ins = (InsertPlanNode) getInlinePlanNode(PlanNodeType.INSERT);
    ProjectionPlanNode proj = (ProjectionPlanNode) getInlinePlanNode(PlanNodeType.PROJECTION);
    if (ins != null) {
        // If this is has an inline insert, then just make the
        // output schema copied from the insert node.
        m_outputSchema = ins.getOutputSchema().copyAndReplaceWithTVE();
        m_hasSignificantOutputSchema = true;
    } else if (proj != null) {
        // Does this operation needs to change complex expressions
        // into tuple value expressions with an column alias?
        // Is this always true for clone?  Or do we need a new method?
        m_outputSchema = proj.getOutputSchema().copyAndReplaceWithTVE();
        // It's just a cheap knock-off of the projection's
        m_hasSignificantOutputSchema = false;
    } else if (m_tableScanSchema.size() != 0) {
        // Order the scan columns according to the table schema
        // before we stick them in the projection output
        int difftor = 0;
        for (SchemaColumn col : m_tableScanSchema.getColumns()) {
            col.setDifferentiator(difftor);
            ++difftor;
            AbstractExpression colExpr = col.getExpression();
            assert (colExpr instanceof TupleValueExpression);
            TupleValueExpression tve = (TupleValueExpression) colExpr;
            tve.setColumnIndexUsingSchema(m_tableSchema);
        }
        // and update their indexes against the table schema
        m_tableScanSchema.sortByTveIndex();
        // Create inline projection to map table outputs to scan outputs
        ProjectionPlanNode projectionNode = new ProjectionPlanNode(m_tableScanSchema);
        addInlinePlanNode(projectionNode);
        // a bit redundant but logically consistent
        m_outputSchema = projectionNode.getOutputSchema().copyAndReplaceWithTVE();
        // It's just a cheap knock-off of the projection's
        m_hasSignificantOutputSchema = false;
    } else {
        // We come here if m_tableScanSchema is empty.
        //
        // m_tableScanSchema might be empty for cases like
        //   select now from table;
        // where there are no columns in the table that are accessed.
        //
        // Just fill m_outputSchema with the table's columns.
        m_outputSchema = m_tableSchema.clone();
        m_hasSignificantOutputSchema = true;
    }
    m_preAggOutputSchema = m_outputSchema;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression)

Example 59 with TupleValueExpression

use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.

the class NestLoopIndexPlanNode method resolveColumnIndexes.

@Override
public void resolveColumnIndexes() {
    IndexScanPlanNode inlineScan = (IndexScanPlanNode) m_inlineNodes.get(PlanNodeType.INDEXSCAN);
    assert (m_children.size() == 1 && inlineScan != null);
    for (AbstractPlanNode child : m_children) {
        child.resolveColumnIndexes();
    }
    LimitPlanNode limit = (LimitPlanNode) getInlinePlanNode(PlanNodeType.LIMIT);
    if (limit != null) {
        // output schema of limit node has not been used
        limit.m_outputSchema = m_outputSchemaPreInlineAgg;
        limit.m_hasSignificantOutputSchema = false;
    }
    // We need the schema from the target table from the inlined index
    final NodeSchema completeInnerTableSchema = inlineScan.getTableSchema();
    // We need the output schema from the child node
    final NodeSchema outerSchema = m_children.get(0).getOutputSchema();
    // pull every expression out of the inlined index scan
    // and resolve all of the TVEs against our two input schema from above.
    //
    // Tickets ENG-9389, ENG-9533: we use the complete schema for the inner
    // table (rather than the smaller schema from the inlined index scan's
    // inlined project node) because the inlined scan has no temp table,
    // so predicates will be accessing the index-scanned table directly.
    resolvePredicate(inlineScan.getPredicate(), outerSchema, completeInnerTableSchema);
    resolvePredicate(inlineScan.getEndExpression(), outerSchema, completeInnerTableSchema);
    resolvePredicate(inlineScan.getInitialExpression(), outerSchema, completeInnerTableSchema);
    resolvePredicate(inlineScan.getSkipNullPredicate(), outerSchema, completeInnerTableSchema);
    resolvePredicate(inlineScan.getSearchKeyExpressions(), outerSchema, completeInnerTableSchema);
    resolvePredicate(m_preJoinPredicate, outerSchema, completeInnerTableSchema);
    resolvePredicate(m_joinPredicate, outerSchema, completeInnerTableSchema);
    resolvePredicate(m_wherePredicate, outerSchema, completeInnerTableSchema);
    // Resolve subquery expression indexes
    resolveSubqueryColumnIndexes();
    // Resolve TVE indexes for each schema column.
    for (int i = 0; i < m_outputSchemaPreInlineAgg.size(); ++i) {
        SchemaColumn col = m_outputSchemaPreInlineAgg.getColumns().get(i);
        // These are all TVEs.
        assert (col.getExpression() instanceof TupleValueExpression);
        TupleValueExpression tve = (TupleValueExpression) col.getExpression();
        int index;
        int tableIdx;
        if (i < outerSchema.size()) {
            // 0 for outer table
            tableIdx = 0;
            index = outerSchema.getIndexOfTve(tve);
            if (index >= 0) {
                tve.setColumnIndex(index);
            }
        } else {
            // 1 for inner table
            tableIdx = 1;
            index = tve.setColumnIndexUsingSchema(completeInnerTableSchema);
        }
        if (index == -1) {
            throw new RuntimeException("Unable to find index for column: " + col.toString());
        }
        tve.setTableIndex(tableIdx);
    }
    // We want the output columns to be ordered like [outer table columns][inner table columns],
    // and further ordered by TVE index within the left- and righthand sides.
    // generateOutputSchema already places outer columns on the left and inner on the right,
    // so we just need to order the left- and righthand sides by TVE index separately.
    m_outputSchemaPreInlineAgg.sortByTveIndex(0, outerSchema.size());
    m_outputSchemaPreInlineAgg.sortByTveIndex(outerSchema.size(), m_outputSchemaPreInlineAgg.size());
    m_hasSignificantOutputSchema = true;
    resolveRealOutputSchema();
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression)

Example 60 with TupleValueExpression

use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.

the class NodeSchema method replaceTableClone.

public NodeSchema replaceTableClone(String tableAlias) {
    NodeSchema copy = new NodeSchema();
    for (int colIndex = 0; colIndex < m_columns.size(); ++colIndex) {
        SchemaColumn column = m_columns.get(colIndex);
        String colAlias = column.getColumnAlias();
        int differentiator = column.getDifferentiator();
        TupleValueExpression tve = new TupleValueExpression(tableAlias, tableAlias, colAlias, colAlias, colIndex, differentiator);
        tve.setTypeSizeAndInBytes(column);
        copy.addColumn(tableAlias, tableAlias, colAlias, colAlias, tve, differentiator);
    }
    return copy;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression)

Aggregations

TupleValueExpression (org.voltdb.expressions.TupleValueExpression)83 AbstractExpression (org.voltdb.expressions.AbstractExpression)59 SchemaColumn (org.voltdb.plannodes.SchemaColumn)19 Column (org.voltdb.catalog.Column)17 ArrayList (java.util.ArrayList)16 HashSet (java.util.HashSet)14 Constraint (org.voltdb.catalog.Constraint)13 Table (org.voltdb.catalog.Table)10 ColumnRef (org.voltdb.catalog.ColumnRef)9 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)9 StmtTableScan (org.voltdb.planner.parseinfo.StmtTableScan)9 JSONException (org.json_voltpatches.JSONException)8 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)8 NodeSchema (org.voltdb.plannodes.NodeSchema)8 ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)7 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)6 Set (java.util.Set)5 Index (org.voltdb.catalog.Index)5 StmtTargetTableScan (org.voltdb.planner.parseinfo.StmtTargetTableScan)5 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)5