1use akar_common::types::Value;
9use akar_common::vector::DataChunk;
10use hashbrown::HashMap;
11use std::sync::Arc;
12
13#[derive(Clone)]
17#[allow(clippy::type_complexity)]
18pub enum ScalarFunction {
19 Arithmetic {
20 op: ArithmeticOp,
21 },
22 Comparison {
23 op: ComparisonOp,
24 },
25 String {
26 op: StringOp,
27 },
28 Cast {
29 target_type: CastTarget,
30 },
31 Date {
32 op: DateOp,
33 },
34 List {
35 op: ListOp,
36 },
37 Map {
38 op: MapOp,
39 },
40 Struct {
41 op: StructOp,
42 },
43 Boolean {
44 op: BooleanOp,
45 },
46 Utility {
47 op: UtilityOp,
48 },
49 Schema {
50 op: SchemaOp,
51 },
52 Array {
53 op: ArrayOp,
54 },
55 Path {
57 op: PathOp,
58 },
59 Uuid,
61 CustomScalar {
64 name: String,
65 execute: Arc<dyn Fn(&[Value]) -> Result<Value, String> + Send + Sync>,
66 },
67 SequenceOp {
70 is_nextval: bool,
71 },
72 Hash {
74 op: HashOp,
75 },
76 Interval {
78 op: IntervalOp,
79 },
80 Blob {
82 op: BlobOp,
83 },
84 Union {
86 op: UnionOp,
87 },
88}
89
90impl std::fmt::Debug for ScalarFunction {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 match self {
93 Self::Arithmetic { op } => f.debug_struct("Arithmetic").field("op", op).finish(),
94 Self::Comparison { op } => f.debug_struct("Comparison").field("op", op).finish(),
95 Self::String { op } => f.debug_struct("String").field("op", op).finish(),
96 Self::Cast { target_type } => f.debug_struct("Cast").field("target_type", target_type).finish(),
97 Self::Date { op } => f.debug_struct("Date").field("op", op).finish(),
98 Self::List { op } => f.debug_struct("List").field("op", op).finish(),
99 Self::Map { op } => f.debug_struct("Map").field("op", op).finish(),
100 Self::Struct { op } => f.debug_struct("Struct").field("op", op).finish(),
101 Self::Boolean { op } => f.debug_struct("Boolean").field("op", op).finish(),
102 Self::Utility { op } => f.debug_struct("Utility").field("op", op).finish(),
103 Self::Schema { op } => f.debug_struct("Schema").field("op", op).finish(),
104 Self::Array { op } => f.debug_struct("Array").field("op", op).finish(),
105 Self::Path { op } => f.debug_struct("Path").field("op", op).finish(),
106 Self::Uuid => f.debug_struct("Uuid").finish(),
107 Self::CustomScalar { name, .. } => f.debug_struct("CustomScalar").field("name", name).finish(),
108 Self::SequenceOp { is_nextval } => f.debug_struct("SequenceOp").field("is_nextval", is_nextval).finish(),
109 Self::Hash { op } => f.debug_struct("Hash").field("op", op).finish(),
110 Self::Interval { op } => f.debug_struct("Interval").field("op", op).finish(),
111 Self::Blob { op } => f.debug_struct("Blob").field("op", op).finish(),
112 Self::Union { op } => f.debug_struct("Union").field("op", op).finish(),
113 }
114 }
115}
116
117#[derive(Debug, Clone, Copy)]
118pub enum ArithmeticOp {
119 Add,
120 Sub,
121 Mul,
122 Div,
123 Mod,
124 Abs,
125 Ceil,
126 Floor,
127 Round,
128 Negate,
129 Power,
130 Sqrt,
131 Log,
132 Exp,
133 Sin,
134 Cos,
135 Tan,
136 Asin,
137 Acos,
138 Atan,
139 Atan2,
140 Sinh,
141 Cosh,
142 Tanh,
143 Degrees,
144 Radians,
145 Sign,
146 Pi,
147 Rand,
148 Cbrt,
150 Cot,
151 Log2,
152 Even,
153 Gcd,
154 Lcm,
155 Factorial,
157 Gamma,
158 Lgamma,
159 SetSeed,
161 BitwiseAnd,
163 BitwiseOr,
164 BitwiseXor,
165 BitShiftLeft,
166 BitShiftRight,
167}
168
169#[derive(Debug, Clone, Copy)]
170pub enum ComparisonOp {
171 Eq,
172 NotEq,
173 Lt,
174 Lte,
175 Gt,
176 Gte,
177 IsNull,
178 IsNotNull,
179}
180
181#[derive(Debug, Clone, Copy)]
182pub enum StringOp {
183 Concat,
184 Contains,
185 StartsWith,
186 EndsWith,
187 ToUpper,
188 ToLower,
189 Trim,
190 LTrim,
191 RTrim,
192 Length,
193 Reverse,
194 Repeat,
195 Replace,
196 Substring,
197 RegexMatches,
198 RegexReplace,
199 Split,
200 Head,
201 Tail,
202 Left,
203 Right,
204 Lpad,
205 Rpad,
206 InitCap,
208 Soundex,
209 ConcatWs,
210 SplitPart,
211 ArrayExtract,
212 RegexpFullMatch,
214 RegexpExtract,
215 RegexpExtractAll,
216 RegexpSplitToArray,
217 Levenshtein,
219 Like,
221}
222
223#[derive(Debug, Clone, Copy)]
224pub enum CastTarget {
225 String,
226 Int64,
227 Int32,
228 Double,
229 Float,
230 Bool,
231 Date,
232 Timestamp,
233 Interval,
234}
235
236#[derive(Debug, Clone, Copy)]
237pub enum DateOp {
238 DatePart,
239 DateTrunc,
240 DateDiff,
241 DateAdd,
242 CurrentDate,
243 CurrentTimestamp,
244 Year,
245 Month,
246 Day,
247 Hour,
248 Minute,
249 Second,
250 DayName,
251 MonthName,
252 LastDay,
253 MakeDate,
254 Century,
256 EpochMs,
257 ToTimestamp,
258 ToEpochMs,
259}
260
261#[derive(Debug, Clone, Copy)]
262pub enum ListOp {
263 Creation,
264 Extract,
265 Concat,
266 Len,
267 Sort,
268 Reverse,
269 Contains,
270 Append,
271 Prepend,
272 Slice,
273 Range,
275 Distinct,
276 Unique,
277 Sum,
278 Product,
279 AnyValue,
280 ToString,
281 Position,
282 HasAll,
283 ReverseSort,
284 Any,
286 All,
287 None,
288 Single,
289 Count,
290 Min,
291 Max,
292 HasAny,
293 Transform,
295 Filter,
296 Reduce,
297}
298
299#[derive(Debug, Clone, Copy)]
300pub enum MapOp {
301 Creation,
302 Extract,
303 MapFromEntries,
304 Keys,
305 Values,
306 Contains,
307}
308
309#[derive(Debug, Clone, Copy)]
310pub enum StructOp {
311 Creation,
312 Extract,
313}
314
315#[derive(Debug, Clone, Copy)]
316pub enum BooleanOp {
317 And,
318 Or,
319 Xor,
320 Not,
321}
322
323#[derive(Debug, Clone, Copy)]
325pub enum UtilityOp {
326 Coalesce,
327 IfNull,
328 TypeOf,
329 NullIf,
330 Size,
331 Error,
332 PgIsReady,
333 Greatest,
335 Least,
337 ConstantOrNull,
340}
341
342#[derive(Debug, Clone, Copy)]
351pub enum SchemaOp {
352 Offset,
353 Id,
354 StartNode,
355 EndNode,
356 Label,
357 Cost,
359 RowId,
361}
362
363#[derive(Debug, Clone, Copy)]
370pub enum PathOp {
371 Nodes,
372 Rels,
373 Length,
374 Properties,
376 IsTrail,
378 IsAcyclic,
380}
381
382#[derive(Debug, Clone, Copy)]
391pub enum ArrayOp {
392 CosineSimilarity,
393 Distance,
394 InnerProduct,
395 DotProduct,
396 CrossProduct,
397 SquaredDistance,
398 Intersect,
399}
400
401#[derive(Debug, Clone, Copy)]
407pub enum HashOp {
408 Md5,
409 Sha256,
410 Hash,
411}
412
413#[derive(Debug, Clone, Copy)]
425pub enum IntervalOp {
426 ToYears,
427 ToMonths,
428 ToDays,
429 ToHours,
430 ToMinutes,
431 ToSeconds,
432 ToMilliseconds,
433 ToMicroseconds,
434}
435
436#[derive(Debug, Clone, Copy)]
442pub enum BlobOp {
443 Encode,
444 Decode,
445 OctetLength,
446 ToBase64,
447 FromBase64,
448 BlobFromBytes,
449}
450
451#[derive(Debug, Clone, Copy)]
458pub enum UnionOp {
459 UnionValue,
460 UnionTag,
461 UnionExtract,
462}
463
464#[derive(Debug, Clone)]
468pub enum AggregateFunction {
469 Count,
470 Sum,
471 Avg,
472 Min,
473 Max,
474 Collect,
475 CountStar,
476 StdDev,
477 Variance,
478 StringAgg {
480 delimiter: String,
481 },
482 PercentileDisc {
484 percentile: f64,
485 },
486 PercentileCont {
488 percentile: f64,
489 },
490 CountIf,
492}
493
494#[derive(Clone)]
498pub enum TableFunction {
499 ScanCsv {
500 path: String,
501 },
502 ScanParquet {
503 path: String,
504 },
505 ScanJson {
506 path: String,
507 },
508 ListTables,
509 ShowColumns {
510 table_name: String,
511 },
512 CurrentSetting {
513 key: String,
514 },
515 Custom {
518 name: String,
519 },
520 #[allow(clippy::type_complexity)]
523 CustomTable {
524 name: String,
525 execute: Arc<dyn Fn(&[Value], &mut DataChunk) -> Result<(), String> + Send + Sync>,
526 },
527}
528
529impl std::fmt::Debug for TableFunction {
530 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531 match self {
532 Self::ScanCsv { path } => f.debug_struct("ScanCsv").field("path", path).finish(),
533 Self::ScanParquet { path } => f.debug_struct("ScanParquet").field("path", path).finish(),
534 Self::ScanJson { path } => f.debug_struct("ScanJson").field("path", path).finish(),
535 Self::ListTables => write!(f, "ListTables"),
536 Self::ShowColumns { table_name } => f.debug_struct("ShowColumns").field("table_name", table_name).finish(),
537 Self::CurrentSetting { key } => f.debug_struct("CurrentSetting").field("key", key).finish(),
538 Self::Custom { name } => f.debug_struct("Custom").field("name", name).finish(),
539 Self::CustomTable { name, .. } => f.debug_struct("CustomTable").field("name", name).finish(),
540 }
541 }
542}
543
544#[derive(Debug, Clone)]
546pub enum ResolvedFunction {
547 Scalar(ScalarFunction),
548 Aggregate(AggregateFunction),
549 Table(TableFunction),
550}
551
552#[derive(Default)]
556pub struct FunctionRegistry {
557 scalar_functions: HashMap<String, ScalarFunction>,
558 aggregate_functions: HashMap<String, AggregateFunction>,
559 table_functions: HashMap<String, TableFunction>,
560}
561
562impl FunctionRegistry {
563 pub fn new() -> Self {
564 let mut reg = Self::default();
565 reg.register_builtins();
566 reg
567 }
568
569 fn register_builtins(&mut self) {
570 self.register_scalar("+", ScalarFunction::Arithmetic { op: ArithmeticOp::Add });
572 self.register_scalar("-", ScalarFunction::Arithmetic { op: ArithmeticOp::Sub });
573 self.register_scalar("*", ScalarFunction::Arithmetic { op: ArithmeticOp::Mul });
574 self.register_scalar("/", ScalarFunction::Arithmetic { op: ArithmeticOp::Div });
575 self.register_scalar("%", ScalarFunction::Arithmetic { op: ArithmeticOp::Mod });
576 self.register_scalar("abs", ScalarFunction::Arithmetic { op: ArithmeticOp::Abs });
577 self.register_scalar("ceil", ScalarFunction::Arithmetic { op: ArithmeticOp::Ceil });
578 self.register_scalar("ceiling", ScalarFunction::Arithmetic { op: ArithmeticOp::Ceil });
580 self.register_scalar(
581 "floor",
582 ScalarFunction::Arithmetic {
583 op: ArithmeticOp::Floor,
584 },
585 );
586 self.register_scalar(
587 "round",
588 ScalarFunction::Arithmetic {
589 op: ArithmeticOp::Round,
590 },
591 );
592 self.register_scalar(
593 "^",
594 ScalarFunction::Arithmetic {
595 op: ArithmeticOp::Power,
596 },
597 );
598 self.register_scalar("sqrt", ScalarFunction::Arithmetic { op: ArithmeticOp::Sqrt });
599 self.register_scalar(
601 "pow",
602 ScalarFunction::Arithmetic {
603 op: ArithmeticOp::Power,
604 },
605 );
606 self.register_scalar("log10", ScalarFunction::Arithmetic { op: ArithmeticOp::Log });
607 self.register_scalar("cbrt", ScalarFunction::Arithmetic { op: ArithmeticOp::Cbrt });
609 self.register_scalar("cot", ScalarFunction::Arithmetic { op: ArithmeticOp::Cot });
610 self.register_scalar("log", ScalarFunction::Arithmetic { op: ArithmeticOp::Log });
611 self.register_scalar("ln", ScalarFunction::Arithmetic { op: ArithmeticOp::Log });
612 self.register_scalar("log2", ScalarFunction::Arithmetic { op: ArithmeticOp::Log2 });
613 self.register_scalar("even", ScalarFunction::Arithmetic { op: ArithmeticOp::Even });
614 self.register_scalar(
615 "factorial",
616 ScalarFunction::Arithmetic {
617 op: ArithmeticOp::Factorial,
618 },
619 );
620 self.register_scalar(
621 "gamma",
622 ScalarFunction::Arithmetic {
623 op: ArithmeticOp::Gamma,
624 },
625 );
626 self.register_scalar(
627 "lgamma",
628 ScalarFunction::Arithmetic {
629 op: ArithmeticOp::Lgamma,
630 },
631 );
632 self.register_scalar(
633 "set_seed",
634 ScalarFunction::Arithmetic {
635 op: ArithmeticOp::SetSeed,
636 },
637 );
638 self.register_scalar("exp", ScalarFunction::Arithmetic { op: ArithmeticOp::Exp });
639 self.register_scalar("sin", ScalarFunction::Arithmetic { op: ArithmeticOp::Sin });
640 self.register_scalar("cos", ScalarFunction::Arithmetic { op: ArithmeticOp::Cos });
641 self.register_scalar("tan", ScalarFunction::Arithmetic { op: ArithmeticOp::Tan });
642 self.register_scalar("asin", ScalarFunction::Arithmetic { op: ArithmeticOp::Asin });
643 self.register_scalar("acos", ScalarFunction::Arithmetic { op: ArithmeticOp::Acos });
644 self.register_scalar("atan", ScalarFunction::Arithmetic { op: ArithmeticOp::Atan });
645 self.register_scalar(
646 "atan2",
647 ScalarFunction::Arithmetic {
648 op: ArithmeticOp::Atan2,
649 },
650 );
651 self.register_scalar(
652 "degrees",
653 ScalarFunction::Arithmetic {
654 op: ArithmeticOp::Degrees,
655 },
656 );
657 self.register_scalar(
658 "radians",
659 ScalarFunction::Arithmetic {
660 op: ArithmeticOp::Radians,
661 },
662 );
663 self.register_scalar("sign", ScalarFunction::Arithmetic { op: ArithmeticOp::Sign });
664 self.register_scalar("pi", ScalarFunction::Arithmetic { op: ArithmeticOp::Pi });
665 self.register_scalar("rand", ScalarFunction::Arithmetic { op: ArithmeticOp::Rand });
666
667 self.register_scalar("sinh", ScalarFunction::Arithmetic { op: ArithmeticOp::Sinh });
668 self.register_scalar("cosh", ScalarFunction::Arithmetic { op: ArithmeticOp::Cosh });
669 self.register_scalar("tanh", ScalarFunction::Arithmetic { op: ArithmeticOp::Tanh });
670 self.register_scalar("gcd", ScalarFunction::Arithmetic { op: ArithmeticOp::Gcd });
671 self.register_scalar("lcm", ScalarFunction::Arithmetic { op: ArithmeticOp::Lcm });
672
673 self.register_scalar(
675 "bitwise_and",
676 ScalarFunction::Arithmetic {
677 op: ArithmeticOp::BitwiseAnd,
678 },
679 );
680 self.register_scalar(
681 "&",
682 ScalarFunction::Arithmetic {
683 op: ArithmeticOp::BitwiseAnd,
684 },
685 );
686 self.register_scalar(
687 "bitwise_or",
688 ScalarFunction::Arithmetic {
689 op: ArithmeticOp::BitwiseOr,
690 },
691 );
692 self.register_scalar(
693 "|",
694 ScalarFunction::Arithmetic {
695 op: ArithmeticOp::BitwiseOr,
696 },
697 );
698 self.register_scalar(
699 "bitwise_xor",
700 ScalarFunction::Arithmetic {
701 op: ArithmeticOp::BitwiseXor,
702 },
703 );
704 self.register_scalar(
705 "#",
706 ScalarFunction::Arithmetic {
707 op: ArithmeticOp::BitwiseXor,
708 },
709 );
710 self.register_scalar(
711 "bit_shift_left",
712 ScalarFunction::Arithmetic {
713 op: ArithmeticOp::BitShiftLeft,
714 },
715 );
716 self.register_scalar(
717 "<<",
718 ScalarFunction::Arithmetic {
719 op: ArithmeticOp::BitShiftLeft,
720 },
721 );
722 self.register_scalar(
723 "bit_shift_right",
724 ScalarFunction::Arithmetic {
725 op: ArithmeticOp::BitShiftRight,
726 },
727 );
728 self.register_scalar(
729 ">>",
730 ScalarFunction::Arithmetic {
731 op: ArithmeticOp::BitShiftRight,
732 },
733 );
734
735 self.register_scalar("=", ScalarFunction::Comparison { op: ComparisonOp::Eq });
737 self.register_scalar(
738 "<>",
739 ScalarFunction::Comparison {
740 op: ComparisonOp::NotEq,
741 },
742 );
743 self.register_scalar("<", ScalarFunction::Comparison { op: ComparisonOp::Lt });
744 self.register_scalar("<=", ScalarFunction::Comparison { op: ComparisonOp::Lte });
745 self.register_scalar(">", ScalarFunction::Comparison { op: ComparisonOp::Gt });
746 self.register_scalar(">=", ScalarFunction::Comparison { op: ComparisonOp::Gte });
747 self.register_scalar(
748 "IS NULL",
749 ScalarFunction::Comparison {
750 op: ComparisonOp::IsNull,
751 },
752 );
753 self.register_scalar(
754 "IS NOT NULL",
755 ScalarFunction::Comparison {
756 op: ComparisonOp::IsNotNull,
757 },
758 );
759
760 self.register_scalar("concat", ScalarFunction::String { op: StringOp::Concat });
762 self.register_scalar("contains", ScalarFunction::String { op: StringOp::Contains });
763 self.register_scalar(
764 "starts_with",
765 ScalarFunction::String {
766 op: StringOp::StartsWith,
767 },
768 );
769 self.register_scalar("ends_with", ScalarFunction::String { op: StringOp::EndsWith });
770 self.register_scalar(
772 "prefix",
773 ScalarFunction::String {
774 op: StringOp::StartsWith,
775 },
776 );
777 self.register_scalar("suffix", ScalarFunction::String { op: StringOp::EndsWith });
778 self.register_scalar("like", ScalarFunction::String { op: StringOp::Like });
779 self.register_scalar("to_upper", ScalarFunction::String { op: StringOp::ToUpper });
780 self.register_scalar("to_lower", ScalarFunction::String { op: StringOp::ToLower });
781 self.register_scalar("upper", ScalarFunction::String { op: StringOp::ToUpper });
783 self.register_scalar("lower", ScalarFunction::String { op: StringOp::ToLower });
784 self.register_scalar("ucase", ScalarFunction::String { op: StringOp::ToUpper });
785 self.register_scalar("lcase", ScalarFunction::String { op: StringOp::ToLower });
786 self.register_scalar("trim", ScalarFunction::String { op: StringOp::Trim });
787 self.register_scalar("ltrim", ScalarFunction::String { op: StringOp::LTrim });
788 self.register_scalar("rtrim", ScalarFunction::String { op: StringOp::RTrim });
789 self.register_scalar("length", ScalarFunction::String { op: StringOp::Length });
790 self.register_scalar("reverse", ScalarFunction::String { op: StringOp::Reverse });
791 self.register_scalar("repeat", ScalarFunction::String { op: StringOp::Repeat });
792 self.register_scalar("replace", ScalarFunction::String { op: StringOp::Replace });
793 self.register_scalar(
794 "substring",
795 ScalarFunction::String {
796 op: StringOp::Substring,
797 },
798 );
799 self.register_scalar(
800 "regex_matches",
801 ScalarFunction::String {
802 op: StringOp::RegexMatches,
803 },
804 );
805 self.register_scalar(
806 "regex_replace",
807 ScalarFunction::String {
808 op: StringOp::RegexReplace,
809 },
810 );
811 self.register_scalar("split", ScalarFunction::String { op: StringOp::Split });
812 self.register_scalar("head", ScalarFunction::String { op: StringOp::Head });
813 self.register_scalar("tail", ScalarFunction::String { op: StringOp::Tail });
814 self.register_scalar("left", ScalarFunction::String { op: StringOp::Left });
815 self.register_scalar("right", ScalarFunction::String { op: StringOp::Right });
816 self.register_scalar("lpad", ScalarFunction::String { op: StringOp::Lpad });
817 self.register_scalar("rpad", ScalarFunction::String { op: StringOp::Rpad });
818
819 self.register_scalar("initcap", ScalarFunction::String { op: StringOp::InitCap });
821 self.register_scalar("concat_ws", ScalarFunction::String { op: StringOp::ConcatWs });
822 self.register_scalar(
823 "split_part",
824 ScalarFunction::String {
825 op: StringOp::SplitPart,
826 },
827 );
828 self.register_scalar(
829 "array_extract",
830 ScalarFunction::String {
831 op: StringOp::ArrayExtract,
832 },
833 );
834
835 self.register_scalar(
837 "regexp_full_match",
838 ScalarFunction::String {
839 op: StringOp::RegexpFullMatch,
840 },
841 );
842 self.register_scalar(
843 "regexp_extract",
844 ScalarFunction::String {
845 op: StringOp::RegexpExtract,
846 },
847 );
848 self.register_scalar(
849 "regexp_extract_all",
850 ScalarFunction::String {
851 op: StringOp::RegexpExtractAll,
852 },
853 );
854 self.register_scalar(
855 "regexp_split_to_array",
856 ScalarFunction::String {
857 op: StringOp::RegexpSplitToArray,
858 },
859 );
860 self.register_scalar(
861 "levenshtein",
862 ScalarFunction::String {
863 op: StringOp::Levenshtein,
864 },
865 );
866 self.register_scalar("soundex", ScalarFunction::String { op: StringOp::Soundex });
867
868 self.register_scalar("md5", ScalarFunction::Hash { op: HashOp::Md5 });
870 self.register_scalar("sha256", ScalarFunction::Hash { op: HashOp::Sha256 });
871 self.register_scalar("hash", ScalarFunction::Hash { op: HashOp::Hash });
872
873 self.register_scalar(
875 "to_years",
876 ScalarFunction::Interval {
877 op: IntervalOp::ToYears,
878 },
879 );
880 self.register_scalar(
881 "to_months",
882 ScalarFunction::Interval {
883 op: IntervalOp::ToMonths,
884 },
885 );
886 self.register_scalar("to_days", ScalarFunction::Interval { op: IntervalOp::ToDays });
887 self.register_scalar(
888 "to_hours",
889 ScalarFunction::Interval {
890 op: IntervalOp::ToHours,
891 },
892 );
893 self.register_scalar(
894 "to_minutes",
895 ScalarFunction::Interval {
896 op: IntervalOp::ToMinutes,
897 },
898 );
899 self.register_scalar(
900 "to_seconds",
901 ScalarFunction::Interval {
902 op: IntervalOp::ToSeconds,
903 },
904 );
905 self.register_scalar(
906 "to_milliseconds",
907 ScalarFunction::Interval {
908 op: IntervalOp::ToMilliseconds,
909 },
910 );
911 self.register_scalar(
912 "to_microseconds",
913 ScalarFunction::Interval {
914 op: IntervalOp::ToMicroseconds,
915 },
916 );
917
918 self.register_scalar("date_part", ScalarFunction::Date { op: DateOp::DatePart });
920 self.register_scalar("date_trunc", ScalarFunction::Date { op: DateOp::DateTrunc });
921 self.register_scalar("date_diff", ScalarFunction::Date { op: DateOp::DateDiff });
922 self.register_scalar("date_add", ScalarFunction::Date { op: DateOp::DateAdd });
923 self.register_scalar(
924 "current_date",
925 ScalarFunction::Date {
926 op: DateOp::CurrentDate,
927 },
928 );
929 self.register_scalar(
930 "current_timestamp",
931 ScalarFunction::Date {
932 op: DateOp::CurrentTimestamp,
933 },
934 );
935 self.register_scalar("year", ScalarFunction::Date { op: DateOp::Year });
936 self.register_scalar("month", ScalarFunction::Date { op: DateOp::Month });
937
938 self.register_scalar("nextval", ScalarFunction::SequenceOp { is_nextval: true });
940 self.register_scalar("currval", ScalarFunction::SequenceOp { is_nextval: false });
941 self.register_scalar("day", ScalarFunction::Date { op: DateOp::Day });
942 self.register_scalar("hour", ScalarFunction::Date { op: DateOp::Hour });
943 self.register_scalar("minute", ScalarFunction::Date { op: DateOp::Minute });
944 self.register_scalar("second", ScalarFunction::Date { op: DateOp::Second });
945 self.register_scalar("dayname", ScalarFunction::Date { op: DateOp::DayName });
946 self.register_scalar("monthname", ScalarFunction::Date { op: DateOp::MonthName });
947 self.register_scalar("last_day", ScalarFunction::Date { op: DateOp::LastDay });
948 self.register_scalar("make_date", ScalarFunction::Date { op: DateOp::MakeDate });
949 self.register_scalar("century", ScalarFunction::Date { op: DateOp::Century });
950 self.register_scalar("epoch_ms", ScalarFunction::Date { op: DateOp::EpochMs });
951 self.register_scalar(
952 "to_timestamp",
953 ScalarFunction::Date {
954 op: DateOp::ToTimestamp,
955 },
956 );
957 self.register_scalar("to_epoch_ms", ScalarFunction::Date { op: DateOp::ToEpochMs });
958
959 self.register_scalar(
961 "CAST",
962 ScalarFunction::Cast {
963 target_type: CastTarget::String,
964 },
965 );
966 self.register_scalar(
967 "cast_string",
968 ScalarFunction::Cast {
969 target_type: CastTarget::String,
970 },
971 );
972 self.register_scalar(
973 "cast_int64",
974 ScalarFunction::Cast {
975 target_type: CastTarget::Int64,
976 },
977 );
978 self.register_scalar(
979 "cast_double",
980 ScalarFunction::Cast {
981 target_type: CastTarget::Double,
982 },
983 );
984 self.register_scalar(
985 "cast_bool",
986 ScalarFunction::Cast {
987 target_type: CastTarget::Bool,
988 },
989 );
990 self.register_scalar(
992 "date",
993 ScalarFunction::Cast {
994 target_type: CastTarget::Date,
995 },
996 );
997 self.register_scalar(
998 "timestamp",
999 ScalarFunction::Cast {
1000 target_type: CastTarget::Timestamp,
1001 },
1002 );
1003 self.register_scalar(
1004 "float",
1005 ScalarFunction::Cast {
1006 target_type: CastTarget::Double,
1007 },
1008 );
1009 self.register_scalar(
1010 "double",
1011 ScalarFunction::Cast {
1012 target_type: CastTarget::Double,
1013 },
1014 );
1015 self.register_scalar(
1016 "int64",
1017 ScalarFunction::Cast {
1018 target_type: CastTarget::Int64,
1019 },
1020 );
1021 self.register_scalar(
1022 "int",
1023 ScalarFunction::Cast {
1024 target_type: CastTarget::Int64,
1025 },
1026 );
1027 self.register_scalar(
1028 "bool",
1029 ScalarFunction::Cast {
1030 target_type: CastTarget::Bool,
1031 },
1032 );
1033 self.register_scalar(
1034 "boolean",
1035 ScalarFunction::Cast {
1036 target_type: CastTarget::Bool,
1037 },
1038 );
1039 self.register_scalar(
1040 "string",
1041 ScalarFunction::Cast {
1042 target_type: CastTarget::String,
1043 },
1044 );
1045 self.register_scalar(
1046 "blob",
1047 ScalarFunction::Cast {
1048 target_type: CastTarget::String,
1049 },
1050 );
1051
1052 self.register_scalar("encode", ScalarFunction::Blob { op: BlobOp::Encode });
1054 self.register_scalar("decode", ScalarFunction::Blob { op: BlobOp::Decode });
1055 self.register_scalar(
1056 "octet_length",
1057 ScalarFunction::Blob {
1058 op: BlobOp::OctetLength,
1059 },
1060 );
1061
1062 self.register_scalar("list_creation", ScalarFunction::List { op: ListOp::Creation });
1064 self.register_scalar("list_extract", ScalarFunction::List { op: ListOp::Extract });
1065 self.register_scalar("list_concat", ScalarFunction::List { op: ListOp::Concat });
1066 self.register_scalar("list_cat", ScalarFunction::List { op: ListOp::Concat });
1067 self.register_scalar("list_len", ScalarFunction::List { op: ListOp::Len });
1068 self.register_scalar("list_sort", ScalarFunction::List { op: ListOp::Sort });
1069 self.register_scalar("list_reverse", ScalarFunction::List { op: ListOp::Reverse });
1070 self.register_scalar("list_contains", ScalarFunction::List { op: ListOp::Contains });
1071 self.register_scalar("list_append", ScalarFunction::List { op: ListOp::Append });
1072 self.register_scalar("list_prepend", ScalarFunction::List { op: ListOp::Prepend });
1073 self.register_scalar("list_slice", ScalarFunction::List { op: ListOp::Slice });
1074
1075 self.register_scalar("range", ScalarFunction::List { op: ListOp::Range });
1077 self.register_scalar("list_distinct", ScalarFunction::List { op: ListOp::Distinct });
1078 self.register_scalar("list_unique", ScalarFunction::List { op: ListOp::Unique });
1079 self.register_scalar("list_sum", ScalarFunction::List { op: ListOp::Sum });
1080 self.register_scalar("list_product", ScalarFunction::List { op: ListOp::Product });
1081 self.register_scalar("list_any_value", ScalarFunction::List { op: ListOp::AnyValue });
1082 self.register_scalar("list_to_string", ScalarFunction::List { op: ListOp::ToString });
1083 self.register_scalar("list_position", ScalarFunction::List { op: ListOp::Position });
1084 self.register_scalar("list_indexof", ScalarFunction::List { op: ListOp::Position });
1085 self.register_scalar("list_has_all", ScalarFunction::List { op: ListOp::HasAll });
1086 self.register_scalar("list_has_any", ScalarFunction::List { op: ListOp::HasAny });
1087 self.register_scalar("list_count", ScalarFunction::List { op: ListOp::Count });
1088 self.register_scalar("list_min", ScalarFunction::List { op: ListOp::Min });
1089 self.register_scalar("list_max", ScalarFunction::List { op: ListOp::Max });
1090 self.register_scalar(
1091 "list_reverse_sort",
1092 ScalarFunction::List {
1093 op: ListOp::ReverseSort,
1094 },
1095 );
1096
1097 self.register_scalar("list_transform", ScalarFunction::List { op: ListOp::Transform });
1099 self.register_scalar("list_filter", ScalarFunction::List { op: ListOp::Filter });
1100 self.register_scalar("list_reduce", ScalarFunction::List { op: ListOp::Reduce });
1101
1102 self.register_scalar("any", ScalarFunction::List { op: ListOp::Any });
1104 self.register_scalar("all", ScalarFunction::List { op: ListOp::All });
1105 self.register_scalar("none", ScalarFunction::List { op: ListOp::None });
1106 self.register_scalar("single", ScalarFunction::List { op: ListOp::Single });
1107
1108 self.register_scalar("map_creation", ScalarFunction::Map { op: MapOp::Creation });
1110 self.register_scalar("map_extract", ScalarFunction::Map { op: MapOp::Extract });
1111 self.register_scalar("element_at", ScalarFunction::Map { op: MapOp::Extract });
1112 self.register_scalar("map_keys", ScalarFunction::Map { op: MapOp::Keys });
1113 self.register_scalar("map_values", ScalarFunction::Map { op: MapOp::Values });
1114
1115 self.register_scalar("struct_creation", ScalarFunction::Struct { op: StructOp::Creation });
1117 self.register_scalar("struct_extract", ScalarFunction::Struct { op: StructOp::Extract });
1118
1119 self.register_scalar(
1121 "union_value",
1122 ScalarFunction::Union {
1123 op: UnionOp::UnionValue,
1124 },
1125 );
1126 self.register_scalar(
1127 "union_extract",
1128 ScalarFunction::Union {
1129 op: UnionOp::UnionExtract,
1130 },
1131 );
1132 self.register_scalar("union_tag", ScalarFunction::Union { op: UnionOp::UnionTag });
1133
1134 self.register_scalar("AND", ScalarFunction::Boolean { op: BooleanOp::And });
1136 self.register_scalar("OR", ScalarFunction::Boolean { op: BooleanOp::Or });
1137 self.register_scalar("XOR", ScalarFunction::Boolean { op: BooleanOp::Xor });
1138 self.register_scalar("NOT", ScalarFunction::Boolean { op: BooleanOp::Not });
1139
1140 self.register_scalar(
1142 "coalesce",
1143 ScalarFunction::Utility {
1144 op: UtilityOp::Coalesce,
1145 },
1146 );
1147 self.register_scalar("ifnull", ScalarFunction::Utility { op: UtilityOp::IfNull });
1148 self.register_scalar("nullif", ScalarFunction::Utility { op: UtilityOp::NullIf });
1149 self.register_scalar("size", ScalarFunction::Utility { op: UtilityOp::Size });
1150 self.register_scalar("cardinality", ScalarFunction::Utility { op: UtilityOp::Size });
1151 self.register_scalar("typeof", ScalarFunction::Utility { op: UtilityOp::TypeOf });
1152 self.register_scalar("error", ScalarFunction::Utility { op: UtilityOp::Error });
1153 self.register_scalar(
1154 "pg_isready",
1155 ScalarFunction::Utility {
1156 op: UtilityOp::PgIsReady,
1157 },
1158 );
1159
1160 self.register_scalar(
1162 "greatest",
1163 ScalarFunction::Utility {
1164 op: UtilityOp::Greatest,
1165 },
1166 );
1167 self.register_scalar("least", ScalarFunction::Utility { op: UtilityOp::Least });
1168 self.register_scalar(
1169 "constant_or_null",
1170 ScalarFunction::Utility {
1171 op: UtilityOp::ConstantOrNull,
1172 },
1173 );
1174
1175 self.register_scalar("OFFSET", ScalarFunction::Schema { op: SchemaOp::Offset });
1177 self.register_scalar("ID", ScalarFunction::Schema { op: SchemaOp::Id });
1178 self.register_scalar(
1179 "START_NODE",
1180 ScalarFunction::Schema {
1181 op: SchemaOp::StartNode,
1182 },
1183 );
1184 self.register_scalar("END_NODE", ScalarFunction::Schema { op: SchemaOp::EndNode });
1185 self.register_scalar("LABEL", ScalarFunction::Schema { op: SchemaOp::Label });
1186 self.register_scalar("COST", ScalarFunction::Schema { op: SchemaOp::Cost });
1187 self.register_scalar("ROWID", ScalarFunction::Schema { op: SchemaOp::RowId });
1188
1189 self.register_scalar(
1191 "array_cosine_similarity",
1192 ScalarFunction::Array {
1193 op: ArrayOp::CosineSimilarity,
1194 },
1195 );
1196 self.register_scalar("array_distance", ScalarFunction::Array { op: ArrayOp::Distance });
1197 self.register_scalar(
1198 "array_inner_product",
1199 ScalarFunction::Array {
1200 op: ArrayOp::InnerProduct,
1201 },
1202 );
1203 self.register_scalar(
1204 "array_dot_product",
1205 ScalarFunction::Array {
1206 op: ArrayOp::DotProduct,
1207 },
1208 );
1209 self.register_scalar(
1210 "array_cross_product",
1211 ScalarFunction::Array {
1212 op: ArrayOp::CrossProduct,
1213 },
1214 );
1215 self.register_scalar(
1216 "array_squared_distance",
1217 ScalarFunction::Array {
1218 op: ArrayOp::SquaredDistance,
1219 },
1220 );
1221 self.register_scalar("array_intersect", ScalarFunction::Array { op: ArrayOp::Intersect });
1222
1223 self.register_scalar("nodes", ScalarFunction::Path { op: PathOp::Nodes });
1225 self.register_scalar("rels", ScalarFunction::Path { op: PathOp::Rels });
1226 self.register_scalar("relationships", ScalarFunction::Path { op: PathOp::Rels });
1227 self.register_scalar("properties", ScalarFunction::Path { op: PathOp::Properties });
1228 self.register_scalar("is_trail", ScalarFunction::Path { op: PathOp::IsTrail });
1229 self.register_scalar("is_acyclic", ScalarFunction::Path { op: PathOp::IsAcyclic });
1230
1231 self.register_scalar("gen_random_uuid", ScalarFunction::Uuid);
1233
1234 self.register_scalar(
1236 "map_from_entries",
1237 ScalarFunction::Map {
1238 op: MapOp::MapFromEntries,
1239 },
1240 );
1241
1242 self.register_scalar(
1244 "blob_from_bytes",
1245 ScalarFunction::Blob {
1246 op: BlobOp::BlobFromBytes,
1247 },
1248 );
1249 self.register_scalar("to_base64", ScalarFunction::Blob { op: BlobOp::ToBase64 });
1250 self.register_scalar("from_base64", ScalarFunction::Blob { op: BlobOp::FromBase64 });
1251
1252 self.register_scalar("array_concat", ScalarFunction::List { op: ListOp::Concat });
1254 self.register_scalar("array_cat", ScalarFunction::List { op: ListOp::Concat });
1255 self.register_scalar("array_append", ScalarFunction::List { op: ListOp::Append });
1256 self.register_scalar("array_push_back", ScalarFunction::List { op: ListOp::Append });
1257 self.register_scalar("array_prepend", ScalarFunction::List { op: ListOp::Prepend });
1258 self.register_scalar("array_push_front", ScalarFunction::List { op: ListOp::Prepend });
1259 self.register_scalar("array_contains", ScalarFunction::List { op: ListOp::Contains });
1260 self.register_scalar("array_has", ScalarFunction::List { op: ListOp::Contains });
1261 self.register_scalar("array_slice", ScalarFunction::List { op: ListOp::Slice });
1262 self.register_scalar("array_value", ScalarFunction::List { op: ListOp::Creation });
1263
1264 self.register_aggregate("COUNT", AggregateFunction::Count);
1266 self.register_aggregate("COUNT(*)", AggregateFunction::CountStar);
1267 self.register_aggregate("COUNT_IF", AggregateFunction::CountIf);
1268 self.register_aggregate("SUM", AggregateFunction::Sum);
1269 self.register_aggregate("AVG", AggregateFunction::Avg);
1270 self.register_aggregate("MIN", AggregateFunction::Min);
1271 self.register_aggregate("MAX", AggregateFunction::Max);
1272 self.register_aggregate("COLLECT", AggregateFunction::Collect);
1273 self.register_aggregate("STDDEV", AggregateFunction::StdDev);
1274 self.register_aggregate("VARIANCE", AggregateFunction::Variance);
1275 self.register_aggregate(
1276 "STRING_AGG",
1277 AggregateFunction::StringAgg {
1278 delimiter: ",".to_string(),
1279 },
1280 );
1281 self.register_aggregate(
1282 "GROUP_CONCAT",
1283 AggregateFunction::StringAgg {
1284 delimiter: ",".to_string(),
1285 },
1286 );
1287 self.register_aggregate("PERCENTILE_DISC", AggregateFunction::PercentileDisc { percentile: 0.5 });
1288 self.register_aggregate("PERCENTILE_CONT", AggregateFunction::PercentileCont { percentile: 0.5 });
1289
1290 self.register_table("list_tables", TableFunction::ListTables);
1292 }
1293
1294 pub fn register_scalar(&mut self, name: &str, func: ScalarFunction) {
1297 self.scalar_functions.insert(name.to_lowercase(), func);
1298 }
1299
1300 pub fn register_aggregate(&mut self, name: &str, func: AggregateFunction) {
1301 self.aggregate_functions.insert(name.to_lowercase(), func);
1302 }
1303
1304 pub fn register_table(&mut self, name: &str, func: TableFunction) {
1305 self.table_functions.insert(name.to_lowercase(), func);
1306 }
1307
1308 pub fn resolve(&self, name: &str) -> Option<ResolvedFunction> {
1311 let lower = name.to_lowercase();
1312 if let Some(f) = self.scalar_functions.get(&lower) {
1313 return Some(ResolvedFunction::Scalar(f.clone()));
1314 }
1315 if let Some(f) = self.aggregate_functions.get(&lower) {
1316 return Some(ResolvedFunction::Aggregate(f.clone()));
1317 }
1318 if let Some(f) = self.table_functions.get(&lower) {
1319 return Some(ResolvedFunction::Table(f.clone()));
1320 }
1321 None
1322 }
1323
1324 pub fn get_scalar(&self, name: &str) -> Option<&ScalarFunction> {
1325 self.scalar_functions.get(&name.to_lowercase())
1326 }
1327
1328 pub fn get_aggregate(&self, name: &str) -> Option<&AggregateFunction> {
1329 self.aggregate_functions.get(&name.to_lowercase())
1330 }
1331
1332 pub fn get_table(&self, name: &str) -> Option<&TableFunction> {
1333 self.table_functions.get(&name.to_lowercase())
1334 }
1335
1336 pub fn list_all(&self) -> Vec<(String, String)> {
1339 let mut result = Vec::new();
1340 for name in self.scalar_functions.keys() {
1341 result.push((name.clone(), "SCALAR".to_string()));
1342 }
1343 for name in self.aggregate_functions.keys() {
1344 result.push((name.clone(), "AGGREGATE".to_string()));
1345 }
1346 for name in self.table_functions.keys() {
1347 result.push((name.clone(), "TABLE".to_string()));
1348 }
1349 result.sort_by(|a, b| a.0.cmp(&b.0));
1350 result
1351 }
1352
1353 pub fn contains(&self, name: &str) -> bool {
1354 let lower = name.to_lowercase();
1355 self.scalar_functions.contains_key(&lower)
1356 || self.aggregate_functions.contains_key(&lower)
1357 || self.table_functions.contains_key(&lower)
1358 }
1359
1360 pub fn scalar_count(&self) -> usize {
1362 self.scalar_functions.len()
1363 }
1364
1365 pub fn aggregate_count(&self) -> usize {
1367 self.aggregate_functions.len()
1368 }
1369
1370 pub fn table_count(&self) -> usize {
1372 self.table_functions.len()
1373 }
1374
1375 pub fn total_count(&self) -> usize {
1377 self.scalar_count() + self.aggregate_count() + self.table_count()
1378 }
1379
1380 pub fn execute_table_function(&self, name: &str, args: &[Value]) -> Result<Vec<Vec<Value>>, String> {
1385 use akar_common::vector::DataChunk;
1386
1387 let func = self
1388 .get_table(name)
1389 .ok_or_else(|| format!("Table function '{}' not found", name))?;
1390
1391 match func {
1392 TableFunction::ListTables => Err("ListTables requires catalog access — handled at connection level".into()),
1393 TableFunction::ShowColumns { .. } => {
1394 Err("ShowColumns requires catalog access — handled at connection level".into())
1395 }
1396 TableFunction::Custom { name: custom_name } => Err(format!(
1397 "Table function '{}' requires an extension or external context to be loaded. \
1398 Use LOAD EXTENSION or CALL with the appropriate handler.",
1399 custom_name
1400 )),
1401 TableFunction::CustomTable { name: _, execute } => {
1402 let mut chunk = DataChunk {
1403 fields: Vec::new(),
1404 field_types: Vec::new(),
1405 size: 0,
1406 field_names: vec![],
1407 sel_vector: None,
1408 };
1409 execute(args, &mut chunk).map(|_| {
1410 let mut rows = Vec::new();
1411 for row in 0..chunk.size {
1412 let mut row_vals = Vec::new();
1413 for field_idx in 0..chunk.fields.len() {
1414 row_vals.push(chunk.get_value(field_idx, row).unwrap_or(Value::Null));
1415 }
1416 rows.push(row_vals);
1417 }
1418 rows
1419 })
1420 }
1421 TableFunction::ScanCsv { .. }
1422 | TableFunction::ScanParquet { .. }
1423 | TableFunction::ScanJson { .. }
1424 | TableFunction::CurrentSetting { .. } => Err(format!(
1425 "Table function '{}' cannot be executed via CALL — it requires file path or catalog context. \
1426 Use COPY FROM 'file' FORMAT CSV/PARQUET/JSON or CALL current_setting('key') via the connection layer.",
1427 name
1428 )),
1429 }
1430 }
1431}