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

Postgres: support for OWNER TO clause #1314

Merged
merged 15 commits into from
Jul 9, 2024

Conversation

gainings
Copy link
Contributor

@gainings gainings commented Jun 15, 2024

Support OWNER TO clause just for Postgres dialect
Closes #1293

@gainings gainings changed the title BigQuery: support for OWNER TO clause Postgres: support for OWNER TO clause Jun 15, 2024
@gainings gainings marked this pull request as ready for review June 15, 2024 14:24
@gainings gainings force-pushed the postgres-add-alter-table-owner-to branch from 3edc55b to 6076c2d Compare June 17, 2024 11:42
src/ast/ddl.rs Outdated

/// `OWNER TO { <new_owner> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
///
/// Note: this is a PostgreSQL-specific operation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we include a link to the docs for the feature? I think it'd be this one https://www.postgresql.org/docs/current/sql-altertable.html

Copy link
Contributor

Choose a reason for hiding this comment

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

done in a3a4996

src/ast/ddl.rs Outdated
Comment on lines 170 to 173
pub enum Owner {
Ident(Ident),
Expr(Expr),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pub enum Owner {
Ident(Ident),
Expr(Expr),
}
pub enum Owner {
Ident(Ident),
CurrentRole,
CurrentUser
SessionUser
}

I'm thinking the Expr might be somewhat opaque to represent the others, from the docs the other variants seem enumerable so figured we can represent them verbatim in the enum as above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@iffyio Thanks for the review!

Currently CURRENT_USER, and SESSION_USER are supported as Expr::Function like this.

2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] Parsing sql 'SELECT CURRENT_USER, CURRENT_ROLE, SESSION_USER;
'...
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] parsing expr
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] prefix: Function(Function { name: ObjectName([Ident { value: "CURRENT_USER", quote_style: None }]), args: None, filter: None, null_treatment: None, over: None, within_group: [] })
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: Comma, location: Location { line: 1, column: 20 } }
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] 0: , 1: CURRENT_ROLE 2: ,
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] next precedence: 0
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] parsing expr
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] prefix: Identifier(Ident { value: "CURRENT_ROLE", quote_style: None })
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: Comma, location: Location { line: 1, column: 34 } }
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] 0: , 1: SESSION_USER 2: ;
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] next precedence: 0
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] parsing expr
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] prefix: Function(Function { name: ObjectName([Ident { value: "SESSION_USER", quote_style: None }]), args: None, filter: None, null_treatment: None, over: None, within_group: [] })
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: SemiColon, location: Location { line: 1, column: 48 } }
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] 0: ; 1: EOF 2: EOF
2024-06-22T13:04:10.639Z DEBUG [sqlparser::parser] next precedence: 0

https://github.com/sqlparser-rs/sqlparser-rs/blob/f16c1afed0fa273228e74a633f3885c9c6609911/src/parser/mod.rs#L998-L1010

I think it would be better to maintain this compatibility.

Additionally, CURRENT_ROLE must also be considered.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see, I think it makes a lot of sense to represent them as functions when parsing arbitrary expressions - when parsing an Owner however, spontaneously doesn't feel the same since the context is much more restricted. Thinking here we can be explicit about what comes out of the parser which would be desirable from an API pov.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree it is better to be explicit and match the allowed postgres syntax more exactly. I double checked https://www.postgresql.org/docs/current/sql-altertable.html and it says:

OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }

...
new_owner
The user name of the new owner of the table.

So I think @iffyio 's suggestion is a good one.

I took the liberty of making this change in 0ff17d7 as I am preparing for a sqlparser release

@@ -6274,6 +6274,30 @@ impl<'a> Parser<'a> {
self.expect_keyword(Keyword::WITH)?;
let table_name = self.parse_object_name(false)?;
AlterTableOperation::SwapWith { table_name }
} else if dialect_of!(self is PostgreSqlDialect)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else if dialect_of!(self is PostgreSqlDialect)
} else if dialect_of!(self is PostgreSqlDialect | GenericDialect)

if no conflicts we can include support for the generic dialect

Copy link
Contributor

Choose a reason for hiding this comment

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

Done in 25d6a40

{
let next_token = self.next_token();
let new_owner = match next_token.token {
Token::DoubleQuotedString(ref s) => Owner::Ident(Ident::new(s.to_string())),
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of having two separate cases (this DoubleQuotedString and NoKeyword below) to handle the ident variant, would it make sense to call parse_identifier if none of the other variants match?
so roughly

match self.parse_one_of_keywords(&[CURRENT_USER, CURRENT_ROLE, SESSION_USER]) {
    Some(CURRENT_USER) => {}
    ...
    _ =|> self.parse_identifier()
}

Copy link
Contributor

Choose a reason for hiding this comment

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

in 0ff17d7

@coveralls
Copy link

coveralls commented Jul 8, 2024

Pull Request Test Coverage Report for Build 9838925240

Details

  • 54 of 58 (93.1%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.007%) to 89.18%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/parser/mod.rs 13 14 92.86%
tests/sqlparser_postgres.rs 33 36 91.67%
Totals Coverage Status
Change from base Build 9838850938: 0.007%
Covered Lines: 26639
Relevant Lines: 29871

💛 - Coveralls

match self.parse_identifier(false) {
Ok(ident) => Owner::Ident(ident),
Err(e) => {
return Err(ParserError::ParserError(format!("Expected CURRENT_USER, CURRENT_ROLE, SESSION_USER or identifier after OWNER TO. {e}")))
Copy link
Contributor

Choose a reason for hiding this comment

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

Making sure the error message had some additional context was the only thing that I found awkward. Otherwise I think @iffyio 's suggestions made the code easier to understand and easier to use overall

Copy link
Contributor

@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.

@gainings and @iffyio if you have a moment to review the changes I made to this PR I would be most appreciative. I am hoping to get a sqlparser-rs release out tomorrow: #1296

Copy link
Contributor

@iffyio iffyio left a comment

Choose a reason for hiding this comment

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

Changes LGTM!

@alamb alamb merged commit 32b8276 into apache:main Jul 9, 2024
10 checks passed
@alamb
Copy link
Contributor

alamb commented Jul 9, 2024

Thanks again @gainings and @iffyio

@gainings
Copy link
Contributor Author

gainings commented Jul 9, 2024

Thank you for @alamb and @iffyio
And I apologize for the delayed response.

@alamb
Copy link
Contributor

alamb commented Jul 9, 2024

No worries -- thank you for the contribution @gainings and I apologize for my late review / update.

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.

Please support "alter table owner to" in Postgres
4 participants