mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 01:58:16 +00:00
WIP commit on glob support
This commit is contained in:
parent
19d2d92115
commit
b87b874ed0
5 changed files with 52 additions and 8 deletions
|
@ -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
1
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1440,6 +1440,9 @@ impl Program {
|
|||
);
|
||||
state.registers[*dest] = result;
|
||||
}
|
||||
ScalarFunc::Glob => {
|
||||
todo!()
|
||||
}
|
||||
ScalarFunc::IfNull => {}
|
||||
ScalarFunc::Like => {
|
||||
let pattern = &state.registers[*start_reg];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue