use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class MockPlanNode method generateOutputSchema.
@Override
public void generateOutputSchema(Database db) {
m_outputSchema = new NodeSchema();
m_hasSignificantOutputSchema = true;
for (int i = 0; i < m_columnNames.length; ++i) {
String colName = m_columnNames[i];
TupleValueExpression tve = new TupleValueExpression(m_tableName, m_tableName, colName, colName, i);
m_outputSchema.addColumn(m_tableName, m_tableName, colName, colName, tve);
}
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class TestScanPlanNode method testOutputSchemaSomeScanColumns.
// test that if scan columns are specified the output schema of
// a scan node consists of those columns
public void testOutputSchemaSomeScanColumns() {
int[] scan_col_indexes = { 1, 3 };
ArrayList<SchemaColumn> scanColumns = new ArrayList<SchemaColumn>();
for (int index : scan_col_indexes) {
TupleValueExpression tve = new TupleValueExpression(TABLE1, TABLE1, COLS[index], COLS[index]);
tve.setValueType(COLTYPES[index]);
tve.setValueSize(COLTYPES[index].getLengthInBytesForFixedTypes());
SchemaColumn col = new SchemaColumn(TABLE1, TABLE1, COLS[index], COLS[index], tve);
scanColumns.add(col);
}
AbstractScanPlanNode dut = SeqScanPlanNode.createDummyForTest(TABLE1, scanColumns);
// Should be able to do this safely and repeatably multiple times
for (int i = 0; i < 3; i++) {
dut.generateOutputSchema(m_voltdb.getDatabase());
NodeSchema dut_schema = dut.getOutputSchema();
System.out.println(dut_schema.toString());
assertEquals(scan_col_indexes.length, dut_schema.size());
for (int index : scan_col_indexes) {
SchemaColumn col = dut_schema.find(TABLE1, TABLE1, COLS[index], "");
assertNotNull(col);
assertEquals(col.getExpression().getExpressionType(), ExpressionType.VALUE_TUPLE);
assertEquals(col.getExpression().getValueType(), COLTYPES[index]);
}
}
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class TestScanPlanNode method testOutputSchemaOverriddenProjection.
// test that if someone provides their own inline projection
// that the output schema of the scan node consists of the output
// schema of the projection. Updates will do this so that the
// inlined projection fills the values of the output tuples correctly
// before it attempts to update them
public void testOutputSchemaOverriddenProjection() {
AbstractScanPlanNode dut = new SeqScanPlanNode(TABLE1, TABLE1);
// Create an output schema like we might see for an inlined projection
// generated for update. We'll have 4 output columns, the first will
// be the tuple address, the second one a parameter expression, next
// will be a constant, and the other will be a more complex expression
// that uses some TVEs.
NodeSchema proj_schema = new NodeSchema();
String[] cols = new String[4];
TupleAddressExpression col1_exp = new TupleAddressExpression();
proj_schema.addColumn("", "", "tuple_address", "tuple_address", col1_exp);
cols[0] = "tuple_address";
// update column 1 with a parameter value
ParameterValueExpression col2_exp = new ParameterValueExpression();
col2_exp.setParameterIndex(0);
col2_exp.setValueType(COLTYPES[1]);
col2_exp.setValueSize(COLTYPES[1].getLengthInBytesForFixedTypes());
// XXX I'm not sure what to do with the name for the updated column yet.
// I think it should be an alias and not the original table name/col name
proj_schema.addColumn(TABLE1, TABLE1, COLS[1], COLS[1], col2_exp);
cols[1] = COLS[1];
// Update column 3 with a constant value
ConstantValueExpression col3_exp = new ConstantValueExpression();
col3_exp.setValueType(COLTYPES[3]);
col3_exp.setValueSize(COLTYPES[3].getLengthInBytesForFixedTypes());
col3_exp.setValue("3.14159");
proj_schema.addColumn(TABLE1, TABLE1, COLS[3], COLS[3], col3_exp);
cols[2] = COLS[3];
// update column 4 with a sum of columns 0 and 2
OperatorExpression col4_exp = new OperatorExpression();
col4_exp.setValueType(COLTYPES[4]);
col4_exp.setValueSize(COLTYPES[4].getLengthInBytesForFixedTypes());
col4_exp.setExpressionType(ExpressionType.OPERATOR_PLUS);
TupleValueExpression left = new TupleValueExpression(TABLE1, TABLE1, COLS[0], COLS[0], 0);
left.setValueType(COLTYPES[0]);
left.setValueSize(COLTYPES[0].getLengthInBytesForFixedTypes());
TupleValueExpression right = new TupleValueExpression(TABLE1, TABLE1, COLS[2], COLS[2], 0);
right.setValueType(COLTYPES[2]);
right.setValueSize(COLTYPES[2].getLengthInBytesForFixedTypes());
col4_exp.setLeft(left);
col4_exp.setRight(right);
proj_schema.addColumn(TABLE1, TABLE1, COLS[4], "C1", col4_exp);
cols[3] = COLS[4];
ProjectionPlanNode proj_node = new ProjectionPlanNode(proj_schema);
dut.addInlinePlanNode(proj_node);
System.out.println("ProjSchema: " + proj_schema.toString());
dut.generateOutputSchema(m_voltdb.getDatabase());
NodeSchema dut_schema = dut.getOutputSchema();
System.out.println(dut_schema.toString());
for (int i = 0; i < cols.length; i++) {
SchemaColumn col = null;
if (i == 0) {
col = dut_schema.find("", "", cols[i], cols[i]);
} else {
col = dut_schema.find(TABLE1, TABLE1, cols[i], cols[i]);
}
assertNotNull(col);
assertEquals(col.getExpression().getExpressionType(), ExpressionType.VALUE_TUPLE);
}
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class ParsedSelectStmt method parseOrderColumn.
private void parseOrderColumn(VoltXMLElement orderByNode, final boolean isDistributed) {
// Aggregation list needs to be cleared before parsing the order by expression
m_aggregationList.clear();
ParsedColInfo.ExpressionAdjuster adjuster = new ParsedColInfo.ExpressionAdjuster() {
@Override
public AbstractExpression adjust(AbstractExpression expr) {
if (isDistributed) {
expr = expr.replaceAVG();
updateAvgExpressions();
}
ExpressionUtil.finalizeValueTypes(expr);
return expr;
}
};
ParsedColInfo order_col = ParsedColInfo.fromOrderByXml(this, orderByNode, adjuster);
AbstractExpression order_exp = order_col.expression;
assert (order_exp != null);
// guards against subquery inside of order by clause
if (order_exp.hasSubquerySubexpression()) {
throw new PlanningErrorException("ORDER BY clauses with subquery expressions are not allowed.");
}
// (for determinism).
for (ParsedColInfo col : m_displayColumns) {
if (col.alias.equals(order_col.alias) || col.expression.equals(order_exp)) {
col.orderBy = true;
col.ascending = order_col.ascending;
order_col.alias = col.alias;
order_col.columnName = col.columnName;
order_col.tableName = col.tableName;
break;
}
}
assert (!(order_exp instanceof ConstantValueExpression));
assert (!(order_exp instanceof ParameterValueExpression));
insertAggExpressionsToAggResultColumns(m_aggregationList, order_col);
if (m_aggregationList.size() >= 1) {
m_hasAggregateExpression = true;
}
// Add TVEs in ORDER BY statement if we have,
// stop recursive finding when we have it in AggResultColumns
List<TupleValueExpression> tveList = new ArrayList<>();
findAllTVEs(order_col.expression, tveList);
insertTVEsToAggResultColumns(tveList);
m_orderColumns.add(order_col);
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class ParsedSelectStmt method needComplexAggregation.
private boolean needComplexAggregation() {
if (!m_hasAggregateExpression && !isGrouped()) {
m_hasComplexAgg = false;
return false;
}
if (hasComplexAgg()) {
return true;
}
int numDisplayCols = m_displayColumns.size();
if (m_aggResultColumns.size() > numDisplayCols) {
m_hasComplexAgg = true;
return true;
}
// Disqualify the case of duplicate columns in the SELECT list
HashSet<ParsedColInfo> tmpContainer = new HashSet<>();
for (ParsedColInfo col : m_displayColumns) {
if (!tmpContainer.add(col)) {
// duplicate display column.
m_hasComplexAgg = true;
return true;
}
AbstractExpression expr = col.expression;
boolean isNewAgg = true;
for (ParsedColInfo existingAggCol : m_aggResultColumns) {
AbstractExpression existingExpr = existingAggCol.expression;
if (expr.equals(existingExpr)) {
isNewAgg = false;
break;
}
}
if (!isNewAgg) {
continue;
}
// Now Only TVEs in displayColumns are left for AggResultColumns
if (!(col.expression instanceof TupleValueExpression)) {
// Col has complex expression (like: TVE + 1, TVE + AGG)
m_hasComplexAgg = true;
return true;
}
m_aggResultColumns.add(col);
}
// numDisplayCols as it would be a substitute of DisplayCols.
if (m_aggResultColumns.size() != numDisplayCols) {
// Display columns have several pass-through columns if group by
// primary key or a HAVING clause using aggs that are
// not in the SELECT list (larger than case).
m_hasComplexAgg = true;
return true;
}
return false;
}
Aggregations