use of org.voltdb.expressions.AggregateExpression 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.expressions.AggregateExpression 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;
}
use of org.voltdb.expressions.AggregateExpression in project voltdb by VoltDB.
the class ParsedSelectStmt method updateAvgExpressions.
private void updateAvgExpressions() {
List<AbstractExpression> optimalAvgAggs = new ArrayList<>();
Iterator<AbstractExpression> itr = m_aggregationList.iterator();
while (itr.hasNext()) {
AbstractExpression aggExpr = itr.next();
assert (aggExpr instanceof AggregateExpression);
if (aggExpr.getExpressionType() == ExpressionType.AGGREGATE_AVG) {
itr.remove();
AbstractExpression left = new AggregateExpression(ExpressionType.AGGREGATE_SUM);
left.setLeft(aggExpr.getLeft().clone());
AbstractExpression right = new AggregateExpression(ExpressionType.AGGREGATE_COUNT);
right.setLeft(aggExpr.getLeft().clone());
optimalAvgAggs.add(left);
optimalAvgAggs.add(right);
}
}
m_aggregationList.addAll(optimalAvgAggs);
}
use of org.voltdb.expressions.AggregateExpression in project voltdb by VoltDB.
the class ParsedSelectStmt method parseHavingExpression.
private void parseHavingExpression(VoltXMLElement havingNode, boolean isDistributed) {
m_aggregationList.clear();
assert (havingNode.children.size() == 1);
m_having = parseConditionTree(havingNode.children.get(0));
assert (m_having != null);
if (m_having.hasSubquerySubexpression()) {
m_aggregationList.clear();
throw new PlanningErrorException("SQL HAVING clauses with subquery expressions are not allowed.");
}
if (isDistributed) {
m_having = m_having.replaceAVG();
updateAvgExpressions();
}
ExpressionUtil.finalizeValueTypes(m_having);
m_having = ExpressionUtil.evaluateExpression(m_having);
// (after the evaluation) simply drop it
if (ConstantValueExpression.isBooleanTrue(m_having)) {
m_aggregationList.clear();
m_having = null;
}
if (m_aggregationList.isEmpty()) {
return;
}
m_hasAggregateExpression = true;
for (AbstractExpression expr : m_aggregationList) {
assert (expr instanceof AggregateExpression);
if (expr.getExpressionType() == ExpressionType.AGGREGATE_AVG) {
m_hasAverage = true;
}
boolean isNewAgg = true;
for (ParsedColInfo existingAggCol : m_aggResultColumns) {
AbstractExpression existingExpr = existingAggCol.expression;
if (expr.equals(existingExpr)) {
isNewAgg = false;
break;
}
}
if (isNewAgg) {
ExpressionUtil.finalizeValueTypes(expr);
ParsedColInfo col = new ParsedColInfo();
col.expression = expr.clone();
col.tableName = TEMP_TABLE_NAME;
col.tableAlias = TEMP_TABLE_NAME;
col.columnName = "";
m_aggResultColumns.add(col);
m_hasComplexAgg = true;
}
}
}
Aggregations