WIP commit on glob support

This commit is contained in:
rjhallsted 2024-09-16 15:51:32 -07:00
parent 19d2d92115
commit b87b874ed0
5 changed files with 52 additions and 8 deletions

View file

@ -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 | |

1
Cargo.lock generated
View file

@ -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",
]

View file

@ -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(),

View file

@ -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,

View file

@ -1440,6 +1440,9 @@ impl Program {
);
state.registers[*dest] = result;
}
ScalarFunc::Glob => {
todo!()
}
ScalarFunc::IfNull => {}
ScalarFunc::Like => {
let pattern = &state.registers[*start_reg];