Search in sources :

Example 1 with ParameterValueExpression

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

the class AbstractParsedStmt method parseParameters.

/**
     * Populate the statement's paramList from the "parameters" element. Each
     * parameter has an id and an index, both of which are numeric. It also has
     * a type and an indication of whether it's a vector parameter. For each
     * parameter, we create a ParameterValueExpression, named pve, which holds
     * the type and vector parameter indication. We add the pve to two maps,
     * m_paramsById and m_paramsByIndex.
     *
     * We also set a counter, MAX_PARAMETER_ID, to the largest id in the
     * expression. This helps give ids to references to correlated expressions
     * of subqueries.
     *
     * @param paramsNode
     */
protected void parseParameters(VoltXMLElement root) {
    VoltXMLElement paramsNode = null;
    for (VoltXMLElement node : root.children) {
        if (node.name.equalsIgnoreCase("parameters")) {
            paramsNode = node;
            break;
        }
    }
    if (paramsNode == null) {
        return;
    }
    long max_parameter_id = -1;
    for (VoltXMLElement node : paramsNode.children) {
        if (node.name.equalsIgnoreCase("parameter")) {
            long id = Long.parseLong(node.attributes.get("id"));
            int index = Integer.parseInt(node.attributes.get("index"));
            if (index > max_parameter_id) {
                max_parameter_id = index;
            }
            String typeName = node.attributes.get("valuetype");
            String isVectorParam = node.attributes.get("isvector");
            VoltType type = VoltType.typeFromString(typeName);
            ParameterValueExpression pve = new ParameterValueExpression();
            pve.setParameterIndex(index);
            pve.setValueType(type);
            if (isVectorParam != null && isVectorParam.equalsIgnoreCase("true")) {
                pve.setParamIsVector();
            }
            m_paramsById.put(id, pve);
            m_paramsByIndex.put(index, pve);
        }
    }
    if (max_parameter_id >= NEXT_PARAMETER_ID) {
        NEXT_PARAMETER_ID = (int) max_parameter_id + 1;
    }
}
Also used : VoltType(org.voltdb.VoltType) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) Constraint(org.voltdb.catalog.Constraint)

Example 2 with ParameterValueExpression

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

the class AbstractParsedStmt method parseValueExpression.

/**
     *
     * @param paramsById
     * @param exprNode
     * @return
     */
private AbstractExpression parseValueExpression(VoltXMLElement exprNode) {
    String isParam = exprNode.attributes.get("isparam");
    String isPlannerGenerated = exprNode.attributes.get("isplannergenerated");
    // A ParameterValueExpression is needed to represent any user-provided or planner-injected parameter.
    boolean needParameter = (isParam != null) && (isParam.equalsIgnoreCase("true"));
    // A ConstantValueExpression is needed to represent a constant in the statement,
    // EVEN if that constant has been "parameterized" by the plan caching code.
    ConstantValueExpression cve = null;
    boolean needConstant = (needParameter == false) || ((isPlannerGenerated != null) && (isPlannerGenerated.equalsIgnoreCase("true")));
    if (needConstant) {
        String type = exprNode.attributes.get("valuetype");
        VoltType vt = VoltType.typeFromString(type);
        assert (vt != VoltType.VOLTTABLE);
        cve = new ConstantValueExpression();
        cve.setValueType(vt);
        if ((vt != VoltType.NULL) && (vt != VoltType.NUMERIC)) {
            int size = vt.getMaxLengthInBytes();
            cve.setValueSize(size);
        }
        if (!needParameter && vt != VoltType.NULL) {
            String valueStr = exprNode.attributes.get("value");
            // given type.
            if (valueStr != null) {
                try {
                    switch(vt) {
                        case BIGINT:
                        case TIMESTAMP:
                            Long.valueOf(valueStr);
                            break;
                        case FLOAT:
                            Double.valueOf(valueStr);
                            break;
                        case DECIMAL:
                            VoltDecimalHelper.stringToDecimal(valueStr);
                            break;
                        default:
                            break;
                    }
                } catch (PlanningErrorException ex) {
                    // We're happy with these.
                    throw ex;
                } catch (NumberFormatException ex) {
                    throw new PlanningErrorException("Numeric conversion error to type " + vt.name() + " " + ex.getMessage().toLowerCase());
                } catch (Exception ex) {
                    throw new PlanningErrorException(ex.getMessage());
                }
            }
            cve.setValue(valueStr);
        }
    }
    if (needParameter) {
        long id = Long.parseLong(exprNode.attributes.get("id"));
        ParameterValueExpression expr = m_paramsById.get(id);
        assert (expr != null);
        if (needConstant) {
            expr.setOriginalValue(cve);
            cve.setValue(m_paramValues[expr.getParameterIndex()]);
        }
        return expr;
    }
    return cve;
}
Also used : VoltType(org.voltdb.VoltType) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) Constraint(org.voltdb.catalog.Constraint) JSONException(org.json_voltpatches.JSONException)

Example 3 with ParameterValueExpression

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

the class AbstractParsedStmt method replaceExpressionsWithPve.

/**
     * Helper method to replace all TVEs and aggregated expressions with the corresponding PVEs.
     * The original expressions are placed into the map to be propagated to the EE.
     * The key to the map is the parameter index.
     *
     *
     * @param stmt - subquery statement
     * @param expr - expression with parent TVEs
     * @return Expression with parent TVE replaced with PVE
     */
protected AbstractExpression replaceExpressionsWithPve(AbstractExpression expr) {
    assert (expr != null);
    if (expr instanceof TupleValueExpression) {
        int paramIdx = NEXT_PARAMETER_ID++;
        ParameterValueExpression pve = new ParameterValueExpression(paramIdx, expr);
        m_parameterTveMap.put(paramIdx, expr);
        return pve;
    }
    if (expr instanceof AggregateExpression) {
        int paramIdx = NEXT_PARAMETER_ID++;
        ParameterValueExpression pve = new ParameterValueExpression(paramIdx, expr);
        // Disallow aggregation of parent columns in a subquery.
        // except the case HAVING AGG(T1.C1) IN (SELECT T2.C2 ...)
        List<TupleValueExpression> tves = ExpressionUtil.getTupleValueExpressions(expr);
        assert (m_parentStmt != null);
        for (TupleValueExpression tve : tves) {
            int origId = tve.getOrigStmtId();
            if (m_stmtId != origId && m_parentStmt.m_stmtId != origId) {
                throw new PlanningErrorException("Subqueries do not support aggregation of parent statement columns");
            }
        }
        m_parameterTveMap.put(paramIdx, expr);
        return pve;
    }
    if (expr.getLeft() != null) {
        expr.setLeft(replaceExpressionsWithPve(expr.getLeft()));
    }
    if (expr.getRight() != null) {
        expr.setRight(replaceExpressionsWithPve(expr.getRight()));
    }
    if (expr.getArgs() != null) {
        List<AbstractExpression> newArgs = new ArrayList<>();
        for (AbstractExpression argument : expr.getArgs()) {
            newArgs.add(replaceExpressionsWithPve(argument));
        }
        expr.setArgs(newArgs);
    }
    return expr;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) ArrayList(java.util.ArrayList) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) AggregateExpression(org.voltdb.expressions.AggregateExpression) Constraint(org.voltdb.catalog.Constraint)

Example 4 with ParameterValueExpression

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

the class AbstractParsedStmt method parseColumnRefExpression.

/**
     *
     * @param exprNode
     * @return
     */
private AbstractExpression parseColumnRefExpression(VoltXMLElement exprNode) {
    String tableName = exprNode.attributes.get("table");
    if (tableName == null) {
        assert (m_DDLIndexedTable != null);
        tableName = m_DDLIndexedTable.getTypeName();
    }
    assert (tableName != null);
    String tableAlias = exprNode.attributes.get("tablealias");
    if (tableAlias == null) {
        tableAlias = tableName;
    }
    String columnName = exprNode.attributes.get("column");
    String columnAlias = exprNode.attributes.get("alias");
    // Whether or not this column is the coalesced column produced by a join with a
    // USING predicate.
    String usingAttr = exprNode.attributes.get("using");
    boolean isUsingColumn = usingAttr != null ? Boolean.parseBoolean(usingAttr) : false;
    // Use the index produced by HSQL as a way to differentiate columns that have
    // the same name with a single table (which can happen for subqueries containing joins).
    int differentiator = Integer.parseInt(exprNode.attributes.get("index"));
    if (differentiator == -1 && isUsingColumn) {
        for (VoltXMLElement usingElem : exprNode.children) {
            String usingTableAlias = usingElem.attributes.get("tablealias");
            if (usingTableAlias != null && usingTableAlias.equals(tableAlias)) {
                differentiator = Integer.parseInt(usingElem.attributes.get("index"));
            }
        }
    }
    TupleValueExpression tve = new TupleValueExpression(tableName, tableAlias, columnName, columnAlias, -1, differentiator);
    // Collect the unique columns used in the plan for a given scan.
    // Resolve the tve and add it to the scan's cache of referenced columns
    // Get tableScan where this TVE is originated from. In case of the
    // correlated queries it may not be THIS statement but its parent
    StmtTableScan tableScan = resolveStmtTableScanByAlias(tableAlias);
    if (tableScan == null) {
        // from TestVoltCompler.testScalarSubqueriesExpectedFailures.
        throw new PlanningErrorException("Object not found: " + tableAlias);
    }
    AbstractExpression resolvedExpr = tableScan.resolveTVE(tve);
    if (m_stmtId == tableScan.getStatementId()) {
        return resolvedExpr;
    }
    // This is a TVE from the correlated expression
    int paramIdx = NEXT_PARAMETER_ID++;
    ParameterValueExpression pve = new ParameterValueExpression(paramIdx, resolvedExpr);
    m_parameterTveMap.put(paramIdx, resolvedExpr);
    return pve;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) Constraint(org.voltdb.catalog.Constraint) StmtTableScan(org.voltdb.planner.parseinfo.StmtTableScan)

Example 5 with ParameterValueExpression

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

the class AbstractParsedStmt method parameterCountIndexById.

/// This is for use with integer-valued row count parameters, namely LIMITs and OFFSETs.
/// It should be called (at least) once for each LIMIT or OFFSET parameter to establish that
/// the parameter is being used in a BIGINT context.
/// There may be limitations elsewhere that restrict limits and offsets to 31-bit unsigned values,
/// but enforcing that at parameter passing/checking time seems a little arbitrary, so we keep
/// the parameters at maximum width -- a 63-bit unsigned BIGINT.
protected int parameterCountIndexById(long paramId) {
    if (paramId == -1) {
        return -1;
    }
    assert (m_paramsById.containsKey(paramId));
    ParameterValueExpression pve = m_paramsById.get(paramId);
    // As a side effect, re-establish these parameters as integer-typed
    // -- this helps to catch type errors earlier in the invocation process
    // and prevents a more serious error in HSQLBackend statement reconstruction.
    // The HSQL parser originally had these correctly pegged as BIGINTs,
    // but the VoltDB code ( @see AbstractParsedStmt#parseParameters )
    // skeptically second-guesses that pending its own verification. This case is now verified.
    pve.refineValueType(VoltType.BIGINT, VoltType.BIGINT.getLengthInBytesForFixedTypes());
    return pve.getParameterIndex();
}
Also used : ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression)

Aggregations

ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)25 AbstractExpression (org.voltdb.expressions.AbstractExpression)16 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)9 ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)8 Constraint (org.voltdb.catalog.Constraint)6 StmtTableScan (org.voltdb.planner.parseinfo.StmtTableScan)5 ArrayList (java.util.ArrayList)4 Statement (org.voltdb.catalog.Statement)4 Table (org.voltdb.catalog.Table)4 SchemaColumn (org.voltdb.plannodes.SchemaColumn)4 VoltType (org.voltdb.VoltType)3 ProcParameter (org.voltdb.catalog.ProcParameter)3 Procedure (org.voltdb.catalog.Procedure)3 StmtParameter (org.voltdb.catalog.StmtParameter)3 StatementPartitioning (org.voltdb.planner.StatementPartitioning)3 QueryType (org.voltdb.types.QueryType)3 HashSet (java.util.HashSet)2 Set (java.util.Set)2 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)2 JSONException (org.json_voltpatches.JSONException)2