You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/11/23 01:31:10 UTC
[shardingsphere] branch master updated: fix ShardingSphereResultSet bug. (#21768)
This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 ad95d407845 fix ShardingSphereResultSet bug. (#21768)
ad95d407845 is described below
commit ad95d407845e2b0dd5d81b24da20770d5c8fd1e9
Author: fang1025 <fa...@126.com>
AuthorDate: Wed Nov 23 09:31:03 2022 +0800
fix ShardingSphereResultSet bug. (#21768)
* fix ShardingSphereResultSet bug.
* fix ShardingSphereResultSet bug.
* fix ShardingSphereResultSet bug.
* merge actualColumns and resultSetColumns to one field
* test ShorthandProjection.resultSetColumns
* fix ProjectionEngineTest&ShorthandProjection code style
* fix ShorthandProjection code style
---
.../select/projection/ProjectionsContext.java | 6 ++--
.../select/projection/engine/ProjectionEngine.java | 31 +++++++++++----------
.../projection/impl/ShorthandProjection.java | 25 +++++++++++++----
.../projection/engine/ProjectionEngineTest.java | 32 ++++++++++++++++++++++
4 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
index 97784c192e6..a5cc6c6cb4f 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
@@ -78,7 +78,7 @@ public final class ProjectionsContext {
List<Projection> result = new ArrayList<>();
for (Projection each : projections) {
if (each instanceof ShorthandProjection) {
- result.addAll(((ShorthandProjection) each).getActualColumns().values());
+ result.addAll(((ShorthandProjection) each).getResultSetColumns().values());
} else if (!(each instanceof DerivedProjection)) {
result.add(each);
}
@@ -107,8 +107,8 @@ public final class ProjectionsContext {
*/
public Optional<String> findAlias(final String projectionName) {
for (Projection each : projections) {
- if (each instanceof ShorthandProjection && ((ShorthandProjection) each).getActualColumns().containsKey(projectionName.toLowerCase())) {
- return ((ShorthandProjection) each).getActualColumns().get(projectionName.toLowerCase()).getAlias();
+ if (each instanceof ShorthandProjection && ((ShorthandProjection) each).getResultSetColumns().containsKey(projectionName.toLowerCase())) {
+ return ((ShorthandProjection) each).getResultSetColumns().get(projectionName.toLowerCase()).getAlias();
}
if (projectionName.equalsIgnoreCase(SQLUtil.getExactlyValue(each.getExpression()))) {
return each.getAlias();
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
index 8f144f0d97e..3709a34a869 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
@@ -115,11 +115,11 @@ public final class ProjectionEngine {
private ShorthandProjection createProjection(final TableSegment table, final ShorthandProjectionSegment projectionSegment) {
String owner = projectionSegment.getOwner().map(optional -> optional.getIdentifier().getValue()).orElse(null);
- Collection<ColumnProjection> columnProjections = new LinkedHashSet<>();
- columnProjections.addAll(getShorthandColumnsFromSimpleTableSegment(table, owner));
- columnProjections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
- columnProjections.addAll(getShorthandColumnsFromJoinTableSegment(table, projectionSegment));
- return new ShorthandProjection(owner, columnProjections);
+ Collection<Projection> projections = new LinkedHashSet<>();
+ projections.addAll(getShorthandColumnsFromSimpleTableSegment(table, owner));
+ projections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
+ projections.addAll(getShorthandColumnsFromJoinTableSegment(table, projectionSegment));
+ return new ShorthandProjection(owner, projections);
}
private ColumnProjection createProjection(final ColumnProjectionSegment projectionSegment) {
@@ -171,34 +171,35 @@ public final class ProjectionEngine {
return result;
}
- private Collection<ColumnProjection> getShorthandColumnsFromSubqueryTableSegment(final TableSegment table) {
+ private Collection<Projection> getShorthandColumnsFromSubqueryTableSegment(final TableSegment table) {
if (!(table instanceof SubqueryTableSegment)) {
return Collections.emptyList();
}
SelectStatement subSelectStatement = ((SubqueryTableSegment) table).getSubquery().getSelect();
Collection<Projection> projections = subSelectStatement.getProjections().getProjections().stream().map(each -> createProjection(subSelectStatement.getFrom(), each).orElse(null))
.filter(Objects::nonNull).collect(Collectors.toList());
- return getColumnProjections(projections);
+ return getResultSetProjections(projections);
}
- private Collection<ColumnProjection> getShorthandColumnsFromJoinTableSegment(final TableSegment table, final ProjectionSegment projectionSegment) {
+ private Collection<Projection> getShorthandColumnsFromJoinTableSegment(final TableSegment table, final ProjectionSegment projectionSegment) {
if (!(table instanceof JoinTableSegment)) {
return Collections.emptyList();
}
Collection<Projection> projections = new LinkedList<>();
createProjection(((JoinTableSegment) table).getLeft(), projectionSegment).ifPresent(projections::add);
createProjection(((JoinTableSegment) table).getRight(), projectionSegment).ifPresent(projections::add);
- return getColumnProjections(projections);
+ return getResultSetProjections(projections);
}
- private Collection<ColumnProjection> getColumnProjections(final Collection<Projection> projections) {
- Collection<ColumnProjection> result = new LinkedList<>();
+ private Collection<Projection> getResultSetProjections(final Collection<Projection> projections) {
+ Collection<Projection> result = new LinkedList<>();
for (Projection each : projections) {
if (each instanceof ColumnProjection) {
- result.add((ColumnProjection) each);
- }
- if (each instanceof ShorthandProjection) {
- result.addAll(((ShorthandProjection) each).getActualColumns().values());
+ result.add(each);
+ } else if (each instanceof ExpressionProjection) {
+ result.add(each);
+ } else if (each instanceof ShorthandProjection) {
+ result.addAll(((ShorthandProjection) each).getResultSetColumns().values());
}
}
return result;
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
index 4be24043b54..44f70ca4a13 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
@@ -37,12 +37,12 @@ import java.util.Optional;
public final class ShorthandProjection implements Projection {
private final String owner;
-
- private final Map<String, ColumnProjection> actualColumns = new LinkedHashMap<>();
-
- public ShorthandProjection(final String owner, final Collection<ColumnProjection> columnProjections) {
+
+ private final Map<String, Projection> resultSetColumns = new LinkedHashMap<>();
+
+ public ShorthandProjection(final String owner, final Collection<Projection> projections) {
this.owner = owner;
- columnProjections.forEach(each -> actualColumns.put(each.getExpression().toLowerCase(), each));
+ projections.forEach(each -> resultSetColumns.put(each.getExpression().toLowerCase(), each));
}
@Override
@@ -68,4 +68,19 @@ public final class ShorthandProjection implements Projection {
public Optional<String> getOwner() {
return Optional.ofNullable(owner);
}
+
+ /**
+ * get actualColumns, exclude ExpressionProjection.
+ *
+ * @return actualColumns
+ */
+ public Map<String, ColumnProjection> getActualColumns() {
+ Map<String, ColumnProjection> actualColumns = new LinkedHashMap<>();
+ for (Map.Entry<String, Projection> entry : resultSetColumns.entrySet()) {
+ if (entry.getValue() instanceof ColumnProjection) {
+ actualColumns.put(entry.getKey(), (ColumnProjection) entry.getValue());
+ }
+ }
+ return actualColumns;
+ }
}
diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
index e63bacd51f4..8493ce69abe 100644
--- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
+++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
@@ -32,18 +32,22 @@ import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
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.AggregationDistinctProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
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.TableNameSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleSelectStatement;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -201,4 +205,32 @@ public final class ProjectionEngineTest {
ShorthandProjectionSegment shorthandProjectionSegment = new ShorthandProjectionSegment(0, 0);
new ProjectionEngine(DefaultDatabase.LOGIC_NAME, Collections.singletonMap(DefaultDatabase.LOGIC_NAME, schema), databaseType).createProjection(tableSegment, shorthandProjectionSegment);
}
+
+ @Test
+ public void assertResultSetColumnsWithColumnProjectionAndExpressionProjectionOfShorthandProjection() {
+ ProjectionsSegment subQuerySegment = new ProjectionsSegment(0, 0);
+ ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("name"));
+ subQuerySegment.getProjections().add(new ColumnProjectionSegment(columnSegment));
+ ExpressionProjectionSegment expressionProjectionSegment = new ExpressionProjectionSegment(0, 0, "nvl(leave_date, '20991231')");
+ expressionProjectionSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("leave_date")));
+ subQuerySegment.getProjections().add(expressionProjectionSegment);
+ OracleSelectStatement subSelectStatement = new OracleSelectStatement();
+ subSelectStatement.setProjections(subQuerySegment);
+ subSelectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("staff_info"))));
+ ShorthandProjectionSegment shorthandProjectionSegment = new ShorthandProjectionSegment(0, 0);
+ SubqueryTableSegment subqueryTableSegment = new SubqueryTableSegment(new SubquerySegment(0, 0, subSelectStatement));
+ Optional<Projection> actual = new ProjectionEngine(DefaultDatabase.LOGIC_NAME, Collections.singletonMap(DefaultDatabase.LOGIC_NAME, schema), databaseType)
+ .createProjection(subqueryTableSegment, shorthandProjectionSegment);
+ assertTrue(actual.isPresent());
+ assertThat(actual.get(), instanceOf(ShorthandProjection.class));
+ assertThat(((ShorthandProjection) actual.get()).getActualColumns().size(), is(1));
+ assertThat(((ShorthandProjection) actual.get()).getResultSetColumns().size(), is(2));
+ Map<String, ColumnProjection> actualColumns = new LinkedHashMap<>();
+ actualColumns.put("name", new ColumnProjection(null, "name", null));
+ assertThat(((ShorthandProjection) actual.get()).getActualColumns(), is(actualColumns));
+ Map<String, Projection> resultSetColumns = new LinkedHashMap<>();
+ resultSetColumns.put("name", new ColumnProjection(null, "name", null));
+ resultSetColumns.put("nvl(leave_date, '20991231')", new ExpressionProjection("nvl(leave_date, '20991231')", "leave_date"));
+ assertThat(((ShorthandProjection) actual.get()).getResultSetColumns(), is(resultSetColumns));
+ }
}