use super::types::DataType;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FunctionKind {
Scalar,
Aggregate,
Window,
Volatile,
}
#[derive(Debug, Clone, Copy)]
pub struct FunctionEntry {
pub name: &'static str,
pub arg_types: &'static [DataType],
pub return_type: DataType,
pub kind: FunctionKind,
pub variadic: bool,
}
const fn entry(
name: &'static str,
arg_types: &'static [DataType],
return_type: DataType,
kind: FunctionKind,
variadic: bool,
) -> FunctionEntry {
FunctionEntry {
name,
arg_types,
return_type,
kind,
variadic,
}
}
const ARGS_INT: &[DataType] = &[DataType::Integer];
const ARGS_FLOAT: &[DataType] = &[DataType::Float];
const ARGS_BIGINT: &[DataType] = &[DataType::BigInt];
const ARGS_TEXT: &[DataType] = &[DataType::Text];
const ARGS_TWO_TEXT: &[DataType] = &[DataType::Text, DataType::Text];
const ARGS_TEXT_INT: &[DataType] = &[DataType::Text, DataType::Integer];
const ARGS_TEXT_TWO_INT: &[DataType] = &[DataType::Text, DataType::Integer, DataType::Integer];
const ARGS_NONE: &[DataType] = &[];
const ARGS_TWO_FLOATS: &[DataType] = &[DataType::Float, DataType::Float];
const ARGS_GEO_PAIR: &[DataType] = &[DataType::GeoPoint, DataType::GeoPoint];
const ARGS_FOUR_FLOATS: &[DataType] = &[
DataType::Float,
DataType::Float,
DataType::Float,
DataType::Float,
];
const ARGS_TIME_BUCKET: &[DataType] = &[DataType::Text, DataType::Timestamp];
const ARGS_VERIFY_PWD: &[DataType] = &[DataType::Password, DataType::Text];
const ARGS_MONEY: &[DataType] = &[DataType::Money];
const ARGS_ONE_TEXT: &[DataType] = &[DataType::Text];
const ARGS_TWO_TEXT_ANY: &[DataType] = &[DataType::Text, DataType::Text];
const ARGS_JSON_TEXT: &[DataType] = &[DataType::Text];
const ARGS_JSON_JSON: &[DataType] = &[DataType::Json];
const ARGS_JSON_EXTRACT_TEXT: &[DataType] = &[DataType::Text, DataType::Text];
const ARGS_JSON_EXTRACT_JSON: &[DataType] = &[DataType::Json, DataType::Text];
const ARGS_JSON_SET_TEXT: &[DataType] = &[DataType::Text, DataType::Text, DataType::Unknown];
const ARGS_JSON_SET_JSON: &[DataType] = &[DataType::Json, DataType::Text, DataType::Unknown];
pub const FUNCTION_CATALOG: &[FunctionEntry] = &[
entry(
"COUNT",
ARGS_INT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"COUNT",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"COUNT",
ARGS_FLOAT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"SUM",
ARGS_INT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"SUM",
ARGS_BIGINT,
DataType::BigInt,
FunctionKind::Aggregate,
false,
),
entry(
"SUM",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"AVG",
ARGS_INT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"AVG",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"MIN",
ARGS_INT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"MIN",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"MIN",
ARGS_TEXT,
DataType::Text,
FunctionKind::Aggregate,
false,
),
entry(
"MAX",
ARGS_INT,
DataType::Integer,
FunctionKind::Aggregate,
false,
),
entry(
"MAX",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"MAX",
ARGS_TEXT,
DataType::Text,
FunctionKind::Aggregate,
false,
),
entry(
"STDDEV",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"VARIANCE",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Aggregate,
false,
),
entry(
"GROUP_CONCAT",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Aggregate,
false,
),
entry(
"STRING_AGG",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Aggregate,
false,
),
entry(
"UPPER",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"LOWER",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"LENGTH",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"CHAR_LENGTH",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"CHARACTER_LENGTH",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"OCTET_LENGTH",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"BIT_LENGTH",
ARGS_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"SUBSTRING",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"SUBSTRING",
ARGS_TEXT_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"SUBSTRING",
ARGS_TEXT_TWO_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"SUBSTR",
ARGS_TEXT_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"SUBSTR",
ARGS_TEXT_TWO_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"POSITION",
ARGS_TWO_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"TRIM",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"TRIM",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"LTRIM",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"LTRIM",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"RTRIM",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"RTRIM",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"BTRIM",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"BTRIM",
ARGS_TWO_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"CONCAT",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
true,
),
entry(
"CONCAT_WS",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
true,
),
entry(
"REVERSE",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"LEFT",
ARGS_TEXT_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"RIGHT",
ARGS_TEXT_INT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"QUOTE_LITERAL",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"COALESCE",
ARGS_TEXT,
DataType::Text,
FunctionKind::Scalar,
true,
),
entry(
"ABS",
ARGS_INT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"ABS",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"ROUND",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"FLOOR",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"CEIL",
ARGS_FLOAT,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"NOW",
ARGS_NONE,
DataType::TimestampMs,
FunctionKind::Volatile,
false,
),
entry(
"CURRENT_TIMESTAMP",
ARGS_NONE,
DataType::TimestampMs,
FunctionKind::Volatile,
false,
),
entry(
"CURRENT_DATE",
ARGS_NONE,
DataType::Date,
FunctionKind::Volatile,
false,
),
entry(
"CURRENT_TENANT",
ARGS_NONE,
DataType::Text,
FunctionKind::Volatile,
false,
),
entry(
"CURRENT_USER",
ARGS_NONE,
DataType::Text,
FunctionKind::Volatile,
false,
),
entry(
"SESSION_USER",
ARGS_NONE,
DataType::Text,
FunctionKind::Volatile,
false,
),
entry(
"CURRENT_ROLE",
ARGS_NONE,
DataType::Text,
FunctionKind::Volatile,
false,
),
entry(
"TIME_BUCKET",
ARGS_TIME_BUCKET,
DataType::TimestampMs,
FunctionKind::Scalar,
false,
),
entry(
"GEO_DISTANCE",
ARGS_GEO_PAIR,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"GEO_DISTANCE",
ARGS_FOUR_FLOATS,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"GEO_BEARING",
ARGS_FOUR_FLOATS,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"HAVERSINE",
ARGS_FOUR_FLOATS,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"VINCENTY",
ARGS_FOUR_FLOATS,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"VERIFY_PASSWORD",
ARGS_VERIFY_PWD,
DataType::Boolean,
FunctionKind::Volatile,
false,
),
entry(
"MONEY",
ARGS_ONE_TEXT,
DataType::Money,
FunctionKind::Scalar,
false,
),
entry(
"MONEY",
ARGS_TWO_TEXT_ANY,
DataType::Money,
FunctionKind::Scalar,
false,
),
entry(
"MONEY_ASSET",
ARGS_MONEY,
DataType::AssetCode,
FunctionKind::Scalar,
false,
),
entry(
"MONEY_MINOR",
ARGS_MONEY,
DataType::BigInt,
FunctionKind::Scalar,
false,
),
entry(
"MONEY_SCALE",
ARGS_MONEY,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"POWER",
ARGS_TWO_FLOATS,
DataType::Float,
FunctionKind::Scalar,
false,
),
entry(
"JSON_EXTRACT",
ARGS_JSON_EXTRACT_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_EXTRACT",
ARGS_JSON_EXTRACT_JSON,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_EXTRACT_TEXT",
ARGS_JSON_EXTRACT_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_EXTRACT_TEXT",
ARGS_JSON_EXTRACT_JSON,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_SET",
ARGS_JSON_SET_TEXT,
DataType::Json,
FunctionKind::Scalar,
false,
),
entry(
"JSON_SET",
ARGS_JSON_SET_JSON,
DataType::Json,
FunctionKind::Scalar,
false,
),
entry(
"JSON_ARRAY_LENGTH",
ARGS_JSON_TEXT,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"JSON_ARRAY_LENGTH",
ARGS_JSON_JSON,
DataType::Integer,
FunctionKind::Scalar,
false,
),
entry(
"JSON_TYPEOF",
ARGS_JSON_TEXT,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_TYPEOF",
ARGS_JSON_JSON,
DataType::Text,
FunctionKind::Scalar,
false,
),
entry(
"JSON_VALID",
ARGS_TEXT,
DataType::Boolean,
FunctionKind::Scalar,
false,
),
entry(
"JSON_ARRAY",
&[DataType::Unknown],
DataType::Json,
FunctionKind::Scalar,
true,
),
entry(
"JSON_OBJECT",
&[DataType::Unknown],
DataType::Json,
FunctionKind::Scalar,
true,
),
];
pub fn lookup(name: &str) -> Vec<&'static FunctionEntry> {
FUNCTION_CATALOG
.iter()
.filter(|e| e.name.eq_ignore_ascii_case(name))
.collect()
}
pub fn resolve(name: &str, arg_types: &[DataType]) -> Option<&'static FunctionEntry> {
super::coercion_spine::resolve_function(name, arg_types).map(|(entry, _)| entry)
}