mz_expr_derive_impl/
lib.rs1mod sqlfunc;
17
18pub use sqlfunc::sqlfunc;
19
20#[cfg(any(feature = "test", test))]
22fn sqlfunc_for_test(
23 attr: proc_macro2::TokenStream,
24 item: proc_macro2::TokenStream,
25) -> darling::Result<proc_macro2::TokenStream> {
26 sqlfunc(attr, item, false)
27}
28
29#[cfg(any(feature = "test", test))]
30pub fn test_sqlfunc(
31 attr: proc_macro2::TokenStream,
32 item: proc_macro2::TokenStream,
33) -> (String, String) {
34 fn rust_fmt(input: &str) -> String {
35 let file = syn::parse_file(input).unwrap();
36 prettyplease::unparse(&file)
37 }
38
39 let input = rust_fmt(&format!("#[sqlfunc({attr})]\n{item}"));
40 let output = rust_fmt(
41 &sqlfunc_for_test(attr, item)
42 .unwrap_or_else(|err| err.write_errors())
43 .to_string(),
44 );
45 (output, input)
46}
47
48#[cfg(any(feature = "test", test))]
49pub fn test_sqlfunc_str(attr: &str, item: &str) -> (String, String) {
50 test_sqlfunc(attr.parse().unwrap(), item.parse().unwrap())
51}
52
53#[cfg(test)]
54mod test {
55 use quote::quote;
56
57 #[cfg_attr(miri, ignore)] #[mz_ore::test]
59 fn insta_test_add_int16() {
60 let attr = quote! {
61 is_monotone = (true, true),
62 output_type = i16,
63 is_infix_op = true,
64 sqlname = "+",
65 propagates_nulls = true,
66 test = true,
67 };
68 let item = quote! {
69 fn add_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
70 a.unwrap_int16()
71 .checked_add(b.unwrap_int16())
72 .ok_or(EvalError::NumericFieldOverflow)
73 .map(Datum::from)
74 }
75 };
76 let (output, input) = super::test_sqlfunc(attr, item);
77 insta::assert_snapshot!("add_int16", output, &input);
78 }
79
80 #[cfg_attr(miri, ignore)] #[mz_ore::test]
82 fn insta_test_unary() {
83 let attr = quote! {test = true};
84 let item = quote! {
85 fn unary_fn<'a>(a: Datum<'a>) -> bool {
86 unimplemented!()
87 }
88 };
89 let (output, input) = super::test_sqlfunc(attr, item);
90 insta::assert_snapshot!("unary_fn", output, &input);
91 }
92
93 #[cfg_attr(miri, ignore)] #[mz_ore::test]
95 fn insta_test_unary_arena() {
96 let attr = quote! {test = true};
97 let item = quote! {
98 fn unary_fn<'a>(a: Datum<'a>, temp_storage: &RowArena) -> bool {
99 unimplemented!()
100 }
101 };
102 let (output, input) = super::test_sqlfunc(attr, item);
103 insta::assert_snapshot!("unary_arena_fn", output, &input);
104 }
105
106 #[cfg_attr(miri, ignore)] #[mz_ore::test]
108 fn insta_test_unary_ref() {
109 let attr = quote! {test = true};
110 let item = quote! {
111 fn unary_fn<'a>(a: &i16) -> bool {
112 unimplemented!()
113 }
114 };
115 let (output, input) = super::test_sqlfunc(attr, item);
116 insta::assert_snapshot!("unary_ref", output, &input);
117 }
118
119 #[cfg_attr(miri, ignore)] #[mz_ore::test]
121 fn insta_test_complex_output_type() {
122 let attr = quote! {
123 is_monotone = (true, true),
124 output_type = "Option<bool>",
125 is_infix_op = true,
126 sqlname = "test",
127 propagates_nulls = true,
128 test = true,
129 };
130 let item = quote! {
131 fn complex_output_type_fn<'a>(
132 a: Datum<'a>,
133 b: Datum<'a>,
134 ) -> Result<Datum<'a>, EvalError> {
135 unimplemented!()
136 }
137 };
138 let (output, input) = super::test_sqlfunc(attr, item);
139 insta::assert_snapshot!("complex_type", output, &input);
140 }
141
142 #[cfg_attr(miri, ignore)] #[mz_ore::test]
144 fn insta_test_binary_arena() {
145 let attr = quote! {test = true};
146 let item = quote! {
147 fn unary_fn<'a>(a: Datum<'a>, b: u16, temp_storage: &RowArena) -> bool {
148 unimplemented!()
149 }
150 };
151 let (output, input) = super::test_sqlfunc(attr, item);
152 insta::assert_snapshot!("binary_arena_fn", output, &input);
153 }
154}