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);
}
}
}
}
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);
}
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);
}
}
}
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;
}
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;
}
Aggregations