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 a8f82f16f31 Add sql error code for encrypt feature and update encrypt
appendix doc (#27990)
a8f82f16f31 is described below
commit a8f82f16f3126dda3a536ca43a7521e78b4264bb
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Tue Aug 8 16:49:41 2023 +0800
Add sql error code for encrypt feature and update encrypt appendix doc
(#27990)
* Add sql error code for encrypt feature and update encrypt appendix doc
* add unit test for EncryptProjectionTokenGenerator
---
.../content/features/encrypt/appendix.cn.md | 3 +-
.../content/features/encrypt/appendix.en.md | 1 +
.../user-manual/error-code/sql-error-code.cn.md | 2 ++
.../user-manual/error-code/sql-error-code.en.md | 2 ++
.../generator/EncryptProjectionTokenGenerator.java | 4 +++
.../EncryptProjectionTokenGeneratorTest.java | 14 +++++++++
.../expression/impl/ColumnSegmentBinder.java | 6 ++--
.../infra/exception/AmbiguousColumnException.java | 33 ++++++++++++++++++++++
.../infra/exception/UnknownColumnException.java | 33 ++++++++++++++++++++++
9 files changed, 95 insertions(+), 3 deletions(-)
diff --git a/docs/document/content/features/encrypt/appendix.cn.md
b/docs/document/content/features/encrypt/appendix.cn.md
index e312be0cea6..88cef38bbd1 100644
--- a/docs/document/content/features/encrypt/appendix.cn.md
+++ b/docs/document/content/features/encrypt/appendix.cn.md
@@ -7,7 +7,8 @@ weight = 3
- 加密字段无法支持查询不区分大小写功能;
- 加密字段无法支持比较操作,如:大于、小于、ORDER BY、BETWEEN 等;
-- 加密字段无法支持计算操作,如:AVG、SUM 以及计算表达式。
+- 加密字段无法支持计算操作,如:AVG、SUM 以及计算表达式;
+- 不支持子查询中包含加密字段,并且外层投影使用星号的 SQL。
其他:
diff --git a/docs/document/content/features/encrypt/appendix.en.md
b/docs/document/content/features/encrypt/appendix.en.md
index 072765e59b9..7a930811872 100644
--- a/docs/document/content/features/encrypt/appendix.en.md
+++ b/docs/document/content/features/encrypt/appendix.en.md
@@ -8,6 +8,7 @@ Unsupported SQL:
- The case-insensitive queries are not supported by encrypted fields.
- Comparison operations are not supported for encrypted fields, such as
GREATER THAN, LESS THAN, ORDER BY, BETWEEN.
- Calculation operations are not supported for encrypted fields, such as AVG,
SUM, and computation expressions.
+- SQL that contains encrypt column in subquery and uses asterisks for outer
projection is not supported.
Other:
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
index 0a05dda66a5..6d05733aa05 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
@@ -19,6 +19,8 @@ SQL 错误码以标准的 SQL State,Vendor Code 和详细错误信息提供,
| 42000 | 10002 | Can not support 3-tier structure for actual data
node \`%s\` with JDBC \`%s\`. |
| HY004 | 10003 | Invalid format for actual data node \`%s\`.
|
| 42000 | 10004 | Unsupported SQL node conversion for SQL statement
\`%s\`. |
+| HY000 | 10005 | Column '%s' in field list is ambiguous.
|
+| 42S02 | 10006 | Unknown column '%s' in 'field list'.
|
| 42000 | 10010 | Rule does not exist.
|
| 42S02 | 10020 | Schema \`%s\` does not exist.
|
| 42S02 | 10021 | Single table \`%s\` does not exist.
|
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.en.md
b/docs/document/content/user-manual/error-code/sql-error-code.en.md
index 9e893b194a9..705b09c015b 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.en.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.en.md
@@ -19,6 +19,8 @@ SQL error codes provide by standard `SQL State`, `Vendor
Code` and `Reason`, whi
| 42000 | 10002 | Can not support 3-tier structure for actual data
node \`%s\` with JDBC \`%s\`. |
| HY004 | 10003 | Invalid format for actual data node \`%s\`.
|
| 42000 | 10004 | Unsupported SQL node conversion for SQL statement
\`%s\`. |
+| HY000 | 10005 | Column '%s' in field list is ambiguous.
|
+| 42S02 | 10006 | Unknown column '%s' in 'field list'.
|
| 42000 | 10010 | Rule does not exist.
|
| 42S02 | 10020 | Schema \`%s\` does not exist.
|
| 42S02 | 10021 | Single table \`%s\` does not exist.
|
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
index e16edc25cbe..7ec6183d2e3 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
@@ -35,6 +35,8 @@ import
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatem
import
org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
+import
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.infra.exception.core.external.sql.type.generic.UnsupportedSQLOperationException;
import
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import
org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
@@ -96,6 +98,8 @@ public final class EncryptProjectionTokenGenerator implements
CollectionSQLToken
sqlTokens.add(generateSQLToken(encryptTable.get().getEncryptColumn(originalColumnName),
columnSegment, columnProjection, subqueryType));
}
}
+ ShardingSpherePreconditions.checkState(!(each instanceof
ShorthandProjectionSegment) ||
!containsTableSubquery(selectStatementContext.getSqlStatement().getFrom()),
+ () -> new UnsupportedSQLOperationException("Can not
support encrypt shorthand expand with subquery statement"));
if (each instanceof ShorthandProjectionSegment) {
ShorthandProjectionSegment shorthandSegment =
(ShorthandProjectionSegment) each;
Collection<Projection> actualColumns =
getShorthandProjection(shorthandSegment,
selectStatementContext.getProjectionsContext()).getActualColumns();
diff --git
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGeneratorTest.java
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGeneratorTest.java
index fe4e21962d3..d30545ceab7 100644
---
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGeneratorTest.java
+++
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGeneratorTest.java
@@ -24,15 +24,20 @@ import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.
import
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
import
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import
org.apache.shardingsphere.infra.exception.core.external.sql.type.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+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.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.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.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -44,6 +49,7 @@ import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -133,4 +139,12 @@ class EncryptProjectionTokenGeneratorTest {
Collection<SQLToken> actual =
generator.generateSQLTokens(sqlStatementContext);
assertThat(actual.size(), is(1));
}
+
+ @Test
+ void assertGenerateSQLTokensWhenShorthandExpandContainsSubqueryTable() {
+ SelectStatementContext sqlStatementContext =
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
+ when(sqlStatementContext.getSqlStatement().getFrom()).thenReturn(new
SubqueryTableSegment(new SubquerySegment(0, 0, mock(SelectStatement.class))));
+
when(sqlStatementContext.getSqlStatement().getProjections().getProjections()).thenReturn(Collections.singleton(new
ShorthandProjectionSegment(0, 0)));
+ assertThrows(UnsupportedSQLOperationException.class, () ->
generator.generateSQLTokens(sqlStatementContext));
+ }
}
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
index bead7512381..5f75ec882c7 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/expression/impl/ColumnSegmentBinder.java
@@ -20,6 +20,8 @@ package
org.apache.shardingsphere.infra.binder.segment.expression.impl;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinderContext;
+import org.apache.shardingsphere.infra.exception.AmbiguousColumnException;
+import org.apache.shardingsphere.infra.exception.UnknownColumnException;
import
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
@@ -67,11 +69,11 @@ public final class ColumnSegmentBinder {
for (TableSegmentBinderContext each : tableBinderContexts) {
ProjectionSegment projectionSegment =
each.getProjectionSegmentByColumnLabel(columnName);
if (projectionSegment instanceof ColumnProjectionSegment) {
- ShardingSpherePreconditions.checkState(null == result, () ->
new IllegalStateException(String.format("Column '%s' in field list is
ambiguous.", columnName)));
+ ShardingSpherePreconditions.checkState(null == result, () ->
new AmbiguousColumnException(columnName));
result = ((ColumnProjectionSegment)
projectionSegment).getColumn();
}
}
- ShardingSpherePreconditions.checkNotNull(result, () -> new
IllegalStateException(String.format("Unknown column '%s' in 'field list'.",
columnName)));
+ ShardingSpherePreconditions.checkNotNull(result, () -> new
UnknownColumnException(columnName));
return result;
}
}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/AmbiguousColumnException.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/AmbiguousColumnException.java
new file mode 100644
index 00000000000..fa874525cb9
--- /dev/null
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/AmbiguousColumnException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.exception;
+
+import
org.apache.shardingsphere.infra.exception.core.external.sql.sqlstate.XOpenSQLState;
+import
org.apache.shardingsphere.infra.exception.core.external.sql.type.kernel.category.MetaDataSQLException;
+
+/**
+ * Ambiguous column exception.
+ */
+public final class AmbiguousColumnException extends MetaDataSQLException {
+
+ private static final long serialVersionUID = -9002743483594729164L;
+
+ public AmbiguousColumnException(final String columnName) {
+ super(XOpenSQLState.GENERAL_ERROR, 5, "Column '%s' in field list is
ambiguous.", columnName);
+ }
+}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/UnknownColumnException.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/UnknownColumnException.java
new file mode 100644
index 00000000000..262a21067fe
--- /dev/null
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/UnknownColumnException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.exception;
+
+import
org.apache.shardingsphere.infra.exception.core.external.sql.sqlstate.XOpenSQLState;
+import
org.apache.shardingsphere.infra.exception.core.external.sql.type.kernel.category.MetaDataSQLException;
+
+/**
+ * Unknown column exception.
+ */
+public final class UnknownColumnException extends MetaDataSQLException {
+
+ private static final long serialVersionUID = -1305402273592303335L;
+
+ public UnknownColumnException(final String columnName) {
+ super(XOpenSQLState.NOT_FOUND, 6, "Unknown column '%s' in 'field
list'.", columnName);
+ }
+}