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 <[email protected]>
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));
+ }
}