Skip to content

Commit 5f70144

Browse files
committed
SGA-12672 Added support for INSERT INTO VALUE, previously only VALUES was allowed
1 parent 308a723 commit 5f70144

File tree

9 files changed

+95
-8
lines changed

9 files changed

+95
-8
lines changed

src/ast/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ pub use self::query::{
9292
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
9393
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
9494
TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
95-
ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill, XmlNamespaceDefinition,
96-
XmlPassingArgument, XmlPassingClause, XmlTableColumn, XmlTableColumnOption,
95+
ValueTableMode, Values, ValuesKeyword, WildcardAdditionalOptions, With, WithFill,
96+
XmlNamespaceDefinition, XmlPassingArgument, XmlPassingClause, XmlTableColumn,
97+
XmlTableColumnOption,
9798
};
9899

99100
pub use self::trigger::{

src/ast/query.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3135,12 +3135,30 @@ pub struct Values {
31353135
/// Was there an explicit ROWs keyword (MySQL)?
31363136
/// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
31373137
pub explicit_row: bool,
3138+
// MySql supports both VALUES and VALUE keywords.
3139+
// <https://dev.mysql.com/doc/refman/9.2/en/insert.html>
3140+
pub keyword: ValuesKeyword,
31383141
pub rows: Vec<Vec<Expr>>,
31393142
}
31403143

3144+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3145+
pub enum ValuesKeyword {
3146+
Values,
3147+
Value,
3148+
}
3149+
3150+
impl fmt::Display for ValuesKeyword {
3151+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3152+
match self {
3153+
ValuesKeyword::Values => write!(f, "VALUES"),
3154+
ValuesKeyword::Value => write!(f, "VALUE"),
3155+
}
3156+
}
3157+
}
3158+
31413159
impl fmt::Display for Values {
31423160
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3143-
f.write_str("VALUES")?;
3161+
write!(f, "{}", self.keyword)?;
31443162
let prefix = if self.explicit_row { "ROW" } else { "" };
31453163
let mut delim = "";
31463164
for row in &self.rows {

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ impl Spanned for Values {
223223
fn span(&self) -> Span {
224224
let Values {
225225
explicit_row: _, // bool,
226+
keyword: _,
226227
rows,
227228
} = self;
228229

src/parser/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::ast::helpers::{
3939
stmt_create_table::{CreateTableBuilder, CreateTableConfiguration},
4040
};
4141
use crate::ast::Statement::CreatePolicy;
42+
use crate::ast::ValuesKeyword;
4243
use crate::ast::*;
4344
use crate::dialect::*;
4445
use crate::keywords::{Keyword, ALL_KEYWORDS};
@@ -12528,7 +12529,10 @@ impl<'a> Parser<'a> {
1252812529
SetExpr::Query(subquery)
1252912530
} else if self.parse_keyword(Keyword::VALUES) {
1253012531
let is_mysql = dialect_of!(self is MySqlDialect);
12531-
SetExpr::Values(self.parse_values(is_mysql)?)
12532+
SetExpr::Values(self.parse_values(is_mysql, ValuesKeyword::Values)?)
12533+
} else if self.parse_keyword(Keyword::VALUE) {
12534+
let is_mysql = dialect_of!(self is MySqlDialect);
12535+
SetExpr::Values(self.parse_values(is_mysql, ValuesKeyword::Value)?)
1253212536
} else if self.parse_keyword(Keyword::TABLE) {
1253312537
SetExpr::Table(Box::new(self.parse_as_table()?))
1253412538
} else {
@@ -13832,7 +13836,7 @@ impl<'a> Parser<'a> {
1383213836
// Snowflake and Databricks allow syntax like below:
1383313837
// SELECT * FROM VALUES (1, 'a'), (2, 'b') AS t (col1, col2)
1383413838
// where there are no parentheses around the VALUES clause.
13835-
let values = SetExpr::Values(self.parse_values(false)?);
13839+
let values = SetExpr::Values(self.parse_values(false, ValuesKeyword::Values)?);
1383613840
let alias = self.maybe_parse_table_alias()?;
1383713841
Ok(TableFactor::Derived {
1383813842
lateral: false,
@@ -16499,7 +16503,11 @@ impl<'a> Parser<'a> {
1649916503
})
1650016504
}
1650116505

16502-
pub fn parse_values(&mut self, allow_empty: bool) -> Result<Values, ParserError> {
16506+
pub fn parse_values(
16507+
&mut self,
16508+
allow_empty: bool,
16509+
keyword: ValuesKeyword,
16510+
) -> Result<Values, ParserError> {
1650316511
let mut explicit_row = false;
1650416512

1650516513
let rows = self.parse_comma_separated(|parser| {
@@ -16517,7 +16525,11 @@ impl<'a> Parser<'a> {
1651716525
Ok(exprs)
1651816526
}
1651916527
})?;
16520-
Ok(Values { explicit_row, rows })
16528+
Ok(Values {
16529+
explicit_row,
16530+
rows,
16531+
keyword,
16532+
})
1652116533
}
1652216534

1652316535
pub fn parse_start_transaction(&mut self) -> Result<Statement, ParserError> {
@@ -16932,7 +16944,7 @@ impl<'a> Parser<'a> {
1693216944
MergeInsertKind::Row
1693316945
} else {
1693416946
self.expect_keyword_is(Keyword::VALUES)?;
16935-
let values = self.parse_values(is_mysql)?;
16947+
let values = self.parse_values(is_mysql, ValuesKeyword::Values)?;
1693616948
MergeInsertKind::Values(values)
1693716949
};
1693816950
MergeAction::Insert(MergeInsertExpr { columns, kind })

tests/sqlparser_bigquery.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,7 @@ fn parse_merge() {
18071807
let insert_action = MergeAction::Insert(MergeInsertExpr {
18081808
columns: vec![Ident::new("product"), Ident::new("quantity")],
18091809
kind: MergeInsertKind::Values(Values {
1810+
keyword: ValuesKeyword::Values,
18101811
explicit_row: false,
18111812
rows: vec![vec![Expr::value(number("1")), Expr::value(number("2"))]],
18121813
}),
@@ -1951,6 +1952,7 @@ fn parse_merge() {
19511952
action: MergeAction::Insert(MergeInsertExpr {
19521953
columns: vec![Ident::new("a"), Ident::new("b"),],
19531954
kind: MergeInsertKind::Values(Values {
1955+
keyword: ValuesKeyword::Values,
19541956
explicit_row: false,
19551957
rows: vec![vec![
19561958
Expr::value(number("1")),
@@ -1965,6 +1967,7 @@ fn parse_merge() {
19651967
action: MergeAction::Insert(MergeInsertExpr {
19661968
columns: vec![],
19671969
kind: MergeInsertKind::Values(Values {
1970+
keyword: ValuesKeyword::Values,
19681971
explicit_row: false,
19691972
rows: vec![vec![
19701973
Expr::value(number("1")),

tests/sqlparser_common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9908,6 +9908,7 @@ fn parse_merge() {
99089908
action: MergeAction::Insert(MergeInsertExpr {
99099909
columns: vec![Ident::new("A"), Ident::new("B"), Ident::new("C")],
99109910
kind: MergeInsertKind::Values(Values {
9911+
keyword: ValuesKeyword::Values,
99119912
explicit_row: false,
99129913
rows: vec![vec![
99139914
Expr::CompoundIdentifier(vec![

tests/sqlparser_databricks.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ fn test_databricks_lambdas() {
157157
#[test]
158158
fn test_values_clause() {
159159
let values = Values {
160+
keyword: ValuesKeyword::Values,
160161
explicit_row: false,
161162
rows: vec![
162163
vec![

tests/sqlparser_mysql.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,7 @@ fn parse_simple_insert() {
18851885
Some(Box::new(Query {
18861886
with: None,
18871887
body: Box::new(SetExpr::Values(Values {
1888+
keyword: ValuesKeyword::Values,
18881889
explicit_row: false,
18891890
rows: vec![
18901891
vec![
@@ -1950,6 +1951,7 @@ fn parse_ignore_insert() {
19501951
Some(Box::new(Query {
19511952
with: None,
19521953
body: Box::new(SetExpr::Values(Values {
1954+
keyword: ValuesKeyword::Values,
19531955
explicit_row: false,
19541956
rows: vec![vec![
19551957
Expr::Value(
@@ -1999,6 +2001,7 @@ fn parse_priority_insert() {
19992001
Some(Box::new(Query {
20002002
with: None,
20012003
body: Box::new(SetExpr::Values(Values {
2004+
keyword: ValuesKeyword::Values,
20022005
explicit_row: false,
20032006
rows: vec![vec![
20042007
Expr::Value(
@@ -2045,6 +2048,7 @@ fn parse_priority_insert() {
20452048
Some(Box::new(Query {
20462049
with: None,
20472050
body: Box::new(SetExpr::Values(Values {
2051+
keyword: ValuesKeyword::Values,
20482052
explicit_row: false,
20492053
rows: vec![vec![
20502054
Expr::Value(
@@ -2097,6 +2101,7 @@ fn parse_insert_as() {
20972101
Some(Box::new(Query {
20982102
with: None,
20992103
body: Box::new(SetExpr::Values(Values {
2104+
keyword: ValuesKeyword::Values,
21002105
explicit_row: false,
21012106
rows: vec![vec![Expr::Value(
21022107
(Value::SingleQuotedString("2024-01-01".to_string())).with_empty_span()
@@ -2156,6 +2161,7 @@ fn parse_insert_as() {
21562161
Some(Box::new(Query {
21572162
with: None,
21582163
body: Box::new(SetExpr::Values(Values {
2164+
keyword: ValuesKeyword::Values,
21592165
explicit_row: false,
21602166
rows: vec![vec![
21612167
Expr::value(number("1")),
@@ -2206,6 +2212,7 @@ fn parse_replace_insert() {
22062212
Some(Box::new(Query {
22072213
with: None,
22082214
body: Box::new(SetExpr::Values(Values {
2215+
keyword: ValuesKeyword::Values,
22092216
explicit_row: false,
22102217
rows: vec![vec![
22112218
Expr::Value(
@@ -2253,6 +2260,7 @@ fn parse_empty_row_insert() {
22532260
Some(Box::new(Query {
22542261
with: None,
22552262
body: Box::new(SetExpr::Values(Values {
2263+
keyword: ValuesKeyword::Values,
22562264
explicit_row: false,
22572265
rows: vec![vec![], vec![]]
22582266
})),
@@ -2303,6 +2311,7 @@ fn parse_insert_with_on_duplicate_update() {
23032311
Some(Box::new(Query {
23042312
with: None,
23052313
body: Box::new(SetExpr::Values(Values {
2314+
keyword: ValuesKeyword::Values,
23062315
explicit_row: false,
23072316
rows: vec![vec![
23082317
Expr::Value(
@@ -4353,3 +4362,41 @@ fn test_create_index_options() {
43534362
"CREATE INDEX idx_name ON t(c1, c2) USING BTREE LOCK = EXCLUSIVE ALGORITHM = DEFAULT",
43544363
);
43554364
}
4365+
4366+
#[test]
4367+
fn test_insert_into_value() {
4368+
let sql = r"INSERT INTO t (id, name) VALUE ('AAA', 'BBB')";
4369+
match mysql_and_generic().verified_stmt(sql) {
4370+
Statement::Insert(Insert { source, .. }) => {
4371+
assert_eq!(
4372+
Some(Box::new(Query {
4373+
with: None,
4374+
body: Box::new(SetExpr::Values(Values {
4375+
keyword: ValuesKeyword::Value,
4376+
explicit_row: false,
4377+
rows: vec![vec![
4378+
Expr::Value(ValueWithSpan {
4379+
value: Value::SingleQuotedString("AAA".to_string()),
4380+
span: Span::empty(),
4381+
}),
4382+
Expr::Value(ValueWithSpan {
4383+
value: Value::SingleQuotedString("BBB".to_string()),
4384+
span: Span::empty(),
4385+
}),
4386+
]],
4387+
})),
4388+
order_by: None,
4389+
limit_clause: None,
4390+
fetch: None,
4391+
locks: vec![],
4392+
for_clause: None,
4393+
settings: None,
4394+
format_clause: None,
4395+
pipe_operators: vec![],
4396+
})),
4397+
source
4398+
);
4399+
}
4400+
_ => unreachable!(),
4401+
}
4402+
}

tests/sqlparser_postgres.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5169,6 +5169,7 @@ fn test_simple_postgres_insert_with_alias() {
51695169
source: Some(Box::new(Query {
51705170
with: None,
51715171
body: Box::new(SetExpr::Values(Values {
5172+
keyword: ValuesKeyword::Values,
51725173
explicit_row: false,
51735174
rows: vec![vec![
51745175
Expr::Identifier(Ident::new("DEFAULT")),
@@ -5238,6 +5239,7 @@ fn test_simple_postgres_insert_with_alias() {
52385239
source: Some(Box::new(Query {
52395240
with: None,
52405241
body: Box::new(SetExpr::Values(Values {
5242+
keyword: ValuesKeyword::Values,
52415243
explicit_row: false,
52425244
rows: vec![vec![
52435245
Expr::Identifier(Ident::new("DEFAULT")),
@@ -5309,6 +5311,7 @@ fn test_simple_insert_with_quoted_alias() {
53095311
source: Some(Box::new(Query {
53105312
with: None,
53115313
body: Box::new(SetExpr::Values(Values {
5314+
keyword: ValuesKeyword::Values,
53125315
explicit_row: false,
53135316
rows: vec![vec![
53145317
Expr::Identifier(Ident::new("DEFAULT")),

0 commit comments

Comments
 (0)