Search in sources :

Example 6 with ConstantValueExpression

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

the class ParsedUnionStmt method parseOrderColumn.

/**
     * This is a stripped down version of the ParsedSelectStmt.parseOrderColumn. Since the SET ops
     * are not allowed to have aggregate expressions (HAVING, GROUP BY) (except the individual SELECTS)
     * all the logic handling the aggregates is omitted here
     * @param orderByNode
     * @param leftmostSelectChild
     */
private void parseOrderColumn(VoltXMLElement orderByNode, ParsedSelectStmt leftmostSelectChild) {
    ParsedColInfo.ExpressionAdjuster adjuster = new ParsedColInfo.ExpressionAdjuster() {

        @Override
        public AbstractExpression adjust(AbstractExpression expr) {
            // Union itself can't have aggregate expression
            return expr;
        }
    };
    // Get the display columns from the first child
    List<ParsedColInfo> displayColumns = leftmostSelectChild.orderByColumns();
    ParsedColInfo order_col = ParsedColInfo.fromOrderByXml(leftmostSelectChild, orderByNode, adjuster);
    AbstractExpression order_exp = order_col.expression;
    assert (order_exp != null);
    // helps later when trying to determine ORDER BY coverage (for determinism).
    for (ParsedColInfo col : displayColumns) {
        if (col.alias.equals(order_col.alias) || col.expression.equals(order_exp)) {
            col.orderBy = true;
            col.ascending = order_col.ascending;
            order_col.alias = col.alias;
            order_col.columnName = col.columnName;
            order_col.tableName = col.tableName;
            break;
        }
    }
    assert (!(order_exp instanceof ConstantValueExpression));
    assert (!(order_exp instanceof ParameterValueExpression));
    m_orderColumns.add(order_col);
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression)

Example 7 with ConstantValueExpression

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

the class ParsedInsertStmt method defaultValueToExpr.

private AbstractExpression defaultValueToExpr(Column column) {
    AbstractExpression expr = null;
    boolean isConstantValue = true;
    if (column.getDefaulttype() == VoltType.TIMESTAMP.getValue()) {
        boolean isFunctionFormat = true;
        String timeValue = column.getDefaultvalue();
        try {
            Long.parseLong(timeValue);
            isFunctionFormat = false;
        } catch (NumberFormatException e) {
        }
        if (isFunctionFormat) {
            try {
                java.sql.Timestamp.valueOf(timeValue);
                isFunctionFormat = false;
            } catch (IllegalArgumentException e) {
            }
        }
        if (isFunctionFormat) {
            String name = timeValue.split(":")[0];
            int id = Integer.parseInt(timeValue.split(":")[1]);
            FunctionExpression funcExpr = new FunctionExpression();
            funcExpr.setAttributes(name, null, id);
            funcExpr.setValueType(VoltType.TIMESTAMP);
            funcExpr.setValueSize(VoltType.TIMESTAMP.getMaxLengthInBytes());
            expr = funcExpr;
            isConstantValue = false;
        }
    }
    if (isConstantValue) {
        // Not Default sql function.
        ConstantValueExpression const_expr = new ConstantValueExpression();
        expr = const_expr;
        if (column.getDefaulttype() != 0) {
            const_expr.setValue(column.getDefaultvalue());
            const_expr.refineValueType(VoltType.get((byte) column.getDefaulttype()), column.getSize());
        } else {
            const_expr.setValue(null);
            const_expr.refineValueType(VoltType.get((byte) column.getType()), column.getSize());
        }
    }
    assert (expr != null);
    return expr;
}
Also used : FunctionExpression(org.voltdb.expressions.FunctionExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression)

Example 8 with ConstantValueExpression

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

the class ParsedSelectStmt method parseDisplayColumn.

private void parseDisplayColumn(int index, VoltXMLElement child, boolean isDistributed) {
    ParsedColInfo col = new ParsedColInfo();
    m_aggregationList.clear();
    // This index calculation is only used for sanity checking
    // materialized views (which use the parsed select statement but
    // don't go through the planner pass that does more involved
    // column index resolution).
    col.index = index;
    // Parse the expression.  We may substitute for this later
    // on, but it's a place to start.
    AbstractExpression colExpr = parseExpressionTree(child);
    if (colExpr instanceof ConstantValueExpression) {
        assert (colExpr.getValueType() != VoltType.NUMERIC);
    }
    assert (colExpr != null);
    if (isDistributed) {
        colExpr = colExpr.replaceAVG();
        updateAvgExpressions();
    }
    ExpressionUtil.finalizeValueTypes(colExpr);
    if (colExpr.getValueType() == VoltType.BOOLEAN) {
        throw new PlanningErrorException("A SELECT clause does not allow a BOOLEAN expression. " + "consider using CASE WHEN to decode the BOOLEAN expression " + "into a value of some other type.");
    }
    // ENG-6291: If parent is UNION, voltdb wants to make inline varchar to be outlined
    if (isParentUnionClause() && AbstractExpression.hasInlineVarType(colExpr)) {
        AbstractExpression expr = new OperatorExpression();
        ;
        expr.setExpressionType(ExpressionType.OPERATOR_CAST);
        VoltType voltType = colExpr.getValueType();
        // We don't support parameterized casting,
        // such as specifically to "VARCHAR(3)" vs. VARCHAR,
        // so assume max length for variable-length types
        // (VARCHAR and VARBINARY).
        int size = expr.getInBytes() ? voltType.getMaxLengthInBytes() : VoltType.MAX_VALUE_LENGTH_IN_CHARACTERS;
        expr.setValueType(voltType);
        expr.setValueSize(size);
        expr.setInBytes(colExpr.getInBytes());
        expr.setLeft(colExpr);
        // switch the new expression for CAST
        colExpr = expr;
    }
    // Remember the column expression.
    col.expression = colExpr;
    calculateColumnNames(child, col);
    insertAggExpressionsToAggResultColumns(m_aggregationList, col);
    if (m_aggregationList.size() >= 1) {
        m_hasAggregateExpression = true;
        for (AbstractExpression agg : m_aggregationList) {
            assert (agg instanceof AggregateExpression);
            if (!m_hasAggregateDistinct && ((AggregateExpression) agg).isDistinct()) {
                m_hasAggregateDistinct = true;
                break;
            }
        }
    }
    // The differentiator is used when ParsedColInfo is converted to a
    // SchemaColumn object, to differentiate between columns that have the
    // same name within a table (which can happen for subqueries or joins).
    col.differentiator = index;
    m_displayColumns.add(col);
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltType(org.voltdb.VoltType) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) OperatorExpression(org.voltdb.expressions.OperatorExpression) AggregateExpression(org.voltdb.expressions.AggregateExpression)

Example 9 with ConstantValueExpression

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

the class IndexCountPlanNode method createOrNull.

// Create an IndexCountPlanNode that replaces the parent aggregate and child
// indexscan IF the indexscan's end expressions are a form that can be
// modeled with an end key.
// The supported forms for end expression are:
//   - null
//   - one filter expression per index key component (ANDed together)
//     as "combined" for the IndexScan.
//   - fewer filter expressions than index key components with one of the
//     (the last) being a LT comparison.
//   - 1 fewer filter expressions than index key components,
//     but all ANDed equality filters
// The LT restriction comes because when index key prefixes are identical
// to the prefix-only end key, the entire index key sorts greater than the
// prefix-only end-key, because it is always longer.
// These prefix-equal cases would be missed in an EQ or LTE filter,
// causing undercounts.
// A prefix-only LT filter discards prefix-equal cases, so it is allowed.
// @return the IndexCountPlanNode or null if one is not possible.
public static IndexCountPlanNode createOrNull(IndexScanPlanNode isp, AggregatePlanNode apn) {
    // add support for reverse scan
    // for ASC scan, check endExpression;
    // for DESC scan (isReverseScan()), check the searchkeys
    List<AbstractExpression> endKeys = new ArrayList<>();
    // Translate the index scan's end condition into a list of end key
    // expressions and note the comparison operand of the last one.
    // Initially assume it to be an equality filter.
    IndexLookupType endType = IndexLookupType.EQ;
    List<AbstractExpression> endComparisons = ExpressionUtil.uncombinePredicate(isp.getEndExpression());
    for (AbstractExpression ae : endComparisons) {
        // LT or LTE expression that resets the end type.
        assert (endType == IndexLookupType.EQ);
        ExpressionType exprType = ae.getExpressionType();
        if (exprType == ExpressionType.COMPARE_LESSTHAN) {
            endType = IndexLookupType.LT;
        } else if (exprType == ExpressionType.COMPARE_LESSTHANOREQUALTO) {
            endType = IndexLookupType.LTE;
        } else {
            assert (exprType == ExpressionType.COMPARE_EQUAL || exprType == ExpressionType.COMPARE_NOTDISTINCT);
        }
        // PlanNodes all need private deep copies of expressions
        // so that the resolveColumnIndexes results
        // don't get bashed by other nodes or subsequent planner runs
        endKeys.add(ae.getRight().clone());
    }
    int indexSize = 0;
    String jsonstring = isp.getCatalogIndex().getExpressionsjson();
    List<ColumnRef> indexedColRefs = null;
    List<AbstractExpression> indexedExprs = null;
    if (jsonstring.isEmpty()) {
        indexedColRefs = CatalogUtil.getSortedCatalogItems(isp.getCatalogIndex().getColumns(), "index");
        indexSize = indexedColRefs.size();
    } else {
        try {
            indexedExprs = AbstractExpression.fromJSONArrayString(jsonstring, isp.getTableScan());
            indexSize = indexedExprs.size();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    int searchKeySize = isp.getSearchKeyExpressions().size();
    int endKeySize = endKeys.size();
    if (!isp.isReverseScan() && endType != IndexLookupType.LT && endKeySize > 0 && endKeySize < indexSize) {
        // That is, when a prefix-only key exists and does not use LT.
        if (endType != IndexLookupType.EQ || searchKeySize != indexSize || endKeySize < indexSize - 1) {
            return null;
        }
        // To use an index count for an equality search of da compound key,
        // both the search key and end key must have a component for each
        // index component.
        // If the search key is long enough but the end key is one component
        // short, it can be patched with a type-appropriate max key value
        // (if one exists for the type), but the end key comparison needs to
        // change from EQ to LTE to compensate.
        VoltType missingEndKeyType;
        // and get the missing key component's indexed expression.
        if (jsonstring.isEmpty()) {
            int lastIndex = indexedColRefs.get(endKeySize).getColumn().getIndex();
            for (AbstractExpression expr : endComparisons) {
                if (((TupleValueExpression) (expr.getLeft())).getColumnIndex() == lastIndex) {
                    return null;
                }
            }
            int catalogTypeCode = indexedColRefs.get(endKeySize).getColumn().getType();
            missingEndKeyType = VoltType.get((byte) catalogTypeCode);
        } else {
            AbstractExpression lastIndexedExpr = indexedExprs.get(endKeySize);
            for (AbstractExpression expr : endComparisons) {
                if (expr.getLeft().bindingToIndexedExpression(lastIndexedExpr) != null) {
                    return null;
                }
            }
            missingEndKeyType = lastIndexedExpr.getValueType();
        }
        String maxValueForType = missingEndKeyType.getMaxValueForKeyPadding();
        // for which all legal values are less than or equal to it.
        if (maxValueForType == null) {
            return null;
        }
        ConstantValueExpression maxKey = new ConstantValueExpression();
        maxKey.setValueType(missingEndKeyType);
        maxKey.setValue(maxValueForType);
        maxKey.setValueSize(missingEndKeyType.getLengthInBytesForFixedTypes());
        endType = IndexLookupType.LTE;
        endKeys.add(maxKey);
    }
    // DESC case
    if (searchKeySize > 0 && searchKeySize < indexSize) {
        return null;
    }
    return new IndexCountPlanNode(isp, apn, endType, endKeys);
}
Also used : IndexLookupType(org.voltdb.types.IndexLookupType) ArrayList(java.util.ArrayList) JSONException(org.json_voltpatches.JSONException) AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltType(org.voltdb.VoltType) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) ColumnRef(org.voltdb.catalog.ColumnRef) ExpressionType(org.voltdb.types.ExpressionType)

Example 10 with ConstantValueExpression

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

the class BranchNode method analyzeJoinExpressions.

@Override
public void analyzeJoinExpressions(List<AbstractExpression> noneList) {
    JoinNode leftChild = getLeftNode();
    JoinNode rightChild = getRightNode();
    leftChild.analyzeJoinExpressions(noneList);
    rightChild.analyzeJoinExpressions(noneList);
    // At this moment all RIGHT joins are already converted to the LEFT ones
    assert (getJoinType() != JoinType.RIGHT);
    ArrayList<AbstractExpression> joinList = new ArrayList<>();
    ArrayList<AbstractExpression> whereList = new ArrayList<>();
    // Collect node's own join and where expressions
    joinList.addAll(ExpressionUtil.uncombineAny(getJoinExpression()));
    whereList.addAll(ExpressionUtil.uncombineAny(getWhereExpression()));
    // Collect children expressions only if a child is a leaf. They are not classified yet
    if (!(leftChild instanceof BranchNode)) {
        joinList.addAll(leftChild.m_joinInnerList);
        leftChild.m_joinInnerList.clear();
        whereList.addAll(leftChild.m_whereInnerList);
        leftChild.m_whereInnerList.clear();
    }
    if (!(rightChild instanceof BranchNode)) {
        joinList.addAll(rightChild.m_joinInnerList);
        rightChild.m_joinInnerList.clear();
        whereList.addAll(rightChild.m_whereInnerList);
        rightChild.m_whereInnerList.clear();
    }
    Collection<String> outerTables = leftChild.generateTableJoinOrder();
    Collection<String> innerTables = rightChild.generateTableJoinOrder();
    // Classify join expressions into the following categories:
    // 1. The OUTER-only join conditions. If any are false for a given outer tuple,
    // then NO inner tuples should match it (and it can automatically get null-padded by the join
    // without even considering the inner table). Testing the outer-only conditions
    // COULD be considered as an optimal first step to processing each outer tuple
    // 2. The INNER-only join conditions apply to the inner tuples (even prior to considering any outer tuple).
    // if true for a given inner tuple, the condition has no effect,
    // if false, it prevents the inner tuple from matching ANY outer tuple,
    // In case of multi-tables join, they could be pushed down to a child node if this node is a join itself
    // 3. The two-sided expressions that get evaluated on each combination of outer and inner tuple
    // and either accept or reject that particular combination.
    // 4. The TVE expressions where neither inner nor outer tables are involved. This is not possible
    // for the currently supported two table joins but could change if number of tables > 2.
    // Constant Value Expression may fall into this category.
    classifyJoinExpressions(joinList, outerTables, innerTables, m_joinOuterList, m_joinInnerList, m_joinInnerOuterList, noneList);
    // Apply implied transitive constant filter to join expressions
    // outer.partkey = ? and outer.partkey = inner.partkey is equivalent to
    // outer.partkey = ? and inner.partkey = ?
    applyTransitiveEquivalence(m_joinOuterList, m_joinInnerList, m_joinInnerOuterList);
    // Classify where expressions into the following categories:
    // 1. The OUTER-only filter conditions. If any are false for a given outer tuple,
    // nothing in the join processing of that outer tuple will get it past this filter,
    // so it makes sense to "push this filter down" to pre-qualify the outer tuples before they enter the join.
    // 2. The INNER-only join conditions. If these conditions reject NULL inner tuple it make sense to
    // move them "up" to the join conditions, otherwise they must remain post-join conditions
    // to preserve outer join semantic
    // 3. The two-sided expressions. Same as the inner only conditions.
    // 4. The TVE expressions where neither inner nor outer tables are involved. Same as for the join expressions
    classifyJoinExpressions(whereList, outerTables, innerTables, m_whereOuterList, m_whereInnerList, m_whereInnerOuterList, noneList);
    // Apply implied transitive constant filter to where expressions
    applyTransitiveEquivalence(m_whereOuterList, m_whereInnerList, m_whereInnerOuterList);
    // In case of multi-table joins certain expressions could be pushed down to the children
    // to improve join performance.
    pushDownExpressions(noneList);
    Iterator<AbstractExpression> iter = noneList.iterator();
    while (iter.hasNext()) {
        AbstractExpression noneExpr = iter.next();
        // better with these predicates pushed down to the inner child node.
        if (noneExpr instanceof ConstantValueExpression) {
            m_whereInnerOuterList.add(noneExpr);
            iter.remove();
        }
    }
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) ArrayList(java.util.ArrayList)

Aggregations

ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)15 AbstractExpression (org.voltdb.expressions.AbstractExpression)12 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)8 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)7 ArrayList (java.util.ArrayList)5 HashSet (java.util.HashSet)3 Set (java.util.Set)3 VoltType (org.voltdb.VoltType)3 ColumnRef (org.voltdb.catalog.ColumnRef)3 StmtTableScan (org.voltdb.planner.parseinfo.StmtTableScan)3 SchemaColumn (org.voltdb.plannodes.SchemaColumn)3 JSONException (org.json_voltpatches.JSONException)2 Column (org.voltdb.catalog.Column)2 Constraint (org.voltdb.catalog.Constraint)2 Index (org.voltdb.catalog.Index)2 Table (org.voltdb.catalog.Table)2 OperatorExpression (org.voltdb.expressions.OperatorExpression)2 HashMap (java.util.HashMap)1 AggregateExpression (org.voltdb.expressions.AggregateExpression)1 ComparisonExpression (org.voltdb.expressions.ComparisonExpression)1