mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-24 07:54:06 +00:00
SQLite: Allow dollar signs in placeholder names (#1620)
This commit is contained in:
parent
d0d4153137
commit
48f025f658
4 changed files with 53 additions and 4 deletions
|
@ -636,6 +636,12 @@ pub trait Dialect: Debug + Any {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this dialect allows dollar placeholders
|
||||||
|
/// e.g. `SELECT $var` (SQLite)
|
||||||
|
fn supports_dollar_placeholder(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Does the dialect support with clause in create index statement?
|
/// Does the dialect support with clause in create index statement?
|
||||||
/// e.g. `CREATE INDEX idx ON t WITH (key = value, key2)`
|
/// e.g. `CREATE INDEX idx ON t WITH (key = value, key2)`
|
||||||
fn supports_create_index_with_clause(&self) -> bool {
|
fn supports_create_index_with_clause(&self) -> bool {
|
||||||
|
|
|
@ -81,4 +81,8 @@ impl Dialect for SQLiteDialect {
|
||||||
fn supports_asc_desc_in_column_definition(&self) -> bool {
|
fn supports_asc_desc_in_column_definition(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_dollar_placeholder(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1509,7 +1509,8 @@ impl<'a> Tokenizer<'a> {
|
||||||
|
|
||||||
chars.next();
|
chars.next();
|
||||||
|
|
||||||
if let Some('$') = chars.peek() {
|
// If the dialect does not support dollar-quoted strings, then `$$` is rather a placeholder.
|
||||||
|
if matches!(chars.peek(), Some('$')) && !self.dialect.supports_dollar_placeholder() {
|
||||||
chars.next();
|
chars.next();
|
||||||
|
|
||||||
let mut is_terminated = false;
|
let mut is_terminated = false;
|
||||||
|
@ -1543,10 +1544,14 @@ impl<'a> Tokenizer<'a> {
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
value.push_str(&peeking_take_while(chars, |ch| {
|
value.push_str(&peeking_take_while(chars, |ch| {
|
||||||
ch.is_alphanumeric() || ch == '_'
|
ch.is_alphanumeric()
|
||||||
|
|| ch == '_'
|
||||||
|
// Allow $ as a placeholder character if the dialect supports it
|
||||||
|
|| matches!(ch, '$' if self.dialect.supports_dollar_placeholder())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if let Some('$') = chars.peek() {
|
// If the dialect does not support dollar-quoted strings, don't look for the end delimiter.
|
||||||
|
if matches!(chars.peek(), Some('$')) && !self.dialect.supports_dollar_placeholder() {
|
||||||
chars.next();
|
chars.next();
|
||||||
|
|
||||||
'searching_for_end: loop {
|
'searching_for_end: loop {
|
||||||
|
@ -2137,7 +2142,7 @@ fn take_char_from_hex_digits(
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::dialect::{
|
use crate::dialect::{
|
||||||
BigQueryDialect, ClickHouseDialect, HiveDialect, MsSqlDialect, MySqlDialect,
|
BigQueryDialect, ClickHouseDialect, HiveDialect, MsSqlDialect, MySqlDialect, SQLiteDialect,
|
||||||
};
|
};
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
@ -2573,6 +2578,30 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tokenize_dollar_placeholder() {
|
||||||
|
let sql = String::from("SELECT $$, $$ABC$$, $ABC$, $ABC");
|
||||||
|
let dialect = SQLiteDialect {};
|
||||||
|
let tokens = Tokenizer::new(&dialect, &sql).tokenize().unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
tokens,
|
||||||
|
vec![
|
||||||
|
Token::make_keyword("SELECT"),
|
||||||
|
Token::Whitespace(Whitespace::Space),
|
||||||
|
Token::Placeholder("$$".into()),
|
||||||
|
Token::Comma,
|
||||||
|
Token::Whitespace(Whitespace::Space),
|
||||||
|
Token::Placeholder("$$ABC$$".into()),
|
||||||
|
Token::Comma,
|
||||||
|
Token::Whitespace(Whitespace::Space),
|
||||||
|
Token::Placeholder("$ABC$".into()),
|
||||||
|
Token::Comma,
|
||||||
|
Token::Whitespace(Whitespace::Space),
|
||||||
|
Token::Placeholder("$ABC".into()),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tokenize_dollar_quoted_string_untagged() {
|
fn tokenize_dollar_quoted_string_untagged() {
|
||||||
let sql =
|
let sql =
|
||||||
|
|
|
@ -561,6 +561,16 @@ fn test_dollar_identifier_as_placeholder() {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $$ is a valid placeholder in SQLite
|
||||||
|
match sqlite().verified_expr("id = $$") {
|
||||||
|
Expr::BinaryOp { op, left, right } => {
|
||||||
|
assert_eq!(op, BinaryOperator::Eq);
|
||||||
|
assert_eq!(left, Box::new(Expr::Identifier(Ident::new("id"))));
|
||||||
|
assert_eq!(right, Box::new(Expr::Value(Placeholder("$$".to_string()))));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sqlite() -> TestedDialects {
|
fn sqlite() -> TestedDialects {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue