Skip to content

Commit 88b9929

Browse files
committed
Add support for case sensitive identifiers
1 parent 5298075 commit 88b9929

File tree

30 files changed

+96
-105
lines changed

30 files changed

+96
-105
lines changed

client/trino-jdbc/src/main/java/io/trino/jdbc/AbstractTrinoResultSet.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@
8484
import static java.math.RoundingMode.HALF_UP;
8585
import static java.util.Collections.unmodifiableList;
8686
import static java.util.Collections.unmodifiableMap;
87-
import static java.util.Locale.ENGLISH;
8887
import static java.util.Objects.requireNonNull;
8988
import static org.joda.time.DateTimeConstants.SECONDS_PER_DAY;
9089

@@ -1916,7 +1915,7 @@ private int columnIndex(String label)
19161915
if (label == null) {
19171916
throw new SQLException("Column label is null");
19181917
}
1919-
Integer index = fieldMap.get(label.toLowerCase(ENGLISH));
1918+
Integer index = fieldMap.get(label);
19201919
if (index == null) {
19211920
throw new SQLException("Invalid column label: " + label);
19221921
}
@@ -1958,7 +1957,7 @@ private static Map<String, Integer> getFieldMap(List<Column> columns)
19581957
{
19591958
Map<String, Integer> map = Maps.newHashMapWithExpectedSize(columns.size());
19601959
for (int i = 0; i < columns.size(); i++) {
1961-
String name = columns.get(i).getName().toLowerCase(ENGLISH);
1960+
String name = columns.get(i).getName();
19621961
if (!map.containsKey(name)) {
19631962
map.put(name, i + 1);
19641963
}

core/trino-main/src/main/java/io/trino/execution/CreateTableTask.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import java.util.HashMap;
5252
import java.util.LinkedHashMap;
5353
import java.util.List;
54-
import java.util.Locale;
5554
import java.util.Map;
5655
import java.util.Map.Entry;
5756
import java.util.Optional;
@@ -186,7 +185,7 @@ ListenableFuture<Void> internalExecute(CreateTable statement, Session session, L
186185
if (type.equals(UNKNOWN)) {
187186
throw semanticException(COLUMN_TYPE_UNKNOWN, element, "Unknown type '%s' for column '%s'", column.getType(), name);
188187
}
189-
if (columns.containsKey(name.getValue().toLowerCase(ENGLISH))) {
188+
if (columns.containsKey(name.getValue())) {
190189
throw semanticException(DUPLICATE_COLUMN_NAME, column, "Column name '%s' specified more than once", name);
191190
}
192191
if (column.getDefaultValue().isPresent() && !supportsDefaultColumnValue) {
@@ -207,8 +206,8 @@ ListenableFuture<Void> internalExecute(CreateTable statement, Session session, L
207206

208207
Type supportedType = getSupportedType(session, catalogHandle, properties, type);
209208
column.getDefaultValue().ifPresent(value -> analyzeDefaultColumnValue(session, plannerContext, accessControl, parameterLookup, warningCollector, supportedType, value));
210-
columns.put(name.getValue().toLowerCase(ENGLISH), ColumnMetadata.builder()
211-
.setName(name.getValue().toLowerCase(ENGLISH))
209+
columns.put(name.getValue(), ColumnMetadata.builder()
210+
.setName(name.getValue())
212211
.setType(supportedType)
213212
.setDefaultValue(column.getDefaultValue().map(Expression::toString))
214213
.setNullable(column.isNullable())
@@ -276,11 +275,11 @@ else if (element instanceof LikeClause likeClause) {
276275
likeTableMetadata.columns().stream()
277276
.filter(column -> !column.isHidden())
278277
.forEach(column -> {
279-
if (columns.containsKey(column.getName().toLowerCase(Locale.ENGLISH))) {
278+
if (columns.containsKey(column.getName())) {
280279
throw semanticException(DUPLICATE_COLUMN_NAME, element, "Column name '%s' specified more than once", column.getName());
281280
}
282281
columns.put(
283-
column.getName().toLowerCase(Locale.ENGLISH),
282+
column.getName(),
284283
ColumnMetadata.builderFrom(column)
285284
.setType(getSupportedType(session, catalogHandle, properties, column.getType()))
286285
.build());

core/trino-main/src/main/java/io/trino/execution/RenameColumnTask.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
4545
import static io.trino.spi.StandardErrorCode.TABLE_NOT_FOUND;
4646
import static io.trino.sql.analyzer.SemanticExceptions.semanticException;
47-
import static java.util.Locale.ENGLISH;
4847
import static java.util.Objects.requireNonNull;
4948

5049
public class RenameColumnTask
@@ -84,8 +83,8 @@ public ListenableFuture<Void> execute(
8483
}
8584
TableHandle tableHandle = redirectionAwareTableHandle.tableHandle().get();
8685

87-
String source = statement.getSource().getParts().get(0).toLowerCase(ENGLISH);
88-
String target = statement.getTarget().getValue().toLowerCase(ENGLISH);
86+
String source = statement.getSource().getParts().get(0);
87+
String target = statement.getTarget().getValue();
8988

9089
QualifiedObjectName qualifiedTableName = redirectionAwareTableHandle.redirectedTableName().orElse(originalTableName);
9190

core/trino-main/src/main/java/io/trino/execution/SetColumnTypeTask.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
import static io.trino.sql.analyzer.TypeSignatureTranslator.toTypeSignature;
5454
import static io.trino.type.UnknownType.UNKNOWN;
5555
import static java.lang.String.format;
56-
import static java.util.Locale.ENGLISH;
5756
import static java.util.Objects.requireNonNull;
5857

5958
public class SetColumnTypeTask
@@ -105,7 +104,7 @@ else if (metadata.isView(session, qualifiedObjectName)) {
105104

106105
TableHandle tableHandle = redirectionAwareTableHandle.tableHandle().get();
107106
Map<String, ColumnHandle> columnHandles = metadata.getColumnHandles(session, tableHandle);
108-
String columnName = statement.getColumnName().getParts().get(0).toLowerCase(ENGLISH);
107+
String columnName = statement.getColumnName().getParts().get(0);
109108
ColumnHandle column = columnHandles.get(columnName);
110109
if (column == null) {
111110
throw semanticException(COLUMN_NOT_FOUND, statement, "Column '%s' does not exist", statement.getColumnName());

core/trino-main/src/main/java/io/trino/execution/UseTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public ListenableFuture<Void> execute(
7979
denyCatalogAccess(catalog);
8080
}
8181

82-
String schema = statement.getSchema().getValue().toLowerCase(ENGLISH);
82+
String schema = statement.getSchema().getValue();
8383

8484
CatalogSchemaName name = new CatalogSchemaName(catalog, schema);
8585
if (!metadata.schemaExists(session, name)) {

core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@
131131
import java.util.LinkedHashMap;
132132
import java.util.LinkedHashSet;
133133
import java.util.List;
134-
import java.util.Locale;
135134
import java.util.Map;
136135
import java.util.Map.Entry;
137136
import java.util.Optional;
@@ -180,7 +179,6 @@
180179
import static io.trino.spi.connector.MaterializedViewFreshness.Freshness.STALE;
181180
import static java.lang.String.format;
182181
import static java.util.Collections.singletonList;
183-
import static java.util.Locale.ENGLISH;
184182
import static java.util.Objects.requireNonNull;
185183

186184
public final class MetadataManager
@@ -267,7 +265,6 @@ public List<String> listSchemaNames(Session session, String catalogName)
267265
for (CatalogHandle catalogHandle : catalogMetadata.listCatalogHandles()) {
268266
ConnectorMetadata metadata = catalogMetadata.getMetadataFor(session, catalogHandle);
269267
metadata.listSchemaNames(connectorSession).stream()
270-
.map(schema -> schema.toLowerCase(Locale.ENGLISH))
271268
.filter(schema -> !isExternalInformationSchema(catalogHandle, schema))
272269
.forEach(schemaNames::add);
273270
}
@@ -519,7 +516,7 @@ public Map<String, ColumnHandle> getColumnHandles(Session session, TableHandle t
519516

520517
ImmutableMap.Builder<String, ColumnHandle> map = ImmutableMap.builder();
521518
for (Entry<String, ColumnHandle> mapEntry : handles.entrySet()) {
522-
map.put(mapEntry.getKey().toLowerCase(ENGLISH), mapEntry.getValue());
519+
map.put(mapEntry.getKey(), mapEntry.getValue());
523520
}
524521
return map.buildOrThrow();
525522
}
@@ -946,7 +943,7 @@ public void renameColumn(Session session, TableHandle tableHandle, CatalogSchema
946943
CatalogHandle catalogHandle = tableHandle.catalogHandle();
947944
CatalogMetadata catalogMetadata = getCatalogMetadataForWrite(session, catalogHandle.getCatalogName().toString());
948945
ConnectorMetadata metadata = getMetadataForWrite(session, catalogHandle);
949-
metadata.renameColumn(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), source, target.toLowerCase(ENGLISH));
946+
metadata.renameColumn(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), source, target);
950947
if (catalogMetadata.getSecurityManagement() == SYSTEM) {
951948
ColumnMetadata columnMetadata = getColumnMetadata(session, tableHandle, source);
952949
systemSecurityMetadata.columnRenamed(session, table, columnMetadata.getName(), target);
@@ -958,7 +955,7 @@ public void renameField(Session session, TableHandle tableHandle, List<String> f
958955
{
959956
CatalogHandle catalogHandle = tableHandle.catalogHandle();
960957
ConnectorMetadata metadata = getMetadataForWrite(session, catalogHandle);
961-
metadata.renameField(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), fieldPath, target.toLowerCase(ENGLISH));
958+
metadata.renameField(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), fieldPath, target);
962959
}
963960

964961
@Override
@@ -2309,7 +2306,6 @@ public Set<String> listRoles(Session session, Optional<String> catalog)
23092306
ConnectorSession connectorSession = session.toConnectorSession(catalogHandle);
23102307
ConnectorMetadata metadata = catalogMetadata.get().getMetadataFor(session, catalogHandle);
23112308
return metadata.listRoles(connectorSession).stream()
2312-
.map(role -> role.toLowerCase(ENGLISH))
23132309
.collect(toImmutableSet());
23142310
}
23152311
}

core/trino-main/src/main/java/io/trino/metadata/MetadataUtil.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import static io.trino.spi.security.PrincipalType.USER;
5151
import static io.trino.sql.analyzer.SemanticExceptions.semanticException;
5252
import static java.lang.String.format;
53-
import static java.util.Locale.ENGLISH;
5453
import static java.util.Objects.requireNonNull;
5554

5655
public final class MetadataUtil
@@ -78,22 +77,21 @@ public static String checkSchemaName(String schemaName)
7877

7978
public static String checkTableName(String tableName)
8079
{
81-
return checkLowerCase(tableName, "tableName");
80+
return requireNonNull(tableName, "tableName");
8281
}
8382

8483
public static void checkObjectName(String catalogName, String schemaName, String objectName)
8584
{
8685
checkLowerCase(catalogName, "catalogName");
87-
checkLowerCase(schemaName, "schemaName");
88-
checkLowerCase(objectName, "objectName");
86+
requireNonNull(schemaName, "schemaName");
87+
requireNonNull(objectName, "objectName");
8988
}
9089

9190
public static String checkLowerCase(String value, String name)
9291
{
9392
if (value == null) {
9493
throw new NullPointerException(format("%s is null", name));
9594
}
96-
checkArgument(value.equals(value.toLowerCase(ENGLISH)), "%s is not lowercase: %s", name, value);
9795
return value;
9896
}
9997

@@ -184,7 +182,6 @@ public static CatalogSchemaName createCatalogSchemaName(Session session, Node no
184182
if (schemaName == null) {
185183
throw semanticException(MISSING_SCHEMA_NAME, node, "Schema must be specified when session schema is not set");
186184
}
187-
188185
return new CatalogSchemaName(catalogName, schemaName);
189186
}
190187

core/trino-main/src/main/java/io/trino/server/HttpRequestSessionContextFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public SessionContext createSessionContext(
105105
throw new BadRequestException(e.getMessage());
106106
}
107107
Optional<String> catalog = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestCatalog()))).map(value -> value.toLowerCase(Locale.ENGLISH));
108-
Optional<String> schema = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestSchema()))).map(value -> value.toLowerCase(Locale.ENGLISH));
108+
Optional<String> schema = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestSchema())));
109109
Optional<String> path = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestPath())));
110110
assertRequest(catalog.isPresent() || schema.isEmpty(), "Schema is set but catalog is not");
111111

core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,6 @@ protected Scope visitInsert(Insert insert, Optional<Scope> scope)
645645
if (insert.getColumns().isPresent()) {
646646
insertColumns = insert.getColumns().get().stream()
647647
.map(Identifier::getValue)
648-
.map(column -> column.toLowerCase(ENGLISH))
649648
.collect(toImmutableList());
650649

651650
Set<String> columnNames = new HashSet<>();
@@ -1554,10 +1553,10 @@ private void validateColumnAliases(List<Identifier> columnAliases, int sourceCol
15541553
validateColumnAliasesCount(columnAliases, sourceColumnSize);
15551554
Set<String> names = new HashSet<>();
15561555
for (Identifier identifier : columnAliases) {
1557-
if (names.contains(identifier.getValue().toLowerCase(ENGLISH))) {
1556+
if (names.contains(identifier.getValue())) {
15581557
throw semanticException(DUPLICATE_COLUMN_NAME, identifier, "Column name '%s' specified more than once", identifier.getValue());
15591558
}
1560-
names.add(identifier.getValue().toLowerCase(ENGLISH));
1559+
names.add(identifier.getValue());
15611560
}
15621561
}
15631562

@@ -2755,6 +2754,9 @@ private List<Field> analyzeTableOutputFields(Table table, QualifiedObjectName ta
27552754
Optional.of(column.getName()),
27562755
false);
27572756
fields.add(field);
2757+
System.out.println("StatementAnalyser.analyzeTableOutputFields() column Name: " + column.getName());
2758+
System.out.println("StatementAnalyser.analyzeTableOutputFields() columnHandle.containsKey(): " + columnHandles.containsKey(column.getName()));
2759+
System.out.println("StatementAnalyser.analyzeTableOutputFields() columnHandle Keys: " + String.join(", ", columnHandles.keySet()));
27582760
ColumnHandle columnHandle = columnHandles.get(column.getName());
27592761
checkArgument(columnHandle != null, "Unknown field %s", field);
27602762
analysis.setColumn(field, columnHandle);
@@ -2778,7 +2780,7 @@ protected Scope visitPatternRecognitionRelation(PatternRecognitionRelation relat
27782780
Set<String> inputNames = new HashSet<>();
27792781
for (Field field : inputScope.getRelationType().getAllFields()) {
27802782
field.getName().ifPresent(name -> {
2781-
if (!inputNames.add(name.toUpperCase(ENGLISH))) {
2783+
if (!inputNames.add(name)) {
27822784
throw semanticException(AMBIGUOUS_NAME, relation.getInput(), "ambiguous column: %s in row pattern input relation", name);
27832785
}
27842786
});
@@ -3082,8 +3084,6 @@ private RelationType aliasTableFunctionInvocation(AliasedRelation relation, Rela
30823084
.map(Field::getName)
30833085
.filter(Optional::isPresent)
30843086
.map(Optional::get)
3085-
// field names are resolved case-insensitive
3086-
.map(name -> name.toLowerCase(ENGLISH))
30873087
.forEach(name -> {
30883088
if (!names.add(name)) {
30893089
throw semanticException(DUPLICATE_COLUMN_NAME, relation.getRelation(), "Duplicate name of table function proper column: %s", name);
@@ -3414,9 +3414,7 @@ private static Map<String, Integer> buildNameToIndex(SetOperation node, Relation
34143414
for (int i = 0; i < relationType.getAllFieldCount(); i++) {
34153415
Field field = relationType.getFieldByIndex(i);
34163416
String name = field.getName()
3417-
.orElseThrow(() -> semanticException(MISSING_COLUMN_NAME, node, "Anonymous columns are not allowed in set operations with CORRESPONDING"))
3418-
// TODO https://github.com/trinodb/trino/issues/17 Add support for case sensitive identifiers
3419-
.toLowerCase(ENGLISH);
3417+
.orElseThrow(() -> semanticException(MISSING_COLUMN_NAME, node, "Anonymous columns are not allowed in set operations with CORRESPONDING"));
34203418
if (nameToIndex.put(name, i) != null) {
34213419
throw semanticException(AMBIGUOUS_NAME, node, "Duplicate columns found when using CORRESPONDING in set operations: %s", name);
34223420
}
@@ -3543,14 +3541,14 @@ protected Scope visitUpdate(Update update, Optional<Scope> scope)
35433541
.collect(toImmutableMap(ColumnSchema::getName, Function.identity()));
35443542

35453543
for (UpdateAssignment assignment : update.getAssignments()) {
3546-
String columnName = assignment.getName().getValue().toLowerCase(ENGLISH);
3544+
String columnName = assignment.getName().getValue();
35473545
if (!columns.containsKey(columnName)) {
35483546
throw semanticException(COLUMN_NOT_FOUND, assignment.getName(), "The UPDATE SET target column %s doesn't exist", columnName);
35493547
}
35503548
}
35513549

35523550
Set<String> assignmentTargets = update.getAssignments().stream()
3553-
.map(assignment -> assignment.getName().getValue().toLowerCase(ENGLISH))
3551+
.map(assignment -> assignment.getName().getValue())
35543552
.collect(toImmutableSet());
35553553
accessControl.checkCanUpdateTableColumns(session.toSecurityContext(), tableName, assignmentTargets);
35563554

@@ -3588,7 +3586,7 @@ protected Scope visitUpdate(Update update, Optional<Scope> scope)
35883586
ImmutableList.Builder<Type> expressionTypesBuilder = ImmutableList.builder();
35893587
ImmutableMap.Builder<String, Set<SourceColumn>> sourceColumnsByColumnNameBuilder = ImmutableMap.builder();
35903588
for (UpdateAssignment assignment : update.getAssignments()) {
3591-
String targetColumnName = assignment.getName().getValue().toLowerCase(ENGLISH);
3589+
String targetColumnName = assignment.getName().getValue();
35923590
Expression expression = assignment.getValue();
35933591
ExpressionAnalysis expressionAnalysis = analyzeExpression(expression, tableScope);
35943592
analysesBuilder.add(expressionAnalysis);
@@ -3606,7 +3604,7 @@ protected Scope visitUpdate(Update update, Optional<Scope> scope)
36063604
Map<String, Set<SourceColumn>> sourceColumnsByColumnName = sourceColumnsByColumnNameBuilder.buildOrThrow();
36073605

36083606
List<Type> tableTypes = update.getAssignments().stream()
3609-
.map(assignment -> requireNonNull(columns.get(assignment.getName().getValue().toLowerCase(ENGLISH))))
3607+
.map(assignment -> requireNonNull(columns.get(assignment.getName().getValue())))
36103608
.map(ColumnSchema::getType)
36113609
.collect(toImmutableList());
36123610

@@ -3965,7 +3963,7 @@ private List<List<ColumnHandle>> buildCaseColumnLists(Merge merge, List<ColumnSc
39653963
private List<String> lowercaseIdentifierList(Collection<Identifier> identifiers)
39663964
{
39673965
return identifiers.stream()
3968-
.map(identifier -> identifier.getValue().toLowerCase(ENGLISH))
3966+
.map(identifier -> identifier.getValue())
39693967
.collect(toImmutableList());
39703968
}
39713969

core/trino-main/src/main/java/io/trino/sql/routine/SqlRoutinePlanner.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@
8484
import static io.trino.sql.relational.Expressions.call;
8585
import static io.trino.sql.relational.Expressions.constantNull;
8686
import static io.trino.sql.relational.Expressions.field;
87-
import static java.util.Locale.ENGLISH;
8887
import static java.util.Objects.requireNonNull;
8988

9089
public final class SqlRoutinePlanner
@@ -363,7 +362,7 @@ private static String identifierValue(Identifier name)
363362
// stop-gap: lowercasing for now to match what is happening during analysis;
364363
// otherwise we do not support non-lowercase variables in functions.
365364
// Rework as part of https://github.com/trinodb/trino/pull/24829
366-
return name.getValue().toLowerCase(ENGLISH);
365+
return name.getValue();
367366
}
368367
}
369368

0 commit comments

Comments
 (0)