Skip to content

Commit 8bd82fc

Browse files
committed
Include location in errors
1 parent 6dc6a01 commit 8bd82fc

File tree

1 file changed

+41
-34
lines changed

1 file changed

+41
-34
lines changed

src/parser/merge.rs

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ use alloc::{boxed::Box, format, string::ToString, vec, vec::Vec};
1818
use crate::{
1919
ast::{
2020
Ident, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr, MergeInsertKind,
21-
MergeUpdateExpr, ObjectName, ObjectNamePart, OutputClause, SetExpr, Statement, TableFactor,
21+
MergeUpdateExpr, ObjectName, ObjectNamePart, OutputClause, SetExpr, Spanned, Statement,
22+
TableFactor,
2223
},
2324
dialect::{BigQueryDialect, GenericDialect, MySqlDialect},
2425
keywords::Keyword,
2526
parser::IsOptional,
26-
tokenizer::TokenWithSpan,
27+
tokenizer::{Location, TokenWithSpan},
2728
};
2829

2930
use super::{Parser, ParserError};
@@ -232,42 +233,48 @@ impl Parser<'_> {
232233
if let Some(alias) = alias {
233234
if alias.columns.is_empty() {
234235
// ~ only the alias is supported at this point
235-
unqualify_columns(cols, None, Some(&alias.name)).map_err(|e| {
236-
ParserError::ParserError(format!(
237-
"Invalid column for INSERT in a {clause_kind} merge clause: {e}"
238-
))
239-
})
236+
match unqualify_columns(cols, None, Some(&alias.name)) {
237+
Ok(column) => Ok(column),
238+
Err((err, loc)) => parser_err!(
239+
format_args!("Invalid column for INSERT in a {clause_kind} merge clause: {err}"),
240+
loc
241+
),
242+
}
240243
} else {
241-
Err(ParserError::ParserError(format!(
242-
"Invalid target ALIAS for INSERT in a {clause_kind} merge clause; must be an identifier"
243-
)))
244+
parser_err!(
245+
format_args!("Invalid target ALIAS for INSERT in a {clause_kind} merge clause; must be an identifier"),
246+
alias.name.span.start
247+
)
244248
}
245249
} else {
246250
// ~ allow the full qualifier, but also just the table name
247251
if name.0.len() == 1 {
248-
unqualify_columns(cols, Some(name), None).map_err(|e| {
249-
ParserError::ParserError(format!(
250-
"Invalid column for INSERT in a {clause_kind} merge clause: {e}"
251-
))
252-
})
253-
} else if let Some(table_name) =
252+
match unqualify_columns(cols, Some(name), None) {
253+
Ok(column) => Ok(column),
254+
Err((err, loc)) => parser_err!(
255+
format_args!("Invalid column for INSERT in a {clause_kind} merge clause: {err}"),
256+
loc)
257+
}
258+
} else if let Some(unqualified_name) =
254259
name.0.last().and_then(ObjectNamePart::as_ident)
255260
{
256-
unqualify_columns(cols, Some(name), Some(table_name)).map_err(|e| {
257-
ParserError::ParserError(format!(
258-
"Invalid column for INSERT in a {clause_kind} merge clause: {e}"
259-
))
260-
})
261+
match unqualify_columns(cols, Some(name), Some(unqualified_name)) {
262+
Ok(column) => Ok(column),
263+
Err((err, loc)) => parser_err!(
264+
format_args!("Invalid column for INSERT in a {clause_kind} merge clause: {err}"),
265+
loc)
266+
}
261267
} else {
262-
Err(ParserError::ParserError(format!(
263-
"Invalid target table NAME for INSERT in a {clause_kind} merge clause; must be an identifier"
264-
)))
268+
parser_err!(
269+
format_args!("Invalid target table NAME for INSERT in a {clause_kind} merge clause; must be an identifier"),
270+
name.span().start
271+
)
265272
}
266273
}
267274
} else {
268-
Err(ParserError::ParserError(format!(
269-
"Invalid target for INSERT in a {clause_kind} merge clause; must be a TABLE identifier"
270-
)))
275+
parser_err!(
276+
format_args!("Invalid target for INSERT in a {clause_kind} merge clause; must be a TABLE identifier"),
277+
target_table.span().start)
271278
}
272279
} else {
273280
self.parse_parenthesized_column_list(IsOptional::Optional, allow_empty)
@@ -302,8 +309,8 @@ impl Parser<'_> {
302309
}
303310
}
304311

305-
/// Helper to unqualify a list of columns with either a qualified prefix or a
306-
/// qualifier identifier
312+
/// Helper to unqualify a list of columns with either a qualified prefix
313+
/// (`allowed_qualifier_1`) or a qualifier identifier (`allowed_qualifier_2`.)
307314
///
308315
/// Oracle allows `INSERT ([qualifier.]column_name, ...)` in MERGE statements
309316
/// with `qualifier` referring to the alias of the target table (if one is
@@ -313,13 +320,13 @@ fn unqualify_columns(
313320
columns: Vec<ObjectName>,
314321
allowed_qualifier_1: Option<&ObjectName>,
315322
allowed_qualifier_2: Option<&Ident>,
316-
) -> Result<Vec<Ident>, &'static str> {
323+
) -> Result<Vec<Ident>, (&'static str, Location)> {
317324
// ~ helper to turn a column name (part) into a plain `ident`
318325
// possibly bailing with error
319-
fn to_ident(name: ObjectNamePart) -> Result<Ident, &'static str> {
326+
fn to_ident(name: ObjectNamePart) -> Result<Ident, (&'static str, Location)> {
320327
match name {
321328
ObjectNamePart::Identifier(ident) => Ok(ident),
322-
ObjectNamePart::Function(_) => Err("not an identifier"),
329+
ObjectNamePart::Function(_) => Err(("not an identifier", name.span().start)),
323330
}
324331
}
325332

@@ -353,7 +360,7 @@ fn unqualify_columns(
353360
let mut unqualified = Vec::<Ident>::with_capacity(columns.len());
354361
for mut name in columns {
355362
if name.0.is_empty() {
356-
return Err("empty column name");
363+
return Err(("empty column name", name.span().start));
357364
}
358365

359366
if name.0.len() == 1 {
@@ -390,7 +397,7 @@ fn unqualify_columns(
390397
}
391398
}
392399

393-
return Err("not matching target table");
400+
return Err(("not matching target table", name.span().start));
394401
}
395402
Ok(unqualified)
396403
}

0 commit comments

Comments
 (0)