@@ -23,31 +23,86 @@ inline void JsonataScalarFun(DataChunk &args, ExpressionState &state, Vector &re
2323 ConstantVector::SetNull (result, true );
2424 return ;
2525 }
26- auto jsonata = ConstantVector::GetData<string_t >(jsonata_vector)[0 ];
27- auto jsonata_expr = jsonata::Jsonata (jsonata.GetString ());
26+ auto jsonata_str = ConstantVector::GetData<string_t >(jsonata_vector)[0 ];
27+
28+ // Parse the JSONata expression once for all rows (constant optimization)
29+ std::unique_ptr<jsonata::Jsonata> jsonata_expr;
30+ try {
31+ jsonata_expr = make_uniq<jsonata::Jsonata>(jsonata_str.GetString ());
32+ } catch (const std::exception &e) {
33+ throw InvalidInputException (" Invalid JSONata expression: %s" , e.what ());
34+ }
2835
2936 UnaryExecutor::Execute<string_t , string_t >(data_vector, result, args.size (), [&](string_t data) {
30- auto parsed = nlohmann::json::parse (string (data.GetData (), data.GetSize ()));
31- auto output = jsonata_expr.evaluate (parsed);
32- auto output_str = output.dump ();
33- return StringVector::AddString (result, output_str);
37+ nlohmann::json parsed;
38+ try {
39+ parsed = nlohmann::json::parse (string (data.GetData (), data.GetSize ()));
40+ } catch (const nlohmann::json::parse_error &e) {
41+ throw InvalidInputException (" Invalid JSON data: %s" , e.what ());
42+ }
43+
44+ nlohmann::json output;
45+ try {
46+ output = jsonata_expr->evaluate (parsed);
47+ } catch (const std::exception &e) {
48+ throw InvalidInputException (" JSONata evaluation error: %s" , e.what ());
49+ }
50+
51+ return StringVector::AddString (result, output.dump ());
3452 });
3553 } else {
3654 BinaryExecutor::Execute<string_t , string_t , string_t >(
37- jsonata_vector, data_vector, result, args.size (), [&](string_t jsonata, string_t data) {
38- auto parsed = nlohmann::json::parse (string (data.GetData (), data.GetSize ()));
39- auto jsonata_expr = jsonata::Jsonata (string (jsonata.GetData (), jsonata.GetSize ()));
40- auto output = jsonata_expr.evaluate (parsed);
41- auto output_str = output.dump ();
42- return StringVector::AddString (result, output_str);
55+ jsonata_vector, data_vector, result, args.size (), [&](string_t jsonata_str, string_t data) {
56+ nlohmann::json parsed;
57+ try {
58+ parsed = nlohmann::json::parse (string (data.GetData (), data.GetSize ()));
59+ } catch (const nlohmann::json::parse_error &e) {
60+ throw InvalidInputException (" Invalid JSON data: %s" , e.what ());
61+ }
62+
63+ std::unique_ptr<jsonata::Jsonata> jsonata_expr;
64+ try {
65+ jsonata_expr = make_uniq<jsonata::Jsonata>(string (jsonata_str.GetData (), jsonata_str.GetSize ()));
66+ } catch (const std::exception &e) {
67+ throw InvalidInputException (" Invalid JSONata expression: %s" , e.what ());
68+ }
69+
70+ nlohmann::json output;
71+ try {
72+ output = jsonata_expr->evaluate (parsed);
73+ } catch (const std::exception &e) {
74+ throw InvalidInputException (" JSONata evaluation error: %s" , e.what ());
75+ }
76+
77+ return StringVector::AddString (result, output.dump ());
4378 });
4479 }
4580}
4681
4782static void LoadInternal (ExtensionLoader &loader) {
83+ ScalarFunctionSet jsonata_function_set (" jsonata" );
4884 auto jsonata_scalar_function =
49- ScalarFunction (" jsonata" , {LogicalType::VARCHAR , LogicalType::JSON ()}, LogicalType::JSON (), JsonataScalarFun);
50- loader.RegisterFunction (jsonata_scalar_function);
85+ ScalarFunction ({LogicalType::VARCHAR , LogicalType::JSON ()}, LogicalType::JSON (), JsonataScalarFun);
86+ jsonata_function_set.AddFunction (jsonata_scalar_function);
87+
88+ CreateScalarFunctionInfo info (jsonata_function_set);
89+ info.descriptions .push_back ({
90+ // parameter_types
91+ {LogicalType::VARCHAR , LogicalType::JSON ()},
92+ // parameter_names
93+ {" expression" , " json_data" },
94+ // description
95+ " Evaluates a JSONata expression against JSON data. JSONata is a lightweight query and transformation "
96+ " language for JSON data. See https://jsonata.org for the full language reference." ,
97+ // examples
98+ {" jsonata('Account.Name', '{\" Account\" : {\" Name\" : \" Firefly\" }}')" ,
99+ " jsonata('$.prices[price > 100]', my_json_column)" ,
100+ " jsonata('$sum(Order.Product.Price)', orders)" },
101+ // categories
102+ {" json" },
103+ });
104+
105+ loader.RegisterFunction (info);
51106
52107 QueryFarmSendTelemetry (loader, " jsonata" , " 2025110901" );
53108}
0 commit comments