Skip to content

Commit

Permalink
Introduce CREATE ROLE and DROP ROLE statements
Browse files Browse the repository at this point in the history
Extracted-From: prestodb/presto#10904
  • Loading branch information
Andrii Rosa authored and sopel39 committed Jan 29, 2019
1 parent eb7f677 commit 42ba503
Show file tree
Hide file tree
Showing 11 changed files with 604 additions and 5 deletions.
1 change: 1 addition & 0 deletions presto-docs/src/main/sphinx/language/reserved.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Keyword SQL:2016 SQL-92
``CUBE`` reserved
``CURRENT_DATE`` reserved reserved
``CURRENT_PATH`` reserved
``CURRENT_ROLE`` reserved reserved
``CURRENT_TIME`` reserved reserved
``CURRENT_TIMESTAMP`` reserved reserved
``CURRENT_USER`` reserved
Expand Down
26 changes: 23 additions & 3 deletions presto-parser/src/main/antlr4/io/prestosql/sql/parser/SqlBase.g4
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ statement
(SECURITY (DEFINER | INVOKER))? AS query #createView
| DROP VIEW (IF EXISTS)? qualifiedName #dropView
| CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')' #call
| CREATE ROLE name=identifier
(WITH ADMIN grantor)?
(IN catalog=identifier)? #createRole
| DROP ROLE name=identifier (IN catalog=identifier)? #dropRole
| GRANT
(privilege (',' privilege)* | ALL PRIVILEGES)
ON TABLE? qualifiedName TO grantee=identifier
Expand Down Expand Up @@ -437,6 +441,18 @@ qualifiedName
: identifier ('.' identifier)*
;

grantor
: principal #specifiedPrincipal
| CURRENT_USER #currentUserGrantor
| CURRENT_ROLE #currentRoleGrantor
;

principal
: identifier #unspecifiedPrincipal
| USER identifier #userPrincipal
| ROLE identifier #rolePrincipal
;

identifier
: IDENTIFIER #unquotedIdentifier
| QUOTED_IDENTIFIER #quotedIdentifier
Expand All @@ -453,7 +469,7 @@ number

nonReserved
// IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved
: ADD | ALL | ANALYZE | ANY | ARRAY | ASC | AT
: ADD | ADMIN | ALL | ANALYZE | ANY | ARRAY | ASC | AT
| BERNOULLI
| CALL | CASCADE | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | CURRENT
| DATA | DATE | DAY | DEFINER | DESC | DISTRIBUTED
Expand All @@ -468,18 +484,19 @@ nonReserved
| NFC | NFD | NFKC | NFKD | NO | NULLIF | NULLS
| ONLY | OPTION | ORDINALITY | OUTPUT | OVER
| PARTITION | PARTITIONS | PATH | POSITION | PRECEDING | PRIVILEGES | PROPERTIES
| RANGE | READ | RENAME | REPEATABLE | REPLACE | RESET | RESTRICT | REVOKE | ROLLBACK | ROW | ROWS
| RANGE | READ | RENAME | REPEATABLE | REPLACE | RESET | RESTRICT | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS
| SCHEMA | SCHEMAS | SECOND | SECURITY | SERIALIZABLE | SESSION | SET | SETS
| SHOW | SOME | START | STATS | SUBSTRING | SYSTEM
| TABLES | TABLESAMPLE | TEXT | TIME | TIMESTAMP | TO | TRANSACTION | TRY_CAST | TYPE
| UNBOUNDED | UNCOMMITTED | USE
| UNBOUNDED | UNCOMMITTED | USE | USER
| VALIDATE | VERBOSE | VIEW
| WORK | WRITE
| YEAR
| ZONE
;

ADD: 'ADD';
ADMIN: 'ADMIN';
ALL: 'ALL';
ALTER: 'ALTER';
ANALYZE: 'ANALYZE';
Expand Down Expand Up @@ -509,6 +526,7 @@ CUBE: 'CUBE';
CURRENT: 'CURRENT';
CURRENT_DATE: 'CURRENT_DATE';
CURRENT_PATH: 'CURRENT_PATH';
CURRENT_ROLE: 'CURRENT_ROLE';
CURRENT_TIME: 'CURRENT_TIME';
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';
CURRENT_USER: 'CURRENT_USER';
Expand Down Expand Up @@ -613,6 +631,7 @@ RESET: 'RESET';
RESTRICT: 'RESTRICT';
REVOKE: 'REVOKE';
RIGHT: 'RIGHT';
ROLE: 'ROLE';
ROLLBACK: 'ROLLBACK';
ROLLUP: 'ROLLUP';
ROW: 'ROW';
Expand Down Expand Up @@ -650,6 +669,7 @@ UNCOMMITTED: 'UNCOMMITTED';
UNION: 'UNION';
UNNEST: 'UNNEST';
USE: 'USE';
USER: 'USER';
USING: 'USING';
VALIDATE: 'VALIDATE';
VALUES: 'VALUES';
Expand Down
55 changes: 55 additions & 0 deletions presto-parser/src/main/java/io/prestosql/sql/SqlFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.prestosql.sql.tree.CallArgument;
import io.prestosql.sql.tree.ColumnDefinition;
import io.prestosql.sql.tree.Commit;
import io.prestosql.sql.tree.CreateRole;
import io.prestosql.sql.tree.CreateSchema;
import io.prestosql.sql.tree.CreateTable;
import io.prestosql.sql.tree.CreateTableAsSelect;
Expand All @@ -32,6 +33,7 @@
import io.prestosql.sql.tree.DescribeInput;
import io.prestosql.sql.tree.DescribeOutput;
import io.prestosql.sql.tree.DropColumn;
import io.prestosql.sql.tree.DropRole;
import io.prestosql.sql.tree.DropSchema;
import io.prestosql.sql.tree.DropTable;
import io.prestosql.sql.tree.DropView;
Expand All @@ -43,6 +45,7 @@
import io.prestosql.sql.tree.ExplainType;
import io.prestosql.sql.tree.Expression;
import io.prestosql.sql.tree.Grant;
import io.prestosql.sql.tree.GrantorSpecification;
import io.prestosql.sql.tree.Identifier;
import io.prestosql.sql.tree.Insert;
import io.prestosql.sql.tree.Intersect;
Expand All @@ -57,6 +60,7 @@
import io.prestosql.sql.tree.Node;
import io.prestosql.sql.tree.OrderBy;
import io.prestosql.sql.tree.Prepare;
import io.prestosql.sql.tree.PrincipalSpecification;
import io.prestosql.sql.tree.Property;
import io.prestosql.sql.tree.QualifiedName;
import io.prestosql.sql.tree.Query;
Expand Down Expand Up @@ -872,6 +876,34 @@ private String formatColumnDefinition(ColumnDefinition column)
formatPropertiesSingleLine(column.getProperties());
}

private static String formatGrantor(GrantorSpecification grantor)
{
GrantorSpecification.Type type = grantor.getType();
switch (type) {
case CURRENT_ROLE:
case CURRENT_USER:
return type.name();
case PRINCIPAL:
return formatPrincipal(grantor.getPrincipal().get());
default:
throw new IllegalArgumentException("Unsupported principal type: " + type);
}
}

private static String formatPrincipal(PrincipalSpecification principal)
{
PrincipalSpecification.Type type = principal.getType();
switch (type) {
case UNSPECIFIED:
return principal.getName().toString();
case USER:
case ROLE:
return format("%s %s", type.name(), principal.getName().toString());
default:
throw new IllegalArgumentException("Unsupported principal type: " + type);
}
}

@Override
protected Void visitDropTable(DropTable node, Integer context)
{
Expand Down Expand Up @@ -1061,6 +1093,29 @@ protected Void visitRollback(Rollback node, Integer context)
return null;
}

@Override
protected Void visitCreateRole(CreateRole node, Integer context)
{
builder.append("CREATE ROLE ").append(node.getName());
if (node.getGrantor().isPresent()) {
builder.append(" WITH ADMIN ").append(formatGrantor(node.getGrantor().get()));
}
if (node.getCatalog().isPresent()) {
builder.append(" IN ").append(node.getCatalog().get());
}
return null;
}

@Override
protected Void visitDropRole(DropRole node, Integer context)
{
builder.append("DROP ROLE ").append(node.getName());
if (node.getCatalog().isPresent()) {
builder.append(" IN ").append(node.getCatalog().get());
}
return null;
}

@Override
public Void visitGrant(Grant node, Integer indent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.prestosql.sql.tree.ColumnDefinition;
import io.prestosql.sql.tree.Commit;
import io.prestosql.sql.tree.ComparisonExpression;
import io.prestosql.sql.tree.CreateRole;
import io.prestosql.sql.tree.CreateSchema;
import io.prestosql.sql.tree.CreateTable;
import io.prestosql.sql.tree.CreateTableAsSelect;
Expand All @@ -50,6 +51,7 @@
import io.prestosql.sql.tree.DescribeOutput;
import io.prestosql.sql.tree.DoubleLiteral;
import io.prestosql.sql.tree.DropColumn;
import io.prestosql.sql.tree.DropRole;
import io.prestosql.sql.tree.DropSchema;
import io.prestosql.sql.tree.DropTable;
import io.prestosql.sql.tree.DropView;
Expand All @@ -66,6 +68,7 @@
import io.prestosql.sql.tree.FunctionCall;
import io.prestosql.sql.tree.GenericLiteral;
import io.prestosql.sql.tree.Grant;
import io.prestosql.sql.tree.GrantorSpecification;
import io.prestosql.sql.tree.GroupBy;
import io.prestosql.sql.tree.GroupingElement;
import io.prestosql.sql.tree.GroupingOperation;
Expand Down Expand Up @@ -102,6 +105,7 @@
import io.prestosql.sql.tree.PathElement;
import io.prestosql.sql.tree.PathSpecification;
import io.prestosql.sql.tree.Prepare;
import io.prestosql.sql.tree.PrincipalSpecification;
import io.prestosql.sql.tree.Property;
import io.prestosql.sql.tree.QualifiedName;
import io.prestosql.sql.tree.QuantifiedComparisonExpression;
Expand Down Expand Up @@ -814,6 +818,25 @@ public Node visitResetSession(SqlBaseParser.ResetSessionContext context)
return new ResetSession(getLocation(context), getQualifiedName(context.qualifiedName()));
}

@Override
public Node visitCreateRole(SqlBaseParser.CreateRoleContext context)
{
return new CreateRole(
getLocation(context),
(Identifier) visit(context.name),
getGrantorSpecificationIfPresent(context.grantor()),
getIdentifierIfPresent(context.catalog));
}

@Override
public Node visitDropRole(SqlBaseParser.DropRoleContext context)
{
return new DropRole(
getLocation(context),
(Identifier) visit(context.name),
getIdentifierIfPresent(context.catalog));
}

@Override
public Node visitGrant(SqlBaseParser.GrantContext context)
{
Expand Down Expand Up @@ -1875,6 +1898,11 @@ private static Optional<String> getTextIfPresent(Token token)
.map(Token::getText);
}

private Optional<Identifier> getIdentifierIfPresent(ParserRuleContext context)
{
return Optional.ofNullable(context).map(c -> (Identifier) visit(c));
}

private static ArithmeticBinaryExpression.Operator getArithmeticBinaryOperator(Token operator)
{
switch (operator.getType()) {
Expand Down Expand Up @@ -2121,6 +2149,43 @@ private String typeParameterToString(SqlBaseParser.TypeParameterContext typePara
throw new IllegalArgumentException("Unsupported typeParameter: " + typeParameter.getText());
}

private Optional<GrantorSpecification> getGrantorSpecificationIfPresent(SqlBaseParser.GrantorContext context)
{
return Optional.ofNullable(context).map(this::getGrantorSpecification);
}

private GrantorSpecification getGrantorSpecification(SqlBaseParser.GrantorContext context)
{
if (context instanceof SqlBaseParser.SpecifiedPrincipalContext) {
return new GrantorSpecification(GrantorSpecification.Type.PRINCIPAL, Optional.of(getPrincipalSpecification(((SqlBaseParser.SpecifiedPrincipalContext) context).principal())));
}
else if (context instanceof SqlBaseParser.CurrentUserGrantorContext) {
return new GrantorSpecification(GrantorSpecification.Type.CURRENT_USER, Optional.empty());
}
else if (context instanceof SqlBaseParser.CurrentRoleGrantorContext) {
return new GrantorSpecification(GrantorSpecification.Type.CURRENT_ROLE, Optional.empty());
}
else {
throw new IllegalArgumentException("Unsupported grantor: " + context);
}
}

private PrincipalSpecification getPrincipalSpecification(SqlBaseParser.PrincipalContext context)
{
if (context instanceof SqlBaseParser.UnspecifiedPrincipalContext) {
return new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, (Identifier) visit(((SqlBaseParser.UnspecifiedPrincipalContext) context).identifier()));
}
else if (context instanceof SqlBaseParser.UserPrincipalContext) {
return new PrincipalSpecification(PrincipalSpecification.Type.USER, (Identifier) visit(((SqlBaseParser.UserPrincipalContext) context).identifier()));
}
else if (context instanceof SqlBaseParser.RolePrincipalContext) {
return new PrincipalSpecification(PrincipalSpecification.Type.ROLE, (Identifier) visit(((SqlBaseParser.RolePrincipalContext) context).identifier()));
}
else {
throw new IllegalArgumentException("Unsupported principal: " + context);
}
}

private static void check(boolean condition, String message, ParserRuleContext context)
{
if (!condition) {
Expand Down
10 changes: 10 additions & 0 deletions presto-parser/src/main/java/io/prestosql/sql/tree/AstVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,16 @@ protected R visitStartTransaction(StartTransaction node, C context)
return visitStatement(node, context);
}

protected R visitCreateRole(CreateRole node, C context)
{
return visitStatement(node, context);
}

protected R visitDropRole(DropRole node, C context)
{
return visitStatement(node, context);
}

protected R visitGrant(Grant node, C context)
{
return visitStatement(node, context);
Expand Down
Loading

0 comments on commit 42ba503

Please sign in to comment.