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

feat: support INSERT INTO [TABLE] FUNCTION of Clickhouse #1633

Merged
merged 12 commits into from
Jan 10, 2025

Conversation

byte-sourcerer
Copy link
Contributor

Support INSERT INTO [TABLE] FUNCTION of Clickhouse.

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.

Thanks @byte-sourcerer!

src/ast/dml.rs Outdated
@@ -470,8 +470,7 @@ pub struct Insert {
/// INTO - optional keyword
pub into: bool,
/// TABLE
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub table_object: TableObject,
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 table_object: TableObject,
pub table: TableObject,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is already a field named table in this struct...

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah right, I didn't notice the existing table property. Looking at the description of that property it feels its naming isn't ideal, I'm thinking as a result we could take the opportunity to rename that one to e.g. has_table_keyword to free up the current one to be called table?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea!

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TableObject {
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 doc comment mentionign this is the target of an insert table statement? And then for the variants that it can either be a tablename or function with example SQL? That would make it easy for folks to get an overview of the struct without having to dig into the code or test out manually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

@@ -8857,6 +8857,23 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_table_object(
&mut self,
in_table_clause: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the in_table_clause flag needed? I imagine it'll always be false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

@@ -8857,6 +8857,23 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_table_object(
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a doc comment for this given its a public method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

&mut self,
in_table_clause: bool,
) -> Result<TableObject, ParserError> {
if dialect_of!(self is ClickHouseDialect) && self.parse_keyword(Keyword::FUNCTION) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use a dialect method for this? e.g.

if self.dialect.supports_function_table_objects() && self.parse_keyword(keyword::FUNCTION)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored.

Comment on lines 8872 to 8875
pub fn parse_table_function(&mut self) -> Result<Function, ParserError> {
let fn_name = self.parse_object_name(false)?;
self.parse_function_call(fn_name)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if its worth having this as a standalone method? It looks like it can be inlined given its only 2 LOC?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

@@ -222,6 +222,11 @@ fn parse_create_table() {
);
}

#[test]
fn parse_insert_into_function() {
clickhouse().verified_stmt(r#"INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table) VALUES (100, 'inserted via remote()')"#);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a similar test case without the TABLE keyword?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

@byte-sourcerer
Copy link
Contributor Author

byte-sourcerer commented Jan 8, 2025

@iffyio Thank you for your time. I have revised the PR according to your comments and hope you can review it.

src/ast/dml.rs Outdated
@@ -470,8 +470,7 @@ pub struct Insert {
/// INTO - optional keyword
pub into: bool,
/// TABLE
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub table_object: TableObject,
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah right, I didn't notice the existing table property. Looking at the description of that property it feels its naming isn't ideal, I'm thinking as a result we could take the opportunity to rename that one to e.g. has_table_keyword to free up the current one to be called table?

src/ast/mod.rs Outdated Show resolved Hide resolved
src/ast/mod.rs Outdated Show resolved Hide resolved
src/ast/mod.rs Outdated Show resolved Hide resolved
src/ast/mod.rs Outdated Show resolved Hide resolved
src/dialect/mod.rs Outdated Show resolved Hide resolved
@byte-sourcerer
Copy link
Contributor Author

Hi @iffyio, I have revised the PR. Could you please review it again?

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.

LGTM! Thanks @byte-sourcerer!
cc @alamb

@iffyio
Copy link
Contributor

iffyio commented Jan 9, 2025

@byte-sourcerer could you take a look when you get the chance to resolve the conflicts on the branch

@byte-sourcerer
Copy link
Contributor Author

@byte-sourcerer could you take a look when you get the chance to resolve the conflicts on the branch

Resolved.

@iffyio iffyio merged commit b09514e into apache:main Jan 10, 2025
9 checks passed
@byte-sourcerer byte-sourcerer deleted the insert-into-function branch January 11, 2025 02:41
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.

2 participants