Skip to main content

surql_parser/upstream/syn/parser/stmt/
insert.rs

1use crate::upstream::sql::statements::InsertStatement;
2use crate::upstream::sql::{Data, Expr};
3use crate::upstream::syn::error::bail;
4use crate::upstream::syn::parser::mac::expected;
5use crate::upstream::syn::parser::{ParseResult, Parser};
6use crate::upstream::syn::token::t;
7use reblessive::Stk;
8impl Parser<'_> {
9	pub async fn parse_insert_stmt(&mut self, stk: &mut Stk) -> ParseResult<InsertStatement> {
10		let relation = self.eat(t!("RELATION"));
11		let ignore = self.eat(t!("IGNORE"));
12		let into = if self.eat(t!("INTO")) {
13			let r = match self.peek().kind {
14				t!("$param") => {
15					let param = self.next_token_value()?;
16					Expr::Param(param)
17				}
18				_ => {
19					let table = self.parse_ident()?;
20					Expr::Table(table)
21				}
22			};
23			Some(r)
24		} else {
25			None
26		};
27		let data = self.parse_insert_values(stk).await?;
28		let update = if self.eat(t!("ON")) {
29			Some(self.parse_insert_update(stk).await?)
30		} else {
31			None
32		};
33		let output = self.try_parse_output(stk).await?;
34		if self.eat(t!("VERSION")) {
35			stk.run(|ctx| self.parse_expr_field(ctx)).await?;
36		}
37		let timeout = self.try_parse_timeout(stk).await?;
38		Ok(InsertStatement {
39			into,
40			data,
41			ignore,
42			update,
43			output,
44			timeout,
45			relation,
46		})
47	}
48	async fn parse_insert_values(&mut self, stk: &mut Stk) -> ParseResult<Data> {
49		let token = self.peek();
50		if token.kind != t!("(") {
51			let value = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
52			return Ok(Data::SingleExpression(value));
53		}
54		let speculate_result = self
55			.speculate(stk, async |stk, this| {
56				this.pop_peek();
57				if Self::kind_starts_statement(this.peek().kind) {
58					return Ok(None);
59				}
60				let Ok(first) = this.parse_plain_idiom(stk).await else {
61					return Ok(None);
62				};
63				let mut idioms = vec![first];
64				let mut ate_comma = false;
65				loop {
66					if !this.eat(t!(",")) {
67						if ate_comma {
68							this.expect_closing_delimiter(t!(")"), token.span)?;
69						} else if !this.eat(t!(")")) {
70							return Ok(None);
71						}
72						break;
73					}
74					ate_comma = true;
75					if this.eat(t!(")")) {
76						break;
77					}
78					idioms.push(this.parse_plain_idiom(stk).await?);
79				}
80				let select_span = token.span.covers(this.last_span());
81				if ate_comma {
82					expected!(this, t!("VALUES"));
83				} else {
84					if !this.eat(t!("VALUES")) {
85						return Ok(None);
86					}
87				}
88				let mut insertions = Vec::new();
89				loop {
90					let mut values = Vec::new();
91					let start = expected!(this, t!("(")).span;
92					loop {
93						values.push(stk.run(|ctx| this.parse_expr_field(ctx)).await?);
94						if !this.eat(t!(",")) {
95							this.expect_closing_delimiter(t!(")"), start)?;
96							break;
97						}
98						if this.eat(t!(")")) {
99							break;
100						}
101					}
102					let span = start.covers(this.last_span());
103					if values.len() != idioms.len() {
104						bail!(
105							"Invalid numbers of values to insert, found {} value(s) but selector requires {} value(s).",
106							values.len(), idioms.len(), @ span, @ select_span =>
107							"This selector has {} field(s)", idioms.len()
108						);
109					}
110					insertions.push(values);
111					if !this.eat(t!(",")) {
112						break;
113					}
114				}
115				Ok(Some(
116					insertions
117						.into_iter()
118						.map(|row| idioms.iter().cloned().zip(row).collect())
119						.collect(),
120				))
121			})
122			.await?;
123		if let Some(x) = speculate_result {
124			Ok(Data::ValuesExpression(x))
125		} else {
126			let expr = stk.run(|stk| self.parse_expr_field(stk)).await?;
127			Ok(Data::SingleExpression(expr))
128		}
129	}
130	async fn parse_insert_update(&mut self, stk: &mut Stk) -> ParseResult<Data> {
131		expected!(self, t!("DUPLICATE"));
132		expected!(self, t!("KEY"));
133		expected!(self, t!("UPDATE"));
134		let mut res = Vec::new();
135		loop {
136			res.push(self.parse_assignment(stk).await?);
137			if !self.eat(t!(",")) {
138				break;
139			}
140		}
141		Ok(Data::UpdateExpression(res))
142	}
143}