mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-07-07 20:45:01 +00:00
820 lines
28 KiB
Rust
820 lines
28 KiB
Rust
use std::fmt;
|
|
use std::fmt::{Debug, Display};
|
|
use std::rc::Rc;
|
|
use turso_ext::{FinalizeFunction, InitAggFunction, ScalarFunction, StepFunction};
|
|
|
|
use crate::LimboError;
|
|
|
|
pub struct ExternalFunc {
|
|
pub name: String,
|
|
pub func: ExtFunc,
|
|
}
|
|
|
|
impl ExternalFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
false // external functions can be whatever so let's just default to false
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum ExtFunc {
|
|
Scalar(ScalarFunction),
|
|
Aggregate {
|
|
argc: usize,
|
|
init: InitAggFunction,
|
|
step: StepFunction,
|
|
finalize: FinalizeFunction,
|
|
},
|
|
}
|
|
|
|
impl ExtFunc {
|
|
pub fn agg_args(&self) -> Result<usize, ()> {
|
|
if let ExtFunc::Aggregate { argc, .. } = self {
|
|
return Ok(*argc);
|
|
}
|
|
Err(())
|
|
}
|
|
}
|
|
|
|
impl ExternalFunc {
|
|
pub fn new_scalar(name: String, func: ScalarFunction) -> Self {
|
|
Self {
|
|
name,
|
|
func: ExtFunc::Scalar(func),
|
|
}
|
|
}
|
|
|
|
pub fn new_aggregate(
|
|
name: String,
|
|
argc: i32,
|
|
func: (InitAggFunction, StepFunction, FinalizeFunction),
|
|
) -> Self {
|
|
Self {
|
|
name,
|
|
func: ExtFunc::Aggregate {
|
|
argc: argc as usize,
|
|
init: func.0,
|
|
step: func.1,
|
|
finalize: func.2,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Debug for ExternalFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", self.name)
|
|
}
|
|
}
|
|
|
|
impl Display for ExternalFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", self.name)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "json")]
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum JsonFunc {
|
|
Json,
|
|
Jsonb,
|
|
JsonArray,
|
|
JsonbArray,
|
|
JsonArrayLength,
|
|
JsonArrowExtract,
|
|
JsonArrowShiftExtract,
|
|
JsonExtract,
|
|
JsonbExtract,
|
|
JsonObject,
|
|
JsonbObject,
|
|
JsonType,
|
|
JsonErrorPosition,
|
|
JsonValid,
|
|
JsonPatch,
|
|
JsonbPatch,
|
|
JsonRemove,
|
|
JsonbRemove,
|
|
JsonReplace,
|
|
JsonbReplace,
|
|
JsonInsert,
|
|
JsonbInsert,
|
|
JsonPretty,
|
|
JsonSet,
|
|
JsonbSet,
|
|
JsonQuote,
|
|
}
|
|
|
|
#[cfg(feature = "json")]
|
|
impl JsonFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
true
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "json")]
|
|
impl Display for JsonFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"{}",
|
|
match self {
|
|
Self::Json => "json".to_string(),
|
|
Self::Jsonb => "jsonb".to_string(),
|
|
Self::JsonArray => "json_array".to_string(),
|
|
Self::JsonbArray => "jsonb_array".to_string(),
|
|
Self::JsonExtract => "json_extract".to_string(),
|
|
Self::JsonbExtract => "jsonb_extract".to_string(),
|
|
Self::JsonArrayLength => "json_array_length".to_string(),
|
|
Self::JsonArrowExtract => "->".to_string(),
|
|
Self::JsonArrowShiftExtract => "->>".to_string(),
|
|
Self::JsonObject => "json_object".to_string(),
|
|
Self::JsonbObject => "jsonb_object".to_string(),
|
|
Self::JsonType => "json_type".to_string(),
|
|
Self::JsonErrorPosition => "json_error_position".to_string(),
|
|
Self::JsonValid => "json_valid".to_string(),
|
|
Self::JsonPatch => "json_patch".to_string(),
|
|
Self::JsonbPatch => "jsonb_patch".to_string(),
|
|
Self::JsonRemove => "json_remove".to_string(),
|
|
Self::JsonbRemove => "jsonb_remove".to_string(),
|
|
Self::JsonReplace => "json_replace".to_string(),
|
|
Self::JsonbReplace => "jsonb_replace".to_string(),
|
|
Self::JsonInsert => "json_insert".to_string(),
|
|
Self::JsonbInsert => "jsonb_insert".to_string(),
|
|
Self::JsonPretty => "json_pretty".to_string(),
|
|
Self::JsonSet => "json_set".to_string(),
|
|
Self::JsonbSet => "jsonb_set".to_string(),
|
|
Self::JsonQuote => "json_quote".to_string(),
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum VectorFunc {
|
|
Vector,
|
|
Vector32,
|
|
Vector64,
|
|
VectorExtract,
|
|
VectorDistanceCos,
|
|
}
|
|
|
|
impl VectorFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
true
|
|
}
|
|
}
|
|
|
|
impl Display for VectorFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let str = match self {
|
|
Self::Vector => "vector".to_string(),
|
|
Self::Vector32 => "vector32".to_string(),
|
|
Self::Vector64 => "vector64".to_string(),
|
|
Self::VectorExtract => "vector_extract".to_string(),
|
|
Self::VectorDistanceCos => "vector_distance_cos".to_string(),
|
|
};
|
|
write!(f, "{}", str)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum AggFunc {
|
|
Avg,
|
|
Count,
|
|
Count0,
|
|
GroupConcat,
|
|
Max,
|
|
Min,
|
|
StringAgg,
|
|
Sum,
|
|
Total,
|
|
#[cfg(feature = "json")]
|
|
JsonbGroupArray,
|
|
#[cfg(feature = "json")]
|
|
JsonGroupArray,
|
|
#[cfg(feature = "json")]
|
|
JsonbGroupObject,
|
|
#[cfg(feature = "json")]
|
|
JsonGroupObject,
|
|
External(Rc<ExtFunc>),
|
|
}
|
|
|
|
impl PartialEq for AggFunc {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
match (self, other) {
|
|
(Self::Avg, Self::Avg)
|
|
| (Self::Count, Self::Count)
|
|
| (Self::GroupConcat, Self::GroupConcat)
|
|
| (Self::Max, Self::Max)
|
|
| (Self::Min, Self::Min)
|
|
| (Self::StringAgg, Self::StringAgg)
|
|
| (Self::Sum, Self::Sum)
|
|
| (Self::Total, Self::Total) => true,
|
|
(Self::External(a), Self::External(b)) => Rc::ptr_eq(a, b),
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AggFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
false // consider aggregate functions nondeterministic since they depend on the number of rows, not only the input arguments
|
|
}
|
|
|
|
pub fn num_args(&self) -> usize {
|
|
match self {
|
|
Self::Avg => 1,
|
|
Self::Count0 => 0,
|
|
Self::Count => 1,
|
|
Self::GroupConcat => 1,
|
|
Self::Max => 1,
|
|
Self::Min => 1,
|
|
Self::StringAgg => 2,
|
|
Self::Sum => 1,
|
|
Self::Total => 1,
|
|
#[cfg(feature = "json")]
|
|
Self::JsonGroupArray | Self::JsonbGroupArray => 1,
|
|
#[cfg(feature = "json")]
|
|
Self::JsonGroupObject | Self::JsonbGroupObject => 2,
|
|
Self::External(func) => func.agg_args().unwrap_or(0),
|
|
}
|
|
}
|
|
|
|
pub fn to_string(&self) -> &str {
|
|
match self {
|
|
Self::Avg => "avg",
|
|
Self::Count0 => "count",
|
|
Self::Count => "count",
|
|
Self::GroupConcat => "group_concat",
|
|
Self::Max => "max",
|
|
Self::Min => "min",
|
|
Self::StringAgg => "string_agg",
|
|
Self::Sum => "sum",
|
|
Self::Total => "total",
|
|
#[cfg(feature = "json")]
|
|
Self::JsonbGroupArray => "jsonb_group_array",
|
|
#[cfg(feature = "json")]
|
|
Self::JsonGroupArray => "json_group_array",
|
|
#[cfg(feature = "json")]
|
|
Self::JsonbGroupObject => "jsonb_group_object",
|
|
#[cfg(feature = "json")]
|
|
Self::JsonGroupObject => "json_group_object",
|
|
Self::External(_) => "extension function",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum ScalarFunc {
|
|
Cast,
|
|
Changes,
|
|
Char,
|
|
Coalesce,
|
|
Concat,
|
|
ConcatWs,
|
|
Glob,
|
|
IfNull,
|
|
Iif,
|
|
Instr,
|
|
Like,
|
|
Abs,
|
|
Upper,
|
|
Lower,
|
|
Random,
|
|
RandomBlob,
|
|
Trim,
|
|
LTrim,
|
|
RTrim,
|
|
Round,
|
|
Length,
|
|
OctetLength,
|
|
Min,
|
|
Max,
|
|
Nullif,
|
|
Sign,
|
|
Substr,
|
|
Substring,
|
|
Soundex,
|
|
Date,
|
|
Time,
|
|
TotalChanges,
|
|
DateTime,
|
|
Typeof,
|
|
Unicode,
|
|
Quote,
|
|
SqliteVersion,
|
|
SqliteSourceId,
|
|
UnixEpoch,
|
|
JulianDay,
|
|
Hex,
|
|
Unhex,
|
|
ZeroBlob,
|
|
LastInsertRowid,
|
|
Replace,
|
|
#[cfg(feature = "fs")]
|
|
LoadExtension,
|
|
StrfTime,
|
|
Printf,
|
|
Likely,
|
|
TimeDiff,
|
|
Likelihood,
|
|
}
|
|
|
|
impl ScalarFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
match self {
|
|
ScalarFunc::Cast => true,
|
|
ScalarFunc::Changes => false, // depends on DB state
|
|
ScalarFunc::Char => true,
|
|
ScalarFunc::Coalesce => true,
|
|
ScalarFunc::Concat => true,
|
|
ScalarFunc::ConcatWs => true,
|
|
ScalarFunc::Glob => true,
|
|
ScalarFunc::IfNull => true,
|
|
ScalarFunc::Iif => true,
|
|
ScalarFunc::Instr => true,
|
|
ScalarFunc::Like => true,
|
|
ScalarFunc::Abs => true,
|
|
ScalarFunc::Upper => true,
|
|
ScalarFunc::Lower => true,
|
|
ScalarFunc::Random => false, // duh
|
|
ScalarFunc::RandomBlob => false, // duh
|
|
ScalarFunc::Trim => true,
|
|
ScalarFunc::LTrim => true,
|
|
ScalarFunc::RTrim => true,
|
|
ScalarFunc::Round => true,
|
|
ScalarFunc::Length => true,
|
|
ScalarFunc::OctetLength => true,
|
|
ScalarFunc::Min => true,
|
|
ScalarFunc::Max => true,
|
|
ScalarFunc::Nullif => true,
|
|
ScalarFunc::Sign => true,
|
|
ScalarFunc::Substr => true,
|
|
ScalarFunc::Substring => true,
|
|
ScalarFunc::Soundex => true,
|
|
ScalarFunc::Date => false,
|
|
ScalarFunc::Time => false,
|
|
ScalarFunc::TotalChanges => false,
|
|
ScalarFunc::DateTime => false,
|
|
ScalarFunc::Typeof => true,
|
|
ScalarFunc::Unicode => true,
|
|
ScalarFunc::Quote => true,
|
|
ScalarFunc::SqliteVersion => true,
|
|
ScalarFunc::SqliteSourceId => true,
|
|
ScalarFunc::UnixEpoch => false,
|
|
ScalarFunc::JulianDay => false,
|
|
ScalarFunc::Hex => true,
|
|
ScalarFunc::Unhex => true,
|
|
ScalarFunc::ZeroBlob => true,
|
|
ScalarFunc::LastInsertRowid => false,
|
|
ScalarFunc::Replace => true,
|
|
#[cfg(feature = "fs")]
|
|
ScalarFunc::LoadExtension => true,
|
|
ScalarFunc::StrfTime => false,
|
|
ScalarFunc::Printf => false,
|
|
ScalarFunc::Likely => true,
|
|
ScalarFunc::TimeDiff => false,
|
|
ScalarFunc::Likelihood => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for ScalarFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let str = match self {
|
|
Self::Cast => "cast".to_string(),
|
|
Self::Changes => "changes".to_string(),
|
|
Self::Char => "char".to_string(),
|
|
Self::Coalesce => "coalesce".to_string(),
|
|
Self::Concat => "concat".to_string(),
|
|
Self::ConcatWs => "concat_ws".to_string(),
|
|
Self::Glob => "glob".to_string(),
|
|
Self::IfNull => "ifnull".to_string(),
|
|
Self::Iif => "iif".to_string(),
|
|
Self::Instr => "instr".to_string(),
|
|
Self::Like => "like(2)".to_string(),
|
|
Self::Abs => "abs".to_string(),
|
|
Self::Upper => "upper".to_string(),
|
|
Self::Lower => "lower".to_string(),
|
|
Self::Random => "random".to_string(),
|
|
Self::RandomBlob => "randomblob".to_string(),
|
|
Self::Trim => "trim".to_string(),
|
|
Self::LTrim => "ltrim".to_string(),
|
|
Self::RTrim => "rtrim".to_string(),
|
|
Self::Round => "round".to_string(),
|
|
Self::Length => "length".to_string(),
|
|
Self::OctetLength => "octet_length".to_string(),
|
|
Self::Min => "min".to_string(),
|
|
Self::Max => "max".to_string(),
|
|
Self::Nullif => "nullif".to_string(),
|
|
Self::Sign => "sign".to_string(),
|
|
Self::Substr => "substr".to_string(),
|
|
Self::Substring => "substring".to_string(),
|
|
Self::Soundex => "soundex".to_string(),
|
|
Self::Date => "date".to_string(),
|
|
Self::Time => "time".to_string(),
|
|
Self::TotalChanges => "total_changes".to_string(),
|
|
Self::Typeof => "typeof".to_string(),
|
|
Self::Unicode => "unicode".to_string(),
|
|
Self::Quote => "quote".to_string(),
|
|
Self::SqliteVersion => "sqlite_version".to_string(),
|
|
Self::SqliteSourceId => "sqlite_source_id".to_string(),
|
|
Self::JulianDay => "julianday".to_string(),
|
|
Self::UnixEpoch => "unixepoch".to_string(),
|
|
Self::Hex => "hex".to_string(),
|
|
Self::Unhex => "unhex".to_string(),
|
|
Self::ZeroBlob => "zeroblob".to_string(),
|
|
Self::LastInsertRowid => "last_insert_rowid".to_string(),
|
|
Self::Replace => "replace".to_string(),
|
|
Self::DateTime => "datetime".to_string(),
|
|
#[cfg(feature = "fs")]
|
|
Self::LoadExtension => "load_extension".to_string(),
|
|
Self::StrfTime => "strftime".to_string(),
|
|
Self::Printf => "printf".to_string(),
|
|
Self::Likely => "likely".to_string(),
|
|
Self::TimeDiff => "timediff".to_string(),
|
|
Self::Likelihood => "likelihood".to_string(),
|
|
};
|
|
write!(f, "{}", str)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum MathFunc {
|
|
Acos,
|
|
Acosh,
|
|
Asin,
|
|
Asinh,
|
|
Atan,
|
|
Atan2,
|
|
Atanh,
|
|
Ceil,
|
|
Ceiling,
|
|
Cos,
|
|
Cosh,
|
|
Degrees,
|
|
Exp,
|
|
Floor,
|
|
Ln,
|
|
Log,
|
|
Log10,
|
|
Log2,
|
|
Mod,
|
|
Pi,
|
|
Pow,
|
|
Power,
|
|
Radians,
|
|
Sin,
|
|
Sinh,
|
|
Sqrt,
|
|
Tan,
|
|
Tanh,
|
|
Trunc,
|
|
}
|
|
|
|
pub enum MathFuncArity {
|
|
Nullary,
|
|
Unary,
|
|
Binary,
|
|
UnaryOrBinary,
|
|
}
|
|
|
|
impl MathFunc {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
true
|
|
}
|
|
pub fn arity(&self) -> MathFuncArity {
|
|
match self {
|
|
Self::Pi => MathFuncArity::Nullary,
|
|
Self::Acos
|
|
| Self::Acosh
|
|
| Self::Asin
|
|
| Self::Asinh
|
|
| Self::Atan
|
|
| Self::Atanh
|
|
| Self::Ceil
|
|
| Self::Ceiling
|
|
| Self::Cos
|
|
| Self::Cosh
|
|
| Self::Degrees
|
|
| Self::Exp
|
|
| Self::Floor
|
|
| Self::Ln
|
|
| Self::Log10
|
|
| Self::Log2
|
|
| Self::Radians
|
|
| Self::Sin
|
|
| Self::Sinh
|
|
| Self::Sqrt
|
|
| Self::Tan
|
|
| Self::Tanh
|
|
| Self::Trunc => MathFuncArity::Unary,
|
|
|
|
Self::Atan2 | Self::Mod | Self::Pow | Self::Power => MathFuncArity::Binary,
|
|
|
|
Self::Log => MathFuncArity::UnaryOrBinary,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for MathFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let str = match self {
|
|
Self::Acos => "acos".to_string(),
|
|
Self::Acosh => "acosh".to_string(),
|
|
Self::Asin => "asin".to_string(),
|
|
Self::Asinh => "asinh".to_string(),
|
|
Self::Atan => "atan".to_string(),
|
|
Self::Atan2 => "atan2".to_string(),
|
|
Self::Atanh => "atanh".to_string(),
|
|
Self::Ceil => "ceil".to_string(),
|
|
Self::Ceiling => "ceiling".to_string(),
|
|
Self::Cos => "cos".to_string(),
|
|
Self::Cosh => "cosh".to_string(),
|
|
Self::Degrees => "degrees".to_string(),
|
|
Self::Exp => "exp".to_string(),
|
|
Self::Floor => "floor".to_string(),
|
|
Self::Ln => "ln".to_string(),
|
|
Self::Log => "log".to_string(),
|
|
Self::Log10 => "log10".to_string(),
|
|
Self::Log2 => "log2".to_string(),
|
|
Self::Mod => "mod".to_string(),
|
|
Self::Pi => "pi".to_string(),
|
|
Self::Pow => "pow".to_string(),
|
|
Self::Power => "power".to_string(),
|
|
Self::Radians => "radians".to_string(),
|
|
Self::Sin => "sin".to_string(),
|
|
Self::Sinh => "sinh".to_string(),
|
|
Self::Sqrt => "sqrt".to_string(),
|
|
Self::Tan => "tan".to_string(),
|
|
Self::Tanh => "tanh".to_string(),
|
|
Self::Trunc => "trunc".to_string(),
|
|
};
|
|
write!(f, "{}", str)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum AlterTableFunc {
|
|
RenameTable,
|
|
RenameColumn,
|
|
}
|
|
|
|
impl Display for AlterTableFunc {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
AlterTableFunc::RenameTable => write!(f, "limbo_rename_table"),
|
|
AlterTableFunc::RenameColumn => write!(f, "limbo_rename_column"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Func {
|
|
Agg(AggFunc),
|
|
Scalar(ScalarFunc),
|
|
Math(MathFunc),
|
|
Vector(VectorFunc),
|
|
#[cfg(feature = "json")]
|
|
Json(JsonFunc),
|
|
AlterTable(AlterTableFunc),
|
|
External(Rc<ExternalFunc>),
|
|
}
|
|
|
|
impl Display for Func {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::Agg(agg_func) => write!(f, "{}", agg_func.to_string()),
|
|
Self::Scalar(scalar_func) => write!(f, "{}", scalar_func),
|
|
Self::Math(math_func) => write!(f, "{}", math_func),
|
|
Self::Vector(vector_func) => write!(f, "{}", vector_func),
|
|
#[cfg(feature = "json")]
|
|
Self::Json(json_func) => write!(f, "{}", json_func),
|
|
Self::External(generic_func) => write!(f, "{}", generic_func),
|
|
Self::AlterTable(alter_func) => write!(f, "{}", alter_func),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct FuncCtx {
|
|
pub func: Func,
|
|
pub arg_count: usize,
|
|
}
|
|
|
|
impl Func {
|
|
pub fn is_deterministic(&self) -> bool {
|
|
match self {
|
|
Self::Agg(agg_func) => agg_func.is_deterministic(),
|
|
Self::Scalar(scalar_func) => scalar_func.is_deterministic(),
|
|
Self::Math(math_func) => math_func.is_deterministic(),
|
|
Self::Vector(vector_func) => vector_func.is_deterministic(),
|
|
#[cfg(feature = "json")]
|
|
Self::Json(json_func) => json_func.is_deterministic(),
|
|
Self::External(external_func) => external_func.is_deterministic(),
|
|
Self::AlterTable(_) => true,
|
|
}
|
|
}
|
|
pub fn resolve_function(name: &str, arg_count: usize) -> Result<Self, LimboError> {
|
|
match name {
|
|
"avg" => {
|
|
if arg_count != 1 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::Avg))
|
|
}
|
|
"count" => {
|
|
// Handle both COUNT() and COUNT(expr) cases
|
|
if arg_count == 0 {
|
|
Ok(Self::Agg(AggFunc::Count0)) // COUNT() case
|
|
} else if arg_count == 1 {
|
|
Ok(Self::Agg(AggFunc::Count)) // COUNT(expr) case
|
|
} else {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
}
|
|
"group_concat" => {
|
|
if arg_count != 1 && arg_count != 2 {
|
|
println!("{}", arg_count);
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::GroupConcat))
|
|
}
|
|
"max" if arg_count > 1 => Ok(Self::Scalar(ScalarFunc::Max)),
|
|
"max" => {
|
|
if arg_count < 1 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::Max))
|
|
}
|
|
"min" if arg_count > 1 => Ok(Self::Scalar(ScalarFunc::Min)),
|
|
"min" => {
|
|
if arg_count < 1 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::Min))
|
|
}
|
|
"nullif" if arg_count == 2 => Ok(Self::Scalar(ScalarFunc::Nullif)),
|
|
"string_agg" => {
|
|
if arg_count != 2 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::StringAgg))
|
|
}
|
|
"sum" => {
|
|
if arg_count != 1 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::Sum))
|
|
}
|
|
"total" => {
|
|
if arg_count != 1 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Agg(AggFunc::Total))
|
|
}
|
|
"timediff" => {
|
|
if arg_count != 2 {
|
|
crate::bail_parse_error!("wrong number of arguments to function {}()", name)
|
|
}
|
|
Ok(Self::Scalar(ScalarFunc::TimeDiff))
|
|
}
|
|
#[cfg(feature = "json")]
|
|
"jsonb_group_array" => Ok(Self::Agg(AggFunc::JsonbGroupArray)),
|
|
#[cfg(feature = "json")]
|
|
"json_group_array" => Ok(Self::Agg(AggFunc::JsonGroupArray)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_group_object" => Ok(Self::Agg(AggFunc::JsonbGroupObject)),
|
|
#[cfg(feature = "json")]
|
|
"json_group_object" => Ok(Self::Agg(AggFunc::JsonGroupObject)),
|
|
"char" => Ok(Self::Scalar(ScalarFunc::Char)),
|
|
"coalesce" => Ok(Self::Scalar(ScalarFunc::Coalesce)),
|
|
"concat" => Ok(Self::Scalar(ScalarFunc::Concat)),
|
|
"concat_ws" => Ok(Self::Scalar(ScalarFunc::ConcatWs)),
|
|
"changes" => Ok(Self::Scalar(ScalarFunc::Changes)),
|
|
"total_changes" => Ok(Self::Scalar(ScalarFunc::TotalChanges)),
|
|
"glob" => Ok(Self::Scalar(ScalarFunc::Glob)),
|
|
"ifnull" => Ok(Self::Scalar(ScalarFunc::IfNull)),
|
|
"iif" => Ok(Self::Scalar(ScalarFunc::Iif)),
|
|
"instr" => Ok(Self::Scalar(ScalarFunc::Instr)),
|
|
"like" => Ok(Self::Scalar(ScalarFunc::Like)),
|
|
"abs" => Ok(Self::Scalar(ScalarFunc::Abs)),
|
|
"upper" => Ok(Self::Scalar(ScalarFunc::Upper)),
|
|
"lower" => Ok(Self::Scalar(ScalarFunc::Lower)),
|
|
"random" => Ok(Self::Scalar(ScalarFunc::Random)),
|
|
"randomblob" => Ok(Self::Scalar(ScalarFunc::RandomBlob)),
|
|
"trim" => Ok(Self::Scalar(ScalarFunc::Trim)),
|
|
"ltrim" => Ok(Self::Scalar(ScalarFunc::LTrim)),
|
|
"rtrim" => Ok(Self::Scalar(ScalarFunc::RTrim)),
|
|
"round" => Ok(Self::Scalar(ScalarFunc::Round)),
|
|
"length" => Ok(Self::Scalar(ScalarFunc::Length)),
|
|
"octet_length" => Ok(Self::Scalar(ScalarFunc::OctetLength)),
|
|
"sign" => Ok(Self::Scalar(ScalarFunc::Sign)),
|
|
"substr" => Ok(Self::Scalar(ScalarFunc::Substr)),
|
|
"substring" => Ok(Self::Scalar(ScalarFunc::Substring)),
|
|
"date" => Ok(Self::Scalar(ScalarFunc::Date)),
|
|
"time" => Ok(Self::Scalar(ScalarFunc::Time)),
|
|
"datetime" => Ok(Self::Scalar(ScalarFunc::DateTime)),
|
|
"typeof" => Ok(Self::Scalar(ScalarFunc::Typeof)),
|
|
"last_insert_rowid" => Ok(Self::Scalar(ScalarFunc::LastInsertRowid)),
|
|
"unicode" => Ok(Self::Scalar(ScalarFunc::Unicode)),
|
|
"quote" => Ok(Self::Scalar(ScalarFunc::Quote)),
|
|
"sqlite_version" => Ok(Self::Scalar(ScalarFunc::SqliteVersion)),
|
|
"sqlite_source_id" => Ok(Self::Scalar(ScalarFunc::SqliteSourceId)),
|
|
"replace" => Ok(Self::Scalar(ScalarFunc::Replace)),
|
|
"likely" => Ok(Self::Scalar(ScalarFunc::Likely)),
|
|
"likelihood" => Ok(Self::Scalar(ScalarFunc::Likelihood)),
|
|
#[cfg(feature = "json")]
|
|
"json" => Ok(Self::Json(JsonFunc::Json)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb" => Ok(Self::Json(JsonFunc::Jsonb)),
|
|
#[cfg(feature = "json")]
|
|
"json_array_length" => Ok(Self::Json(JsonFunc::JsonArrayLength)),
|
|
#[cfg(feature = "json")]
|
|
"json_array" => Ok(Self::Json(JsonFunc::JsonArray)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_array" => Ok(Self::Json(JsonFunc::JsonbArray)),
|
|
#[cfg(feature = "json")]
|
|
"json_extract" => Ok(Func::Json(JsonFunc::JsonExtract)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_extract" => Ok(Func::Json(JsonFunc::JsonbExtract)),
|
|
#[cfg(feature = "json")]
|
|
"json_object" => Ok(Func::Json(JsonFunc::JsonObject)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_object" => Ok(Func::Json(JsonFunc::JsonbObject)),
|
|
#[cfg(feature = "json")]
|
|
"json_type" => Ok(Func::Json(JsonFunc::JsonType)),
|
|
#[cfg(feature = "json")]
|
|
"json_error_position" => Ok(Self::Json(JsonFunc::JsonErrorPosition)),
|
|
#[cfg(feature = "json")]
|
|
"json_valid" => Ok(Self::Json(JsonFunc::JsonValid)),
|
|
#[cfg(feature = "json")]
|
|
"json_patch" => Ok(Self::Json(JsonFunc::JsonPatch)),
|
|
#[cfg(feature = "json")]
|
|
"json_remove" => Ok(Self::Json(JsonFunc::JsonRemove)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_remove" => Ok(Self::Json(JsonFunc::JsonbRemove)),
|
|
#[cfg(feature = "json")]
|
|
"json_replace" => Ok(Self::Json(JsonFunc::JsonReplace)),
|
|
#[cfg(feature = "json")]
|
|
"json_insert" => Ok(Self::Json(JsonFunc::JsonInsert)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_insert" => Ok(Self::Json(JsonFunc::JsonbInsert)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_replace" => Ok(Self::Json(JsonFunc::JsonReplace)),
|
|
#[cfg(feature = "json")]
|
|
"json_pretty" => Ok(Self::Json(JsonFunc::JsonPretty)),
|
|
#[cfg(feature = "json")]
|
|
"json_set" => Ok(Self::Json(JsonFunc::JsonSet)),
|
|
#[cfg(feature = "json")]
|
|
"jsonb_set" => Ok(Self::Json(JsonFunc::JsonbSet)),
|
|
#[cfg(feature = "json")]
|
|
"json_quote" => Ok(Self::Json(JsonFunc::JsonQuote)),
|
|
"unixepoch" => Ok(Self::Scalar(ScalarFunc::UnixEpoch)),
|
|
"julianday" => Ok(Self::Scalar(ScalarFunc::JulianDay)),
|
|
"hex" => Ok(Self::Scalar(ScalarFunc::Hex)),
|
|
"unhex" => Ok(Self::Scalar(ScalarFunc::Unhex)),
|
|
"zeroblob" => Ok(Self::Scalar(ScalarFunc::ZeroBlob)),
|
|
"soundex" => Ok(Self::Scalar(ScalarFunc::Soundex)),
|
|
"acos" => Ok(Self::Math(MathFunc::Acos)),
|
|
"acosh" => Ok(Self::Math(MathFunc::Acosh)),
|
|
"asin" => Ok(Self::Math(MathFunc::Asin)),
|
|
"asinh" => Ok(Self::Math(MathFunc::Asinh)),
|
|
"atan" => Ok(Self::Math(MathFunc::Atan)),
|
|
"atan2" => Ok(Self::Math(MathFunc::Atan2)),
|
|
"atanh" => Ok(Self::Math(MathFunc::Atanh)),
|
|
"ceil" => Ok(Self::Math(MathFunc::Ceil)),
|
|
"ceiling" => Ok(Self::Math(MathFunc::Ceiling)),
|
|
"cos" => Ok(Self::Math(MathFunc::Cos)),
|
|
"cosh" => Ok(Self::Math(MathFunc::Cosh)),
|
|
"degrees" => Ok(Self::Math(MathFunc::Degrees)),
|
|
"exp" => Ok(Self::Math(MathFunc::Exp)),
|
|
"floor" => Ok(Self::Math(MathFunc::Floor)),
|
|
"ln" => Ok(Self::Math(MathFunc::Ln)),
|
|
"log" => Ok(Self::Math(MathFunc::Log)),
|
|
"log10" => Ok(Self::Math(MathFunc::Log10)),
|
|
"log2" => Ok(Self::Math(MathFunc::Log2)),
|
|
"mod" => Ok(Self::Math(MathFunc::Mod)),
|
|
"pi" => Ok(Self::Math(MathFunc::Pi)),
|
|
"pow" => Ok(Self::Math(MathFunc::Pow)),
|
|
"power" => Ok(Self::Math(MathFunc::Power)),
|
|
"radians" => Ok(Self::Math(MathFunc::Radians)),
|
|
"sin" => Ok(Self::Math(MathFunc::Sin)),
|
|
"sinh" => Ok(Self::Math(MathFunc::Sinh)),
|
|
"sqrt" => Ok(Self::Math(MathFunc::Sqrt)),
|
|
"tan" => Ok(Self::Math(MathFunc::Tan)),
|
|
"tanh" => Ok(Self::Math(MathFunc::Tanh)),
|
|
"trunc" => Ok(Self::Math(MathFunc::Trunc)),
|
|
#[cfg(feature = "fs")]
|
|
"load_extension" => Ok(Self::Scalar(ScalarFunc::LoadExtension)),
|
|
"strftime" => Ok(Self::Scalar(ScalarFunc::StrfTime)),
|
|
"printf" => Ok(Self::Scalar(ScalarFunc::Printf)),
|
|
"vector" => Ok(Self::Vector(VectorFunc::Vector)),
|
|
"vector32" => Ok(Self::Vector(VectorFunc::Vector32)),
|
|
"vector64" => Ok(Self::Vector(VectorFunc::Vector64)),
|
|
"vector_extract" => Ok(Self::Vector(VectorFunc::VectorExtract)),
|
|
"vector_distance_cos" => Ok(Self::Vector(VectorFunc::VectorDistanceCos)),
|
|
_ => crate::bail_parse_error!("no such function: {}", name),
|
|
}
|
|
}
|
|
}
|