surrealdb-sql 3.3.1

A scalable, distributed, collaborative, document-graph database, for the realtime web
Documentation
//! The static mirror of the builtin method dispatch tables.
//!
//! Method-call syntax (`value.name(args)`) dispatches to a builtin function
//! when `name` is a registered method, and otherwise falls through to a
//! closure stored under that name on the receiver. Read-only classification
//! has to make that distinction before any engine resolves the call: a
//! builtin method writes nothing the classifier cannot already see in its
//! arguments, while an unregistered name invokes a runtime value whose body
//! is invisible, so it must be over-approximated as writable.
//!
//! [`BUILTIN_METHOD_NAMES`] mirrors the names registered by the executor's
//! method registry (`build_method_registry` in the core crate), which cannot
//! be consulted from here without inverting the crate dependency. A test in
//! that module asserts the two stay identical.
//!
//! It lives in this layer rather than the expression layer because both the
//! surface AST and the expression tree classify a method call the same way.

/// Every method name that dispatches to a builtin function, sorted so
/// membership is a binary search.
pub const BUILTIN_METHOD_NAMES: &[&str] = &[
	"abs",
	"acos",
	"acot",
	"add",
	"all",
	"any",
	"append",
	"area",
	"asin",
	"at",
	"atan",
	"bearing",
	"boolean_and",
	"boolean_not",
	"boolean_or",
	"boolean_xor",
	"bucket",
	"capitalize",
	"ceil",
	"centroid",
	"chain",
	"clump",
	"combine",
	"complement",
	"concat",
	"contains",
	"copy",
	"copy_if_not_exists",
	"cos",
	"cot",
	"day",
	"days",
	"deg2rad",
	"delete",
	"diff",
	"difference",
	"distance",
	"distance_damerau_levenshtein",
	"distance_hamming",
	"distance_levenshtein",
	"distance_normalized_damerau_levenshtein",
	"distance_normalized_levenshtein",
	"distinct",
	"ends_with",
	"entries",
	"every",
	"exists",
	"expect",
	"extend",
	"fill",
	"filter",
	"filter_index",
	"find",
	"find_index",
	"first",
	"flatten",
	"floor",
	"fold",
	"format",
	"get",
	"group",
	"hash_decode",
	"hash_encode",
	"head",
	"hour",
	"hours",
	"html_encode",
	"html_sanitize",
	"id",
	"includes",
	"index_of",
	"insert",
	"intersect",
	"is_alpha",
	"is_alphanum",
	"is_array",
	"is_ascii",
	"is_bool",
	"is_bytes",
	"is_collection",
	"is_datetime",
	"is_decimal",
	"is_domain",
	"is_duration",
	"is_edge",
	"is_email",
	"is_empty",
	"is_float",
	"is_geometry",
	"is_hexadecimal",
	"is_int",
	"is_ip",
	"is_ipv4",
	"is_ipv6",
	"is_latitude",
	"is_leap_year",
	"is_line",
	"is_longitude",
	"is_multiline",
	"is_multipoint",
	"is_multipolygon",
	"is_none",
	"is_null",
	"is_number",
	"is_numeric",
	"is_object",
	"is_point",
	"is_polygon",
	"is_range",
	"is_record",
	"is_semver",
	"is_set",
	"is_string",
	"is_ulid",
	"is_url",
	"is_uuid",
	"is_valid",
	"join",
	"key",
	"keys",
	"last",
	"len",
	"list",
	"ln",
	"log",
	"log10",
	"log2",
	"logical_and",
	"logical_or",
	"logical_xor",
	"lowercase",
	"map",
	"matches",
	"max",
	"micros",
	"millis",
	"min",
	"mins",
	"minute",
	"month",
	"nano",
	"nanos",
	"patch",
	"pop",
	"prepend",
	"push",
	"put",
	"put_if_not_exists",
	"rad2deg",
	"reduce",
	"remove",
	"rename",
	"rename_if_not_exists",
	"repeat",
	"replace",
	"reverse",
	"round",
	"second",
	"secs",
	"semver_compare",
	"semver_inc_major",
	"semver_inc_minor",
	"semver_inc_patch",
	"semver_major",
	"semver_minor",
	"semver_patch",
	"semver_set_major",
	"semver_set_minor",
	"semver_set_patch",
	"set_day",
	"set_hour",
	"set_minute",
	"set_month",
	"set_nanosecond",
	"set_second",
	"set_year",
	"shuffle",
	"sign",
	"similarity_fuzzy",
	"similarity_jaro",
	"similarity_jaro_winkler",
	"similarity_smithwaterman",
	"similarity_sorensen_dice",
	"sin",
	"slice",
	"slug",
	"some",
	"sort",
	"sort_asc",
	"sort_desc",
	"sort_lexical",
	"sort_natural",
	"sort_natural_lexical",
	"split",
	"starts_with",
	"swap",
	"table",
	"tan",
	"tb",
	"to_array",
	"to_bool",
	"to_bytes",
	"to_datetime",
	"to_decimal",
	"to_duration",
	"to_float",
	"to_geometry",
	"to_int",
	"to_number",
	"to_point",
	"to_range",
	"to_record",
	"to_set",
	"to_string",
	"to_string_lossy",
	"to_uuid",
	"transpose",
	"trim",
	"type_of",
	"union",
	"unix",
	"uppercase",
	"values",
	"vector_add",
	"vector_angle",
	"vector_cross",
	"vector_distance_chebyshev",
	"vector_distance_euclidean",
	"vector_distance_hamming",
	"vector_distance_mahalanobis",
	"vector_distance_manhattan",
	"vector_distance_minkowski",
	"vector_divide",
	"vector_dot",
	"vector_magnitude",
	"vector_multiply",
	"vector_normalize",
	"vector_project",
	"vector_scale",
	"vector_similarity_cosine",
	"vector_similarity_jaccard",
	"vector_similarity_pearson",
	"vector_similarity_spearman",
	"vector_subtract",
	"vector_sum",
	"wday",
	"week",
	"weeks",
	"windows",
	"words",
	"yday",
	"year",
	"years",
];

/// Whether `name` in `value.name(args)` dispatches to a builtin function
/// rather than a closure stored on the receiver.
pub fn is_builtin_method(name: &str) -> bool {
	BUILTIN_METHOD_NAMES.binary_search(&name).is_ok()
}

/// Whether the named builtin can evaluate arbitrary nested statements, and so
/// needs a write transaction whatever its arguments look like.
///
/// Every other builtin writes nothing of its own; only its arguments carry
/// user expressions. Both `read_only` predicates and the planner's access-mode
/// choice ask this, so a builtin added to one is added to all three.
pub fn is_writer_builtin(name: &str) -> bool {
	matches!(name, "api::invoke" | "eval::gql" | "eval::surql")
}

#[cfg(test)]
mod tests {
	use super::BUILTIN_METHOD_NAMES;

	/// Membership is a binary search, which is only correct on a sorted,
	/// duplicate-free table.
	#[test]
	fn the_name_table_is_sorted_and_unique() {
		for pair in BUILTIN_METHOD_NAMES.windows(2) {
			assert!(pair[0] < pair[1], "{:?} must sort strictly before {:?}", pair[0], pair[1]);
		}
	}
}