Merge 'replace some matches with match_ignore_ascii_case macro' from Lâm Hoàng Phúc

Reviewed-by: Nikita Sivukhin (@sivukhin)

Closes #2903
This commit is contained in:
Preston Thorpe
2025-09-03 17:03:19 -04:00
committed by GitHub
5 changed files with 60 additions and 47 deletions

View File

@@ -90,6 +90,7 @@ pub use storage::{
};
use tracing::{instrument, Level};
use translate::select::prepare_select_plan;
use turso_macros::match_ignore_ascii_case;
use turso_parser::{ast, ast::Cmd, parser::Parser};
use types::IOResult;
pub use types::RefValue;
@@ -1911,21 +1912,23 @@ impl Connection {
// Check if this is a qualified name (database.table) or unqualified
if let Some(db_name) = &qualified_name.db_name {
let db_name_normalized = normalize_ident(db_name.as_str());
if db_name_normalized.eq_ignore_ascii_case("main") {
Ok(0)
} else if db_name_normalized.eq_ignore_ascii_case("temp") {
Ok(1)
} else {
// Look up attached database
if let Some((idx, _attached_db)) = self.get_attached_database(&db_name_normalized) {
Ok(idx)
} else {
Err(LimboError::InvalidArgument(format!(
"no such database: {db_name_normalized}"
)))
let name_bytes = db_name_normalized.as_bytes();
match_ignore_ascii_case!(match name_bytes {
b"main" => Ok(0),
b"temp" => Ok(1),
_ => {
// Look up attached database
if let Some((idx, _attached_db)) =
self.get_attached_database(&db_name_normalized)
{
Ok(idx)
} else {
Err(LimboError::InvalidArgument(format!(
"no such database: {db_name_normalized}"
)))
}
}
}
})
} else {
// Unqualified table name - use main database
Ok(0)

View File

@@ -1368,9 +1368,14 @@ impl<'a> LogicalPlanBuilder<'a> {
fn build_literal(lit: &ast::Literal) -> Result<Value> {
match lit {
ast::Literal::Null => Ok(Value::Null),
ast::Literal::Keyword(k) if k.eq_ignore_ascii_case("true") => Ok(Value::Integer(1)), // SQLite uses int for bool
ast::Literal::Keyword(k) if k.eq_ignore_ascii_case("false") => Ok(Value::Integer(0)), // SQLite uses int for bool
ast::Literal::Keyword(k) => Ok(Value::Text(k.clone().into())),
ast::Literal::Keyword(k) => {
let k_bytes = k.as_bytes();
match_ignore_ascii_case!(match k_bytes {
b"true" => Ok(Value::Integer(1)), // SQLite uses int for bool
b"false" => Ok(Value::Integer(0)), // SQLite uses int for bool
_ => Ok(Value::Text(k.clone().into())),
})
}
ast::Literal::Numeric(s) => {
if let Ok(i) = s.parse::<i64>() {
Ok(Value::Integer(i))

View File

@@ -8,6 +8,7 @@ use join::{compute_best_join_order, BestJoinOrderResult};
use lift_common_subexpressions::lift_common_subexpressions_from_binary_or_terms;
use order::{compute_order_target, plan_satisfies_order_target, EliminatesSortBy};
use turso_ext::{ConstraintInfo, ConstraintUsage};
use turso_macros::match_ignore_ascii_case;
use turso_parser::ast::{self, Expr, SortOrder};
use crate::{
@@ -1405,13 +1406,16 @@ pub fn rewrite_expr(top_level_expr: &mut ast::Expr, param_idx: &mut usize) -> Re
match expr {
ast::Expr::Id(id) => {
// Convert "true" and "false" to 1 and 0
if id.as_str().eq_ignore_ascii_case("true") {
*expr = ast::Expr::Literal(ast::Literal::Numeric(1.to_string()));
return Ok(());
}
if id.as_str().eq_ignore_ascii_case("false") {
*expr = ast::Expr::Literal(ast::Literal::Numeric(0.to_string()));
}
let id_bytes = id.as_str().as_bytes();
match_ignore_ascii_case!(match id_bytes {
b"true" => {
*expr = ast::Expr::Literal(ast::Literal::Numeric("1".to_owned()));
}
b"false" => {
*expr = ast::Expr::Literal(ast::Literal::Numeric("0".to_owned()));
}
_ => {}
})
}
ast::Expr::Variable(var) => {
if var.is_empty() {

View File

@@ -19,6 +19,7 @@ use crate::{
vdbe::{builder::TableRefIdCounter, BranchOffset},
Result,
};
use turso_macros::match_ignore_ascii_case;
use turso_parser::ast::Literal::Null;
use turso_parser::ast::{
self, As, Expr, FromClause, JoinType, Limit, Literal, Materialized, QualifiedName,
@@ -114,11 +115,13 @@ pub fn bind_column_references(
Expr::Id(id) => {
// true and false are special constants that are effectively aliases for 1 and 0
// and not identifiers of columns
if id.as_str().eq_ignore_ascii_case("true")
|| id.as_str().eq_ignore_ascii_case("false")
{
return Ok(());
}
let id_bytes = id.as_str().as_bytes();
match_ignore_ascii_case!(match id_bytes {
b"true" | b"false" => {
return Ok(());
}
_ => {}
});
let normalized_id = normalize_ident(id.as_str());
if !referenced_tables.joined_tables().is_empty() {
@@ -1127,13 +1130,12 @@ pub fn parse_limit(limit: &Limit) -> Result<(Option<isize>, Option<isize>)> {
crate::bail_parse_error!("Invalid LIMIT clause");
}
} else if let Expr::Id(id) = limit.expr.as_ref() {
if id.as_str().eq_ignore_ascii_case("true") {
Ok((Some(1), offset_val))
} else if id.as_str().eq_ignore_ascii_case("false") {
Ok((Some(0), offset_val))
} else {
crate::bail_parse_error!("Invalid LIMIT clause");
}
let id_bytes = id.as_str().as_bytes();
match_ignore_ascii_case!(match id_bytes {
b"true" => Ok((Some(1), offset_val)),
b"false" => Ok((Some(0), offset_val)),
_ => crate::bail_parse_error!("Invalid LIMIT clause"),
})
} else {
crate::bail_parse_error!("Invalid LIMIT clause");
}

View File

@@ -1763,25 +1763,24 @@ pub fn op_type_check(
}
let col_affinity = col.affinity();
let ty_str = &col.ty_str;
let ty_bytes = ty_str.as_bytes();
let applied = apply_affinity_char(reg, col_affinity);
let value_type = reg.get_value().value_type();
match value_type {
ValueType::Integer
if ty_str.eq_ignore_ascii_case("INTEGER")
|| ty_str.eq_ignore_ascii_case("INT") => {}
ValueType::Float if ty_str.eq_ignore_ascii_case("REAL") => {}
ValueType::Blob if ty_str.eq_ignore_ascii_case("BLOB") => {}
ValueType::Text if ty_str.eq_ignore_ascii_case("TEXT") => {}
_ if ty_str.eq_ignore_ascii_case("ANY") => {}
v => bail_constraint_error!(
match_ignore_ascii_case!(match ty_bytes {
b"INTEGER" | b"INT" if value_type == ValueType::Integer => {}
b"REAL" if value_type == ValueType::Float => {}
b"BLOB" if value_type == ValueType::Blob => {}
b"TEXT" if value_type == ValueType::Text => {}
b"ANY" => {}
_ => bail_constraint_error!(
"cannot store {} value in {} column {}.{} ({})",
v,
value_type,
ty_str,
&table_reference.name,
col.name.as_deref().unwrap_or(""),
SQLITE_CONSTRAINT
),
};
});
Ok(())
})?;