use of org.voltdb.types.ExpressionType in project voltdb by VoltDB.
the class AggregateExpression method finalizeAggregateValueTypes.
public static void finalizeAggregateValueTypes(AbstractExpression expr) {
expr.finalizeChildValueTypes();
ExpressionType type = expr.getExpressionType();
AbstractExpression aggArg;
switch(type) {
case AGGREGATE_COUNT:
case AGGREGATE_WINDOWED_RANK:
case AGGREGATE_WINDOWED_DENSE_RANK:
case AGGREGATE_WINDOWED_COUNT:
case AGGREGATE_COUNT_STAR:
case AGGREGATE_APPROX_COUNT_DISTINCT:
case AGGREGATE_HYPERLOGLOGS_TO_CARD:
//
// Always an integer
//
expr.m_valueType = VoltType.BIGINT;
expr.m_valueSize = expr.m_valueType.getLengthInBytesForFixedTypes();
break;
case AGGREGATE_VALS_TO_HYPERLOGLOG:
expr.m_valueType = VoltType.VARBINARY;
expr.m_valueSize = 65537;
break;
case AGGREGATE_AVG:
case AGGREGATE_MAX:
case AGGREGATE_MIN:
case AGGREGATE_WINDOWED_MIN:
case AGGREGATE_WINDOWED_MAX:
//
// It's always whatever the base type is
//
aggArg = expr.getFirstArgument();
assert (aggArg != null);
expr.m_valueType = aggArg.getValueType();
expr.m_valueSize = aggArg.getValueSize();
// non-deterministic on floating point types.
if (expr.m_valueType == VoltType.FLOAT && type == ExpressionType.AGGREGATE_AVG) {
expr.updateContentDeterminismMessage(FLOAT_AGG_ERR_MSG);
}
break;
case AGGREGATE_WINDOWED_SUM:
case AGGREGATE_SUM:
aggArg = expr.getFirstArgument();
assert (aggArg != null);
if (aggArg.getValueType() == VoltType.TINYINT || aggArg.getValueType() == VoltType.SMALLINT || aggArg.getValueType() == VoltType.INTEGER) {
expr.m_valueType = VoltType.BIGINT;
expr.m_valueSize = expr.m_valueType.getLengthInBytesForFixedTypes();
} else {
expr.m_valueType = aggArg.getValueType();
expr.m_valueSize = aggArg.getValueSize();
}
if (expr.m_valueType == VoltType.FLOAT) {
expr.updateContentDeterminismMessage(FLOAT_AGG_ERR_MSG);
}
break;
default:
throw new RuntimeException("ERROR: Invalid Expression type '" + type + "' for Expression '" + expr + "'");
}
}
use of org.voltdb.types.ExpressionType in project voltdb by VoltDB.
the class AbstractExpression method isColumnEquivalenceFilter.
public boolean isColumnEquivalenceFilter() {
// Ignore expressions that are not of COMPARE_EQUAL or
// COMPARE_NOTDISTINCT type
ExpressionType type = getExpressionType();
if (type != ExpressionType.COMPARE_EQUAL && type != ExpressionType.COMPARE_NOTDISTINCT) {
return false;
}
AbstractExpression leftExpr = getLeft();
// Can't use an expression that is based on a column value but is not just a simple column value.
if ((!(leftExpr instanceof TupleValueExpression)) && leftExpr.hasAnySubexpressionOfClass(TupleValueExpression.class)) {
return false;
}
AbstractExpression rightExpr = getRight();
if ((!(rightExpr instanceof TupleValueExpression)) && rightExpr.hasAnySubexpressionOfClass(TupleValueExpression.class)) {
return false;
}
return true;
}
use of org.voltdb.types.ExpressionType in project voltdb by VoltDB.
the class AbstractParsedStmt method rejectDisallowedRowOpExpressions.
private void rejectDisallowedRowOpExpressions(AbstractExpression expr) {
ExpressionType exprType = expr.getExpressionType();
// searching for row op subquery expressions.
if (ExpressionType.CONJUNCTION_AND == exprType || ExpressionType.CONJUNCTION_OR == exprType) {
rejectDisallowedRowOpExpressions(expr.getLeft());
rejectDisallowedRowOpExpressions(expr.getRight());
return;
}
if (ExpressionType.OPERATOR_NOT == exprType) {
rejectDisallowedRowOpExpressions(expr.getLeft());
}
// The problem cases are all comparison ops.
if (!(expr instanceof ComparisonExpression)) {
return;
}
// The problem cases all have row expressions as an operand.
AbstractExpression rowExpression = expr.getLeft();
if (rowExpression instanceof RowSubqueryExpression) {
rejectDisallowedRowColumns(rowExpression);
}
rowExpression = expr.getRight();
if (rowExpression instanceof RowSubqueryExpression) {
rejectDisallowedRowColumns(rowExpression);
}
}
use of org.voltdb.types.ExpressionType in project voltdb by VoltDB.
the class AbstractParsedStmt method parseWindowedAggregationExpression.
/**
* Parse a windowed expression. This actually just returns a TVE. The
* WindowFunctionExpression is squirreled away in the m_windowFunctionExpressions
* object, though, because we will need it later.
*
* @param exprNode
* @return
*/
private AbstractExpression parseWindowedAggregationExpression(VoltXMLElement exprNode) {
int id = Integer.parseInt(exprNode.attributes.get("id"));
String optypeName = exprNode.attributes.get("optype");
ExpressionType optype = ExpressionType.get(optypeName);
if (optype == ExpressionType.INVALID) {
throw new PlanningErrorException("Undefined windowed function call " + optypeName);
}
// the windowed expression, then this is an error.
if (!m_parsingInDisplayColumns) {
if (m_windowFunctionExpressions.size() > 0) {
WindowFunctionExpression we = m_windowFunctionExpressions.get(0);
if (we.getXMLID() == id) {
// away in the windowed expression.
return we.getDisplayListExpression();
}
}
throw new PlanningErrorException("Windowed function call expressions can only appear in the selection list of a query or subquery.");
}
// Parse individual aggregate expressions
List<AbstractExpression> partitionbyExprs = new ArrayList<>();
List<AbstractExpression> orderbyExprs = new ArrayList<>();
List<SortDirectionType> orderbyDirs = new ArrayList<>();
List<AbstractExpression> aggParams = new ArrayList<>();
for (VoltXMLElement childEle : exprNode.children) {
if (childEle.name.equals("winspec")) {
for (VoltXMLElement ele : childEle.children) {
if (ele.name.equals("partitionbyList")) {
for (VoltXMLElement childNode : ele.children) {
AbstractExpression expr = parseExpressionNode(childNode);
ExpressionUtil.finalizeValueTypes(expr);
partitionbyExprs.add(expr);
}
} else if (ele.name.equals("orderbyList")) {
for (VoltXMLElement childNode : ele.children) {
SortDirectionType sortDir = Boolean.valueOf(childNode.attributes.get("descending")) ? SortDirectionType.DESC : SortDirectionType.ASC;
AbstractExpression expr = parseExpressionNode(childNode.children.get(0));
ExpressionUtil.finalizeValueTypes(expr);
orderbyExprs.add(expr);
orderbyDirs.add(sortDir);
}
}
}
} else {
AbstractExpression aggParam = parseExpressionNode(childEle);
if (aggParam != null) {
aggParam.finalizeValueTypes();
aggParams.add(aggParam);
}
}
}
String alias = WINDOWED_AGGREGATE_COLUMN_NAME;
if (exprNode.attributes.containsKey("alias")) {
alias = exprNode.attributes.get("alias");
}
WindowFunctionExpression rankExpr = new WindowFunctionExpression(optype, partitionbyExprs, orderbyExprs, orderbyDirs, aggParams, id);
ExpressionUtil.finalizeValueTypes(rankExpr);
// Only offset 0 is useful. But we keep the index anyway.
int offset = m_windowFunctionExpressions.size();
m_windowFunctionExpressions.add(rankExpr);
TupleValueExpression tve = new TupleValueExpression(TEMP_TABLE_NAME, TEMP_TABLE_NAME, alias, alias, rankExpr, offset);
// This tve does not ever need a differentiator.
tve.setNeedsNoDifferentiation();
rankExpr.setDisplayListExpression(tve);
return tve;
}
use of org.voltdb.types.ExpressionType in project voltdb by VoltDB.
the class SubPlanAssembler method isPartialIndexPredicateCovered.
/**
* Split the index WHERE clause into a list of sub-expressions and process
* each expression separately searching the query (or matview) for a
* covering expression for each of these expressions.
* All index WHERE sub-expressions must be covered to enable the index.
* Collect the query expressions that EXACTLY match the index expression.
* They can be eliminated from the post-filters as an optimization.
*
* @param tableScan The source table.
* @param coveringExprs The set of query predicate expressions.
* @param index The partial index to cover.
* @param exactMatchCoveringExprs The output subset of the query predicates that EXACTLY match the
* index predicate expression(s)
* @return TRUE if the index has a predicate that is completely covered by the query expressions.
*/
public static boolean isPartialIndexPredicateCovered(StmtTableScan tableScan, List<AbstractExpression> coveringExprs, String predicatejson, List<AbstractExpression> exactMatchCoveringExprs) {
assert (!predicatejson.isEmpty());
AbstractExpression indexPredicate = null;
try {
indexPredicate = AbstractExpression.fromJSONString(predicatejson, tableScan);
} catch (JSONException e) {
e.printStackTrace();
assert (false);
return false;
}
List<AbstractExpression> exprsToCover = ExpressionUtil.uncombinePredicate(indexPredicate);
for (AbstractExpression coveringExpr : coveringExprs) {
if (exprsToCover.isEmpty()) {
// We are done there. All the index predicate expressions are covered.
break;
}
// Each covering expression and its reversed copy need to be tested for the index expression coverage.
AbstractExpression reversedCoveringExpr = null;
ExpressionType reverseCoveringType = ComparisonExpression.reverses.get(coveringExpr.getExpressionType());
if (reverseCoveringType != null) {
// reverse the expression
reversedCoveringExpr = new ComparisonExpression(reverseCoveringType, coveringExpr.getRight(), coveringExpr.getLeft());
}
// Exact match first.
if (removeExactMatchCoveredExpressions(coveringExpr, exprsToCover)) {
exactMatchCoveringExprs.add(coveringExpr);
}
// Try the reversed expression for the exact match
if (reversedCoveringExpr != null && removeExactMatchCoveredExpressions(reversedCoveringExpr, exprsToCover)) {
// It is the original expression that we need to remember
exactMatchCoveringExprs.add(coveringExpr);
}
}
// Handle the remaining NOT NULL index predicate expressions that can be covered by NULL rejecting expressions
exprsToCover = removeNotNullCoveredExpressions(tableScan, coveringExprs, exprsToCover);
// All index predicate expressions must be covered for index to be selected
return exprsToCover.isEmpty();
}
Aggregations