Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,19 +298,30 @@ impl fmt::Display for SetQuantifier {
/// A [`TABLE` command](https://www.postgresql.org/docs/current/sql-select.html#SQL-TABLE)
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Table {
/// `ONLY` modifier before the table name.
pub only: bool,
/// Optional table name (absent for e.g. `TABLE` command without argument).
pub table_name: Option<Ident>,
/// Optional schema/catalog name qualifying the table.
pub schema_name: Option<Ident>,
/// Trailing `*` modifier after the table name.
pub with_asterisk: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should name this field has_asterisk to follow pre-existing standard.

Suggested change
pub with_asterisk: bool,
pub has_asterisk: bool,

}

impl fmt::Display for Table {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref table_name) = self.table_name {
write!(f, "TABLE ")?;
if self.only {
write!(f, "ONLY ")?;
}
if let Some(ref schema_name) = self.schema_name {
write!(f, "TABLE {}.{}", schema_name, table_name,)?;
write!(f, "{}.{}", schema_name, table_name,)?;
} else {
write!(f, "TABLE {}", table_name)?;
write!(f, "{}", table_name)?;
}
if self.with_asterisk {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should follow the has_asterisk rename here.

Suggested change
if self.with_asterisk {
if self.has_asterisk {

write!(f, " *")?;
}
} else {
write!(f, "TABLE")?;
Expand Down
21 changes: 19 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,11 @@ impl<'a> Parser<'a> {
self.prev_token();
self.parse_raise_stmt().map(Into::into)
}
Keyword::SELECT | Keyword::WITH | Keyword::VALUES | Keyword::FROM => {
Keyword::SELECT
| Keyword::TABLE
| Keyword::WITH
| Keyword::VALUES
| Keyword::FROM => {
self.prev_token();
self.parse_query().map(Into::into)
}
Expand Down Expand Up @@ -14496,7 +14500,15 @@ impl<'a> Parser<'a> {
}
}

match self.maybe_parse(|parser| parser.parse_statement())? {
let statement = if self.dialect.describe_requires_table_keyword()
&& self.peek_keyword(Keyword::TABLE)
{
None
} else {
self.maybe_parse(|parser| parser.parse_statement())?
};

match statement {
Some(Statement::Explain { .. }) | Some(Statement::ExplainTable { .. }) => Err(
ParserError::ParserError("Explain must be root of the plan".to_string()),
),
Expand Down Expand Up @@ -15625,17 +15637,22 @@ impl<'a> Parser<'a> {

/// Parse `CREATE TABLE x AS TABLE y`
pub fn parse_as_table(&mut self) -> Result<Table, ParserError> {
let only = self.parse_keyword(Keyword::ONLY);
let first_name = self.parse_identifier()?;
if self.consume_token(&Token::Period) {
let second_name = self.parse_identifier()?;
Ok(Table {
only,
table_name: Some(second_name),
schema_name: Some(first_name),
with_asterisk: self.consume_token(&Token::Mul),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should follow the has_asterisk rename here.

Suggested change
with_asterisk: self.consume_token(&Token::Mul),
has_asterisk: self.consume_token(&Token::Mul),

})
} else {
Ok(Table {
only,
table_name: Some(first_name),
schema_name: None,
with_asterisk: self.consume_token(&Token::Mul),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should follow the has_asterisk rename here.

Suggested change
with_asterisk: self.consume_token(&Token::Mul),
has_asterisk: self.consume_token(&Token::Mul),

})
}
}
Expand Down
60 changes: 60 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4848,8 +4848,10 @@ fn parse_create_table_as_table() {
let expected_query1 = Box::new(Query {
with: None,
body: Box::new(SetExpr::Table(Box::new(Table {
only: false,
Comment thread
BenSatori marked this conversation as resolved.
table_name: Some(Ident::new("old_table")),
schema_name: None,
with_asterisk: false,
}))),
order_by: None,
limit_clause: None,
Expand All @@ -4874,8 +4876,10 @@ fn parse_create_table_as_table() {
let expected_query2 = Box::new(Query {
with: None,
body: Box::new(SetExpr::Table(Box::new(Table {
only: false,
table_name: Some(Ident::new("old_table")),
schema_name: Some(Ident::new("schema_name")),
with_asterisk: false,
}))),
order_by: None,
limit_clause: None,
Expand All @@ -4894,6 +4898,62 @@ fn parse_create_table_as_table() {
}
_ => unreachable!(),
}

let sql3 = "CREATE TABLE new_table AS TABLE ONLY old_table";

let expected_query3 = Box::new(Query {
with: None,
body: Box::new(SetExpr::Table(Box::new(Table {
only: true,
table_name: Some(Ident::new("old_table")),
schema_name: None,
with_asterisk: false,
}))),
order_by: None,
limit_clause: None,
fetch: None,
locks: vec![],
for_clause: None,
settings: None,
format_clause: None,
pipe_operators: vec![],
});

match verified_stmt(sql3) {
Statement::CreateTable(CreateTable { query, name, .. }) => {
assert_eq!(name, ObjectName::from(vec![Ident::new("new_table")]));
assert_eq!(query.unwrap(), expected_query3);
}
_ => unreachable!(),
}

let sql4 = "CREATE TABLE new_table AS TABLE old_table *";

let expected_query4 = Box::new(Query {
with: None,
body: Box::new(SetExpr::Table(Box::new(Table {
only: false,
table_name: Some(Ident::new("old_table")),
schema_name: None,
with_asterisk: true,
}))),
order_by: None,
limit_clause: None,
fetch: None,
locks: vec![],
for_clause: None,
settings: None,
format_clause: None,
pipe_operators: vec![],
});

match verified_stmt(sql4) {
Statement::CreateTable(CreateTable { query, name, .. }) => {
assert_eq!(name, ObjectName::from(vec![Ident::new("new_table")]));
assert_eq!(query.unwrap(), expected_query4);
}
_ => unreachable!(),
}
}

#[test]
Expand Down
7 changes: 7 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10037,3 +10037,10 @@ fn parse_bitstring_literal_escaping() {
pg_and_generic().verified_stmt("SELECT B''''");
pg_and_generic().verified_stmt("SELECT B'it''s'");
}

#[test]
fn parse_table_command() {
pg_and_generic().verified_stmt("TABLE customers ORDER BY contact_name LIMIT 1");
pg_and_generic().verified_stmt("TABLE ONLY customers");
pg_and_generic().verified_stmt("TABLE customers *");
}
Loading