private boolean isDirectLookup() { for (TableFilter tf : filters) { if (!tf.isFromTableMate() && !isNestedJoinTable(tf)) { return false; } } if (filters.size() == 1) { return true; } else { List<TableFilter> shardingTableFilter = New.arrayList(); for (TableFilter tf : filters) { if (isNestedJoinTable(tf)) { continue; } if (!isGropTableFilter(tf)) { return false; } TableMate table = (TableMate) tf.getTable(); if (table.getRuleColumns() != null) { shardingTableFilter.add(tf); } } if (shardingTableFilter.size() < 2) { return true; } this.joinTableChain = New.hashSet(); evaluationJoinChain(shardingTableFilter.iterator().next()); return joinTableChain.containsAll(shardingTableFilter); } }
private void evaluationJoinChain(TableFilter filter) { TableMate table1 = (TableMate) filter.getTable(); Column[] columns1 = table1.getRuleColumns(); if (columns1 == null) { throw new IllegalArgumentException("not sharding TableFilter"); } ArrayList<IndexCondition> conditions = getIndexConditions(filter); List<IndexCondition> masks = New.arrayList(10); List<Column> compareColumns = New.arrayList(10); for (Column column : columns1) { for (IndexCondition condition : conditions) { Column compareColumn = condition.getCompareColumn(); if ((condition.getMask(conditions) & IndexCondition.EQUALITY) != IndexCondition.EQUALITY) { continue; } if (condition.getColumn() != column || compareColumn == null) { continue; } masks.add(condition); compareColumns.add(compareColumn); } } Set<Table> tables = New.hashSet(); for (IndexCondition mask : masks) { Column compareColumn = mask.getCompareColumn(); Table table = compareColumn.getTable(); if (!(table instanceof TableMate)) { continue; } TableMate tableMate = (TableMate) table; Column[] rc = tableMate.getRuleColumns(); if (compareColumns.containsAll(Arrays.asList(rc))) { tables.add(table); } } if (tables.isEmpty()) { return; } for (Table table : tables) { for (TableFilter tf : filters) { if (tf.getTable() == table && !joinTableChain.contains(tf)) { joinTableChain.add(tf); evaluationJoinChain(tf); } } } }
private boolean isGropTableFilter(TableFilter filter) { TableMate table1 = (TableMate) filter.getTable(); for (TableFilter item : filters) { if (item == filter || isNestedJoinTable(item)) { continue; } TableMate table2 = (TableMate) item.getTable(); TableRule rule1 = table1.getTableRule(); TableRule rule2 = table2.getTableRule(); if (!rule1.isNodeComparable(rule2)) { return false; } } return true; }
private DirectLookupEstimator(ArrayList<TableFilter> topFilters) { this.filters = New.arrayList(); this.joinCond = New.arrayList(); for (TableFilter f : topFilters) { f.visit( new TableFilterVisitor() { @Override public void accept(TableFilter f) { filters.add(f); if (f.getJoinCondition() != null) { joinCond.add(f.getJoinCondition()); } } }); } }
private ArrayList<IndexCondition> getIndexConditions(TableFilter filter) { ArrayList<IndexCondition> indexConditions = filter.getIndexConditions(); if (joinCond.isEmpty()) { return indexConditions; } ArrayList<IndexCondition> original = New.arrayList(indexConditions); ArrayList<IndexCondition> result; try { for (Expression cond : joinCond) { // add to indexConditions cond.createIndexConditions(filter.getSession(), filter); } result = New.arrayList(indexConditions); return result; } finally { indexConditions.clear(); indexConditions.addAll(original); } }
private RoutingResult doRoute(Select prepare) { List<TableFilter> filters = filterNotTableMate(prepare.getTopTableFilter()); List<TableFilter> shards = New.arrayList(filters.size()); List<TableFilter> globals = New.arrayList(filters.size()); List<TableFilter> fixeds = New.arrayList(filters.size()); for (TableFilter tf : filters) { TableMate table = getTableMate(tf); switch (table.getTableRule().getType()) { case TableRule.SHARDED_NODE_TABLE: shards.add(tf); break; case TableRule.GLOBAL_NODE_TABLE: globals.add(tf); break; case TableRule.FIXED_NODE_TABLE: fixeds.add(tf); break; default: break; } } RoutingResult result = null; if (!shards.isEmpty()) { for (TableFilter f : shards) { f.setEvaluatable(f, false); if (f.isJoinOuter() || f.isJoinOuterIndirect()) { prepare.getCondition().createIndexConditions(session, f); } TableMate table = getTableMate(f); ConditionExtractor extractor = new ConditionExtractor(f); RoutingResult r = routingHandler.doRoute( table, extractor.getStart(), extractor.getEnd(), extractor.getInColumns()); result = (result == null || r.compareTo(result) < 0) ? r : result; } for (TableFilter f : shards) { f.setEvaluatable(f, true); } } else if (!fixeds.isEmpty()) { for (TableFilter tf : shards) { TableMate table = getTableMate(tf); RoutingResult r = routingHandler.doRoute(table); result = r; } } else if (!globals.isEmpty()) { // 全部为全局表查询,随机取一个第一个表结点 GlobalTableRule tableRule = (GlobalTableRule) getTableRule(globals.iterator().next()); RoutingResult r = tableRule.getRandomRoutingResult(); result = r; } else { throw DbException.throwInternalError("SQL_ROUTING_ERROR"); } ObjectNode[] selectNodes = result.getSelectNodes(); if (selectNodes.length == 0) { throw DbException.throwInternalError("SQL_ROUTING_ERROR,empty result"); } setConsistencyTableNodes(selectNodes, filters); return result; }
private boolean isNestedJoinTable(TableFilter f) { return f.getTable() instanceof RangeTable && StringUtils.startsWith(f.getTableAlias(), Constants.PREFIX_JOIN); }