diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/GlueIcebergTableOperations.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/GlueIcebergTableOperations.java index ec3879218bd4..0302ee108373 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/GlueIcebergTableOperations.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/GlueIcebergTableOperations.java @@ -37,8 +37,10 @@ import javax.annotation.Nullable; +import java.util.Map; import java.util.Optional; +import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Verify.verify; import static io.trino.plugin.hive.ViewReaderUtil.isHiveOrPrestoView; import static io.trino.plugin.hive.ViewReaderUtil.isPrestoView; @@ -83,15 +85,16 @@ protected String getRefreshedLocation(boolean invalidateCaches) Table table = getTable(); glueVersionId = table.getVersionId(); - if (isPrestoView(table.getParameters()) && isHiveOrPrestoView(table.getTableType())) { + Map parameters = firstNonNull(table.getParameters(), ImmutableMap.of()); + if (isPrestoView(parameters) && isHiveOrPrestoView(table.getTableType())) { // this is a Presto Hive view, hence not a table throw new TableNotFoundException(getSchemaTableName()); } - if (!isIcebergTable(table.getParameters())) { + if (!isIcebergTable(parameters)) { throw new UnknownTableTypeException(getSchemaTableName()); } - String metadataLocation = table.getParameters().get(METADATA_LOCATION_PROP); + String metadataLocation = parameters.get(METADATA_LOCATION_PROP); if (metadataLocation == null) { throw new TrinoException(ICEBERG_INVALID_METADATA, format("Table is missing [%s] property: %s", METADATA_LOCATION_PROP, getSchemaTableName())); } diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java index ac12212da2ae..32bdee9aff11 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java @@ -74,6 +74,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; +import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableList.toImmutableList; @@ -405,12 +406,13 @@ private Optional getTable(ConnectorSess .withName(schemaTableName.getTableName())) .getTable()); - if (isIcebergTable(table.getParameters()) && !tableMetadataCache.containsKey(schemaTableName)) { + Map parameters = firstNonNull(table.getParameters(), ImmutableMap.of()); + if (isIcebergTable(parameters) && !tableMetadataCache.containsKey(schemaTableName)) { if (viewCache.containsKey(schemaTableName) || materializedViewCache.containsKey(schemaTableName)) { throw new TrinoException(GENERIC_INTERNAL_ERROR, "Glue table cache inconsistency. Table cannot also be a view/materialized view"); } - String metadataLocation = table.getParameters().get(METADATA_LOCATION_PROP); + String metadataLocation = parameters.get(METADATA_LOCATION_PROP); try { // Cache the TableMetadata while we have the Table retrieved anyway TableOperations operations = tableOperationsProvider.createTableOperations( @@ -427,7 +429,7 @@ private Optional getTable(ConnectorSess LOG.warn(e, "Failed to cache table metadata from table at %s", metadataLocation); } } - else if (isTrinoMaterializedView(table.getTableType(), table.getParameters())) { + else if (isTrinoMaterializedView(table.getTableType(), parameters)) { if (viewCache.containsKey(schemaTableName) || tableMetadataCache.containsKey(schemaTableName)) { throw new TrinoException(GENERIC_INTERNAL_ERROR, "Glue table cache inconsistency. Materialized View cannot also be a table or view"); } @@ -440,7 +442,7 @@ else if (isTrinoMaterializedView(table.getTableType(), table.getParameters())) { LOG.warn(e, "Failed to cache materialized view from %s", schemaTableName); } } - else if (isPrestoView(table.getParameters()) && !viewCache.containsKey(schemaTableName)) { + else if (isPrestoView(parameters) && !viewCache.containsKey(schemaTableName)) { if (materializedViewCache.containsKey(schemaTableName) || tableMetadataCache.containsKey(schemaTableName)) { throw new TrinoException(GENERIC_INTERNAL_ERROR, "Glue table cache inconsistency. View cannot also be a materialized view or table"); } @@ -449,7 +451,7 @@ else if (isPrestoView(table.getParameters()) && !viewCache.containsKey(schemaTab getView(schemaTableName, Optional.ofNullable(table.getViewOriginalText()), table.getTableType(), - table.getParameters(), + parameters, Optional.ofNullable(table.getOwner())) .ifPresent(viewDefinition -> viewCache.put(schemaTableName, viewDefinition)); } @@ -535,7 +537,7 @@ private void doCreateView(ConnectorSession session, SchemaTableName schemaViewNa { Optional existing = getTable(session, schemaViewName); if (existing.isPresent()) { - if (!replace || !isPrestoView(existing.get().getParameters())) { + if (!replace || !isPrestoView(firstNonNull(existing.get().getParameters(), ImmutableMap.of()))) { // TODO: ViewAlreadyExists is misleading if the name is used by a table https://github.com/trinodb/trino/issues/10037 throw new ViewAlreadyExistsException(schemaViewName); } @@ -631,7 +633,7 @@ public List listViews(ConnectorSession session, Optional isPrestoView(table.getParameters())) + .filter(table -> isPrestoView(firstNonNull(table.getParameters(), ImmutableMap.of()))) .map(table -> new SchemaTableName(glueNamespace, table.getName())); } catch (EntityNotFoundException e) { @@ -668,7 +670,7 @@ public Optional getView(ConnectorSession session, Schem viewName, Optional.ofNullable(viewDefinition.getViewOriginalText()), viewDefinition.getTableType(), - viewDefinition.getParameters(), + firstNonNull(viewDefinition.getParameters(), ImmutableMap.of()), Optional.ofNullable(viewDefinition.getOwner())); } @@ -715,7 +717,7 @@ public List listMaterializedViews(ConnectorSession session, Opt stats.getGetTables()) .map(GetTablesResult::getTableList) .flatMap(List::stream) - .filter(table -> isTrinoMaterializedView(table.getTableType(), table.getParameters())) + .filter(table -> isTrinoMaterializedView(table.getTableType(), firstNonNull(table.getParameters(), ImmutableMap.of()))) .map(table -> new SchemaTableName(glueNamespace, table.getName())); } catch (EntityNotFoundException e) { @@ -741,7 +743,7 @@ public void createMaterializedView( Optional existing = getTable(session, viewName); if (existing.isPresent()) { - if (!isTrinoMaterializedView(existing.get().getTableType(), existing.get().getParameters())) { + if (!isTrinoMaterializedView(existing.get().getTableType(), firstNonNull(existing.get().getParameters(), ImmutableMap.of()))) { throw new TrinoException(UNSUPPORTED_TABLE_TYPE, "Existing table is not a Materialized View: " + viewName); } if (!replace) { @@ -793,7 +795,7 @@ public void dropMaterializedView(ConnectorSession session, SchemaTableName viewN com.amazonaws.services.glue.model.Table view = getTable(session, viewName) .orElseThrow(() -> new MaterializedViewNotFoundException(viewName)); - if (!isTrinoMaterializedView(view.getTableType(), view.getParameters())) { + if (!isTrinoMaterializedView(view.getTableType(), firstNonNull(view.getParameters(), ImmutableMap.of()))) { throw new TrinoException(UNSUPPORTED_TABLE_TYPE, "Not a Materialized View: " + view.getDatabaseName() + "." + view.getName()); } materializedViewCache.remove(viewName); @@ -803,9 +805,10 @@ public void dropMaterializedView(ConnectorSession session, SchemaTableName viewN private void dropStorageTable(ConnectorSession session, com.amazonaws.services.glue.model.Table view) { - String storageTableName = view.getParameters().get(STORAGE_TABLE); + Map parameters = firstNonNull(view.getParameters(), ImmutableMap.of()); + String storageTableName = parameters.get(STORAGE_TABLE); if (storageTableName != null) { - String storageSchema = Optional.ofNullable(view.getParameters().get(STORAGE_SCHEMA)) + String storageSchema = Optional.ofNullable(parameters.get(STORAGE_SCHEMA)) .orElse(view.getDatabaseName()); try { dropTable(session, new SchemaTableName(storageSchema, storageTableName)); @@ -835,7 +838,7 @@ protected Optional doGetMaterializedView(Co } com.amazonaws.services.glue.model.Table table = maybeTable.get(); - if (!isTrinoMaterializedView(table.getTableType(), table.getParameters())) { + if (!isTrinoMaterializedView(table.getTableType(), firstNonNull(table.getParameters(), ImmutableMap.of()))) { return Optional.empty(); } @@ -847,7 +850,7 @@ private Optional createMaterializedViewDefi SchemaTableName viewName, com.amazonaws.services.glue.model.Table table) { - Map materializedViewParameters = table.getParameters(); + Map materializedViewParameters = firstNonNull(table.getParameters(), ImmutableMap.of()); String storageTable = materializedViewParameters.get(STORAGE_TABLE); checkState(storageTable != null, "Storage table missing in definition of materialized view " + viewName); String storageSchema = Optional.ofNullable(materializedViewParameters.get(STORAGE_SCHEMA)) @@ -886,7 +889,7 @@ public void renameMaterializedView(ConnectorSession session, SchemaTableName sou com.amazonaws.services.glue.model.Table glueTable = getTable(session, source) .orElseThrow(() -> new TableNotFoundException(source)); materializedViewCache.remove(source); - if (!isTrinoMaterializedView(glueTable.getTableType(), glueTable.getParameters())) { + if (!isTrinoMaterializedView(glueTable.getTableType(), firstNonNull(glueTable.getParameters(), ImmutableMap.of()))) { throw new TrinoException(UNSUPPORTED_TABLE_TYPE, "Not a Materialized View: " + source); } TableInput tableInput = getMaterializedViewTableInput(target.getTableName(), glueTable.getViewOriginalText(), glueTable.getOwner(), glueTable.getParameters()); @@ -936,7 +939,7 @@ public Optional redirectTable(ConnectorSession session, if (table.isEmpty() || VIRTUAL_VIEW.name().equals(table.get().getTableType())) { return Optional.empty(); } - if (!isIcebergTable(table.get().getParameters())) { + if (!isIcebergTable(firstNonNull(table.get().getParameters(), ImmutableMap.of()))) { // After redirecting, use the original table name, with "$partitions" and similar suffixes return targetCatalogName.map(catalog -> new CatalogSchemaTableName(catalog, tableName)); }