Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NPE when Glue Table parameters are null #14577

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -83,15 +85,16 @@ protected String getRefreshedLocation(boolean invalidateCaches)
Table table = getTable();
glueVersionId = table.getVersionId();

if (isPrestoView(table.getParameters()) && isHiveOrPrestoView(table.getTableType())) {
Map<String, String> 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()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -405,12 +406,13 @@ private Optional<com.amazonaws.services.glue.model.Table> getTable(ConnectorSess
.withName(schemaTableName.getTableName()))
.getTable());

if (isIcebergTable(table.getParameters()) && !tableMetadataCache.containsKey(schemaTableName)) {
Map<String, String> 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(
Expand All @@ -427,7 +429,7 @@ private Optional<com.amazonaws.services.glue.model.Table> 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");
}
Expand All @@ -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");
}
Expand All @@ -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));
}
Expand Down Expand Up @@ -535,7 +537,7 @@ private void doCreateView(ConnectorSession session, SchemaTableName schemaViewNa
{
Optional<com.amazonaws.services.glue.model.Table> 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);
}
Expand Down Expand Up @@ -631,7 +633,7 @@ public List<SchemaTableName> listViews(ConnectorSession session, Optional<String
stats.getGetTables())
.map(GetTablesResult::getTableList)
.flatMap(List::stream)
.filter(table -> isPrestoView(table.getParameters()))
.filter(table -> isPrestoView(firstNonNull(table.getParameters(), ImmutableMap.of())))
.map(table -> new SchemaTableName(glueNamespace, table.getName()));
}
catch (EntityNotFoundException e) {
Expand Down Expand Up @@ -668,7 +670,7 @@ public Optional<ConnectorViewDefinition> getView(ConnectorSession session, Schem
viewName,
Optional.ofNullable(viewDefinition.getViewOriginalText()),
viewDefinition.getTableType(),
viewDefinition.getParameters(),
firstNonNull(viewDefinition.getParameters(), ImmutableMap.of()),
Optional.ofNullable(viewDefinition.getOwner()));
}

Expand Down Expand Up @@ -715,7 +717,7 @@ public List<SchemaTableName> 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) {
Expand All @@ -741,7 +743,7 @@ public void createMaterializedView(
Optional<com.amazonaws.services.glue.model.Table> 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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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<String, String> 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));
Expand Down Expand Up @@ -835,7 +838,7 @@ protected Optional<ConnectorMaterializedViewDefinition> 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();
}

Expand All @@ -847,7 +850,7 @@ private Optional<ConnectorMaterializedViewDefinition> createMaterializedViewDefi
SchemaTableName viewName,
com.amazonaws.services.glue.model.Table table)
{
Map<String, String> materializedViewParameters = table.getParameters();
Map<String, String> 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))
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -936,7 +939,7 @@ public Optional<CatalogSchemaTableName> 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));
}
Expand Down