Search in sources :

Example 1 with IndexCondition

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);
    }
}
Also used : ExpressionColumn(com.wplatform.ddal.command.expression.ExpressionColumn) IndexCondition(com.wplatform.ddal.dbobject.index.IndexCondition)

Example 2 with IndexCondition

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();
}
Also used : StatementBuilder(com.wplatform.ddal.util.StatementBuilder) IndexCondition(com.wplatform.ddal.dbobject.index.IndexCondition)

Example 3 with IndexCondition

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;
}
Also used : SortOrder(com.wplatform.ddal.result.SortOrder) IndexCondition(com.wplatform.ddal.dbobject.index.IndexCondition)

Example 4 with IndexCondition

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);
    }
}
Also used : TableFilter(com.wplatform.ddal.dbobject.table.TableFilter) IndexCondition(com.wplatform.ddal.dbobject.index.IndexCondition)

Example 5 with IndexCondition

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;
    }
}
Also used : ResultInterface(com.wplatform.ddal.result.ResultInterface) Column(com.wplatform.ddal.dbobject.table.Column) Value(com.wplatform.ddal.value.Value) List(java.util.List) IndexCondition(com.wplatform.ddal.dbobject.index.IndexCondition) SearchRow(com.wplatform.ddal.result.SearchRow)

Aggregations

IndexCondition (com.wplatform.ddal.dbobject.index.IndexCondition)5 ExpressionColumn (com.wplatform.ddal.command.expression.ExpressionColumn)1 Column (com.wplatform.ddal.dbobject.table.Column)1 TableFilter (com.wplatform.ddal.dbobject.table.TableFilter)1 ResultInterface (com.wplatform.ddal.result.ResultInterface)1 SearchRow (com.wplatform.ddal.result.SearchRow)1 SortOrder (com.wplatform.ddal.result.SortOrder)1 StatementBuilder (com.wplatform.ddal.util.StatementBuilder)1 Value (com.wplatform.ddal.value.Value)1 List (java.util.List)1