handle single, double and unquoted strings in values clause

This commit is contained in:
Mikaël Francoeur
2025-08-07 15:52:05 -04:00
parent 7b4703eba4
commit 2cf4e4fe96
6 changed files with 35 additions and 11 deletions

View File

@@ -2715,11 +2715,6 @@ pub fn sanitize_double_quoted_string(input: &str) -> String {
input[1..input.len() - 1].replace("\"\"", "\"").to_string()
}
/// Checks if an identifier represents a double-quoted string that should get fallback behavior
pub fn is_double_quoted_identifier(id_str: &str) -> bool {
id_str.len() >= 2 && id_str.starts_with('"') && id_str.ends_with('"')
}
/// Returns the components of a binary expression
/// e.g. t.x = 5 -> Some((t.x, =, 5))
pub fn as_binary_components(

View File

@@ -1,7 +1,8 @@
use std::sync::Arc;
use turso_sqlite3_parser::ast::{
DistinctNames, Expr, InsertBody, OneSelect, QualifiedName, ResolveType, ResultColumn, With,
self, DistinctNames, Expr, InsertBody, OneSelect, QualifiedName, ResolveType, ResultColumn,
With,
};
use crate::error::{SQLITE_CONSTRAINT_NOTNULL, SQLITE_CONSTRAINT_PRIMARYKEY};
@@ -111,6 +112,14 @@ pub fn translate_insert(
}
let mut param_idx = 1;
for expr in values_expr.iter_mut().flat_map(|v| v.iter_mut()) {
if let Expr::Id(name) = expr {
if name.is_double_quoted() {
*expr = Expr::Literal(ast::Literal::String(format!("{name}")));
} else {
// an INSERT INTO ... VALUES (...) cannot reference columns
crate::bail_parse_error!("no such column: {name}");
}
}
rewrite_expr(expr, &mut param_idx)?;
}
values = values_expr.pop();

View File

@@ -14,9 +14,8 @@ use crate::{
parameters::PARAM_PREFIX,
schema::{Index, IndexColumn, Schema, Table},
translate::{
expr::is_double_quoted_identifier, expr::walk_expr_mut,
optimizer::access_method::AccessMethodParams, optimizer::constraints::TableConstraints,
plan::Scan, plan::TerminationKey,
expr::walk_expr_mut, optimizer::access_method::AccessMethodParams,
optimizer::constraints::TableConstraints, plan::Scan, plan::TerminationKey,
},
types::SeekOp,
LimboError, Result,
@@ -701,7 +700,7 @@ impl Optimizable for ast::Expr {
Expr::FunctionCallStar { .. } => false,
Expr::Id(id) => {
// If we got here with an id, this has to be double-quotes identifier
assert!(is_double_quoted_identifier(id.as_str()));
assert!(id.is_double_quoted());
true
}
Expr::Column { .. } => false,

View File

@@ -205,7 +205,7 @@ pub fn bind_column_references(
}
// SQLite behavior: Only double-quoted identifiers get fallback to string literals
// Single quotes are handled as literals earlier, unquoted identifiers must resolve to columns
if crate::translate::expr::is_double_quoted_identifier(id.as_str()) {
if id.is_double_quoted() {
// Convert failed double-quoted identifier to string literal
*expr = Expr::Literal(Literal::String(id.as_str().to_string()));
Ok(())