use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class SelectSubPlanAssembler method hasInnerOuterIndexExpression.
/**
* For a join node, determines whether any of the inner-outer expressions were used
* for an inner index access -- this requires joining with a NestLoopIndexJoin.
* These are detected as TVE references in the various clauses that drive the indexing
* -- as opposed to TVE references in post-filters that pose no problem with either
* NLIJ or the more efficient (one-pass through the index) NestLoopJoin.
*
* @param innerTable - the Table of all inner TVEs that are exempt from the check.
* @param indexExprs - a list of expressions used in the indexing
* @param initialExpr - a list of expressions used in the indexing
* @param endExprs - a list of expressions used in the indexing
* @return true if at least one of the expression lists references a TVE.
*/
private static boolean hasInnerOuterIndexExpression(String innerTableAlias, Collection<AbstractExpression> indexExprs, Collection<AbstractExpression> initialExpr, Collection<AbstractExpression> endExprs) {
HashSet<AbstractExpression> indexedExprs = new HashSet<>();
indexedExprs.addAll(indexExprs);
indexedExprs.addAll(initialExpr);
indexedExprs.addAll(endExprs);
// Find an outer TVE by ignoring any TVEs based on the inner table.
for (AbstractExpression indexed : indexedExprs) {
Collection<TupleValueExpression> indexedTVEs = indexed.findAllTupleValueSubexpressions();
for (AbstractExpression indexedTVExpr : indexedTVEs) {
if (!TupleValueExpression.isOperandDependentOnTable(indexedTVExpr, innerTableAlias)) {
return true;
}
}
}
return false;
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class SubPlanAssembler method bindingIfValidIndexedFilterOperand.
private static List<AbstractExpression> bindingIfValidIndexedFilterOperand(StmtTableScan tableScan, AbstractExpression indexableExpr, AbstractExpression otherExpr, AbstractExpression coveringExpr, int coveringColId) {
// Do some preliminary disqualifications.
VoltType keyType = indexableExpr.getValueType();
VoltType otherType = otherExpr.getValueType();
// Do not choose an index that requires such a cast.
if (!keyType.canExactlyRepresentAnyValueOf(otherType)) {
// So, accept any pair of integer types.
if (!(keyType.isBackendIntegerType() && otherType.isBackendIntegerType())) {
return null;
}
}
// e.g. where t.a = t.b is not indexable with the current technology.
if (isOperandDependentOnTable(otherExpr, tableScan)) {
return null;
}
if (coveringExpr == null) {
// Match only the table's column that has the coveringColId
if ((indexableExpr.getExpressionType() != ExpressionType.VALUE_TUPLE)) {
return null;
}
TupleValueExpression tve = (TupleValueExpression) indexableExpr;
// Handle a simple indexed column identified by its column id.
if ((coveringColId == tve.getColumnIndex()) && (tableScan.getTableAlias().equals(tve.getTableAlias()))) {
// A column match never requires parameter binding. Return an empty list.
return s_reusableImmutableEmptyBinding;
}
return null;
}
// Do a possibly more extensive match with coveringExpr which MAY require bound parameters.
List<AbstractExpression> binding = indexableExpr.bindingToIndexedExpression(coveringExpr);
return binding;
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class AbstractJoinPlanNode method resolveColumnIndexes.
// Given any non-inlined type of join, this method will resolve the column
// order and TVE indexes for the output SchemaColumns.
@Override
public void resolveColumnIndexes() {
// First, assert that our topology is sane and then
// recursively resolve all child/inline column indexes
IndexScanPlanNode index_scan = (IndexScanPlanNode) getInlinePlanNode(PlanNodeType.INDEXSCAN);
assert (m_children.size() == 2 && index_scan == null);
for (AbstractPlanNode child : m_children) {
child.resolveColumnIndexes();
}
final NodeSchema outer_schema = m_children.get(0).getOutputSchema();
final NodeSchema inner_schema = m_children.get(1).getOutputSchema();
final int outerSize = outer_schema.size();
final int innerSize = inner_schema.size();
// resolve predicates
resolvePredicate(m_preJoinPredicate, outer_schema, inner_schema);
resolvePredicate(m_joinPredicate, outer_schema, inner_schema);
resolvePredicate(m_wherePredicate, outer_schema, inner_schema);
// Resolve subquery expression indexes
resolveSubqueryColumnIndexes();
// Resolve TVE indexes for each schema column.
for (int i = 0; i < m_outputSchemaPreInlineAgg.size(); ++i) {
SchemaColumn col = m_outputSchemaPreInlineAgg.getColumns().get(i);
// These will all be TVEs.
assert (col.getExpression() instanceof TupleValueExpression);
TupleValueExpression tve = (TupleValueExpression) col.getExpression();
int index;
if (i < outerSize) {
index = tve.setColumnIndexUsingSchema(outer_schema);
} else {
index = tve.setColumnIndexUsingSchema(inner_schema);
index += outerSize;
}
if (index == -1) {
throw new RuntimeException("Unable to find index for column: " + col.toString());
}
tve.setColumnIndex(index);
tve.setDifferentiator(index);
}
// We want the output columns to be ordered like [outer table columns][inner table columns],
// and further ordered by TVE index within the left- and righthand sides.
// generateOutputSchema already places outer columns on the left and inner on the right,
// so we just need to order the left- and righthand sides by TVE index separately.
m_outputSchemaPreInlineAgg.sortByTveIndex(0, outer_schema.size());
m_outputSchemaPreInlineAgg.sortByTveIndex(outer_schema.size(), m_outputSchemaPreInlineAgg.size());
m_hasSignificantOutputSchema = true;
resolveRealOutputSchema();
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class AbstractOperationPlanNode method generateOutputSchema.
@Override
public void generateOutputSchema(Database db) {
// are truncating the entire table
if (m_children.size() == 1) {
m_children.get(0).generateOutputSchema(db);
}
// Our output schema isn't ever going to change, only generate this once
if (m_outputSchema == null) {
m_outputSchema = new NodeSchema();
// If there is a child node, its output schema will depend on that.
// If not, mark this flag true to get initialized in EE.
m_hasSignificantOutputSchema = (m_children.size() == 0);
// This TVE is magic and repeats unfortunately like this
// throughout the planner. Consolidate at some point --izzy
TupleValueExpression tve = new TupleValueExpression(AbstractParsedStmt.TEMP_TABLE_NAME, AbstractParsedStmt.TEMP_TABLE_NAME, "modified_tuples", "modified_tuples", 0);
tve.setValueType(VoltType.BIGINT);
tve.setValueSize(VoltType.BIGINT.getLengthInBytesForFixedTypes());
m_outputSchema.addColumn(AbstractParsedStmt.TEMP_TABLE_NAME, AbstractParsedStmt.TEMP_TABLE_NAME, "modified_tuples", "modified_tuples", tve);
}
return;
}
use of org.voltdb.expressions.TupleValueExpression in project voltdb by VoltDB.
the class StmtSubqueryScan method promoteSinglePartitionInfo.
/**
* upgrade single partitioning expression to parent level
* add the info to equality sets and input value equivalence
* @param valueEquivalence
* @param eqSets
*/
public void promoteSinglePartitionInfo(HashMap<AbstractExpression, Set<AbstractExpression>> valueEquivalence, Set<Set<AbstractExpression>> eqSets) {
assert (m_subqueriesPartitioning != null);
if (m_subqueriesPartitioning.getCountOfPartitionedTables() == 0 || m_subqueriesPartitioning.requiresTwoFragments()) {
return;
}
// This subquery is a single partitioned query on partitioned tables
// promoting the single partition expression up to its parent level.
AbstractExpression spExpr = m_subqueriesPartitioning.singlePartitioningExpression();
for (SchemaColumn col : m_partitioningColumns) {
AbstractExpression tveKey = col.getExpression();
assert (tveKey instanceof TupleValueExpression);
Set<AbstractExpression> values = null;
if (valueEquivalence.containsKey(tveKey)) {
values = valueEquivalence.get(tveKey);
} else if (valueEquivalence.containsKey(spExpr)) {
values = valueEquivalence.get(spExpr);
} else {
for (SchemaColumn otherCol : m_partitioningColumns) {
if (col != otherCol && valueEquivalence.containsKey(otherCol.getExpression())) {
values = valueEquivalence.get(otherCol.getExpression());
break;
}
}
if (values == null) {
values = new HashSet<>();
}
}
updateEqualSets(values, valueEquivalence, eqSets, tveKey, spExpr);
}
}
Aggregations