Search in sources :

Example 36 with VoltXMLElement

use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.

the class ParsedColInfo method fromOrderByXml.

/** Construct a ParsedColInfo from Volt XML.
     *  Allow caller to specify actions to finalize the parsed expression.
     */
public static ParsedColInfo fromOrderByXml(AbstractParsedStmt parsedStmt, VoltXMLElement orderByXml, ExpressionAdjuster adjuster) {
    // make sure everything is kosher
    assert (orderByXml.name.equalsIgnoreCase("orderby"));
    // get desc/asc
    String desc = orderByXml.attributes.get("desc");
    boolean descending = (desc != null) && (desc.equalsIgnoreCase("true"));
    // get the columnref or other expression inside the orderby node
    VoltXMLElement child = orderByXml.children.get(0);
    assert (child != null);
    // create the orderby column
    ParsedColInfo orderCol = new ParsedColInfo();
    orderCol.orderBy = true;
    orderCol.ascending = !descending;
    AbstractExpression orderExpr = parsedStmt.parseExpressionTree(child);
    assert (orderExpr != null);
    orderCol.expression = adjuster.adjust(orderExpr);
    // right thing later.
    if (orderExpr instanceof TupleValueExpression) {
        TupleValueExpression tve = (TupleValueExpression) orderExpr;
        orderCol.columnName = tve.getColumnName();
        orderCol.tableName = tve.getTableName();
        orderCol.tableAlias = tve.getTableAlias();
        if (orderCol.tableAlias == null) {
            orderCol.tableAlias = orderCol.tableName;
        }
        orderCol.alias = tve.getColumnAlias();
    } else {
        String alias = child.attributes.get("alias");
        orderCol.alias = alias;
        orderCol.tableName = AbstractParsedStmt.TEMP_TABLE_NAME;
        orderCol.tableAlias = AbstractParsedStmt.TEMP_TABLE_NAME;
        orderCol.columnName = "";
        if ((child.name.equals("operation") == false) && (child.name.equals("aggregation") == false) && (child.name.equals("win_aggregation") == false) && (child.name.equals("function") == false) && (child.name.equals("rank") == false) && (child.name.equals("value") == false) && (child.name.equals("columnref") == false)) {
            throw new RuntimeException("ORDER BY parsed with strange child node type: " + child.name);
        }
    }
    return orderCol;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Example 37 with VoltXMLElement

use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.

the class AbstractParsedStmt method parseTargetColumns.

void parseTargetColumns(VoltXMLElement columnsNode, Table table, HashMap<Column, AbstractExpression> columns) {
    for (VoltXMLElement child : columnsNode.children) {
        assert (child.name.equals("column"));
        String name = child.attributes.get("name");
        assert (name != null);
        Column col = table.getColumns().getExact(name.trim());
        // May be no children of column node in the case of
        //   INSERT INTO ... SELECT ...
        AbstractExpression expr = null;
        if (child.children.size() != 0) {
            assert (child.children.size() == 1);
            VoltXMLElement subChild = child.children.get(0);
            expr = parseExpressionTree(subChild);
            assert (expr != null);
            expr.refineValueType(VoltType.get((byte) col.getType()), col.getSize());
            ExpressionUtil.finalizeValueTypes(expr);
        }
        columns.put(col, expr);
    }
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) Column(org.voltdb.catalog.Column) SchemaColumn(org.voltdb.plannodes.SchemaColumn) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Example 38 with VoltXMLElement

use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.

the class AbstractParsedStmt method parseOperationExpression.

/**
     *
     * @param paramsById
     * @param exprNode
     * @return
     */
private AbstractExpression parseOperationExpression(VoltXMLElement exprNode) {
    String optype = exprNode.attributes.get("optype");
    ExpressionType exprType = ExpressionType.get(optype);
    AbstractExpression expr = null;
    if (exprType == ExpressionType.INVALID) {
        throw new PlanningErrorException("Unsupported operation type '" + optype + "'");
    }
    try {
        expr = exprType.getExpressionClass().newInstance();
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage(), e);
    }
    expr.setExpressionType(exprType);
    if (exprType == ExpressionType.OPERATOR_CASE_WHEN || exprType == ExpressionType.OPERATOR_ALTERNATIVE) {
        String valueType = exprNode.attributes.get("valuetype");
        expr.setValueType(VoltType.typeFromString(valueType));
    }
    if (expr instanceof ComparisonExpression) {
        String opsubtype = exprNode.attributes.get("opsubtype");
        if (opsubtype != null) {
            QuantifierType quantifier = QuantifierType.get(opsubtype);
            if (quantifier != QuantifierType.NONE) {
                ((ComparisonExpression) expr).setQuantifier(quantifier);
            }
        }
    }
    // get the first (left) node that is an element
    VoltXMLElement leftExprNode = exprNode.children.get(0);
    assert (leftExprNode != null);
    // recursively parse the left subtree (could be another operator or
    // a constant/tuple/param value operand).
    AbstractExpression leftExpr = parseExpressionNode(leftExprNode);
    assert ((leftExpr != null) || (exprType == ExpressionType.AGGREGATE_COUNT));
    expr.setLeft(leftExpr);
    // get the second (right) node that is an element (might be null)
    VoltXMLElement rightExprNode = null;
    if (exprNode.children.size() > 1) {
        rightExprNode = exprNode.children.get(1);
    }
    if (expr.needsRightExpression()) {
        assert (rightExprNode != null);
        // recursively parse the right subtree
        AbstractExpression rightExpr = parseExpressionNode(rightExprNode);
        assert (rightExpr != null);
        expr.setRight(rightExpr);
    } else {
        assert (rightExprNode == null);
        if (exprType == ExpressionType.OPERATOR_CAST) {
            String valuetype = exprNode.attributes.get("valuetype");
            assert (valuetype != null);
            VoltType voltType = VoltType.typeFromString(valuetype);
            expr.setValueType(voltType);
            // 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 = voltType.getMaxLengthInBytes();
            expr.setValueSize(size);
        }
    }
    if (exprType == ExpressionType.COMPARE_EQUAL && QuantifierType.ANY == ((ComparisonExpression) expr).getQuantifier()) {
        // Break up UNION/INTERSECT (ALL) set ops into individual selects connected by
        // AND/OR operator
        // col IN ( queryA UNION queryB ) - > col IN (queryA) OR col IN (queryB)
        // col IN ( queryA INTERSECTS queryB ) - > col IN (queryA) AND col IN (queryB)
        expr = ParsedUnionStmt.breakUpSetOpSubquery(expr);
    } else if (exprType == ExpressionType.OPERATOR_EXISTS) {
        expr = optimizeExistsExpression(expr);
    }
    return expr;
}
Also used : ComparisonExpression(org.voltdb.expressions.ComparisonExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltType(org.voltdb.VoltType) QuantifierType(org.voltdb.types.QuantifierType) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) ExpressionType(org.voltdb.types.ExpressionType) JSONException(org.json_voltpatches.JSONException) Constraint(org.voltdb.catalog.Constraint)

Example 39 with VoltXMLElement

use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.

the class IndexAVL method voltGetIndexXML.

/**
     * VoltDB added method to get a non-catalog-dependent
     * representation of this HSQLDB object.
     * @param session The current Session object may be needed to resolve
     * some names.
     * @return XML, correctly indented, representing this object.
     * @throws HSQLParseException
     */
@Override
public VoltXMLElement voltGetIndexXML(Session session, String tableName, Map<String, VoltXMLElement> indexConstraintMapping) throws org.hsqldb_voltpatches.HSQLInterface.HSQLParseException {
    org.hsqldb_voltpatches.VoltXMLElement index = new org.hsqldb_voltpatches.VoltXMLElement("index");
    // Add any expressions to the XML representation of the index,
    // and compute a hash that will help uniquify the generated name,
    // if a name was not provided.
    int exprHash = 0;
    if (exprs != null) {
        org.hsqldb_voltpatches.VoltXMLElement indexedExprs = new org.hsqldb_voltpatches.VoltXMLElement("exprs");
        index.children.add(indexedExprs);
        String hashExprString = new String();
        String sep = "";
        for (org.hsqldb_voltpatches.Expression expression : exprs) {
            org.hsqldb_voltpatches.VoltXMLElement xml = expression.voltGetExpressionXML(session, (Table) table);
            indexedExprs.children.add(xml);
            hashExprString += sep + expression.getSQL();
            sep = ",";
        }
        byte[] bytes = hashExprString.getBytes();
        for (int ii = 0; ii < bytes.length; ii++) {
            exprHash = 31 * exprHash + bytes[ii];
        }
    }
    String hsqlIndexName = getName().name;
    String voltdbIndexName = null;
    boolean isHashIndex = false;
    if (indexConstraintMapping.containsKey(hsqlIndexName)) {
        // This is an index backing a constraint.
        VoltXMLElement constraintXml = indexConstraintMapping.get(hsqlIndexName);
        indexConstraintMapping.remove(hsqlIndexName);
        boolean isAutoName = constraintXml.attributes.get("nameisauto").equals("true");
        // This is either a [ASSUME]UNIQUE constraint or a PK.
        String constraintType = constraintXml.attributes.get("constrainttype");
        String hsqlConstraintName = constraintXml.attributes.get("name");
        if (!isAutoName) {
            isHashIndex = isNameRequestingHashIndex(hsqlConstraintName);
            voltdbIndexName = HSQLInterface.AUTO_GEN_NAMED_CONSTRAINT_IDX + hsqlConstraintName;
        } else {
            String prefix = null;
            boolean isPrimaryKey = constraintType.equals("PRIMARY_KEY");
            if (isPrimaryKey) {
                prefix = HSQLInterface.AUTO_GEN_PRIMARY_KEY_PREFIX;
            } else {
                prefix = HSQLInterface.AUTO_GEN_UNIQUE_IDX_PREFIX;
            }
            String namePart = tableName + "_" + StringUtils.join(getColumnNameList().toArray(), "_");
            if (exprs != null) {
                namePart += "_" + java.lang.Math.abs(exprHash % 100000);
            }
            voltdbIndexName = prefix + namePart;
            // Also name the constraint here based on our naming scheme.
            String voltdbConstraintName = null;
            if (isPrimaryKey) {
                voltdbConstraintName = HSQLInterface.AUTO_GEN_CONSTRAINT_PREFIX + "_PK_" + namePart;
            } else {
                voltdbConstraintName = HSQLInterface.AUTO_GEN_CONSTRAINT_PREFIX + "_CT_" + namePart;
            }
            constraintXml.attributes.put("name", voltdbConstraintName);
        }
        // Update the index name in the constraint.
        constraintXml.attributes.put("index", voltdbIndexName);
    } else {
        // This is an index created via CREATE INDEX
        isHashIndex = isNameRequestingHashIndex(hsqlIndexName);
        voltdbIndexName = hsqlIndexName;
    }
    index.attributes.put("name", voltdbIndexName);
    index.attributes.put("ishashindex", isHashIndex ? "true" : "false");
    index.attributes.put("assumeunique", isAssumeUnique() ? "true" : "false");
    index.attributes.put("unique", isUnique() ? "true" : "false");
    Object[] columnList = getColumnNameList().toArray();
    index.attributes.put("columns", StringUtils.join(columnList, ","));
    if (predicate != null) {
        org.hsqldb_voltpatches.VoltXMLElement partialExpr = new org.hsqldb_voltpatches.VoltXMLElement("predicate");
        index.children.add(partialExpr);
        org.hsqldb_voltpatches.VoltXMLElement xml = predicate.voltGetExpressionXML(session, (Table) table);
        partialExpr.children.add(xml);
    }
    return index;
}
Also used : VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) SchemaObject(org.hsqldb_voltpatches.SchemaObject) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Example 40 with VoltXMLElement

use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.

the class ParsedSelectStmt method parse.

@Override
void parse(VoltXMLElement stmtNode) {
    String node;
    if ((node = stmtNode.attributes.get("distinct")) != null) {
        m_distinct = Boolean.parseBoolean(node);
    }
    VoltXMLElement limitElement = null;
    VoltXMLElement offsetElement = null;
    VoltXMLElement havingElement = null;
    VoltXMLElement displayElement = null;
    VoltXMLElement orderbyElement = null;
    VoltXMLElement groupbyElement = null;
    for (VoltXMLElement child : stmtNode.children) {
        if (child.name.equalsIgnoreCase("limit")) {
            assert (limitElement == null);
            limitElement = child;
        } else if (child.name.equalsIgnoreCase("offset")) {
            assert (offsetElement == null);
            offsetElement = child;
        } else if (child.name.equalsIgnoreCase("columns")) {
            assert (displayElement == null);
            displayElement = child;
        } else if (child.name.equalsIgnoreCase("ordercolumns")) {
            assert (orderbyElement == null);
            orderbyElement = child;
        } else if (child.name.equalsIgnoreCase("groupcolumns")) {
            assert (groupbyElement == null);
            groupbyElement = child;
        } else if (child.name.equalsIgnoreCase("having")) {
            assert (havingElement == null);
            havingElement = child;
        }
    }
    parseLimitAndOffset(limitElement, offsetElement, m_limitOffset);
    if (m_aggregationList == null) {
        m_aggregationList = new ArrayList<>();
    }
    // finding TVEs for pass-through columns.
    assert (displayElement != null);
    parseDisplayColumns(displayElement, false);
    // rewrite DISTINCT
    // function may need to change the groupbyElement by rewriting.
    groupbyElement = processDistinct(displayElement, groupbyElement, havingElement);
    if (groupbyElement != null) {
        parseGroupByColumns(groupbyElement);
        insertToColumnList(m_aggResultColumns, m_groupByColumns);
    }
    if (havingElement != null) {
        parseHavingExpression(havingElement, false);
    }
    if (orderbyElement != null && !hasAOneRowResult()) {
        parseOrderColumns(orderbyElement, false);
    }
    // At this point, we have collected all aggregations in the select
    // statement. We do not need aggregationList container in parseXMLtree
    // Make it null to prevent others adding elements to it when parsing
    // the tree.
    m_aggregationList = null;
    if (needComplexAggregation()) {
        fillUpAggResultColumns();
    } else {
        m_aggResultColumns = m_displayColumns;
    }
    // If we have seen any windowed expressions we will have
    // saved them in m_windowFunctionExpressions by now.  We need to
    // verify their validity.
    verifyWindowFunctionExpressions();
    /*
         * Calculate the content determinism message before we place the TVEs in
         * the columns. After the TVEs are placed the actual expressions are
         * hard to find.
         */
    calculateContentDeterminismMessage();
    placeTVEsinColumns();
    // prepare the limit plan node if it needs one.
    if (hasLimitOrOffset()) {
        m_limitOffset.m_limitCanPushdown = canPushdownLimit();
        prepareLimitPlanNode(this, m_limitOffset);
    }
    // Prepare for the AVG push-down optimization only if it might be required.
    if (mayNeedAvgPushdown()) {
        processAvgPushdownOptimization(displayElement, groupbyElement, havingElement, orderbyElement);
    }
    prepareMVBasedQueryFix();
}
Also used : VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Aggregations

VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)62 AbstractExpression (org.voltdb.expressions.AbstractExpression)14 Constraint (org.voltdb.catalog.Constraint)13 VoltCompilerException (org.voltdb.compiler.VoltCompiler.VoltCompilerException)10 ArrayList (java.util.ArrayList)9 VoltType (org.voltdb.VoltType)7 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)6 HSQLInterface (org.hsqldb_voltpatches.HSQLInterface)5 VoltXMLDiff (org.hsqldb_voltpatches.VoltXMLElement.VoltXMLDiff)5 Column (org.voltdb.catalog.Column)5 Table (org.voltdb.catalog.Table)5 Matcher (java.util.regex.Matcher)4 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 HSQLParseException (org.hsqldb_voltpatches.HSQLInterface.HSQLParseException)3 JSONException (org.json_voltpatches.JSONException)3 Index (org.voltdb.catalog.Index)3 Statement (org.voltdb.catalog.Statement)3 StmtSubqueryScan (org.voltdb.planner.parseinfo.StmtSubqueryScan)3 ExpressionType (org.voltdb.types.ExpressionType)3