use of org.hsqldb_voltpatches.VoltXMLElement 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;
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class AbstractParsedStmt method parseTables.
/**
*
* @param tablesNode
*/
private void parseTables(VoltXMLElement tablesNode) {
Set<String> visited = new HashSet<>();
for (VoltXMLElement node : tablesNode.children) {
if (node.name.equalsIgnoreCase("tablescan")) {
String visitedTable = node.attributes.get("tablealias");
if (visitedTable == null) {
visitedTable = node.attributes.get("table");
}
assert (visitedTable != null);
if (visited.contains(visitedTable)) {
throw new PlanningErrorException("Not unique table/alias: " + visitedTable);
}
parseTable(node);
visited.add(visitedTable);
}
}
}
use of org.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class AbstractParsedStmt method parseSubqueryExpression.
/**
* Parse an expression subquery
*/
private SelectSubqueryExpression parseSubqueryExpression(VoltXMLElement exprNode) {
assert (exprNode.children.size() == 1);
VoltXMLElement subqueryElmt = exprNode.children.get(0);
AbstractParsedStmt subqueryStmt = parseSubquery(subqueryElmt);
// add table to the query cache
String withoutAlias = null;
StmtSubqueryScan stmtSubqueryScan = addSubqueryToStmtCache(subqueryStmt, withoutAlias);
// Set to the default SELECT_SUBQUERY. May be overridden depending on the context
return new SelectSubqueryExpression(ExpressionType.SELECT_SUBQUERY, stmtSubqueryScan);
}
use of org.hsqldb_voltpatches.VoltXMLElement 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.hsqldb_voltpatches.VoltXMLElement in project voltdb by VoltDB.
the class AbstractParsedStmt method parseFunctionExpression.
/**
*
* @param paramsById
* @param exprNode
* @return a new Function Expression
*/
private AbstractExpression parseFunctionExpression(VoltXMLElement exprNode) {
String name = exprNode.attributes.get("name").toLowerCase();
String disabled = exprNode.attributes.get("disabled");
if (disabled != null) {
throw new PlanningErrorException("Function '" + name + "' is not supported in VoltDB: " + disabled);
}
String value_type_name = exprNode.attributes.get("valuetype");
VoltType value_type = VoltType.typeFromString(value_type_name);
String function_id = exprNode.attributes.get("function_id");
assert (function_id != null);
int idArg = 0;
try {
idArg = Integer.parseInt(function_id);
} catch (NumberFormatException nfe) {
}
assert (idArg > 0);
String result_type_parameter_index = exprNode.attributes.get("result_type_parameter_index");
String implied_argument = exprNode.attributes.get("implied_argument");
ArrayList<AbstractExpression> args = new ArrayList<>();
for (VoltXMLElement argNode : exprNode.children) {
assert (argNode != null);
// recursively parse each argument subtree (could be any kind of expression).
AbstractExpression argExpr = parseExpressionNode(argNode);
assert (argExpr != null);
args.add(argExpr);
}
FunctionExpression expr = new FunctionExpression();
expr.setAttributes(name, implied_argument, idArg);
expr.setArgs(args);
if (value_type != null) {
expr.setValueType(value_type);
if (value_type != VoltType.INVALID && value_type != VoltType.NUMERIC) {
int size = value_type.getMaxLengthInBytes();
expr.setValueSize(size);
}
}
if (result_type_parameter_index != null) {
int parameter_idx = -1;
try {
parameter_idx = Integer.parseInt(result_type_parameter_index);
} catch (NumberFormatException nfe) {
}
// better be valid by now.
assert (parameter_idx >= 0);
// must refer to a provided argument
assert (parameter_idx < args.size());
expr.setResultTypeParameterIndex(parameter_idx);
expr.negotiateInitialValueTypes();
}
return expr;
}
Aggregations