This is an automated email from the ASF dual-hosted git repository.

zhaojinchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new f8dea45a23a Bind oracle merge source subquery table projection 
parameters (#30559)
f8dea45a23a is described below

commit f8dea45a23aebd128f3c1c555b233bc6a4218807
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Wed Mar 20 17:04:13 2024 +0800

    Bind oracle merge source subquery table projection parameters (#30559)
---
 .../from/SimpleTableSegmentBinderContext.java      | 10 +++++-----
 .../from/impl/SubqueryTableSegmentBinder.java      | 22 +++++++++++++++++++++-
 .../binder/statement/dml/MergeStatementBinder.java | 17 +++++++++++++++++
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/SimpleTableSegmentBinderContext.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/SimpleTableSegmentBinderContext.java
index 82852b7d83d..c7d80ce133f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/SimpleTableSegmentBinderContext.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/SimpleTableSegmentBinderContext.java
@@ -17,12 +17,12 @@
 
 package org.apache.shardingsphere.infra.binder.segment.from;
 
+import com.cedarsoftware.util.CaseInsensitiveMap;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
 
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
 
@@ -35,21 +35,21 @@ public final class SimpleTableSegmentBinderContext 
implements TableSegmentBinder
     private final Map<String, ProjectionSegment> columnLabelProjectionSegments;
     
     public SimpleTableSegmentBinderContext(final Collection<ProjectionSegment> 
projectionSegments) {
-        columnLabelProjectionSegments = new 
LinkedHashMap<>(projectionSegments.size(), 1F);
+        columnLabelProjectionSegments = new 
CaseInsensitiveMap<>(projectionSegments.size(), 1F);
         projectionSegments.forEach(each -> 
putColumnLabelProjectionSegments(each, columnLabelProjectionSegments));
     }
     
     private void putColumnLabelProjectionSegments(final ProjectionSegment 
projectionSegment, final Map<String, ProjectionSegment> 
columnLabelProjectionSegments) {
         if (projectionSegment instanceof ShorthandProjectionSegment) {
-            ((ShorthandProjectionSegment) 
projectionSegment).getActualProjectionSegments().forEach(each -> 
columnLabelProjectionSegments.put(each.getColumnLabel().toLowerCase(), each));
+            ((ShorthandProjectionSegment) 
projectionSegment).getActualProjectionSegments().forEach(each -> 
columnLabelProjectionSegments.put(each.getColumnLabel(), each));
         } else {
-            
columnLabelProjectionSegments.put(projectionSegment.getColumnLabel().toLowerCase(),
 projectionSegment);
+            
columnLabelProjectionSegments.put(projectionSegment.getColumnLabel(), 
projectionSegment);
         }
     }
     
     @Override
     public Optional<ProjectionSegment> 
findProjectionSegmentByColumnLabel(final String columnLabel) {
-        return 
Optional.ofNullable(columnLabelProjectionSegments.get(columnLabel.toLowerCase()));
+        return 
Optional.ofNullable(columnLabelProjectionSegments.get(columnLabel));
     }
     
     @Override
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
index 258b201dd23..22e6dffd2eb 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/from/impl/SubqueryTableSegmentBinder.java
@@ -22,9 +22,11 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.segment.from.SimpleTableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinderContext;
+import 
org.apache.shardingsphere.infra.binder.segment.parameter.impl.ParameterMarkerExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementBinder;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
@@ -37,6 +39,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectState
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Map;
 
@@ -62,14 +65,31 @@ public final class SubqueryTableSegmentBinder {
                 statementBinderContext.getDefaultDatabaseName(), 
outerTableBinderContexts, 
statementBinderContext.getExternalTableBinderContexts());
         SubquerySegment boundedSubquerySegment = new 
SubquerySegment(segment.getSubquery().getStartIndex(), 
segment.getSubquery().getStopIndex(), boundedSelect, 
segment.getSubquery().getText());
         
boundedSubquerySegment.setSubqueryType(segment.getSubquery().getSubqueryType());
+        IdentifierValue subqueryTableName = 
segment.getAliasSegment().map(AliasSegment::getIdentifier).orElseGet(() -> new 
IdentifierValue(""));
+        bindParameterMarkerProjection(boundedSubquerySegment, 
subqueryTableName);
         SubqueryTableSegment result = new 
SubqueryTableSegment(boundedSubquerySegment);
         segment.getAliasSegment().ifPresent(result::setAlias);
-        IdentifierValue subqueryTableName = 
segment.getAliasSegment().map(AliasSegment::getIdentifier).orElseGet(() -> new 
IdentifierValue(""));
         tableBinderContexts.put(subqueryTableName.getValue().toLowerCase(),
                 new 
SimpleTableSegmentBinderContext(createSubqueryProjections(boundedSelect.getProjections().getProjections(),
 subqueryTableName)));
         return result;
     }
     
+    private static void bindParameterMarkerProjection(final SubquerySegment 
boundedSubquerySegment, final IdentifierValue subqueryTableName) {
+        SelectStatement boundedSelect = boundedSubquerySegment.getSelect();
+        Collection<ProjectionSegment> projections = new 
LinkedList<>(boundedSelect.getProjections().getProjections());
+        boundedSelect.getProjections().getProjections().clear();
+        for (ProjectionSegment each : projections) {
+            if (!(each instanceof ParameterMarkerExpressionSegment)) {
+                boundedSelect.getProjections().getProjections().add(each);
+                continue;
+            }
+            ParameterMarkerExpressionSegment parameterMarkerProjection = 
(ParameterMarkerExpressionSegment) each;
+            // TODO add database and schema in ColumnSegmentBoundedInfo
+            
boundedSelect.getProjections().getProjections().add(ParameterMarkerExpressionSegmentBinder.bind(parameterMarkerProjection,
 Collections.singletonMap(parameterMarkerProjection,
+                    new ColumnSegmentBoundedInfo(new IdentifierValue(""), new 
IdentifierValue(""), subqueryTableName, 
parameterMarkerProjection.getAlias().orElseGet(() -> new 
IdentifierValue(""))))));
+        }
+    }
+    
     private static void fillPivotColumnNamesInBinderContext(final 
SubqueryTableSegment segment, final SQLStatementBinderContext 
statementBinderContext) {
         segment.getPivot().ifPresent(optional -> 
optional.getPivotColumns().forEach(each -> 
statementBinderContext.getPivotColumnNames().add(each.getIdentifier().getValue().toLowerCase())));
     }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java
index 6a76783424b..dfe873eec0b 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java
@@ -37,11 +37,13 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.Column
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionWithParamsSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ParameterMarkerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.bounded.ColumnSegmentBoundedInfo;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.MergeStatement;
@@ -99,10 +101,25 @@ public final class MergeStatementBinder implements 
SQLStatementBinder<MergeState
     
     private void addParameterMarkerSegments(final MergeStatement 
mergeStatement) {
         // TODO bind parameter marker segments for merge statement
+        
mergeStatement.addParameterMarkerSegments(getSourceSubqueryTableProjectionParameterMarkers(mergeStatement.getSource()));
         mergeStatement.getInsert().ifPresent(optional -> 
mergeStatement.addParameterMarkerSegments(optional.getParameterMarkerSegments()));
         mergeStatement.getUpdate().ifPresent(optional -> 
mergeStatement.addParameterMarkerSegments(optional.getParameterMarkerSegments()));
     }
     
+    private Collection<ParameterMarkerSegment> 
getSourceSubqueryTableProjectionParameterMarkers(final TableSegment 
tableSegment) {
+        if (!(tableSegment instanceof SubqueryTableSegment)) {
+            return Collections.emptyList();
+        }
+        SubqueryTableSegment subqueryTable = (SubqueryTableSegment) 
tableSegment;
+        Collection<ParameterMarkerSegment> result = new LinkedList<>();
+        for (ProjectionSegment each : 
subqueryTable.getSubquery().getSelect().getProjections().getProjections()) {
+            if (each instanceof ParameterMarkerExpressionSegment) {
+                result.add((ParameterMarkerSegment) each);
+            }
+        }
+        return result;
+    }
+    
     @SneakyThrows
     private InsertStatement bindMergeInsert(final InsertStatement 
sqlStatement, final SimpleTableSegment tableSegment, final 
SQLStatementBinderContext statementBinderContext,
                                             final Map<String, 
TableSegmentBinderContext> targetTableBinderContexts, final Map<String, 
TableSegmentBinderContext> sourceTableBinderContexts) {

Reply via email to