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) {