diff --git a/src/main/java/com/actiontech/dble/plan/node/view/ViewUtil.java b/src/main/java/com/actiontech/dble/plan/node/view/ViewUtil.java index 91126c430..20e34e975 100644 --- a/src/main/java/com/actiontech/dble/plan/node/view/ViewUtil.java +++ b/src/main/java/com/actiontech/dble/plan/node/view/ViewUtil.java @@ -31,6 +31,6 @@ public final class ViewUtil { boolean selectsAllowMerge = viewSelNode.type() != PlanNode.PlanNodeType.MERGE; // TODO as the same as LEX::can_be_merged(); boolean existAggr = PlanUtil.existAggr(viewSelNode); - return selectsAllowMerge && viewSelNode.getReferedTableNodes().size() >= 1 && !existAggr; + return selectsAllowMerge && viewSelNode.getReferedTableNodes().size() == 1 && !existAggr; } } diff --git a/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryPreProcessor.java b/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryPreProcessor.java index 80b91257d..e60d5820e 100644 --- a/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryPreProcessor.java +++ b/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryPreProcessor.java @@ -18,6 +18,7 @@ import com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEq import com.actiontech.dble.plan.common.item.function.operator.logic.ItemCondAnd; import com.actiontech.dble.plan.common.item.function.operator.logic.ItemCondOr; import com.actiontech.dble.plan.common.item.subquery.*; +import com.actiontech.dble.plan.common.ptr.BoolPtr; import com.actiontech.dble.plan.node.JoinNode; import com.actiontech.dble.plan.util.FilterUtils; import com.actiontech.dble.plan.util.PlanUtil; @@ -35,63 +36,67 @@ public final class SubQueryPreProcessor { public static PlanNode optimize(PlanNode qtn) { MergeHavingFilter.optimize(qtn); - qtn = findComparisonsSubQueryToJoinNode(qtn); + qtn = findComparisonsSubQueryToJoinNode(qtn, new BoolPtr(false)); return qtn; } /** * http://dev.mysql.com/doc/refman/5.0/en/comparisons-using-subqueries.html */ - private static PlanNode findComparisonsSubQueryToJoinNode(PlanNode qtn) { + private static PlanNode findComparisonsSubQueryToJoinNode(PlanNode qtn, BoolPtr childTransform) { for (int i = 0; i < qtn.getChildren().size(); i++) { PlanNode child = qtn.getChildren().get(i); - qtn.getChildren().set(i, findComparisonsSubQueryToJoinNode(child)); + qtn.getChildren().set(i, findComparisonsSubQueryToJoinNode(child, childTransform)); } SubQueryFilter find = new SubQueryFilter(); find.query = qtn; find.filter = null; Item where = qtn.getWhereFilter(); - SubQueryFilter result = buildSubQuery(qtn, find, where, false); + SubQueryFilter result = buildSubQuery(qtn, find, where, false, childTransform); if (result != find) { // that means where filter only contains sub query,just replace it result.query.query(result.filter); qtn.query(null); // change result.filter and rebuild result.query.setUpFields(); + childTransform.set(true); return result.query; } else { + if (childTransform.get()) { + qtn.setUpFields(); + } return qtn; } } - private static SubQueryFilter buildSubQuery(PlanNode node, SubQueryFilter qtn, Item filter, boolean isOrChild) { + private static SubQueryFilter buildSubQuery(PlanNode node, SubQueryFilter qtn, Item filter, boolean isOrChild, BoolPtr childTransform) { if (filter == null) return qtn; if (!filter.isWithSubQuery()) { qtn.filter = filter; } else if (filter instanceof ItemCondOr) { - return buildSubQueryWithOrFilter(node, qtn, (ItemCondOr) filter); + return buildSubQueryWithOrFilter(node, qtn, (ItemCondOr) filter, childTransform); } else if (filter instanceof ItemCondAnd) { - return buildSubQueryWithAndFilter(node, qtn, (ItemCondAnd) filter, isOrChild); + return buildSubQueryWithAndFilter(node, qtn, (ItemCondAnd) filter, isOrChild, childTransform); } else { - return buildSubQueryByFilter(node, qtn, filter, isOrChild); + return buildSubQueryByFilter(node, qtn, filter, isOrChild, childTransform); } return qtn; } - private static SubQueryFilter buildSubQueryByFilter(PlanNode node, SubQueryFilter qtn, Item filter, boolean isOrChild) { + private static SubQueryFilter buildSubQueryByFilter(PlanNode node, SubQueryFilter qtn, Item filter, boolean isOrChild, BoolPtr childTransform) { if (filter instanceof ItemInSubQuery && !isOrChild) { - return transformInSubQuery(qtn, (ItemInSubQuery) filter); + return transformInSubQuery(qtn, (ItemInSubQuery) filter, childTransform); } else if (filter instanceof ItemInSubQuery) { - addSubQuey(node, (ItemInSubQuery) filter); + addSubQuey(node, (ItemInSubQuery) filter, childTransform); return qtn; } else if (PlanUtil.isCmpFunc(filter)) { ItemBoolFunc2 eqFilter = (ItemBoolFunc2) filter; Item arg0 = eqFilter.arguments().get(0); if (arg0.type().equals(ItemType.SUBSELECT_ITEM)) { if (arg0 instanceof ItemScalarSubQuery) { - addSubQuey(node, ((ItemScalarSubQuery) arg0)); + addSubQuey(node, (ItemScalarSubQuery) arg0, childTransform); } else { //todo: when happened? throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "not support subquery of:" + filter.type()); @@ -101,9 +106,9 @@ public final class SubQueryPreProcessor { Item arg1 = eqFilter.arguments().get(1); if (arg1.type().equals(ItemType.SUBSELECT_ITEM)) { if (arg1 instanceof ItemScalarSubQuery) { - addSubQuey(node, ((ItemScalarSubQuery) arg1)); + addSubQuey(node, (ItemScalarSubQuery) arg1, childTransform); } else if (arg1 instanceof ItemAllAnySubQuery) { - addSubQuey(node, ((ItemAllAnySubQuery) arg1)); + addSubQuey(node, (ItemAllAnySubQuery) arg1, childTransform); } else { //todo: when happened? throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "not support subquery of:" + filter.type()); @@ -112,7 +117,7 @@ public final class SubQueryPreProcessor { return qtn; } else if (filter.type().equals(ItemType.SUBSELECT_ITEM)) { if (filter instanceof ItemExistsSubQuery) { - addSubQuey(node, ((ItemExistsSubQuery) filter)); + addSubQuey(node, (ItemExistsSubQuery) filter, childTransform); } else { //todo: when happened? throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "not support subquery of:" + filter.type()); @@ -124,16 +129,16 @@ public final class SubQueryPreProcessor { } } - private static void addSubQuey(PlanNode node, ItemSubQuery subQuery) { + private static void addSubQuey(PlanNode node, ItemSubQuery subQuery, BoolPtr childTransform) { node.getSubQueries().add(subQuery); - PlanNode subNode = findComparisonsSubQueryToJoinNode(subQuery.getPlanNode()); + PlanNode subNode = findComparisonsSubQueryToJoinNode(subQuery.getPlanNode(), childTransform); subQuery.setPlanNode(subNode); } - private static SubQueryFilter transformInSubQuery(SubQueryFilter qtn, ItemInSubQuery filter) { + private static SubQueryFilter transformInSubQuery(SubQueryFilter qtn, ItemInSubQuery filter, BoolPtr childTransform) { Item leftColumn = filter.getLeftOperand(); PlanNode query = filter.getPlanNode(); - query = findComparisonsSubQueryToJoinNode(query); + query = findComparisonsSubQueryToJoinNode(query, childTransform); if (StringUtils.isEmpty(query.getAlias())) query.alias(AUTOALIAS + query.getPureName()); if (query.getColumnsSelected().size() != 1) @@ -205,16 +210,16 @@ public final class SubQueryPreProcessor { return result; } - private static SubQueryFilter buildSubQueryWithOrFilter(PlanNode node, SubQueryFilter qtn, ItemCondOr filter) { + private static SubQueryFilter buildSubQueryWithOrFilter(PlanNode node, SubQueryFilter qtn, ItemCondOr filter, BoolPtr childTransform) { for (int index = 0; index < filter.getArgCount(); index++) { - buildSubQuery(node, qtn, filter.arguments().get(index), true); + buildSubQuery(node, qtn, filter.arguments().get(index), true, childTransform); } return qtn; } - private static SubQueryFilter buildSubQueryWithAndFilter(PlanNode node, SubQueryFilter qtn, ItemCondAnd filter, boolean isOrChild) { + private static SubQueryFilter buildSubQueryWithAndFilter(PlanNode node, SubQueryFilter qtn, ItemCondAnd filter, boolean isOrChild, BoolPtr childTransform) { for (int index = 0; index < filter.getArgCount(); index++) { - SubQueryFilter result = buildSubQuery(node, qtn, filter.arguments().get(index), isOrChild); + SubQueryFilter result = buildSubQuery(node, qtn, filter.arguments().get(index), isOrChild, childTransform); if (result != qtn) { if (result.filter == null) { result.filter = new ItemInt(1); diff --git a/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java b/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java index 699e388b4..e9a124ed2 100644 --- a/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java +++ b/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java @@ -237,7 +237,7 @@ public class MySQLPlanNodeVisitor { this.tableNode.setSubQuery(true); if (subQueryTables.getAlias() != null) { tableNode.alias(subQueryTables.getAlias()); - if (tableNode.getSubAlias() == null && tableNode.type() == PlanNode.PlanNodeType.TABLE) { + if (tableNode.getSubAlias() == null && tableNode.type() == PlanNode.PlanNodeType.TABLE && !tableNode.isSubQuery()) { tableNode.setSubAlias(tableNode.getAlias()); } } diff --git a/src/test/java/demo/test/Testparser.java b/src/test/java/demo/test/Testparser.java index 20c8876e2..8804bb78b 100644 --- a/src/test/java/demo/test/Testparser.java +++ b/src/test/java/demo/test/Testparser.java @@ -229,14 +229,14 @@ public class Testparser { + " from char_columns where id =1 and name = 'x';"; // obj.test(selectSQl); - selectSQl = "select * from constant_one where id > SOME(select name from constant_two);"; - obj.test(selectSQl); - selectSQl = "select * from constant_one where id > ANY(select name from constant_two);"; - obj.test(selectSQl); - selectSQl = "select * from constant_one where id > ALL(select name from constant_two);"; - obj.test(selectSQl); - selectSQl = "select * from constant_one where id <> ALL(select name from constant_two);"; - obj.test(selectSQl); +// selectSQl = "select * from constant_one where id > SOME(select name from constant_two);"; +// obj.test(selectSQl); +// selectSQl = "select * from constant_one where id > ANY(select name from constant_two);"; +// obj.test(selectSQl); +// selectSQl = "select * from constant_one where id > ALL(select name from constant_two);"; +// obj.test(selectSQl); +// selectSQl = "select * from constant_one where id <> ALL(select name from constant_two);"; +// obj.test(selectSQl); // selectSQl = "SELECT BINARY 'a' = 'A';"; // obj.test(selectSQl); // selectSQl = "SELECT b'1000001';"; @@ -362,6 +362,8 @@ public class Testparser { // //not support // selectSQl = "select sql_big_result distinct pad from sbtest1;"; // obj.test(selectSQl); + String insertSQl = "insert into test_shard values(1,1,'a\\%string','test001');"; + obj.test(insertSQl); }