Search in sources :

Example 31 with VoltType

use of org.voltdb.VoltType in project voltdb by VoltDB.

the class ParsedSelectStmt method verifyWindowFunctionExpressions.

/**
     * Verify the validity of the windowed expressions.
     *
     * @return
     */
private void verifyWindowFunctionExpressions() {
    // Check for windowed expressions.
    if (m_windowFunctionExpressions.size() > 0) {
        if (m_windowFunctionExpressions.size() > 1) {
            throw new PlanningErrorException("Only one windowed function call may appear in a selection list.");
        }
        if (m_hasAggregateExpression) {
            throw new PlanningErrorException("Use of window functions (in an OVER clause) isn't supported with other aggregate functions on the SELECT list.");
        }
        if (m_windowFunctionExpressions.get(0).hasSubqueryArgs()) {
            throw new PlanningErrorException("Window function calls with subquery expression arguments are not allowed.");
        }
        //
        // This could be an if statement, but I think it's better to
        // leave this as a pattern in case we decide to implement more
        // legality conditions for other windowed operators.
        //
        WindowFunctionExpression windowFunctionExpression = m_windowFunctionExpressions.get(0);
        List<AbstractExpression> orderByExpressions = windowFunctionExpression.getOrderByExpressions();
        ExpressionType exprType = windowFunctionExpression.getExpressionType();
        String aggName = exprType.symbol().toUpperCase();
        switch(exprType) {
            case AGGREGATE_WINDOWED_RANK:
            case AGGREGATE_WINDOWED_DENSE_RANK:
                if (orderByExpressions.size() == 0) {
                    throw new PlanningErrorException("Windowed " + aggName + " function call expressions require an ORDER BY specification.");
                }
                VoltType valType = orderByExpressions.get(0).getValueType();
                assert (valType != null);
                if (!valType.isAnyIntegerType() && (valType != VoltType.TIMESTAMP)) {
                    throw new PlanningErrorException("Windowed function call expressions can have only integer or TIMESTAMP value types in the ORDER BY expression of their window.");
                }
                break;
            case AGGREGATE_WINDOWED_COUNT:
                if (windowFunctionExpression.getAggregateArguments().size() > 1) {
                    throw new PlanningErrorException(String.format("Windowed COUNT must have either exactly one argument or else a star for an argument"));
                }
                // Any type is ok, so we won't inspect the type.
                break;
            case AGGREGATE_WINDOWED_MAX:
            case AGGREGATE_WINDOWED_MIN:
                if (windowFunctionExpression.getAggregateArguments().size() != 1) {
                    throw new PlanningErrorException(String.format("Windowed %s must have exactly one argument", aggName));
                }
                // Any type is ok, so we won't inspect the type.
                break;
            case AGGREGATE_WINDOWED_SUM:
                if (windowFunctionExpression.getAggregateArguments().size() != 1) {
                    throw new PlanningErrorException(String.format("Windowed SUM must have exactly one numeric argument"));
                }
                AbstractExpression arg = windowFunctionExpression.getAggregateArguments().get(0);
                VoltType vt = arg.getValueType();
                assert (vt != null);
                if (!vt.isNumber()) {
                    throw new PlanningErrorException("Windowed SUM must have exactly one numeric argument");
                }
                break;
            default:
                {
                    String opName = (exprType == null) ? "NULL" : exprType.symbol();
                    throw new PlanningErrorException("Unknown windowed aggregate function type: " + opName);
                }
        }
    }
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) VoltType(org.voltdb.VoltType) WindowFunctionExpression(org.voltdb.expressions.WindowFunctionExpression) ExpressionType(org.voltdb.types.ExpressionType)

Example 32 with VoltType

use of org.voltdb.VoltType 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 33 with VoltType

use of org.voltdb.VoltType in project voltdb by VoltDB.

the class AdHocNTBase method runNonDDLAdHoc.

/**
     * Plan and execute a batch of DML/DQL sql. Any DDL has been filtered out at this point.
     */
protected CompletableFuture<ClientResponse> runNonDDLAdHoc(CatalogContext context, List<String> sqlStatements, boolean inferPartitioning, Object userPartitionKey, ExplainMode explainMode, boolean isSwapTables, Object[] userParamSet) {
    // catch races vs. updateApplicationCatalog.
    if (context == null) {
        context = VoltDB.instance().getCatalogContext();
    }
    List<String> errorMsgs = new ArrayList<>();
    List<AdHocPlannedStatement> stmts = new ArrayList<>();
    int partitionParamIndex = -1;
    VoltType partitionParamType = null;
    Object partitionParamValue = null;
    assert (sqlStatements != null);
    boolean inferSP = (sqlStatements.size() == 1) && inferPartitioning;
    if (userParamSet != null && userParamSet.length > 0) {
        if (sqlStatements.size() != 1) {
            return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, AdHocErrorResponseMessage);
        }
    }
    for (final String sqlStatement : sqlStatements) {
        try {
            AdHocPlannedStatement result = compileAdHocSQL(context, sqlStatement, inferSP, userPartitionKey, explainMode, isSwapTables, userParamSet);
            // and generated a partition parameter.
            if (inferSP) {
                partitionParamIndex = result.getPartitioningParameterIndex();
                partitionParamType = result.getPartitioningParameterType();
                partitionParamValue = result.getPartitioningParameterValue();
            }
            stmts.add(result);
        } catch (AdHocPlanningException e) {
            errorMsgs.add(e.getMessage());
        }
    }
    if (!errorMsgs.isEmpty()) {
        String errorSummary = StringUtils.join(errorMsgs, "\n");
        return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, errorSummary);
    }
    AdHocPlannedStmtBatch plannedStmtBatch = new AdHocPlannedStmtBatch(userParamSet, stmts, partitionParamIndex, partitionParamType, partitionParamValue, userPartitionKey == null ? null : new Object[] { userPartitionKey });
    if (adhocLog.isDebugEnabled()) {
        logBatch(context, plannedStmtBatch, userParamSet);
    }
    final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.CI);
    if (traceLog != null) {
        traceLog.add(() -> VoltTrace.endAsync("planadhoc", getClientHandle()));
    }
    if (explainMode == ExplainMode.EXPLAIN_ADHOC) {
        return processExplainPlannedStmtBatch(plannedStmtBatch);
    } else if (explainMode == ExplainMode.EXPLAIN_DEFAULT_PROC) {
        return processExplainDefaultProc(plannedStmtBatch);
    } else {
        try {
            return createAdHocTransaction(plannedStmtBatch, isSwapTables);
        } catch (VoltTypeException vte) {
            String msg = "Unable to execute adhoc sql statement(s): " + vte.getMessage();
            return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, msg);
        }
    }
}
Also used : VoltTrace(org.voltdb.utils.VoltTrace) ArrayList(java.util.ArrayList) VoltTypeException(org.voltdb.VoltTypeException) AdHocPlannedStmtBatch(org.voltdb.compiler.AdHocPlannedStmtBatch) AdHocPlannedStatement(org.voltdb.compiler.AdHocPlannedStatement) VoltType(org.voltdb.VoltType)

Example 34 with VoltType

use of org.voltdb.VoltType in project voltdb by VoltDB.

the class SavedTableConverter method convertTable.

public static VoltTable convertTable(VoltTable inputTable, Table outputTableSchema, boolean shouldPreserveDRHiddenColumn) throws VoltTypeException {
    VoltTable new_table;
    if (shouldPreserveDRHiddenColumn) {
        // if the DR hidden column should be preserved in conversion, append it to the end of target schema
        new_table = CatalogUtil.getVoltTable(outputTableSchema, CatalogUtil.DR_HIDDEN_COLUMN_INFO);
    } else {
        new_table = CatalogUtil.getVoltTable(outputTableSchema);
    }
    Map<Integer, Integer> column_copy_index_map = computeColumnCopyIndexMap(inputTable, new_table);
    // if original table does not have hidden column present, we need to add
    boolean addDRHiddenColumn = shouldPreserveDRHiddenColumn && !column_copy_index_map.containsKey(new_table.getColumnCount() - 1);
    Column catalogColumnForHiddenColumn = null;
    if (addDRHiddenColumn) {
        catalogColumnForHiddenColumn = new Column();
        catalogColumnForHiddenColumn.setName(CatalogUtil.DR_HIDDEN_COLUMN_NAME);
        catalogColumnForHiddenColumn.setType(VoltType.BIGINT.getValue());
        catalogColumnForHiddenColumn.setSize(VoltType.BIGINT.getLengthInBytesForFixedTypes());
        catalogColumnForHiddenColumn.setInbytes(false);
        // small hack here to let logic below fill VoltType.NULL_BIGINT in for the hidden column
        // actually this column is not nullable in EE, but it will be set to correct value before
        // insert(restore) to the corresponding table
        catalogColumnForHiddenColumn.setNullable(true);
    }
    // Copy all the old tuples into the new table
    while (inputTable.advanceRow()) {
        Object[] coerced_values = new Object[new_table.getColumnCount()];
        for (int i = 0; i < new_table.getColumnCount(); i++) {
            if (column_copy_index_map.containsKey(i)) {
                int orig_column_index = column_copy_index_map.get(i);
                // For column we have in new table convert and make compatible value.
                coerced_values[i] = ParameterConverter.tryToMakeCompatible(new_table.getColumnType(i).classFromType(), inputTable.get(orig_column_index, inputTable.getColumnType(orig_column_index)));
            } else {
                // otherwise if it's nullable, insert null,
                Column catalog_column = outputTableSchema.getColumns().get(new_table.getColumnName(i));
                // construct an artificial catalog column for dr hidden column
                if (shouldPreserveDRHiddenColumn && catalog_column == null) {
                    catalog_column = catalogColumnForHiddenColumn;
                }
                VoltType default_type = VoltType.get((byte) catalog_column.getDefaulttype());
                if (default_type != VoltType.INVALID) {
                    // insert the default value
                    try {
                        coerced_values[i] = VoltTypeUtil.getObjectFromString(default_type, catalog_column.getDefaultvalue());
                    } catch (ParseException e) {
                        String message = "Column: ";
                        message += new_table.getColumnName(i);
                        message += " has an unparseable default: ";
                        message += catalog_column.getDefaultvalue();
                        message += " for VoltType: ";
                        message += default_type.toString();
                        throw new VoltTypeException(message);
                    }
                } else if (catalog_column.getNullable()) {
                    coerced_values[i] = null;
                } else {
                    throw new VoltTypeException("Column: " + new_table.getColumnName(i) + " has no default " + "and null is not permitted");
                }
            }
        }
        new_table.addRow(coerced_values);
    }
    return new_table;
}
Also used : Column(org.voltdb.catalog.Column) VoltType(org.voltdb.VoltType) ParseException(java.text.ParseException) VoltTypeException(org.voltdb.VoltTypeException) VoltTable(org.voltdb.VoltTable)

Example 35 with VoltType

use of org.voltdb.VoltType in project voltdb by VoltDB.

the class SavedTableConverter method needsConversion.

public static Boolean needsConversion(VoltTable inputTable, Table outputTableSchema, boolean shouldPreserveDRHiddenColumn) {
    int columnsToMatch;
    if (shouldPreserveDRHiddenColumn) {
        // We are expecting the hidden column in inputTable
        columnsToMatch = inputTable.getColumnCount() - 1;
        if (columnsToMatch != outputTableSchema.getColumns().size()) {
            return true;
        }
        if (!inputTable.getColumnName(columnsToMatch).equalsIgnoreCase(CatalogUtil.DR_HIDDEN_COLUMN_NAME) || inputTable.getColumnType(columnsToMatch) != VoltType.BIGINT) {
            // passive DR table to active DR table, must be converted
            return true;
        }
    } else {
        columnsToMatch = inputTable.getColumnCount();
        if (columnsToMatch != outputTableSchema.getColumns().size()) {
            return true;
        }
    }
    for (int ii = 0; ii < columnsToMatch; ii++) {
        final String name = inputTable.getColumnName(ii);
        final VoltType type = inputTable.getColumnType(ii);
        final Column column = outputTableSchema.getColumns().get(name);
        if (column == null) {
            return true;
        }
        if (column.getIndex() != ii) {
            return true;
        }
        if (column.getType() != type.getValue()) {
            return true;
        }
    }
    return false;
}
Also used : VoltType(org.voltdb.VoltType) Column(org.voltdb.catalog.Column)

Aggregations

VoltType (org.voltdb.VoltType)54 AbstractExpression (org.voltdb.expressions.AbstractExpression)10 Constraint (org.voltdb.catalog.Constraint)9 BigDecimal (java.math.BigDecimal)8 ArrayList (java.util.ArrayList)8 Column (org.voltdb.catalog.Column)8 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)7 VoltTypeException (org.voltdb.VoltTypeException)7 VoltCompilerException (org.voltdb.compiler.VoltCompiler.VoltCompilerException)6 JSONException (org.json_voltpatches.JSONException)5 ExpressionType (org.voltdb.types.ExpressionType)5 VoltTable (org.voltdb.VoltTable)4 Index (org.voltdb.catalog.Index)4 SQLException (java.sql.SQLException)3 ColumnRef (org.voltdb.catalog.ColumnRef)3 Table (org.voltdb.catalog.Table)3 ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)3 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)3 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)3 GeographyPointValue (org.voltdb.types.GeographyPointValue)3