From 8f939b14241caf3c45caf1dcf34d17dd744e19d7 Mon Sep 17 00:00:00 2001 From: ZhangCheng Date: Wed, 23 Oct 2024 10:47:45 +0800 Subject: [PATCH] Fix the combine statement cannot find the outer table when bind --- .../segment/combine/CombineSegmentBinder.java | 15 +++++++++++---- .../statement/dml/SelectStatementBinder.java | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java index c42b98ea975e4..a21b4a8bea17e 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java @@ -17,8 +17,11 @@ package org.apache.shardingsphere.infra.binder.engine.segment.combine; +import com.cedarsoftware.util.CaseInsensitiveMap; +import com.google.common.collect.Multimap; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext; import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext; import org.apache.shardingsphere.infra.binder.engine.statement.dml.SelectStatementBinder; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.combine.CombineSegment; @@ -35,19 +38,23 @@ public final class CombineSegmentBinder { * * @param segment table segment * @param binderContext SQL statement binder context + * @param outerTableBinderContexts outer table binder contexts * @return bound combine segment */ - public static CombineSegment bind(final CombineSegment segment, final SQLStatementBinderContext binderContext) { + public static CombineSegment bind(final CombineSegment segment, final SQLStatementBinderContext binderContext, + final Multimap outerTableBinderContexts) { return new CombineSegment(segment.getStartIndex(), segment.getStopIndex(), - bindSubquerySegment(segment.getLeft(), binderContext), segment.getCombineType(), bindSubquerySegment(segment.getRight(), binderContext)); + bindSubquerySegment(segment.getLeft(), binderContext, outerTableBinderContexts), segment.getCombineType(), + bindSubquerySegment(segment.getRight(), binderContext, outerTableBinderContexts)); } - private static SubquerySegment bindSubquerySegment(final SubquerySegment segment, final SQLStatementBinderContext binderContext) { + private static SubquerySegment bindSubquerySegment(final SubquerySegment segment, final SQLStatementBinderContext binderContext, + final Multimap outerTableBinderContexts) { SubquerySegment result = new SubquerySegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText()); result.setSubqueryType(segment.getSubqueryType()); SQLStatementBinderContext subqueryBinderContext = new SQLStatementBinderContext(segment.getSelect(), binderContext.getMetaData(), binderContext.getCurrentDatabaseName()); subqueryBinderContext.getExternalTableBinderContexts().putAll(binderContext.getExternalTableBinderContexts()); - result.setSelect(new SelectStatementBinder().bind(segment.getSelect(), subqueryBinderContext)); + result.setSelect(new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSelect(), subqueryBinderContext)); return result; } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java index c0a5da62a6d5c..be63bc0c7a815 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java @@ -55,7 +55,7 @@ public SelectStatement bind(final SelectStatement sqlStatement, final SQLStateme boundTableSegment.ifPresent(result::setFrom); result.setProjections(ProjectionsSegmentBinder.bind(sqlStatement.getProjections(), binderContext, boundTableSegment.orElse(null), tableBinderContexts, outerTableBinderContexts)); sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, binderContext, tableBinderContexts, outerTableBinderContexts))); - sqlStatement.getCombine().ifPresent(optional -> result.setCombine(CombineSegmentBinder.bind(optional, binderContext))); + sqlStatement.getCombine().ifPresent(optional -> result.setCombine(CombineSegmentBinder.bind(optional, binderContext, outerTableBinderContexts))); sqlStatement.getLock().ifPresent(optional -> result.setLock(LockSegmentBinder.bind(optional, binderContext, tableBinderContexts, outerTableBinderContexts))); // TODO support other segment bind in select statement return result;