From b87b874ed002a6d20b330b7849aed263bbfd409a Mon Sep 17 00:00:00 2001 From: rjhallsted Date: Mon, 16 Sep 2024 15:51:32 -0700 Subject: [PATCH] WIP commit on glob support --- COMPAT.md | 2 +- Cargo.lock | 1 + core/function.rs | 2 ++ core/translate/expr.rs | 52 ++++++++++++++++++++++++++++++++++++------ core/vdbe/mod.rs | 3 +++ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/COMPAT.md b/COMPAT.md index 4b306c2c8..9bb087639 100644 --- a/COMPAT.md +++ b/COMPAT.md @@ -68,7 +68,7 @@ This document describes the SQLite compatibility status of Limbo: | concat(X,...) | Yes | | | concat_ws(SEP,X,...) | Yes | | | format(FORMAT,...) | No | | -| glob(X,Y) | No | | +| glob(X,Y) | Yes | | | hex(X) | No | | | ifnull(X,Y) | Yes | | | iif(X,Y,Z) | No | | diff --git a/Cargo.lock b/Cargo.lock index 07e8a94c1..b1964d8fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1078,6 +1078,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" dependencies = [ + "cc", "pkg-config", "vcpkg", ] diff --git a/core/function.rs b/core/function.rs index 2cbd6166c..54790df07 100644 --- a/core/function.rs +++ b/core/function.rs @@ -44,6 +44,7 @@ pub enum ScalarFunc { Coalesce, Concat, ConcatWs, + Glob, IfNull, Like, Abs, @@ -75,6 +76,7 @@ impl ToString for ScalarFunc { ScalarFunc::Coalesce => "coalesce".to_string(), ScalarFunc::Concat => "concat".to_string(), ScalarFunc::ConcatWs => "concat_ws".to_string(), + ScalarFunc::Glob => "glob".to_string(), ScalarFunc::IfNull => "ifnull".to_string(), ScalarFunc::Like => "like(2)".to_string(), ScalarFunc::Abs => "abs".to_string(), diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 9f3e443ab..24a48dc5e 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -1,5 +1,5 @@ use crate::{function::JsonFunc, Result}; -use sqlite3_parser::ast::{self, UnaryOperator}; +use sqlite3_parser::ast::{self, LikeOperator, UnaryOperator}; use std::rc::Rc; use super::optimizer::CachedResult; @@ -452,9 +452,10 @@ pub fn translate_condition_expr( } => { let cur_reg = program.alloc_register(); match op { - ast::LikeOperator::Like => { + ast::LikeOperator::Like | ast::LikeOperator::Glob => { let pattern_reg = program.alloc_register(); let column_reg = program.alloc_register(); + let mut constant_mask = 0; let _ = translate_expr( program, Some(referenced_tables), @@ -476,20 +477,23 @@ pub fn translate_condition_expr( )?; if let ast::Expr::Literal(_) = rhs.as_ref() { program.mark_last_insn_constant(); + constant_mask = 1; } + let func = match op { + ast::LikeOperator::Like => ScalarFunc::Like, + ast::LikeOperator::Glob => ScalarFunc::Glob, + _ => unreachable!(), + }; program.emit_insn(Insn::Function { - // Only constant patterns for LIKE are supported currently, so this - // is always 1 - constant_mask: 1, + constant_mask, start_reg: pattern_reg, dest: cur_reg, func: FuncCtx { - func: Func::Scalar(ScalarFunc::Like), + func: Func::Scalar(func), arg_count: 2, }, }); } - ast::LikeOperator::Glob => todo!(), ast::LikeOperator::Match => todo!(), ast::LikeOperator::Regexp => todo!(), } @@ -902,6 +906,40 @@ pub fn translate_expr( }); Ok(target_register) } + ScalarFunc::Glob => { + let args = match args { + Some(args) if args.len() == 2 => args, + Some(_) | None => crate::bail_parse_error!( + "{} function requires exactly 2 arguments", + srf.to_string() + ), + }; + let mut constant_mask = 0; + for (idx, arg) in args.iter().enumerate() { + let reg = program.alloc_register(); + let _ = translate_expr( + program, + referenced_tables, + arg, + reg, + cursor_hint, + cached_results, + )?; + if let ast::Expr::Literal(_) = arg { + program.mark_last_insn_constant(); + if idx == 0 { + constant_mask = 1; + } + } + } + program.emit_insn(Insn::Function { + constant_mask, + start_reg: target_register + 1, + dest: target_register, + func: func_ctx, + }); + Ok(target_register) + } ScalarFunc::IfNull => { let args = match args { Some(args) if args.len() == 2 => args, diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 09914d5e2..633f5b7a6 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -1440,6 +1440,9 @@ impl Program { ); state.registers[*dest] = result; } + ScalarFunc::Glob => { + todo!() + } ScalarFunc::IfNull => {} ScalarFunc::Like => { let pattern = &state.registers[*start_reg];