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

Support CREATE ROLE and DROP ROLE #598

Merged
merged 6 commits into from Sep 27, 2022
Merged

Support CREATE ROLE and DROP ROLE #598

merged 6 commits into from Sep 27, 2022

Conversation

blx
Copy link
Contributor

@blx blx commented Sep 1, 2022

Adds some support for parsing CREATE ROLE and DROP ROLE.

CREATE ROLE varies considerably across dialects:

Not yet handled:

  • optional parameters for Clickhouse or Oracle
  • I haven't looked at other dialects beyond that

@coveralls
Copy link

coveralls commented Sep 1, 2022

Pull Request Test Coverage Report for Build 2969593123

  • 269 of 329 (81.76%) changed or added relevant lines in 6 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.1%) to 85.411%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tests/sqlparser_postgres.rs 58 61 95.08%
src/ast/mod.rs 44 69 63.77%
src/parser.rs 117 149 78.52%
Totals Coverage Status
Change from base Build 2957846519: -0.1%
Covered Lines: 9941
Relevant Lines: 11639

💛 - Coveralls

}
}
Keyword::IN => {
if self.parse_keyword(Keyword::ROLE) || self.parse_keyword(Keyword::GROUP) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IN GROUP is an obsolete spelling of IN ROLE.

(postgres docs)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the typical pattern in sqlparser is that we parse the sql as provided into an AST that could recover the same pattern rather than applying semantic meaning

So in this case, can you please change CreateRole to have an explicit group: Option<Ident> rather than reusing in_role?

The same comment applies to Role/User

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is my proposal: #628

self.expected("ROLE or GROUP after IN", self.peek_token())
}
}
Keyword::ROLE | Keyword::USER => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The USER clause is an obsolete spelling of the ROLE clause.

(postgres docs)

Copy link
Collaborator

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great @blx -- thank you for the contribution; There is one bug I think but I will provide a follow on PR to fix it.

let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let names = self.parse_comma_separated(Parser::parse_object_name)?;

let _ = self.parse_keyword(Keyword::WITH);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As written this ignores errors. I think it should be

Suggested change
let _ = self.parse_keyword(Keyword::WITH);
self.parse_keyword(Keyword::WITH)?;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry -- I misunderstood this code. It actually skips the optional WITH clause. Added a PR with a test #627

}
}
Keyword::IN => {
if self.parse_keyword(Keyword::ROLE) || self.parse_keyword(Keyword::GROUP) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the typical pattern in sqlparser is that we parse the sql as provided into an AST that could recover the same pattern rather than applying semantic meaning

So in this case, can you please change CreateRole to have an explicit group: Option<Ident> rather than reusing in_role?

The same comment applies to Role/User

Comment on lines +1062 to +1071
login: Option<bool>,
inherit: Option<bool>,
bypassrls: Option<bool>,
password: Option<Password>,
superuser: Option<bool>,
create_db: Option<bool>,
create_role: Option<bool>,
replication: Option<bool>,
connection_limit: Option<Expr>,
valid_until: Option<Expr>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One downside with this implementation is that the order of the grants is not preserved and thus the original SQL can not be reconstructed

What do you think about an alternate encoding like:

...
role_grants: Vec<RoleGrant>
...

And then

enum RoleGrant {
  Login, 
  Inherit,
  Password(Password)
   ..
}

However, I see this PR follows the model of GRANT so I think it is also fine as is

vec!["browser"],
grantees.iter().map(ToString::to_string).collect::<Vec<_>>()
);
assert_eq_vec(&["public"], &schemas);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you -- this is much nicer

@alamb alamb merged commit 91087fc into sqlparser-rs:main Sep 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants