use of org.voltdb.planner.parseinfo.StmtTableScan in project voltdb by VoltDB.
the class ScanDeterminizer method recursivelyApply.
private static AbstractPlanNode recursivelyApply(AbstractPlanNode plan) {
assert (plan != null);
// depth first:
// Find Sequential Scan node.
// Replace with any unique tree index scan if possible.
ArrayList<AbstractPlanNode> children = new ArrayList<AbstractPlanNode>();
for (int i = 0; i < plan.getChildCount(); i++) {
children.add(plan.getChild(i));
}
for (AbstractPlanNode child : children) {
// TODO this will break when children feed multiple parents
AbstractPlanNode newChild = recursivelyApply(child);
// Do a graft into the (parent) plan only if a replacement for a child was found.
if (newChild == child) {
continue;
}
boolean replaced = plan.replaceChild(child, newChild);
assert (replaced);
}
// skip the meat if this isn't a scan node
if (!(plan instanceof SeqScanPlanNode)) {
return plan;
}
SeqScanPlanNode scanNode = (SeqScanPlanNode) plan;
if (scanNode.isSubQuery()) {
// This is a sub-query and can't have indexes
return plan;
}
// got here? we're got ourselves a sequential scan over a real table
assert (scanNode.getChildCount() == 0);
StmtTableScan tableScan = scanNode.getTableScan();
assert (tableScan != null);
Index indexToScan = null;
// does anything for performance at all.
for (Index index : tableScan.getIndexes()) {
// skip non-unique indexes
if (index.getUnique() == false) {
continue;
} else // skip hash indexes
if (index.getType() != IndexType.BALANCED_TREE.getValue()) {
continue;
} else // skip partial indexes
if (!index.getPredicatejson().isEmpty()) {
continue;
} else if (indexToScan == null || CatalogUtil.getCatalogIndexSize(indexToScan) > CatalogUtil.getCatalogIndexSize(index)) {
indexToScan = index;
}
}
if (indexToScan == null) {
return plan;
}
// make an index node from the scan node
IndexScanPlanNode indexScanNode = new IndexScanPlanNode(scanNode, null, indexToScan, SortDirectionType.ASC);
indexScanNode.setForDeterminismOnly();
return indexScanNode;
}
use of org.voltdb.planner.parseinfo.StmtTableScan in project voltdb by VoltDB.
the class ReplaceWithIndexLimit method checkIndex.
private boolean checkIndex(Index index, AbstractExpression aggExpr, List<AbstractExpression> filterExprs, List<AbstractExpression> bindingExprs, String fromTableAlias) {
if (!IndexType.isScannable(index.getType())) {
return false;
}
// Skip partial indexes
if (!index.getPredicatejson().isEmpty()) {
return false;
}
String exprsjson = index.getExpressionsjson();
if (exprsjson.isEmpty()) {
// if the index is on simple columns, aggregate expression must be a simple column too
if (aggExpr.getExpressionType() != ExpressionType.VALUE_TUPLE) {
return false;
}
return checkPureColumnIndex(index, ((TupleValueExpression) aggExpr).getColumnIndex(), filterExprs);
} else {
// either pure expression index or mix of expressions and simple columns
List<AbstractExpression> indexedExprs = null;
StmtTableScan tableScan = m_parsedStmt.getStmtTableScanByAlias(fromTableAlias);
try {
indexedExprs = AbstractExpression.fromJSONArrayString(exprsjson, tableScan);
} catch (JSONException e) {
e.printStackTrace();
assert (false);
return false;
}
return checkExpressionIndex(indexedExprs, aggExpr, filterExprs, bindingExprs);
}
}
use of org.voltdb.planner.parseinfo.StmtTableScan in project voltdb by VoltDB.
the class AbstractPlanNode method hasReplicatedResult.
public boolean hasReplicatedResult() {
Map<String, StmtTargetTableScan> tablesRead = new TreeMap<>();
getTablesAndIndexes(tablesRead, null);
for (StmtTableScan tableScan : tablesRead.values()) {
if (!tableScan.getIsReplicated()) {
return false;
}
}
return true;
}
Aggregations