Skip to content

Commit 87a2bd6

Browse files
authored
Add quotes to encrypt rewrite derived columns (#34950)
* Add quotes to encrypt rewrite derived columns * Fix rewrite IT * Fix rewrite IT * Fix rewrite IT * Fix rewrite IT * Fix rewrite IT * Fix rewrite IT
1 parent 2b8be84 commit 87a2bd6

25 files changed

+261
-176
lines changed

RELEASE-NOTES.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
1. SQL Parser: Support MySQL INSERT with GEOMCOLLECTION function parse - [#34654](https://github.com/apache/shardingsphere/pull/34654)
2626
1. SQL Parser: Support MySQL DELETE with statement parse - [#34817](https://github.com/apache/shardingsphere/pull/34817)
2727
1. Encrypt: Use EncryptDerivedColumnSuffix to enhance encrypt table subquery rewrite logic - [#34829](https://github.com/apache/shardingsphere/pull/34829)
28+
1. Encrypt: Add quotes to encrypt rewrite derived columns - [#34950](https://github.com/apache/shardingsphere/pull/34950)
2829

2930
### Bug Fixes
3031

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/assignment/EncryptAssignmentTokenGenerator.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
2727
import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
2828
import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
29+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
2930
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
3031
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
3132
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
@@ -64,37 +65,40 @@ public Collection<SQLToken> generateSQLTokens(final TablesContext tablesContext,
6465
EncryptTable encryptTable = rule.getEncryptTable(tableName);
6566
Collection<SQLToken> result = new LinkedList<>();
6667
String schemaName = tablesContext.getSchemaName().orElseGet(() -> new DatabaseTypeRegistry(databaseType).getDefaultSchemaName(databaseName));
68+
QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getQuoteCharacter();
6769
for (ColumnAssignmentSegment each : setAssignmentSegment.getAssignments()) {
6870
String columnName = each.getColumns().get(0).getIdentifier().getValue();
6971
if (encryptTable.isEncryptColumn(columnName)) {
70-
generateSQLToken(schemaName, encryptTable.getTable(), encryptTable.getEncryptColumn(columnName), each).ifPresent(result::add);
72+
generateSQLToken(schemaName, encryptTable.getTable(), encryptTable.getEncryptColumn(columnName), each, quoteCharacter).ifPresent(result::add);
7173
}
7274
}
7375
return result;
7476
}
7577

76-
private Optional<EncryptAssignmentToken> generateSQLToken(final String schemaName, final String tableName, final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment) {
78+
private Optional<EncryptAssignmentToken> generateSQLToken(final String schemaName, final String tableName, final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment,
79+
final QuoteCharacter quoteCharacter) {
7780
if (segment.getValue() instanceof ParameterMarkerExpressionSegment) {
78-
return Optional.of(generateParameterSQLToken(encryptColumn, segment));
81+
return Optional.of(generateParameterSQLToken(encryptColumn, segment, quoteCharacter));
7982
}
8083
if (segment.getValue() instanceof LiteralExpressionSegment) {
81-
return Optional.of(generateLiteralSQLToken(schemaName, tableName, encryptColumn, segment));
84+
return Optional.of(generateLiteralSQLToken(schemaName, tableName, encryptColumn, segment, quoteCharacter));
8285
}
8386
return Optional.empty();
8487
}
8588

86-
private EncryptAssignmentToken generateParameterSQLToken(final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment) {
89+
private EncryptAssignmentToken generateParameterSQLToken(final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment, final QuoteCharacter quoteCharacter) {
8790
EncryptParameterAssignmentToken result =
88-
new EncryptParameterAssignmentToken(segment.getColumns().get(0).getStartIndex(), segment.getStopIndex(), segment.getColumns().get(0).getIdentifier().getQuoteCharacter());
91+
new EncryptParameterAssignmentToken(segment.getColumns().get(0).getStartIndex(), segment.getStopIndex(), quoteCharacter);
8992
result.addColumnName(encryptColumn.getCipher().getName());
9093
encryptColumn.getAssistedQuery().ifPresent(optional -> result.addColumnName(optional.getName()));
9194
encryptColumn.getLikeQuery().ifPresent(optional -> result.addColumnName(optional.getName()));
9295
return result;
9396
}
9497

95-
private EncryptAssignmentToken generateLiteralSQLToken(final String schemaName, final String tableName, final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment) {
98+
private EncryptAssignmentToken generateLiteralSQLToken(final String schemaName, final String tableName, final EncryptColumn encryptColumn, final ColumnAssignmentSegment segment,
99+
final QuoteCharacter quoteCharacter) {
96100
EncryptLiteralAssignmentToken result =
97-
new EncryptLiteralAssignmentToken(segment.getColumns().get(0).getStartIndex(), segment.getStopIndex(), segment.getColumns().get(0).getIdentifier().getQuoteCharacter());
101+
new EncryptLiteralAssignmentToken(segment.getColumns().get(0).getStartIndex(), segment.getStopIndex(), quoteCharacter);
98102
addCipherAssignment(schemaName, tableName, encryptColumn, segment, result);
99103
addAssistedQueryAssignment(schemaName, tableName, encryptColumn, segment, result);
100104
addLikeAssignment(schemaName, tableName, encryptColumn, segment, result);

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertCipherNameTokenGenerator.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
3030
import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
3131
import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
32+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
33+
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
3234
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
3335
import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
3436
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.CollectionSQLTokenGenerator;
@@ -66,6 +68,7 @@ public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext)
6668
public Collection<SQLToken> generateSQLTokens(final InsertStatementContext insertStatementContext) {
6769
Optional<InsertColumnsSegment> insertColumnsSegment = insertStatementContext.getSqlStatement().getInsertColumns();
6870
Preconditions.checkState(insertColumnsSegment.isPresent());
71+
QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(insertStatementContext.getDatabaseType()).getDialectDatabaseMetaData().getQuoteCharacter();
6972
Collection<ColumnSegment> insertColumns = insertColumnsSegment.get().getColumns();
7073
if (null != insertStatementContext.getInsertSelectContext()) {
7174
checkInsertSelectEncryptor(insertStatementContext.getInsertSelectContext().getSelectStatementContext(), insertColumns);
@@ -78,7 +81,7 @@ public Collection<SQLToken> generateSQLTokens(final InsertStatementContext inser
7881
for (ColumnSegment each : insertColumns) {
7982
String columnName = each.getIdentifier().getValue();
8083
if (encryptTable.get().isEncryptColumn(columnName)) {
81-
IdentifierValue name = new IdentifierValue(encryptTable.get().getEncryptColumn(columnName).getCipher().getName(), each.getIdentifier().getQuoteCharacter());
84+
IdentifierValue name = new IdentifierValue(encryptTable.get().getEncryptColumn(columnName).getCipher().getName(), quoteCharacter);
8285
Collection<Projection> projections = Collections.singleton(new ColumnProjection(null, name, null, insertStatementContext.getDatabaseType()));
8386
result.add(new SubstitutableColumnNameToken(each.getStartIndex(), each.getStopIndex(), projections, insertStatementContext.getDatabaseType()));
8487
}

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertDerivedColumnsTokenGenerator.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
2626
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
2727
import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
28+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
29+
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
2830
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.CollectionSQLTokenGenerator;
2931
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
3032
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.InsertColumnsToken;
@@ -57,11 +59,12 @@ public Collection<SQLToken> generateSQLTokens(final InsertStatementContext inser
5759
if (!encryptTable.isPresent()) {
5860
return Collections.emptyList();
5961
}
62+
QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(insertStatementContext.getDatabaseType()).getDialectDatabaseMetaData().getQuoteCharacter();
6063
Collection<SQLToken> result = new LinkedList<>();
6164
for (ColumnSegment each : insertStatementContext.getSqlStatement().getColumns()) {
6265
List<String> derivedColumnNames = getDerivedColumnNames(encryptTable.get(), each);
6366
if (!derivedColumnNames.isEmpty()) {
64-
result.add(new InsertColumnsToken(each.getStopIndex() + 1, derivedColumnNames, each.getIdentifier().getQuoteCharacter()));
67+
result.add(new InsertColumnsToken(each.getStopIndex() + 1, derivedColumnNames, quoteCharacter));
6568
}
6669
}
6770
return result;

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertOnUpdateTokenGenerator.java

+14-13
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
3434
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
3535
import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
36+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
3637
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
3738
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
3839
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.CollectionSQLTokenGenerator;
@@ -79,6 +80,7 @@ public Collection<SQLToken> generateSQLTokens(final InsertStatementContext inser
7980
.orElseGet(() -> new DatabaseTypeRegistry(insertStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName()));
8081
String tableName = insertStatement.getTable().map(optional -> optional.getTableName().getIdentifier().getValue()).orElse("");
8182
EncryptTable encryptTable = rule.getEncryptTable(tableName);
83+
QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(insertStatementContext.getDatabaseType()).getDialectDatabaseMetaData().getQuoteCharacter();
8284
Collection<SQLToken> result = new LinkedList<>();
8385
for (ColumnAssignmentSegment each : onDuplicateKeyColumnsSegments) {
8486
boolean leftColumnIsEncrypt = encryptTable.isEncryptColumn(each.getColumns().get(0).getIdentifier().getValue());
@@ -94,28 +96,27 @@ public Collection<SQLToken> generateSQLTokens(final InsertStatementContext inser
9496
continue;
9597
}
9698
EncryptColumn encryptColumn = encryptTable.getEncryptColumn(each.getColumns().get(0).getIdentifier().getValue());
97-
generateSQLToken(schemaName, encryptTable, encryptColumn, each).ifPresent(result::add);
99+
generateSQLToken(schemaName, encryptTable, encryptColumn, each, quoteCharacter).ifPresent(result::add);
98100
}
99101
return result;
100102
}
101103

102104
private Optional<EncryptAssignmentToken> generateSQLToken(final String schemaName, final EncryptTable encryptTable,
103-
final EncryptColumn encryptColumn, final ColumnAssignmentSegment assignmentSegment) {
105+
final EncryptColumn encryptColumn, final ColumnAssignmentSegment assignmentSegment, final QuoteCharacter quoteCharacter) {
104106
if (assignmentSegment.getValue() instanceof ParameterMarkerExpressionSegment) {
105-
return Optional.of(generateParameterSQLToken(encryptTable, assignmentSegment));
107+
return Optional.of(generateParameterSQLToken(encryptTable, assignmentSegment, quoteCharacter));
106108
}
107109
if (assignmentSegment.getValue() instanceof FunctionSegment && "VALUES".equalsIgnoreCase(((FunctionSegment) assignmentSegment.getValue()).getFunctionName())) {
108-
return Optional.of(generateValuesSQLToken(encryptTable, assignmentSegment, (FunctionSegment) assignmentSegment.getValue()));
110+
return Optional.of(generateValuesSQLToken(encryptTable, assignmentSegment, (FunctionSegment) assignmentSegment.getValue(), quoteCharacter));
109111
}
110112
if (assignmentSegment.getValue() instanceof LiteralExpressionSegment) {
111-
return Optional.of(generateLiteralSQLToken(schemaName, encryptTable.getTable(), encryptColumn, assignmentSegment));
113+
return Optional.of(generateLiteralSQLToken(schemaName, encryptTable.getTable(), encryptColumn, assignmentSegment, quoteCharacter));
112114
}
113115
return Optional.empty();
114116
}
115117

116-
private EncryptAssignmentToken generateParameterSQLToken(final EncryptTable encryptTable, final ColumnAssignmentSegment assignmentSegment) {
117-
EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex(),
118-
assignmentSegment.getColumns().get(0).getIdentifier().getQuoteCharacter());
118+
private EncryptAssignmentToken generateParameterSQLToken(final EncryptTable encryptTable, final ColumnAssignmentSegment assignmentSegment, final QuoteCharacter quoteCharacter) {
119+
EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex(), quoteCharacter);
119120
String columnName = assignmentSegment.getColumns().get(0).getIdentifier().getValue();
120121
EncryptColumn encryptColumn = encryptTable.getEncryptColumn(columnName);
121122
result.addColumnName(encryptColumn.getCipher().getName());
@@ -125,23 +126,23 @@ private EncryptAssignmentToken generateParameterSQLToken(final EncryptTable encr
125126
}
126127

127128
private EncryptAssignmentToken generateLiteralSQLToken(final String schemaName, final String tableName,
128-
final EncryptColumn encryptColumn, final ColumnAssignmentSegment assignmentSegment) {
129-
EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex(),
130-
assignmentSegment.getColumns().get(0).getIdentifier().getQuoteCharacter());
129+
final EncryptColumn encryptColumn, final ColumnAssignmentSegment assignmentSegment, final QuoteCharacter quoteCharacter) {
130+
EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex(), quoteCharacter);
131131
addCipherAssignment(schemaName, tableName, encryptColumn, assignmentSegment, result);
132132
addAssistedQueryAssignment(schemaName, tableName, encryptColumn, assignmentSegment, result);
133133
addLikeAssignment(schemaName, tableName, encryptColumn, assignmentSegment, result);
134134
return result;
135135
}
136136

137-
private EncryptAssignmentToken generateValuesSQLToken(final EncryptTable encryptTable, final ColumnAssignmentSegment assignmentSegment, final FunctionSegment functionSegment) {
137+
private EncryptAssignmentToken generateValuesSQLToken(final EncryptTable encryptTable, final ColumnAssignmentSegment assignmentSegment, final FunctionSegment functionSegment,
138+
final QuoteCharacter quoteCharacter) {
138139
ColumnSegment columnSegment = assignmentSegment.getColumns().get(0);
139140
String column = columnSegment.getIdentifier().getValue();
140141
Optional<ExpressionSegment> valueColumnSegment = functionSegment.getParameters().stream().findFirst();
141142
Preconditions.checkState(valueColumnSegment.isPresent());
142143
String valueColumn = ((ColumnSegment) valueColumnSegment.get()).getIdentifier().getValue();
143144
EncryptFunctionAssignmentToken result =
144-
new EncryptFunctionAssignmentToken(columnSegment.getStartIndex(), assignmentSegment.getStopIndex(), assignmentSegment.getColumns().get(0).getIdentifier().getQuoteCharacter());
145+
new EncryptFunctionAssignmentToken(columnSegment.getStartIndex(), assignmentSegment.getStopIndex(), quoteCharacter);
145146
boolean isEncryptColumn = encryptTable.isEncryptColumn(column);
146147
boolean isEncryptValueColumn = encryptTable.isEncryptColumn(valueColumn);
147148
EncryptColumn encryptColumn = encryptTable.getEncryptColumn(column);

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
3434
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
3535
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
36+
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
3637
import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
3738
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
3839
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.SubstitutableColumnNameToken;
@@ -170,12 +171,18 @@ private Collection<Projection> generateProjections(final EncryptColumn encryptCo
170171

171172
private ColumnProjection generateProjection(final EncryptColumn encryptColumn, final ColumnProjection columnProjection) {
172173
String encryptColumnName = getEncryptColumnName(columnProjection, encryptColumn);
173-
IdentifierValue cipherColumnName = new IdentifierValue(encryptColumnName, columnProjection.getName().getQuoteCharacter());
174+
QuoteCharacter quoteCharacter = getQuoteCharacter(columnProjection);
175+
IdentifierValue cipherColumnName = new IdentifierValue(encryptColumnName, quoteCharacter);
174176
IdentifierValue cipherColumnAlias = columnProjection.getAlias().orElse(columnProjection.getName());
175177
return new ColumnProjection(columnProjection.getOwner().orElse(null), cipherColumnName, cipherColumnAlias,
176178
databaseType, columnProjection.getLeftParentheses().orElse(null), columnProjection.getRightParentheses().orElse(null));
177179
}
178180

181+
private QuoteCharacter getQuoteCharacter(final ColumnProjection columnProjection) {
182+
QuoteCharacter databaseQuoteCharacter = new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getQuoteCharacter();
183+
return TableSourceType.PHYSICAL_TABLE == columnProjection.getColumnBoundInfo().getTableSourceType() ? databaseQuoteCharacter : columnProjection.getName().getQuoteCharacter();
184+
}
185+
179186
private String getEncryptColumnName(final ColumnProjection columnProjection, final EncryptColumn encryptColumn) {
180187
IdentifierValue columnName = columnProjection.getName();
181188
return TableSourceType.TEMPORARY_TABLE == columnProjection.getColumnBoundInfo().getTableSourceType()

0 commit comments

Comments
 (0)