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
8 changes: 6 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11028,8 +11028,12 @@ impl<'a> Parser<'a> {
legacy_options.push(opt);
}
let values = if let CopyTarget::Stdin = target {
self.expect_token(&Token::SemiColon)?;
self.parse_tsv()
if self.peek_token_ref().token == Token::EOF {
vec![]
} else {
self.expect_token(&Token::SemiColon)?;
self.parse_tsv()
}
} else {
vec![]
};
Expand Down
55 changes: 55 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,61 @@ PHP ₱ USD $
pg_and_generic().one_statement_parses_to(sql, "");
}

#[test]
fn parse_copy_from_stdin_without_semicolon() {
let stmt = pg().verified_stmt("COPY bitwise_test FROM STDIN NULL 'null'");
assert_eq!(
stmt,
Statement::Copy {
source: CopySource::Table {
table_name: ObjectName::from(vec!["bitwise_test".into()]),
columns: vec![],
},
to: false,
target: CopyTarget::Stdin,
options: vec![],
legacy_options: vec![CopyLegacyOption::Null("null".into())],
values: vec![],
}
);
}

#[test]
fn parse_copy_from_stdin_without_semicolon_variants() {
let cases = [
"COPY bool_test FROM STDIN NULL 'null'",
"COPY varbit_table FROM stdin",
"COPY bit_table FROM stdin",
"copy copytest2(test) from stdin",
"copy copytest3 from stdin csv header",
"copy copytest4 from stdin (header)",
"copy parted_copytest from stdin",
"copy tab_progress_reporting from stdin",
"copy oversized_column_default from stdin",
"COPY x (a, b, c, d, e) from stdin",
"copy header_copytest (c, a) from stdin",
"COPY atest5 (two) FROM stdin",
"COPY main_table (a, b) FROM stdin",
];

for sql in cases {
match pg().one_statement_parses_to(sql, "") {
Statement::Copy {
to: false,
target: CopyTarget::Stdin,
values,
..
} => {
assert!(
values.is_empty(),
"expected no inline COPY payload for `{sql}`"
);
}
_ => panic!("expected COPY ... FROM STDIN statement for `{sql}`"),
}
}
}

#[test]
fn test_copy_from() {
let stmt = pg().verified_stmt("COPY users FROM 'data.csv'");
Expand Down