From a662f1d9851441f430e892c58feb78151ae165d5 Mon Sep 17 00:00:00 2001 From: terrymanu Date: Sat, 11 May 2019 17:12:24 +0800 Subject: [PATCH] for #1753, parse subquery for order by & group by --- .../impl/dml/select/SelectItemsExtractor.java | 4 +++- .../dml/select/groupby/GroupByExtractor.java | 17 ++++++++++++++++- .../dml/select/orderby/OrderByExtractor.java | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/SelectItemsExtractor.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/SelectItemsExtractor.java index 1a3be42522..c0f5ab07f0 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/SelectItemsExtractor.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/SelectItemsExtractor.java @@ -80,9 +80,11 @@ public final class SelectItemsExtractor implements OptionalSQLSegmentExtractor { } ParserRuleContext result = tableReferencesNode.get(); Optional subqueryNode = ExtractorUtils.findSingleNodeFromFirstDescendant(tableReferencesNode.get(), RuleName.SUBQUERY); + boolean isFromRecursiveInMethod = false; if (subqueryNode.isPresent()) { + isFromRecursiveInMethod = true; result = findMainQueryNode(subqueryNode.get(), true); } - return isFromRecursive ? result : ancestorNode; + return isFromRecursive || isFromRecursiveInMethod ? result : ancestorNode; } } diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/groupby/GroupByExtractor.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/groupby/GroupByExtractor.java index e07a3e92f6..8f760d1b10 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/groupby/GroupByExtractor.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/groupby/GroupByExtractor.java @@ -42,8 +42,23 @@ public abstract class GroupByExtractor implements OptionalSQLSegmentExtractor { @Override public final Optional extract(final ParserRuleContext ancestorNode, final Map parameterMarkerIndexes) { - Optional groupByNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.GROUP_BY_CLAUSE); + Optional groupByNode = ExtractorUtils.findFirstChildNode(findMainQueryNode(ancestorNode, false), RuleName.GROUP_BY_CLAUSE); return groupByNode.isPresent() ? Optional.of(new GroupBySegment(groupByNode.get().getStop().getStopIndex(), orderByItemExtractor.extract(groupByNode.get(), parameterMarkerIndexes))) : Optional.absent(); } + + private ParserRuleContext findMainQueryNode(final ParserRuleContext ancestorNode, final boolean isFromRecursive) { + Optional tableReferencesNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.TABLE_REFERENCES); + if (!tableReferencesNode.isPresent()) { + return ancestorNode; + } + ParserRuleContext result = tableReferencesNode.get(); + Optional subqueryNode = ExtractorUtils.findSingleNodeFromFirstDescendant(tableReferencesNode.get(), RuleName.SUBQUERY); + boolean isFromRecursiveInMethod = false; + if (subqueryNode.isPresent()) { + isFromRecursiveInMethod = true; + result = findMainQueryNode(subqueryNode.get(), true); + } + return isFromRecursive || isFromRecursiveInMethod ? result : ancestorNode; + } } diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/orderby/OrderByExtractor.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/orderby/OrderByExtractor.java index 1ecf79859e..aeee2116a3 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/orderby/OrderByExtractor.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/antlr/extractor/impl/dml/select/orderby/OrderByExtractor.java @@ -40,7 +40,22 @@ public abstract class OrderByExtractor implements OptionalSQLSegmentExtractor { @Override public final Optional extract(final ParserRuleContext ancestorNode, final Map parameterMarkerIndexes) { - Optional orderByNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.ORDER_BY_CLAUSE); + Optional orderByNode = ExtractorUtils.findFirstChildNode(findMainQueryNode(ancestorNode, false), RuleName.ORDER_BY_CLAUSE); return orderByNode.isPresent() ? Optional.of(new OrderBySegment(orderByItemExtractor.extract(orderByNode.get(), parameterMarkerIndexes))) : Optional.absent(); } + + private ParserRuleContext findMainQueryNode(final ParserRuleContext ancestorNode, final boolean isFromRecursive) { + Optional tableReferencesNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.TABLE_REFERENCES); + if (!tableReferencesNode.isPresent()) { + return ancestorNode; + } + ParserRuleContext result = tableReferencesNode.get(); + Optional subqueryNode = ExtractorUtils.findSingleNodeFromFirstDescendant(tableReferencesNode.get(), RuleName.SUBQUERY); + boolean isFromRecursiveInMethod = false; + if (subqueryNode.isPresent()) { + isFromRecursiveInMethod = true; + result = findMainQueryNode(subqueryNode.get(), true); + } + return isFromRecursive || isFromRecursiveInMethod ? result : ancestorNode; + } } -- GitLab