Skip to content

Commit 2bd2c18

Browse files
WIP - Mixed case identifier support
1 parent 94d6def commit 2bd2c18

File tree

71 files changed

+537
-229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+537
-229
lines changed

presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/BaseJdbcClient.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.facebook.presto.spi.SchemaTableName;
3131
import com.facebook.presto.spi.TableNotFoundException;
3232
import com.facebook.presto.spi.statistics.TableStatistics;
33-
import com.google.common.base.CharMatcher;
3433
import com.google.common.base.Joiner;
3534
import com.google.common.cache.Cache;
3635
import com.google.common.cache.CacheBuilder;
@@ -77,7 +76,6 @@
7776
import static com.google.common.base.Preconditions.checkArgument;
7877
import static com.google.common.base.Strings.emptyToNull;
7978
import static com.google.common.base.Strings.isNullOrEmpty;
80-
import static com.google.common.base.Verify.verify;
8179
import static com.google.common.collect.ImmutableMap.toImmutableMap;
8280
import static com.google.common.collect.ImmutableSet.toImmutableSet;
8381
import static com.google.common.collect.Iterables.getOnlyElement;
@@ -150,7 +148,7 @@ public final Set<String> getSchemaNames(ConnectorSession session, JdbcIdentity i
150148
{
151149
try (Connection connection = connectionFactory.openConnection(identity)) {
152150
return listSchemas(connection).stream()
153-
.map(schemaName -> schemaName.toLowerCase(ENGLISH))
151+
.map(schemaName -> normalizeIdentifier(session, schemaName))
154152
.collect(toImmutableSet());
155153
}
156154
catch (SQLException e) {
@@ -186,7 +184,8 @@ public List<SchemaTableName> getTableNames(ConnectorSession session, JdbcIdentit
186184
while (resultSet.next()) {
187185
String tableSchema = getTableSchemaName(resultSet);
188186
String tableName = resultSet.getString("TABLE_NAME");
189-
list.add(new SchemaTableName(tableSchema.toLowerCase(ENGLISH), tableName.toLowerCase(ENGLISH)));
187+
list.add(new SchemaTableName(normalizeIdentifier(session, tableSchema),
188+
normalizeIdentifier(session, tableName)));
190189
}
191190
return list.build();
192191
}
@@ -605,6 +604,12 @@ public PreparedStatement getPreparedStatement(ConnectorSession session, Connecti
605604
return connection.prepareStatement(sql);
606605
}
607606

607+
@Override
608+
public String normalizeIdentifier(ConnectorSession session, String identifier)
609+
{
610+
return identifier.toLowerCase(ENGLISH);
611+
}
612+
608613
protected ResultSet getTables(Connection connection, Optional<String> schemaName, Optional<String> tableName)
609614
throws SQLException
610615
{
@@ -626,7 +631,7 @@ protected String getTableSchemaName(ResultSet resultSet)
626631
protected String toRemoteSchemaName(JdbcIdentity identity, Connection connection, String schemaName)
627632
{
628633
requireNonNull(schemaName, "schemaName is null");
629-
verify(CharMatcher.forPredicate(Character::isUpperCase).matchesNoneOf(schemaName), "Expected schema name from internal metadata to be lowercase: %s", schemaName);
634+
// verify(CharMatcher.forPredicate(Character::isUpperCase).matchesNoneOf(schemaName), "Expected schema name from internal metadata to be lowercase: %s", schemaName);
630635

631636
if (caseInsensitiveNameMatching) {
632637
try {
@@ -671,7 +676,7 @@ protected String toRemoteTableName(JdbcIdentity identity, Connection connection,
671676
{
672677
requireNonNull(remoteSchema, "remoteSchema is null");
673678
requireNonNull(tableName, "tableName is null");
674-
verify(CharMatcher.forPredicate(Character::isUpperCase).matchesNoneOf(tableName), "Expected table name from internal metadata to be lowercase: %s", tableName);
679+
// verify(CharMatcher.forPredicate(Character::isUpperCase).matchesNoneOf(tableName), "Expected table name from internal metadata to be lowercase: %s", tableName);
675680

676681
if (caseInsensitiveNameMatching) {
677682
try {

presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,6 @@ PreparedStatement getPreparedStatement(ConnectorSession session, Connection conn
9898
throws SQLException;
9999

100100
TableStatistics getTableStatistics(ConnectorSession session, JdbcTableHandle handle, List<JdbcColumnHandle> columnHandles, TupleDomain<ColumnHandle> tupleDomain);
101+
102+
String normalizeIdentifier(ConnectorSession session, String identifier);
101103
}

presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcMetadata.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,10 @@ public TableStatistics getTableStatistics(ConnectorSession session, ConnectorTab
267267
List<JdbcColumnHandle> columns = columnHandles.stream().map(JdbcColumnHandle.class::cast).collect(Collectors.toList());
268268
return jdbcClient.getTableStatistics(session, handle, columns, constraint.getSummary());
269269
}
270+
271+
@Override
272+
public String normalizeIdentifier(ConnectorSession session, String identifier)
273+
{
274+
return jdbcClient.normalizeIdentifier(session, identifier);
275+
}
270276
}

presto-common/src/main/java/com/facebook/presto/common/CatalogSchemaName.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.util.Objects;
2121

22-
import static java.util.Locale.ENGLISH;
2322
import static java.util.Objects.requireNonNull;
2423

2524
@ThriftStruct
@@ -33,8 +32,8 @@ public final class CatalogSchemaName
3332
@ThriftConstructor
3433
public CatalogSchemaName(String catalogName, String schemaName)
3534
{
36-
this.catalogName = requireNonNull(catalogName, "catalogName is null").toLowerCase(ENGLISH);
37-
this.schemaName = requireNonNull(schemaName, "schemaName is null").toLowerCase(ENGLISH);
35+
this.catalogName = requireNonNull(catalogName, "catalogName is null");
36+
this.schemaName = requireNonNull(schemaName, "schemaName is null");
3837
}
3938

4039
@ThriftField(1)

presto-common/src/main/java/com/facebook/presto/common/QualifiedObjectName.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ public static QualifiedObjectName valueOf(String catalogName, String schemaName,
6161
@ThriftConstructor
6262
public QualifiedObjectName(String catalogName, String schemaName, String objectName)
6363
{
64-
checkLowerCase(catalogName, "catalogName");
65-
checkLowerCase(schemaName, "schemaName");
66-
checkLowerCase(objectName, "objectName");
6764
this.catalogName = catalogName;
6865
this.schemaName = schemaName;
6966
this.objectName = objectName;
7067
}
7168

69+
public String getLegacyCatalogName()
70+
{
71+
return catalogName.toLowerCase(ENGLISH);
72+
}
73+
7274
public CatalogSchemaName getCatalogSchemaName()
7375
{
7476
return new CatalogSchemaName(catalogName, schemaName);

presto-common/src/main/java/com/facebook/presto/common/type/BigintEnumType.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import static com.facebook.presto.common.type.TypeUtils.normalizeEnumMap;
3232
import static com.facebook.presto.common.type.TypeUtils.validateEnumMap;
3333
import static java.lang.String.format;
34-
import static java.util.Locale.ENGLISH;
3534
import static java.util.Objects.requireNonNull;
3635
import static java.util.stream.Collectors.toMap;
3736

@@ -93,7 +92,7 @@ public static class LongEnumMap
9392
public LongEnumMap(@JsonProperty("typeName") String typeName, @JsonProperty("enumMap") Map<String, Long> enumMap)
9493
{
9594
validateEnumMap(requireNonNull(enumMap, "enumMap is null"));
96-
this.typeName = requireNonNull(typeName.toLowerCase(ENGLISH), "typeName is null");
95+
this.typeName = requireNonNull(typeName, "typeName is null");
9796
this.enumMap = normalizeEnumMap(enumMap);
9897
this.flippedEnumMap = this.enumMap.entrySet().stream()
9998
.collect(toMap(Map.Entry::getValue, Map.Entry::getKey));

presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedTestBase.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
import com.facebook.presto.hive.s3.PrestoS3ConfigurationUpdater;
3737
import com.facebook.presto.hive.s3.S3ConfigurationUpdater;
3838
import com.facebook.presto.iceberg.delete.DeleteFile;
39+
import com.facebook.presto.metadata.CatalogManager;
3940
import com.facebook.presto.metadata.CatalogMetadata;
4041
import com.facebook.presto.metadata.Metadata;
4142
import com.facebook.presto.metadata.MetadataUtil;
4243
import com.facebook.presto.spi.ColumnHandle;
44+
import com.facebook.presto.spi.ConnectorId;
4345
import com.facebook.presto.spi.Constraint;
4446
import com.facebook.presto.spi.PrestoException;
4547
import com.facebook.presto.spi.TableHandle;
@@ -2526,10 +2528,22 @@ private Table updateTable(String tableName)
25262528

25272529
protected Table loadTable(String tableName)
25282530
{
2531+
tableName = normalizeIdentifier(tableName);
25292532
Catalog catalog = CatalogUtil.loadCatalog(catalogType.getCatalogImpl(), "test-hive", getProperties(), new Configuration());
25302533
return catalog.loadTable(TableIdentifier.of("tpch", tableName));
25312534
}
25322535

2536+
protected String normalizeIdentifier(String name)
2537+
{
2538+
Metadata metadata = getQueryRunner().getMetadata();
2539+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
2540+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
2541+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
2542+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
2543+
2544+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
2545+
}
2546+
25332547
protected Map<String, String> getProperties()
25342548
{
25352549
Path metastoreDir = getCatalogDirectory();

presto-iceberg/src/test/java/com/facebook/presto/iceberg/hive/TestIcebergDistributedHive.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public void testManifestFileCachingDisabled()
175175
@Override
176176
protected Table loadTable(String tableName)
177177
{
178+
tableName = normalizeIdentifier(tableName);
178179
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
179180
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
180181

presto-iceberg/src/test/java/com/facebook/presto/iceberg/hive/TestIcebergHiveStatistics.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ private void deleteTableStatistics(String tableName)
586586

587587
private Table loadTable(String tableName)
588588
{
589+
tableName = normalizeIdentifier(tableName);
589590
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
590591
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
591592

@@ -597,6 +598,17 @@ private Table loadTable(String tableName)
597598
SchemaTableName.valueOf("tpch." + tableName));
598599
}
599600

601+
private String normalizeIdentifier(String name)
602+
{
603+
Metadata metadata = getQueryRunner().getMetadata();
604+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
605+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
606+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
607+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
608+
609+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
610+
}
611+
600612
protected ExtendedHiveMetastore getFileHiveMetastore()
601613
{
602614
IcebergFileHiveMetastore fileHiveMetastore = new IcebergFileHiveMetastore(getHdfsEnvironment(),

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestExpireSnapshotProcedure.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@
1515

1616
import com.facebook.presto.Session;
1717
import com.facebook.presto.Session.SessionBuilder;
18+
import com.facebook.presto.common.transaction.TransactionId;
1819
import com.facebook.presto.common.type.TimeZoneKey;
1920
import com.facebook.presto.iceberg.IcebergConfig;
2021
import com.facebook.presto.iceberg.IcebergQueryRunner;
22+
import com.facebook.presto.metadata.CatalogManager;
23+
import com.facebook.presto.metadata.Metadata;
24+
import com.facebook.presto.spi.ConnectorId;
25+
import com.facebook.presto.spi.security.AllowAllAccessControl;
2126
import com.facebook.presto.testing.QueryRunner;
2227
import com.facebook.presto.tests.AbstractTestQueryFramework;
2328
import com.google.common.collect.ImmutableMap;
@@ -248,10 +253,22 @@ private String getTimestampString(long timeMillsUtc, String zoneId)
248253

249254
private Table loadTable(String tableName)
250255
{
256+
tableName = normalizeIdentifier(tableName);
251257
Catalog catalog = CatalogUtil.loadCatalog(HadoopCatalog.class.getName(), ICEBERG_CATALOG, getProperties(), new Configuration());
252258
return catalog.loadTable(TableIdentifier.of(TEST_SCHEMA, tableName));
253259
}
254260

261+
protected String normalizeIdentifier(String name)
262+
{
263+
Metadata metadata = getQueryRunner().getMetadata();
264+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
265+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
266+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
267+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
268+
269+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
270+
}
271+
255272
private Map<String, String> getProperties()
256273
{
257274
File metastoreDir = getCatalogDirectory();

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestFastForwardBranchProcedure.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@
1313
*/
1414
package com.facebook.presto.iceberg.procedure;
1515

16+
import com.facebook.presto.Session;
17+
import com.facebook.presto.common.transaction.TransactionId;
1618
import com.facebook.presto.iceberg.IcebergConfig;
1719
import com.facebook.presto.iceberg.IcebergQueryRunner;
20+
import com.facebook.presto.metadata.CatalogManager;
21+
import com.facebook.presto.metadata.Metadata;
22+
import com.facebook.presto.spi.ConnectorId;
23+
import com.facebook.presto.spi.security.AllowAllAccessControl;
1824
import com.facebook.presto.testing.QueryRunner;
1925
import com.facebook.presto.tests.AbstractTestQueryFramework;
2026
import com.google.common.collect.ImmutableMap;
@@ -262,10 +268,22 @@ public void testFastForwardNonExistingBranch()
262268

263269
private Table loadTable(String tableName)
264270
{
271+
tableName = normalizeIdentifier(tableName);
265272
Catalog catalog = CatalogUtil.loadCatalog(HadoopCatalog.class.getName(), ICEBERG_CATALOG, getProperties(), new Configuration());
266273
return catalog.loadTable(TableIdentifier.of(TEST_SCHEMA, tableName));
267274
}
268275

276+
protected String normalizeIdentifier(String name)
277+
{
278+
Metadata metadata = getQueryRunner().getMetadata();
279+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
280+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
281+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
282+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
283+
284+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
285+
}
286+
269287
private Map<String, String> getProperties()
270288
{
271289
File metastoreDir = getCatalogDirectory();

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestRemoveOrphanFilesProcedureBase.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.facebook.presto.Session;
1717
import com.facebook.presto.Session.SessionBuilder;
18+
import com.facebook.presto.common.transaction.TransactionId;
1819
import com.facebook.presto.common.type.TimeZoneKey;
1920
import com.facebook.presto.hive.HdfsConfiguration;
2021
import com.facebook.presto.hive.HdfsConfigurationInitializer;
@@ -26,8 +27,12 @@
2627
import com.facebook.presto.iceberg.CatalogType;
2728
import com.facebook.presto.iceberg.IcebergConfig;
2829
import com.facebook.presto.iceberg.IcebergQueryRunner;
30+
import com.facebook.presto.metadata.CatalogManager;
31+
import com.facebook.presto.metadata.Metadata;
32+
import com.facebook.presto.spi.ConnectorId;
2933
import com.facebook.presto.spi.ConnectorSession;
3034
import com.facebook.presto.spi.SchemaTableName;
35+
import com.facebook.presto.spi.security.AllowAllAccessControl;
3136
import com.facebook.presto.testing.QueryRunner;
3237
import com.facebook.presto.tests.AbstractTestQueryFramework;
3338
import com.google.common.collect.ImmutableMap;
@@ -49,6 +54,7 @@
4954
import java.util.Map;
5055

5156
import static com.facebook.presto.SystemSessionProperties.LEGACY_TIMESTAMP;
57+
import static com.facebook.presto.iceberg.IcebergQueryRunner.ICEBERG_CATALOG;
5258
import static com.facebook.presto.iceberg.IcebergQueryRunner.getIcebergDataDirectoryPath;
5359
import static com.facebook.presto.iceberg.IcebergUtil.dataLocation;
5460
import static com.facebook.presto.iceberg.IcebergUtil.metadataLocation;
@@ -295,6 +301,17 @@ private Session sessionForTimezone(String zoneId, boolean legacyTimestamp)
295301
return sessionBuilder.build();
296302
}
297303

304+
protected String normalizeIdentifier(String name)
305+
{
306+
Metadata metadata = getQueryRunner().getMetadata();
307+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
308+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
309+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
310+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
311+
312+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
313+
}
314+
298315
protected File getCatalogDirectory(CatalogType type)
299316
{
300317
Path dataDirectory = getDistributedQueryRunner().getCoordinator().getDataDirectory();

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestRemoveOrphanFilesProcedureHadoop.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Table createTable(String tableName, String targetPath, Map<String, String> table
7474
@Override
7575
Table loadTable(String tableName)
7676
{
77+
tableName = normalizeIdentifier(tableName);
7778
Catalog catalog = CatalogUtil.loadCatalog(HADOOP.getCatalogImpl(), ICEBERG_CATALOG, getProperties(), new Configuration());
7879
return catalog.loadTable(TableIdentifier.of(TEST_SCHEMA, tableName));
7980
}

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestRemoveOrphanFilesProcedureHive.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Table createTable(String tableName, String targetPath, Map<String, String> table
8989
@Override
9090
Table loadTable(String tableName)
9191
{
92+
tableName = normalizeIdentifier(tableName);
9293
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
9394
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
9495

presto-iceberg/src/test/java/com/facebook/presto/iceberg/procedure/TestRollbackToTimestampProcedure.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@
1515

1616
import com.facebook.presto.Session;
1717
import com.facebook.presto.Session.SessionBuilder;
18+
import com.facebook.presto.common.transaction.TransactionId;
1819
import com.facebook.presto.common.type.TimeZoneKey;
1920
import com.facebook.presto.iceberg.IcebergConfig;
2021
import com.facebook.presto.iceberg.IcebergQueryRunner;
22+
import com.facebook.presto.metadata.CatalogManager;
23+
import com.facebook.presto.metadata.Metadata;
24+
import com.facebook.presto.spi.ConnectorId;
25+
import com.facebook.presto.spi.security.AllowAllAccessControl;
2126
import com.facebook.presto.testing.QueryRunner;
2227
import com.facebook.presto.tests.AbstractTestQueryFramework;
2328
import com.google.common.collect.ImmutableMap;
@@ -251,10 +256,22 @@ private static String getTimestampString(long timeMillsUtc, String zoneId)
251256

252257
private Table loadTable(String tableName)
253258
{
259+
tableName = normalizeIdentifier(tableName);
254260
Catalog catalog = CatalogUtil.loadCatalog(HADOOP.getCatalogImpl(), ICEBERG_CATALOG, getProperties(), new Configuration());
255261
return catalog.loadTable(TableIdentifier.of(TEST_SCHEMA, tableName));
256262
}
257263

264+
protected String normalizeIdentifier(String name)
265+
{
266+
Metadata metadata = getQueryRunner().getMetadata();
267+
TransactionId txid = getQueryRunner().getTransactionManager().beginTransaction(false);
268+
Session session = getSession().beginTransactionId(txid, getQueryRunner().getTransactionManager(), new AllowAllAccessControl());
269+
CatalogManager catalogManager = getDistributedQueryRunner().getCoordinator().getCatalogManager();
270+
ConnectorId connectorId = catalogManager.getCatalog(ICEBERG_CATALOG).get().getConnectorId();
271+
272+
return metadata.normalizeIdentifier(session, connectorId.getCatalogName(), name);
273+
}
274+
258275
private Map<String, String> getProperties()
259276
{
260277
File metastoreDir = getCatalogDirectory();

0 commit comments

Comments
 (0)