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 1a3be42522cd67558fabf20b1c223c2113ef33b9..c0f5ab07f00d31a7f2c4c2e9da8f70c788d4cc4a 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 e07a3e92f638a2fc2e47eb643afbef0b16bb6e15..8f760d1b101bc0c97be69f0c204b8d060fbd1c41 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 1ecf79859e554f84039003761cf13ad033137e58..aeee2116a34cf6fe05e4bc6d789b7181f74fa7bf 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; + } }