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

Handle Postgres schema name for sea-query statements #385

Merged
merged 14 commits into from
Aug 7, 2022
Merged

Handle Postgres schema name for sea-query statements #385

merged 14 commits into from
Aug 7, 2022

Conversation

nahuakang
Copy link
Contributor

@nahuakang nahuakang commented Jul 16, 2022

PR Info

Fixes

This should enable SchemaManager in sea-orm-migration to inject table reference & schema information for Postgres.

@nahuakang nahuakang changed the title Handle Postgres schema name for sea-query statements [WIP] Handle Postgres schema name for sea-query statements Jul 16, 2022
@nahuakang
Copy link
Contributor Author

@billy1624 @ikrivosheev 👋 Hey guys, I've made some adjustments to all table-related statements used by SchemaManager:

  • TableCreateStatement
  • TableAlterStatement
  • TableDropStatement
  • TableRenameStatement
  • TableTruncateStatement

Then, I made some changes for index-related statements for SchemaManager (including a copy-paste, which I wonder if it's okay to do so):

  • IndexCreateStatement
  • IndexDropStatement

Is this going in the right direction? The remaining are the ForeignKey and Type related statements.

@billy1624 You mentioned:

Also, some statement support schema scope, for example, type name could have schema prefix e.g. in Postgres. We can update it from Iden to IdenList.

I'm still not sure where to find this in the code base :D Can you give some more hints? 🙏

Copy link
Member

@ikrivosheev ikrivosheev left a comment

Choose a reason for hiding this comment

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

@nahuakang thank you for PR! Some comments...

src/backend/sqlite/table.rs Outdated Show resolved Hide resolved
@ikrivosheev
Copy link
Member

ikrivosheev commented Jul 17, 2022

I'm still not sure where to find this in the code base :D Can you give some more hints? pray

@nahuakang I think @billy1624 mean: https://github.com/SeaQL/sea-query/blob/master/src/extension/postgres/types.rs

@nahuakang
Copy link
Contributor Author

@billy1624 Besides the question on Type, do we need to change the table from Option<DynIden> to Option<TableRef> for both ForeignKeyDropStatement and TableForeignKey (even if the former contains the latter and thus contains TableRef)?

pub struct ForeignKeyDropStatement {
    pub(crate) foreign_key: TableForeignKey,
    pub(crate) table: Option<DynIden>,
}

#[derive(Debug, Clone)]
pub struct TableForeignKey {
    pub(crate) name: Option<String>,
    pub(crate) table: Option<DynIden>,
    pub(crate) ref_table: Option<DynIden>,
    pub(crate) columns: Vec<DynIden>,
    pub(crate) ref_columns: Vec<DynIden>,
    pub(crate) on_delete: Option<ForeignKeyAction>,
    pub(crate) on_update: Option<ForeignKeyAction>,
}

And is it safe to assume that schema can be prepended to the table names in any statement involving creating & dropping foreign keys (both the from and to tables)? Thanks :)

@billy1624
Copy link
Member

@billy1624
Copy link
Member

Do we need to change the table from Option<DynIden> to Option<TableRef> for both ForeignKeyDropStatement and TableForeignKey (even if the former contains the latter and thus contains TableRef)?

Yes, we should change both to Option<TableRef>

And is it safe to assume that schema can be prepended to the table names in any statement involving creating & dropping foreign keys (both the from and to tables)? Thanks :)

This assumption is valid :)

@nahuakang nahuakang changed the title [WIP] Handle Postgres schema name for sea-query statements Handle Postgres schema name for sea-query statements Jul 20, 2022
@nahuakang nahuakang marked this pull request as ready for review July 20, 2022 19:52
@tyt2y3
Copy link
Member

tyt2y3 commented Jul 23, 2022

Thank you for the hard work! My question is why do we needed TypeRef in addition to TableRef?
It seems like TypeRef a subset of TableRef's variants.
And so, we can either reuse TableRef or make TypeRef more similar to TableRef, I mean having three variants, Name, SchemaName and DatabaseSchemaName?

Copy link
Member

@ikrivosheev ikrivosheev left a comment

Choose a reason for hiding this comment

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

@nahuakang thank you for PR! Some comments

src/backend/index_builder.rs Outdated Show resolved Hide resolved
src/types.rs Outdated Show resolved Hide resolved
@nahuakang
Copy link
Contributor Author

@tyt2y3 Thanks for your review :) I think we shouldn't reuse TableRef since we need a specific way to mark a type name that might be schema-qualified.

If we must have consistency between TabelRef and TypeRef, perhaps we could do the following (and adjust the IntoTypeRef implementations as well as the prepare_type_ref for TypeBuilder? (wdyt @ikrivosheev since Ivan came up with TypeRef?)

#[derive(Debug, Clone)]
pub enum TypeRef {
    Type(DynIden),
    SchemaType(DynIden, DynIden),
    DatabaseSchemaType(DynIden, DynIden, DynIden),
}

@ikrivosheev
Copy link
Member

Thank you for the hard work! My question is why do we needed TypeRef in addition to TableRef? It seems like TypeRef a subset of TableRef's variants. And so, we can either reuse TableRef or make TypeRef more similar to TableRef, I mean having three variants, Name, SchemaName and DatabaseSchemaName?

This was my idea. We don't need all the options from TableRef and this solution looks more type-safe then panic with invalid option

@nahuakang nahuakang requested a review from ikrivosheev July 23, 2022 11:55
Comment on lines 89 to 95
TableRef::DatabaseSchemaTable(database, schema, table) => {
database.prepare(sql, self.quote());
write!(sql, ".").unwrap();
schema.prepare(sql, self.quote());
write!(sql, ".").unwrap();
table.prepare(sql, self.quote());
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can create index across database? i.e.

CREATE INDEX idx_aaa 
ON aaa.public.accounts (password); # `public.accounts` is valid but not `aaa.public.accounts`

https://dbfiddle.uk/?rdbms=postgres_14&fiddle=67b77e58c1c524174d1675ff92511e2d

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was removed :) Thanks for catching this. I think I probably missed testing this in my test DB 🙏

Copy link
Member

@billy1624 billy1624 left a comment

Choose a reason for hiding this comment

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

Hey @nahuakang, all in all it looks good!
Thanks @nahuakang @ikrivosheev for the contrition and help :D

@nahuakang nahuakang requested a review from billy1624 July 25, 2022 09:42
Copy link
Member

@ikrivosheev ikrivosheev left a comment

Choose a reason for hiding this comment

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

@nahuakang thank you! LGMT!

@billy1624 billy1624 self-assigned this Aug 6, 2022
Copy link
Member

@billy1624 billy1624 left a comment

Choose a reason for hiding this comment

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

Hey @nahuakang, sorry for the long delay. I think we can refactor it by adding a TableRefBuilder trait. To handle the writing of TableRef as SQL string. From my perspective that looks cleaner and we don't need to repeat same piece of code again and again.

Please check if that make any sense :)
Thanks!!

@nahuakang
Copy link
Contributor Author

nahuakang commented Aug 6, 2022

@billy1624 This refactoring makes perfect sense and is a lot cleaner for the hierarchy of the trait requirements. Hope it's okay that I merge it into my branch? :)

Add TableRefBuilder trait (credit to Billy)
@tyt2y3
Copy link
Member

tyt2y3 commented Aug 6, 2022

Thank you for your patience and diligence!

@tyt2y3 tyt2y3 merged commit 5fd27af into SeaQL:master Aug 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

sea-query statements should qualify schema name
4 participants