use of com.wplatform.ddal.dbobject.index.IndexCondition in project jdbc-shards by wplatform.
the class TableFilter method prepare.
/**
* Prepare reading rows. This method will remove all index conditions that
* can not be used, and optimize the conditions.
*/
public void prepare() {
// the indexConditions list may be modified here
for (int i = 0; i < indexConditions.size(); i++) {
IndexCondition condition = indexConditions.get(i);
if (!condition.isAlwaysFalse()) {
Column col = condition.getColumn();
if (col.getColumnId() >= 0) {
if (index.getColumnIndex(col) < 0) {
indexConditions.remove(i);
i--;
}
}
}
}
if (nestedJoin != null) {
if (SysProperties.CHECK && nestedJoin == this) {
DbException.throwInternalError("self join");
}
nestedJoin.prepare();
}
if (join != null) {
if (SysProperties.CHECK && join == this) {
DbException.throwInternalError("self join");
}
join.prepare();
}
if (filterCondition != null) {
filterCondition = filterCondition.optimize(session);
}
if (joinCondition != null) {
joinCondition = joinCondition.optimize(session);
}
}
use of com.wplatform.ddal.dbobject.index.IndexCondition in project jdbc-shards by wplatform.
the class TableFilter method getPlanSQL.
/**
* Get the query execution plan text to use for this table filter.
*
* @param isJoin if this is a joined table
* @return the SQL statement snippet
*/
public String getPlanSQL(boolean isJoin) {
StringBuilder buff = new StringBuilder();
if (isJoin) {
if (joinOuter) {
buff.append("LEFT OUTER JOIN ");
} else {
buff.append("INNER JOIN ");
}
}
if (nestedJoin != null) {
StringBuffer buffNested = new StringBuffer();
TableFilter n = nestedJoin;
do {
buffNested.append(n.getPlanSQL(n != nestedJoin));
buffNested.append('\n');
n = n.getJoin();
} while (n != null);
String nested = buffNested.toString();
boolean enclose = !nested.startsWith("(");
if (enclose) {
buff.append("(\n");
}
buff.append(StringUtils.indent(nested, 4, false));
if (enclose) {
buff.append(')');
}
if (isJoin) {
buff.append(" ON ");
if (joinCondition == null) {
// need to have a ON expression,
// otherwise the nesting is unclear
buff.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
}
}
return buff.toString();
}
buff.append(table.getSQL());
if (alias != null) {
buff.append(' ').append(Parser.quoteIdentifier(alias));
}
if (index != null) {
buff.append('\n');
StatementBuilder planBuff = new StatementBuilder();
planBuff.append(index.getSQL());
if (indexConditions.size() > 0) {
planBuff.append(": ");
for (IndexCondition condition : indexConditions) {
planBuff.appendExceptFirst("\n AND ");
planBuff.append(condition.getSQL());
}
}
String plan = StringUtils.quoteRemarkSQL(planBuff.toString());
if (plan.indexOf('\n') >= 0) {
plan += "\n";
}
buff.append(StringUtils.indent("/* " + plan + " */", 4, false));
}
if (isJoin) {
buff.append("\n ON ");
if (joinCondition == null) {
// need to have a ON expression, otherwise the nesting is
// unclear
buff.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
}
}
if (filterCondition != null) {
buff.append('\n');
String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = "/* WHERE " + StringUtils.quoteRemarkSQL(condition) + "\n*/";
buff.append(StringUtils.indent(condition, 4, false));
}
if (scanCount > 0) {
buff.append("\n /* scanCount: ").append(scanCount).append(" */");
}
return buff.toString();
}
use of com.wplatform.ddal.dbobject.index.IndexCondition in project jdbc-shards by wplatform.
the class TableFilter method getBestPlanItem.
/**
* Get the best plan item (index, cost) to use use for the current join
* order.
*
* @param s the session
* @param level 1 for the first table in a join, 2 for the second, and so on
* @return the best plan item
*/
public PlanItem getBestPlanItem(Session s, int level) {
PlanItem item;
if (indexConditions.size() == 0) {
item = new PlanItem();
item.setIndex(table.getScanIndex(s));
item.cost = item.getIndex().getCost(s, null, null, null);
} else {
int len = table.getColumns().length;
int[] masks = new int[len];
for (IndexCondition condition : indexConditions) {
if (condition.isEvaluatable()) {
if (condition.isAlwaysFalse()) {
masks = null;
break;
}
int id = condition.getColumn().getColumnId();
if (id >= 0) {
masks[id] |= condition.getMask(indexConditions);
}
}
}
SortOrder sortOrder = null;
if (select != null) {
sortOrder = select.getSortOrder();
}
item = table.getBestPlanItem(s, masks, this, sortOrder);
// The more index conditions, the earlier the table.
// This is to ensure joins without indexes run quickly:
// x (x.a=10); y (x.b=y.b) - see issue 113
item.cost -= item.cost * indexConditions.size() / 100 / level;
}
if (nestedJoin != null) {
setEvaluatable(nestedJoin);
item.setNestedJoinPlan(nestedJoin.getBestPlanItem(s, level));
// TODO optimizer: calculate cost of a join: should use separate
// expected row number and lookup cost
item.cost += item.cost * item.getNestedJoinPlan().cost;
}
if (join != null) {
setEvaluatable(join);
item.setJoinPlan(join.getBestPlanItem(s, level));
// TODO optimizer: calculate cost of a join: should use separate
// expected row number and lookup cost
item.cost += item.cost * item.getJoinPlan().cost;
}
return item;
}
use of com.wplatform.ddal.dbobject.index.IndexCondition in project jdbc-shards by wplatform.
the class ExpressionColumn method createIndexConditions.
@Override
public void createIndexConditions(Session session, TableFilter filter) {
TableFilter tf = getTableFilter();
if (filter == tf && column.getType() == Value.BOOLEAN) {
IndexCondition cond = IndexCondition.get(Comparison.EQUAL, this, ValueExpression.get(ValueBoolean.get(true)));
filter.addIndexCondition(cond);
}
}
use of com.wplatform.ddal.dbobject.index.IndexCondition in project jdbc-shards by wplatform.
the class RoutingHandlerImpl method doRoute.
@Override
public RoutingResult doRoute(TableMate table, Session session, List<IndexCondition> indexConditions) {
TableRouter tr = table.getTableRouter();
if (tr == null) {
return fixedRoutingResult(table.getShards());
} else {
Map<String, List<Value>> routingArgs = New.hashMap();
List<RuleColumn> ruleCols = tr.getRuleColumns();
SearchRow start = null, end = null;
for (IndexCondition condition : indexConditions) {
Column column = condition.getColumn();
String colName = column.getName();
RuleColumn matched = null;
for (RuleColumn ruleColumn : ruleCols) {
if (colName.equalsIgnoreCase(ruleColumn.getName())) {
matched = ruleColumn;
}
}
if (matched == null) {
continue;
}
List<Value> values = routingArgs.get(matched.getName());
if (values == null) {
values = New.arrayList();
routingArgs.put(matched.getName(), values);
}
if (condition.getCompareType() == Comparison.IN_LIST) {
Value[] inList = condition.getCurrentValueList(session);
for (Value value : inList) {
values.add(value);
}
} else if (condition.getCompareType() == Comparison.IN_QUERY) {
ResultInterface result = condition.getCurrentResult();
while (result.next()) {
Value v = result.currentRow()[0];
if (v != ValueNull.INSTANCE) {
v = column.convert(v);
values.add(v);
}
}
} else {
int columnId = column.getColumnId();
Value v = condition.getCurrentValue(session);
boolean isStart = condition.isStart();
boolean isEnd = condition.isEnd();
if (isStart) {
start = getSearchRow(table, session, start, columnId, v, true);
}
if (isEnd) {
end = getSearchRow(table, session, end, columnId, v, false);
}
}
}
exportRangeArg(table, start, end, routingArgs);
RoutingResult rr = trc.calculate(tr, routingArgs);
return rr;
}
}
Aggregations