Skip to content

Commit 8dbc8e2

Browse files
committed
Add support for ALTER MATERIALIZED VIEW .. SET AUTHORIZATION
This commit adds support for `SET AUTHORIZATION` on a materialized view. Previously, this was only available on views.
1 parent c2eaffd commit 8dbc8e2

File tree

12 files changed

+112
-60
lines changed

12 files changed

+112
-60
lines changed

core/trino-grammar/src/main/antlr4/io/trino/grammar/sql/SqlBase.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ grantObject
953953
;
954954

955955
ownedEntityKind
956-
: TABLE | SCHEMA | VIEW | identifier
956+
: TABLE | SCHEMA | VIEW | MATERIALIZED VIEW | identifier
957957
;
958958

959959
qualifiedName

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ private void setEntityAuthorization(Session session, SetAuthorizationStatement s
104104
throw semanticException(TABLE_NOT_FOUND, statement, "View '%s' does not exist", viewName);
105105
}
106106
}
107+
case "MATERIALIZED VIEW" -> {
108+
QualifiedObjectName viewName = new QualifiedObjectName(name.get(0), name.get(1), name.get(2));
109+
getRequiredCatalogHandle(metadata, session, statement, viewName.catalogName());
110+
if (!metadata.isMaterializedView(session, viewName)) {
111+
throw semanticException(TABLE_NOT_FOUND, statement, "Materialized view '%s' does not exist", viewName);
112+
}
113+
}
107114
}
108115

109116
TrinoPrincipal principal = createPrincipal(statement.getPrincipal());

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
public final class MetadataManager
181181
implements Metadata
182182
{
183-
private static final Set<String> ENTITY_KINDS_WITH_CATALOG = ImmutableSet.of("SCHEMA", "TABLE", "VIEW");
183+
private static final Set<String> ENTITY_KINDS_WITH_CATALOG = ImmutableSet.of("SCHEMA", "TABLE", "VIEW", "MATERIALIZED VIEW");
184184
private static final Logger log = Logger.get(MetadataManager.class);
185185

186186
@VisibleForTesting
@@ -2860,7 +2860,7 @@ public void setEntityAuthorization(Session session, EntityKindAndName entityKind
28602860
if (catalogMetadata.getSecurityManagement() != SYSTEM) {
28612861
switch (ownedKind) {
28622862
case "TABLE" -> metadata.setTableAuthorization(session.toConnectorSession(catalogHandle), new SchemaTableName(name.get(1), name.get(2)), principal);
2863-
case "VIEW" -> metadata.setViewAuthorization(session.toConnectorSession(catalogHandle), new SchemaTableName(name.get(1), name.get(2)), principal);
2863+
case "VIEW", "MATERIALIZED VIEW" -> metadata.setViewAuthorization(session.toConnectorSession(catalogHandle), new SchemaTableName(name.get(1), name.get(2)), principal);
28642864
case "SCHEMA" -> metadata.setSchemaAuthorization(session.toConnectorSession(catalogHandle), name.get(1), principal);
28652865
default -> throw new IllegalArgumentException("Unsupported owned kind: " + ownedKind);
28662866
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public static List<String> fillInNameParts(Session session, Node node, String en
133133
throw new TrinoException(GENERIC_USER_ERROR, "Invalid entity %s for entity kind %s".formatted(joinName(name), entityKind));
134134
}
135135
break;
136-
case "TABLE", "VIEW":
136+
case "TABLE", "VIEW", "MATERIALIZED VIEW":
137137
switch (name.size()) {
138138
case 1:
139139
if (session.getCatalog().isPresent() && session.getSchema().isPresent()) {

core/trino-main/src/main/java/io/trino/security/AccessControlManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ public void checkCanSetEntityAuthorization(SecurityContext securityContext, Enti
14131413
case "TABLE":
14141414
control.checkCanSetTableAuthorization(context, new SchemaTableName(name.get(1), name.get(2)), principal);
14151415
break;
1416-
case "VIEW":
1416+
case "VIEW", "MATERIALIZED VIEW":
14171417
control.checkCanSetViewAuthorization(context, new SchemaTableName(name.get(1), name.get(2)), principal);
14181418
break;
14191419
default:

core/trino-parser/src/main/java/io/trino/sql/parser/AstBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.trino.grammar.sql.SqlBaseParser.CorrespondingContext;
2323
import io.trino.grammar.sql.SqlBaseParser.CreateCatalogContext;
2424
import io.trino.grammar.sql.SqlBaseParser.DropCatalogContext;
25+
import io.trino.grammar.sql.SqlBaseParser.OwnedEntityKindContext;
2526
import io.trino.sql.tree.AddColumn;
2627
import io.trino.sql.tree.AliasedRelation;
2728
import io.trino.sql.tree.AllColumns;
@@ -321,6 +322,7 @@
321322
import java.util.Optional;
322323
import java.util.Set;
323324
import java.util.function.Function;
325+
import java.util.stream.IntStream;
324326
import java.util.stream.Stream;
325327

326328
import static com.google.common.base.Preconditions.checkArgument;
@@ -511,9 +513,13 @@ public Node visitRenameSchema(SqlBaseParser.RenameSchemaContext context)
511513
@Override
512514
public Node visitSetAuthorization(SqlBaseParser.SetAuthorizationContext context)
513515
{
516+
OwnedEntityKindContext ownedEntityKindContext = context.ownedEntityKind();
517+
String ownedEntityKind = IntStream.range(0, ownedEntityKindContext.getChildCount())
518+
.mapToObj(i -> ownedEntityKindContext.getChild(i).getText())
519+
.reduce("", (a, b) -> String.format("%s %s", a, b).trim());
514520
return new SetAuthorizationStatement(
515521
getLocation(context),
516-
context.ownedEntityKind().getText().toUpperCase(ENGLISH),
522+
ownedEntityKind.toUpperCase(ENGLISH),
517523
getQualifiedName(context.qualifiedName()),
518524
getPrincipalSpecification(context.principal()));
519525
}

core/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParser.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3556,6 +3556,29 @@ public void testAlterViewSetAuthorization()
35563556
new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier(location(1, 47), "qux", false))));
35573557
}
35583558

3559+
@Test
3560+
public void testAlterMaterializedViewSetAuthorization()
3561+
{
3562+
assertThat(statement("ALTER MATERIALIZED VIEW foo.bar.baz SET AUTHORIZATION qux")).isEqualTo(
3563+
new SetAuthorizationStatement(
3564+
location(1, 1),
3565+
"MATERIALIZED VIEW",
3566+
QualifiedName.of(ImmutableList.of(new Identifier(location(1, 25), "foo", false), new Identifier(location(1, 29), "bar", false), new Identifier(location(1, 33), "baz", false))),
3567+
new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier(location(1, 55), "qux", false))));
3568+
assertThat(statement("ALTER MATERIALIZED VIEW foo.bar.baz SET AUTHORIZATION USER qux")).isEqualTo(
3569+
new SetAuthorizationStatement(
3570+
location(1, 1),
3571+
"MATERIALIZED VIEW",
3572+
QualifiedName.of(ImmutableList.of(new Identifier(location(1, 25), "foo", false), new Identifier(location(1, 29), "bar", false), new Identifier(location(1, 33), "baz", false))),
3573+
new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier(location(1, 60), "qux", false))));
3574+
assertThat(statement("ALTER MATERIALIZED VIEW foo.bar.baz SET AUTHORIZATION ROLE qux")).isEqualTo(
3575+
new SetAuthorizationStatement(
3576+
location(1, 1),
3577+
"MATERIALIZED VIEW",
3578+
QualifiedName.of(ImmutableList.of(new Identifier(location(1, 25), "foo", false), new Identifier(location(1, 29), "bar", false), new Identifier(location(1, 33), "baz", false))),
3579+
new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier(location(1, 60), "qux", false))));
3580+
}
3581+
35593582
@Test
35603583
public void testTableExecute()
35613584
{

core/trino-spi/src/main/java/io/trino/spi/security/SystemAccessControl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,9 +959,9 @@ default void checkCanSetEntityAuthorization(SystemSecurityContext context, Entit
959959
}
960960
checkCanSetTableAuthorization(context, new CatalogSchemaTableName(name.get(0), name.get(1), name.get(2)), principal);
961961
break;
962-
case "VIEW":
962+
case "VIEW", "MATERIALIZED VIEW":
963963
if (name.size() != 3) {
964-
throw new TrinoException(StandardErrorCode.INVALID_ARGUMENTS, "The view name %s must have three elements".formatted(name));
964+
throw new TrinoException(StandardErrorCode.INVALID_ARGUMENTS, "The %s name %s must have three elements".formatted(kind.toLowerCase(Locale.ROOT), name));
965965
}
966966
checkCanSetViewAuthorization(context, new CatalogSchemaTableName(name.get(0), name.get(1), name.get(2)), principal);
967967
break;

lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedSystemAccessControl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ public void checkCanSetEntityAuthorization(SystemSecurityContext context, Entity
11001100
CatalogSchemaName schema = new CatalogSchemaName(name.get(0), name.get(1));
11011101
denied = !isSchemaOwner(context, schema) || !checkCanSetAuthorization(context, principal);
11021102
break;
1103-
case "TABLE", "VIEW":
1103+
case "TABLE", "VIEW", "MATERIALIZED VIEW":
11041104
CatalogSchemaTableName table = new CatalogSchemaTableName(name.get(0), name.get(1), name.get(2));
11051105
denied = !checkTablePermission(context, table, OWNERSHIP) || !checkCanSetAuthorization(context, principal);
11061106
break;

0 commit comments

Comments
 (0)