Search in sources :

Example 31 with VoltXMLElement

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

the class ParsedInsertStmt method parse.

@Override
void parse(VoltXMLElement stmtNode) {
    // but those table scans will belong to the corresponding ParsedSelectStmt
    assert (m_tableList.isEmpty());
    String tableName = stmtNode.attributes.get("table");
    // Need to add the table to the cache. It may be required to resolve the
    // correlated TVE in case of WHERE clause contains IN subquery
    Table table = getTableFromDB(tableName);
    addTableToStmtCache(table, tableName);
    m_tableList.add(table);
    for (VoltXMLElement node : stmtNode.children) {
        if (node.name.equals("columns")) {
            parseTargetColumns(node, table, m_columns);
        } else if (node.name.equals(SELECT_NODE_NAME)) {
            m_subquery = new StmtSubqueryScan(parseSubquery(node), "__VOLT_INSERT_SUBQUERY__");
            // Until scalar subqueries are allowed in INSERT ... VALUES statements,
            // The top-level SELECT subquery in an INSERT ... SELECT statement
            // is the only possible subselect in an INSERT statement.
            m_scans.add(m_subquery);
        } else if (node.name.equals(UNION_NODE_NAME)) {
            throw new PlanningErrorException("INSERT INTO ... SELECT is not supported for UNION or other set operations.");
        }
    }
    calculateContentDeterminismMessage();
}
Also used : StmtSubqueryScan(org.voltdb.planner.parseinfo.StmtSubqueryScan) Table(org.voltdb.catalog.Table) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Example 32 with VoltXMLElement

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

the class AbstractParsedStmt method parseTable.

/**
     *
     * @param tableNode
     */
private void parseTable(VoltXMLElement tableNode) {
    String tableName = tableNode.attributes.get("table");
    assert (tableName != null);
    String tableAlias = tableNode.attributes.get("tablealias");
    if (tableAlias == null) {
        tableAlias = tableName;
    }
    // Hsql rejects name conflicts in a single query
    m_tableAliasListAsJoinOrder.add(tableAlias);
    VoltXMLElement subqueryElement = null;
    // Possible sub-query
    for (VoltXMLElement childNode : tableNode.children) {
        if (!childNode.name.equals("tablesubquery")) {
            continue;
        }
        if (childNode.children.isEmpty()) {
            continue;
        }
        // sub-query FROM (SELECT ...)
        subqueryElement = childNode.children.get(0);
        break;
    }
    // add table to the query cache before processing the JOIN/WHERE expressions
    // The order is important because processing sub-query expressions assumes that
    // the sub-query is already registered
    StmtTableScan tableScan = null;
    Table table = null;
    // In case of a subquery we need to preserve its filter expressions
    AbstractExpression simplifiedSubqueryFilter = null;
    if (subqueryElement == null) {
        table = getTableFromDB(tableName);
        assert (table != null);
        tableScan = addTableToStmtCache(table, tableAlias);
        m_tableList.add(table);
    } else {
        AbstractParsedStmt subquery = parseFromSubQuery(subqueryElement);
        StmtSubqueryScan subqueryScan = addSubqueryToStmtCache(subquery, tableAlias);
        tableScan = subqueryScan;
        StmtTargetTableScan simpler = simplifierForSubquery(subquery);
        if (simpler != null) {
            tableScan = addSimplifiedSubqueryToStmtCache(subqueryScan, simpler);
            table = simpler.getTargetTable();
            // Extract subquery's filters
            assert (subquery.m_joinTree != null);
            // Adjust the table alias in all TVEs from the eliminated
            // subquery expressions. Example:
            // SELECT TA2.CA FROM (SELECT C CA FROM T TA1 WHERE C > 0) TA2
            // The table alias TA1 from the original TVE (T)TA1.C from the
            // subquery WHERE condition needs to be replaced with the alias
            // TA2. The new TVE will be (T)TA2.C.
            // The column alias does not require an adjustment.
            simplifiedSubqueryFilter = subquery.m_joinTree.getAllFilters();
            List<TupleValueExpression> tves = ExpressionUtil.getTupleValueExpressions(simplifiedSubqueryFilter);
            for (TupleValueExpression tve : tves) {
                tve.setTableAlias(tableScan.getTableAlias());
                tve.setOrigStmtId(m_stmtId);
            }
        }
    }
    AbstractExpression joinExpr = parseJoinCondition(tableNode);
    AbstractExpression whereExpr = parseWhereCondition(tableNode);
    if (simplifiedSubqueryFilter != null) {
        // Add subqueruy's expressions as JOIN filters to make sure they will
        // stay at the node level in case of an OUTER joins and won't affect
        // the join simplification process:
        // select * from T LEFT JOIN (select C FROM T1 WHERE C > 2) S ON T.C = S.C;
        joinExpr = (joinExpr != null) ? ExpressionUtil.combine(joinExpr, simplifiedSubqueryFilter) : simplifiedSubqueryFilter;
    }
    // The join type of the leaf node is always INNER
    // For a new tree its node's ids start with 0 and keep incrementing by 1
    int nodeId = (m_joinTree == null) ? 0 : m_joinTree.getId() + 1;
    JoinNode leafNode;
    if (table != null) {
        assert (tableScan instanceof StmtTargetTableScan);
        leafNode = new TableLeafNode(nodeId, joinExpr, whereExpr, (StmtTargetTableScan) tableScan);
    } else {
        assert (tableScan instanceof StmtSubqueryScan);
        leafNode = new SubqueryLeafNode(nodeId, joinExpr, whereExpr, (StmtSubqueryScan) tableScan);
        leafNode.updateContentDeterminismMessage(((StmtSubqueryScan) tableScan).calculateContentDeterminismMessage());
    }
    if (m_joinTree == null) {
        // this is the first table
        m_joinTree = leafNode;
    } else {
        // Build the tree by attaching the next table always to the right
        // The node's join type is determined by the type of its right node
        JoinType joinType = JoinType.get(tableNode.attributes.get("jointype"));
        assert (joinType != JoinType.INVALID);
        JoinNode joinNode = new BranchNode(nodeId + 1, joinType, m_joinTree, leafNode);
        m_joinTree = joinNode;
    }
}
Also used : StmtSubqueryScan(org.voltdb.planner.parseinfo.StmtSubqueryScan) TupleValueExpression(org.voltdb.expressions.TupleValueExpression) Table(org.voltdb.catalog.Table) TableLeafNode(org.voltdb.planner.parseinfo.TableLeafNode) JoinNode(org.voltdb.planner.parseinfo.JoinNode) JoinType(org.voltdb.types.JoinType) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) Constraint(org.voltdb.catalog.Constraint) StmtTableScan(org.voltdb.planner.parseinfo.StmtTableScan) BranchNode(org.voltdb.planner.parseinfo.BranchNode) AbstractExpression(org.voltdb.expressions.AbstractExpression) SubqueryLeafNode(org.voltdb.planner.parseinfo.SubqueryLeafNode) StmtTargetTableScan(org.voltdb.planner.parseinfo.StmtTargetTableScan)

Example 33 with VoltXMLElement

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

the class AbstractParsedStmt method parseAggregationExpression.

/**
     *
     * @param paramsById
     * @param exprNode
     * @return
     */
private AbstractExpression parseAggregationExpression(VoltXMLElement exprNode) {
    String type = exprNode.attributes.get("optype");
    ExpressionType exprType = ExpressionType.get(type);
    if (exprType == ExpressionType.INVALID) {
        throw new PlanningErrorException("Unsupported aggregation type '" + type + "'");
    }
    assert (exprNode.children.size() <= 1);
    // get the single required child node
    VoltXMLElement childExprNode = exprNode.children.get(0);
    assert (childExprNode != null);
    // recursively parse the child subtree -- could (in theory) be an operator or
    // a constant, column, or param value operand or null in the specific case of "COUNT(*)".
    AbstractExpression childExpr = parseExpressionNode(childExprNode);
    if (childExpr == null) {
        assert (exprType == ExpressionType.AGGREGATE_COUNT);
        exprType = ExpressionType.AGGREGATE_COUNT_STAR;
    }
    AggregateExpression expr = new AggregateExpression(exprType);
    expr.setLeft(childExpr);
    String node;
    if ((node = exprNode.attributes.get("distinct")) != null && Boolean.parseBoolean(node)) {
        expr.setDistinct();
    }
    if (m_aggregationList != null) {
        ExpressionUtil.finalizeValueTypes(expr);
        m_aggregationList.add(expr);
    }
    return expr;
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) AggregateExpression(org.voltdb.expressions.AggregateExpression) ExpressionType(org.voltdb.types.ExpressionType)

Example 34 with VoltXMLElement

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

the class ParameterizationInfo method findUserParametersRecursively.

public static void findUserParametersRecursively(final VoltXMLElement xmlSQL, Set<Integer> paramIds) {
    if (xmlSQL.name.equals("union")) {
        // UNION has its parameters on the individual selects level
        for (VoltXMLElement xmlChildSQL : xmlSQL.children) {
            findUserParametersRecursively(xmlChildSQL, paramIds);
        }
    } else {
        // find the parameters xml node
        for (VoltXMLElement child : xmlSQL.children) {
            if (!child.name.equals("parameters")) {
                continue;
            }
            // also including its subqueries if it has.
            for (VoltXMLElement node : child.children) {
                String idStr = node.attributes.get("id");
                assert (idStr != null);
                // ID attribute is assumed to be global unique per query.
                // but for UNION query, "paramerters" are copied to each query level.
                paramIds.add(Integer.parseInt(idStr));
            }
            // there is ONLY one parameters element per query
            break;
        }
    }
}
Also used : VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement)

Example 35 with VoltXMLElement

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

the class ParameterizationInfo method parameterizeRecursively.

static void parameterizeRecursively(VoltXMLElement node, VoltXMLElement paramsNode, Map<String, Integer> idToParamIndexMap, List<String> paramValues) {
    if (node.name.equals("value")) {
        String idStr = node.attributes.get("id");
        assert (idStr != null);
        // A value id is currently a "string-formatted long", but there's no need to commit
        // to that format in this early processing -- here, the id just needs to be a unique
        // string for each parsed value. It allows hsql to replicate a parameter reference
        // within its parse trees without causing code like this to lose track of its identity.
        Integer paramIndex = idToParamIndexMap.get(idStr);
        if (paramIndex == null) {
            // Use the next param index for each new value with an unfamiliar id,
            // starting at 0.
            paramIndex = paramValues.size();
            // Later references to this value's id will re-use this same param index.
            idToParamIndexMap.put(idStr, paramIndex);
            VoltXMLElement paramIndexNode = new VoltXMLElement("parameter");
            paramIndexNode.attributes.put("index", String.valueOf(paramIndex));
            paramIndexNode.attributes.put("id", idStr);
            paramsNode.children.add(paramIndexNode);
            // handle parameter value type
            String typeStr = node.attributes.get("valuetype");
            VoltType vt = VoltType.typeFromString(typeStr);
            String value = null;
            if (vt != VoltType.NULL) {
                value = node.attributes.get("value");
            }
            paramValues.add(value);
            // Thanks for Hsqldb 1.9, FLOAT literal values have been handled well with E sign.
            if (vt == VoltType.NUMERIC) {
                vt = VoltTypeUtil.getNumericLiteralType(VoltType.BIGINT, value);
            }
            node.attributes.put("valuetype", vt.getName());
            paramIndexNode.attributes.put("valuetype", vt.getName());
        }
        // Assume that all values, whether or not their ids have been seen before, can
        // be considered planner-generated parameters (proxies for user-provided constants).
        // This is one simplification that leverages the fact that statements that came with
        // user-provided parameters were barred from being (further) parameterized.
        node.attributes.put("isparam", "true");
        node.attributes.put("isplannergenerated", "true");
        // Remove the "value" attribute -- this is the critical step to folding
        // different raw VoltXML trees into the same parameterized VoltXML tree.
        // The value differences are extracted into paramValues for future reference by:
        //     the execution engine which needs to substitute actual values for all parameters
        //         to run the query
        //     the index scan planner which may need to "bind" the parameters to their original
        //     values to apply indexes on expressions like "(colA + 2 * colB)" when used in a query
        //     like "... WHERE t2.colA + 2 * t2.colB > 3*t1.colC".
        node.attributes.remove("value");
    }
    for (VoltXMLElement child : node.children) {
        parameterizeRecursively(child, paramsNode, idToParamIndexMap, paramValues);
    }
}
Also used : VoltType(org.voltdb.VoltType) 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