-
Notifications
You must be signed in to change notification settings - Fork 567
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
Postgres: support for OWNER TO
clause
#1314
Conversation
OWNER TO
clauseOWNER TO
clause
3edc55b
to
6076c2d
Compare
src/ast/ddl.rs
Outdated
|
||
/// `OWNER TO { <new_owner> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }` | ||
/// | ||
/// Note: this is a PostgreSQL-specific operation. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
pub enum Owner { | ||
Ident(Ident), | ||
Expr(Expr), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
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
I think it would be better to maintain this compatibility.
Additionally, CURRENT_ROLE
must also be considered.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
src/parser/mod.rs
Outdated
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 25d6a40
src/parser/mod.rs
Outdated
{ | ||
let next_token = self.next_token(); | ||
let new_owner = match next_token.token { | ||
Token::DoubleQuotedString(ref s) => Owner::Ident(Ident::new(s.to_string())), |
There was a problem hiding this comment.
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()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in 0ff17d7
Pull Request Test Coverage Report for Build 9838925240Details
💛 - Coveralls |
src/parser/mod.rs
Outdated
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}"))) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM!
No worries -- thank you for the contribution @gainings and I apologize for my late review / update. |
Support
OWNER TO
clause just for Postgres dialectCloses #1293