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

Add ALTER TABLE SET PROPERTIES statement #21495

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 @@ -55,6 +55,7 @@
import com.facebook.presto.sql.tree.Revoke;
import com.facebook.presto.sql.tree.RevokeRoles;
import com.facebook.presto.sql.tree.Rollback;
import com.facebook.presto.sql.tree.SetProperties;
import com.facebook.presto.sql.tree.SetRole;
import com.facebook.presto.sql.tree.SetSession;
import com.facebook.presto.sql.tree.ShowCatalogs;
Expand Down Expand Up @@ -142,6 +143,7 @@ private StatementUtils() {}
builder.put(DropFunction.class, QueryType.CONTROL);
builder.put(Use.class, QueryType.CONTROL);
builder.put(SetSession.class, QueryType.CONTROL);
builder.put(SetProperties.class, QueryType.DATA_DEFINITION);
builder.put(ResetSession.class, QueryType.CONTROL);
builder.put(StartTransaction.class, QueryType.CONTROL);
builder.put(Commit.class, QueryType.CONTROL);
Expand Down
10 changes: 8 additions & 2 deletions presto-docs/src/main/sphinx/connector/iceberg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ that is stored using the ORC file format, partitioned by ``ds`` and
partitioning = ARRAY['ds', 'country']
)

Create an Iceberg table with Iceberg format version 2::
Create an Iceberg table with Iceberg format version 2 and with commit_retries set to 5::

CREATE TABLE iceberg.web.page_views_v2 (
view_time timestamp,
Expand All @@ -1063,7 +1063,8 @@ Create an Iceberg table with Iceberg format version 2::
WITH (
format = 'ORC',
partitioning = ARRAY['ds', 'country'],
format_version = '2'
format_version = '2',
commit_retries = 5
)

Partition Column Transform
Expand Down Expand Up @@ -1203,6 +1204,11 @@ The table is partitioned by the transformed value of the column::

ALTER TABLE iceberg.web.page_views ADD COLUMN ts timestamp WITH (partitioning = 'hour');

Table properties can be modified for an Iceberg table using an ALTER TABLE SET PROPERTIES statement. Only `commit_retries` can be modified at present.
For example, to set `commit_retries` to 6 for the table `iceberg.web.page_views_v2`, use::

ALTER TABLE iceberg.web.page_views_v2 SET PROPERTIES (commit_retries = 6);

TRUNCATE
^^^^^^^^

Expand Down
5 changes: 5 additions & 0 deletions presto-docs/src/main/sphinx/sql/alter-table.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Synopsis
ALTER TABLE [ IF EXISTS ] name ADD [ CONSTRAINT constraint_name ] { PRIMARY KEY | UNIQUE } ( { column_name [, ...] } ) [ { ENABLED | DISABLED } ] [ [ NOT ] RELY ] [ [ NOT ] ENFORCED } ]
ALTER TABLE [ IF EXISTS ] name DROP CONSTRAINT [ IF EXISTS ] constraint_name
ALTER TABLE [ IF EXISTS ] name ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL
ALTER TABLE [ IF EXISTS ] name SET PROPERTIES (property_name=value, [, ...])
Description
-----------
Expand Down Expand Up @@ -89,6 +90,10 @@ Drop not null constraint from column ``zip`` in the ``users`` table::

ALTER TABLE users ALTER COLUMN zip DROP NOT NULL;

Set table property (``x=y``) to table ``users``::

ALTER TABLE users SET PROPERTIES (x='y');

See Also
--------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import javax.inject.Inject;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -101,6 +102,11 @@ public void checkCanCreateTable(ConnectorTransactionHandle transaction, Connecto
{
}

@Override
public void checkCanSetTableProperties(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName, Map<String, Object> properties)
{
}

@Override
public void checkCanDropTable(ConnectorTransactionHandle transaction, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import javax.inject.Inject;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -74,6 +75,7 @@
import static com.facebook.presto.spi.security.AccessDeniedException.denySelectTable;
import static com.facebook.presto.spi.security.AccessDeniedException.denySetCatalogSessionProperty;
import static com.facebook.presto.spi.security.AccessDeniedException.denySetRole;
import static com.facebook.presto.spi.security.AccessDeniedException.denySetTableProperties;
import static com.facebook.presto.spi.security.AccessDeniedException.denyShowRoles;
import static com.facebook.presto.spi.security.AccessDeniedException.denyTruncateTable;
import static com.facebook.presto.spi.security.AccessDeniedException.denyUpdateTableColumns;
Expand Down Expand Up @@ -186,6 +188,24 @@ public void checkCanCreateTable(ConnectorTransactionHandle transaction, Connecto
}
}

@Override
public void checkCanSetTableProperties(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName, Map<String, Object> properties)
pratyakshsharma marked this conversation as resolved.
Show resolved Hide resolved
{
MetastoreContext metastoreContext = new MetastoreContext(identity,
context.getQueryId().getId(),
context.getClientInfo(),
context.getClientTags(),
context.getSource(),
Optional.empty(),
false,
HiveColumnConverterProvider.DEFAULT_COLUMN_CONVERTER_PROVIDER,
context.getWarningCollector(),
context.getRuntimeStats());
if (!isTableOwner(transactionHandle, identity, metastoreContext, tableName)) {
denySetTableProperties(tableName.toString());
}
}

@Override
public void checkCanDropTable(ConnectorTransactionHandle transaction, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.facebook.presto.spi.security.PrestoPrincipal;
import com.facebook.presto.spi.security.Privilege;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -83,6 +84,12 @@ public void checkCanCreateTable(ConnectorTransactionHandle transactionHandle, Co
delegate.checkCanCreateTable(transactionHandle, identity, context, tableName);
}

@Override
public void checkCanSetTableProperties(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName, Map<String, Object> properties)
{
delegate.checkCanSetTableProperties(transactionHandle, identity, context, tableName, properties);
}

@Override
public void checkCanDropTable(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, AccessControlContext context, SchemaTableName tableName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@
import org.apache.iceberg.Schema;
import org.apache.iceberg.SchemaParser;
import org.apache.iceberg.Table;
import org.apache.iceberg.TableProperties;
import org.apache.iceberg.Transaction;
import org.apache.iceberg.UpdateProperties;
import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.iceberg.types.Type;
import org.apache.iceberg.types.TypeUtil;
Expand Down Expand Up @@ -122,6 +124,7 @@
import static com.facebook.presto.iceberg.IcebergPartitionType.ALL;
import static com.facebook.presto.iceberg.IcebergSessionProperties.getCompressionCodec;
import static com.facebook.presto.iceberg.IcebergSessionProperties.isPushdownFilterEnabled;
import static com.facebook.presto.iceberg.IcebergTableProperties.COMMIT_RETRIES;
import static com.facebook.presto.iceberg.IcebergTableProperties.DELETE_MODE;
import static com.facebook.presto.iceberg.IcebergTableProperties.FILE_FORMAT_PROPERTY;
import static com.facebook.presto.iceberg.IcebergTableProperties.FORMAT_VERSION;
Expand Down Expand Up @@ -990,6 +993,28 @@ public OptionalLong metadataDelete(ConnectorSession session, ConnectorTableHandl
return removeScanFiles(icebergTable, domainPredicate);
}

@Override
public void setTableProperties(ConnectorSession session, ConnectorTableHandle tableHandle, Map<String, Object> properties)
{
IcebergTableHandle handle = (IcebergTableHandle) tableHandle;
Table icebergTable = getIcebergTable(session, handle.getSchemaTableName());
transaction = icebergTable.newTransaction();

UpdateProperties updateProperties = transaction.updateProperties();
for (Map.Entry<String, Object> entry : properties.entrySet()) {
switch (entry.getKey()) {
case COMMIT_RETRIES:
updateProperties.set(TableProperties.COMMIT_NUM_RETRIES, String.valueOf(entry.getValue()));
break;
default:
throw new PrestoException(NOT_SUPPORTED, "Updating property " + entry.getKey() + " is not supported currently");
}
}

updateProperties.commit();
transaction.commitTransaction();
}

/**
* Deletes all the files for a specific predicate
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import static java.util.stream.Collectors.joining;
import static java.util.stream.IntStream.range;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
Expand Down Expand Up @@ -1808,4 +1809,46 @@ private Session sessionForTimezone(String zoneId, boolean legacyTimestamp)
}
return sessionBuilder.build();
}

@Test
public void testUpdatingInvalidProperty()
{
Session session = getSession();
String tableName = "test_invalid_property_update";
assertUpdate(session, "CREATE TABLE " + tableName + " (c1 integer, c2 varchar) WITH(commit_retries = 4)");
assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + tableName + " SET PROPERTIES (format = 'PARQUET')"))
.hasMessage("Updating property format is not supported currently");
assertUpdate("DROP TABLE " + tableName);
}

@Test
public void testUpdatingRandomProperty()
{
Session session = getSession();
String tableName = "test_random_property_update";
assertUpdate(session, "CREATE TABLE " + tableName + " (c1 integer, c2 varchar) WITH(commit_retries = 4)");
assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + tableName + " SET PROPERTIES (some_config = 2)"))
.hasMessage("Catalog 'iceberg' does not support table property 'some_config'");
assertUpdate("DROP TABLE " + tableName);
}

@Test
public void testUpdatingCommitRetries()
{
Session session = getSession();
String tableName = "test_commit_retries_update";
assertUpdate(session, "CREATE TABLE " + tableName + " (c1 integer, c2 varchar) WITH(commit_retries = 4)");
assertQuery("SELECT value FROM \"" + tableName + "$properties\" WHERE key = 'commit.retry.num-retries'", "VALUES 4");
assertUpdate("ALTER TABLE " + tableName + " SET PROPERTIES (commit_retries = 5)");
assertUpdate("ALTER TABLE IF EXISTS " + tableName + " SET PROPERTIES (commit_retries = 6)");
assertQuery("SELECT value FROM \"" + tableName + "$properties\" WHERE key = 'commit.retry.num-retries'", "VALUES 6");
assertUpdate("DROP TABLE " + tableName);
}
pratyakshsharma marked this conversation as resolved.
Show resolved Hide resolved

@Test
public void testUpdateNonExistentTable()
{
assertQuerySucceeds("ALTER TABLE IF EXISTS non_existent_test_table1 SET PROPERTIES (commit_retries = 6)");
assertQueryFails("ALTER TABLE non_existent_test_table2 SET PROPERTIES (commit_retries = 6)", "Table does not exist: iceberg.tpch.non_existent_test_table2");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.facebook.presto.spi.ColumnMetadata;
import com.facebook.presto.spi.ConnectorId;
import com.facebook.presto.spi.MaterializedViewDefinition;
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.TableHandle;
import com.facebook.presto.spi.WarningCollector;
import com.facebook.presto.spi.security.AccessControl;
Expand All @@ -39,7 +38,7 @@
import static com.facebook.presto.common.type.TypeSignature.parseTypeSignature;
import static com.facebook.presto.common.type.UnknownType.UNKNOWN;
import static com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName;
import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND;
import static com.facebook.presto.metadata.MetadataUtil.getConnectorIdOrThrow;
import static com.facebook.presto.spi.connector.ConnectorCapabilities.NOT_NULL_COLUMN_CONSTRAINT;
import static com.facebook.presto.sql.NodeUtils.mapFromProperties;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.COLUMN_ALREADY_EXISTS;
Expand Down Expand Up @@ -78,8 +77,7 @@ public ListenableFuture<?> execute(AddColumn statement, TransactionManager trans
return immediateFuture(null);
}

ConnectorId connectorId = metadata.getCatalogHandle(session, tableName.getCatalogName())
.orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + tableName.getCatalogName()));
ConnectorId connectorId = getConnectorIdOrThrow(session, metadata, tableName.getCatalogName());

accessControl.checkCanAddColumns(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), tableName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@
import java.util.function.Predicate;

import static com.facebook.presto.common.type.TypeUtils.writeNativeValue;
import static com.facebook.presto.metadata.MetadataUtil.catalogError;
import static com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName;
import static com.facebook.presto.metadata.MetadataUtil.getConnectorIdOrThrow;
import static com.facebook.presto.metadata.MetadataUtil.toSchemaTableName;
import static com.facebook.presto.spi.StandardErrorCode.INVALID_PROCEDURE_ARGUMENT;
import static com.facebook.presto.spi.StandardErrorCode.INVALID_PROCEDURE_DEFINITION;
import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED;
import static com.facebook.presto.spi.StandardErrorCode.PROCEDURE_CALL_FAILED;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_PROCEDURE_ARGUMENTS;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_CATALOG;
import static com.facebook.presto.sql.analyzer.utils.ParameterUtils.parameterExtractor;
import static com.facebook.presto.sql.planner.ExpressionInterpreter.evaluateConstantExpression;
import static com.facebook.presto.util.Failures.checkCondition;
Expand All @@ -81,8 +82,7 @@ public ListenableFuture<?> execute(Call call, TransactionManager transactionMana
}

QualifiedObjectName procedureName = createQualifiedObjectName(session, call, call.getName());
ConnectorId connectorId = metadata.getCatalogHandle(session, procedureName.getCatalogName())
.orElseThrow(() -> new SemanticException(MISSING_CATALOG, call, "Catalog %s does not exist", procedureName.getCatalogName()));
ConnectorId connectorId = getConnectorIdOrThrow(session, metadata, procedureName.getCatalogName(), call, catalogError);
Procedure procedure = metadata.getProcedureRegistry().resolve(connectorId, toSchemaTableName(procedureName));

// map declared argument names to positions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.facebook.presto.common.QualifiedObjectName;
import com.facebook.presto.metadata.Metadata;
import com.facebook.presto.spi.ColumnMetadata;
import com.facebook.presto.spi.ConnectorId;
import com.facebook.presto.spi.ConnectorTableMetadata;
import com.facebook.presto.spi.MaterializedViewDefinition;
import com.facebook.presto.spi.PrestoException;
Expand All @@ -44,9 +43,9 @@
import java.util.Optional;

import static com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName;
import static com.facebook.presto.metadata.MetadataUtil.getConnectorIdOrThrow;
import static com.facebook.presto.metadata.MetadataUtil.toSchemaTableName;
import static com.facebook.presto.spi.StandardErrorCode.ALREADY_EXISTS;
import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND;
import static com.facebook.presto.sql.NodeUtils.mapFromProperties;
import static com.facebook.presto.sql.SqlFormatterUtil.getFormattedSql;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MATERIALIZED_VIEW_ALREADY_EXISTS;
Expand Down Expand Up @@ -93,16 +92,14 @@ public ListenableFuture<?> execute(CreateMaterializedView statement, Transaction
Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterLookup, warningCollector);
Analysis analysis = analyzer.analyze(statement);

ConnectorId connectorId = metadata.getCatalogHandle(session, viewName.getCatalogName())
.orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + viewName.getCatalogName()));
List<ColumnMetadata> columnMetadata = analysis.getOutputDescriptor(statement.getQuery())
.getVisibleFields().stream()
.map(field -> new ColumnMetadata(field.getName().get(), field.getType()))
.collect(toImmutableList());

Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(
connectorId,
getConnectorIdOrThrow(session, metadata, viewName.getCatalogName()),
viewName.getCatalogName(),
sqlProperties,
session,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
import com.facebook.presto.Session;
import com.facebook.presto.common.CatalogSchemaName;
import com.facebook.presto.metadata.Metadata;
import com.facebook.presto.spi.ConnectorId;
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.WarningCollector;
import com.facebook.presto.spi.security.AccessControl;
import com.facebook.presto.sql.analyzer.SemanticException;
Expand All @@ -31,7 +29,7 @@
import java.util.Optional;

import static com.facebook.presto.metadata.MetadataUtil.createCatalogSchemaName;
import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND;
import static com.facebook.presto.metadata.MetadataUtil.getConnectorIdOrThrow;
import static com.facebook.presto.sql.NodeUtils.mapFromProperties;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.SCHEMA_ALREADY_EXISTS;
import static com.facebook.presto.sql.analyzer.utils.ParameterUtils.parameterExtractor;
Expand Down Expand Up @@ -68,11 +66,8 @@ public ListenableFuture<?> execute(CreateSchema statement, TransactionManager tr
return immediateFuture(null);
}

ConnectorId connectorId = metadata.getCatalogHandle(session, schema.getCatalogName())
.orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + schema.getCatalogName()));

Map<String, Object> properties = metadata.getSchemaPropertyManager().getProperties(
connectorId,
getConnectorIdOrThrow(session, metadata, schema.getCatalogName()),
schema.getCatalogName(),
mapFromProperties(statement.getProperties()),
session,
Expand Down
Loading
Loading