@@ -65,30 +65,30 @@ static DefaultMacro chsql_macros[] = {
65
65
{DEFAULT_SCHEMA, " toFloatOrNull" , {" x" , nullptr }, {{nullptr , nullptr }}, R"( TRY_CAST(x AS DOUBLE))" },
66
66
{DEFAULT_SCHEMA, " toFloatOrZero" , {" x" , nullptr }, {{nullptr , nullptr }}, R"( CASE WHEN TRY_CAST(x AS DOUBLE) IS NOT NULL THEN CAST(x AS DOUBLE) ELSE 0 END)" },
67
67
// -- Arithmetic macros
68
- {DEFAULT_SCHEMA, " intDiv" , {" a" , " b" }, {{nullptr , nullptr }}, R"( (CAST(a AS BIGINT) // CAST(b AS BIGINT)))" },
69
- {DEFAULT_SCHEMA, " intDivOrNull" , {" a" , " b" }, {{nullptr , nullptr }}, R"( TRY_CAST((TRY_CAST(a AS BIGINT) // TRY_CAST(b AS BIGINT)) AS BIGINT))" },
68
+ {DEFAULT_SCHEMA, " intDiv" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (CAST(a AS BIGINT) // CAST(b AS BIGINT)))" },
69
+ {DEFAULT_SCHEMA, " intDivOrNull" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( TRY_CAST((TRY_CAST(a AS BIGINT) // TRY_CAST(b AS BIGINT)) AS BIGINT))" },
70
70
{DEFAULT_SCHEMA, " intDivOZero" , {" x" , nullptr }, {{nullptr , nullptr }}, R"( COALESCE((TRY_CAST((TRY_CAST(a AS BIGINT) // TRY_CAST(b AS BIGINT)) AS BIGINT)),0))" },
71
- {DEFAULT_SCHEMA, " plus" , {" a" , " b" }, {{nullptr , nullptr }}, R"( add(a, b))" },
72
- {DEFAULT_SCHEMA, " minus" , {" a" , " b" }, {{nullptr , nullptr }}, R"( subtract(a, b))" },
73
- {DEFAULT_SCHEMA, " modulo" , {" a" , " b" }, {{nullptr , nullptr }}, R"( CAST(a AS BIGINT) % CAST(b AS BIGINT))" },
74
- {DEFAULT_SCHEMA, " moduloOrZero" , {" a" , " b" }, {{nullptr , nullptr }}, R"( COALESCE(((TRY_CAST(a AS BIGINT) % TRY_CAST(b AS BIGINT))),0))" },
71
+ {DEFAULT_SCHEMA, " plus" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( add(a, b))" },
72
+ {DEFAULT_SCHEMA, " minus" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( subtract(a, b))" },
73
+ {DEFAULT_SCHEMA, " modulo" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( CAST(a AS BIGINT) % CAST(b AS BIGINT))" },
74
+ {DEFAULT_SCHEMA, " moduloOrZero" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( COALESCE(((TRY_CAST(a AS BIGINT) % TRY_CAST(b AS BIGINT))),0))" },
75
75
// -- Tuple macros
76
- {DEFAULT_SCHEMA, " tupleIntDiv" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] // CAST(x AS BIGINT)))" },
77
- {DEFAULT_SCHEMA, " tupleIntDivByNumber" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) // CAST(x AS BIGINT)))" },
78
- {DEFAULT_SCHEMA, " tupleDivide" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] / CAST(x AS BIGINT)))" },
79
- {DEFAULT_SCHEMA, " tupleMultiply" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> CAST(apply(b, x -> CAST(x AS BIGINT))[i] as BIGINT) * CAST(x AS BIGINT)))" },
80
- {DEFAULT_SCHEMA, " tupleMinus" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] - CAST(x AS BIGINT)))" },
81
- {DEFAULT_SCHEMA, " tuplePlus" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] + CAST(x AS BIGINT)))" },
82
- {DEFAULT_SCHEMA, " tupleMultiplyByNumber" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) * CAST(x AS BIGINT)))" },
83
- {DEFAULT_SCHEMA, " tupleDivideByNumber" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) / CAST(x AS BIGINT)))" },
84
- {DEFAULT_SCHEMA, " tupleModulo" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) % CAST(x AS BIGINT)))" },
85
- {DEFAULT_SCHEMA, " tupleModuloByNumber" , {" a" , " b" }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) % CAST(x AS BIGINT)))" },
86
- {DEFAULT_SCHEMA, " tupleConcat" , {" a" , " b" }, {{nullptr , nullptr }}, R"( list_concat(a, b))" },
76
+ {DEFAULT_SCHEMA, " tupleIntDiv" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] // CAST(x AS BIGINT)))" },
77
+ {DEFAULT_SCHEMA, " tupleIntDivByNumber" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) // CAST(x AS BIGINT)))" },
78
+ {DEFAULT_SCHEMA, " tupleDivide" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] / CAST(x AS BIGINT)))" },
79
+ {DEFAULT_SCHEMA, " tupleMultiply" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> CAST(apply(b, x -> CAST(x AS BIGINT))[i] as BIGINT) * CAST(x AS BIGINT)))" },
80
+ {DEFAULT_SCHEMA, " tupleMinus" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] - CAST(x AS BIGINT)))" },
81
+ {DEFAULT_SCHEMA, " tuplePlus" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x,i) -> apply(b, x -> CAST(x AS BIGINT))[i] + CAST(x AS BIGINT)))" },
82
+ {DEFAULT_SCHEMA, " tupleMultiplyByNumber" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) * CAST(x AS BIGINT)))" },
83
+ {DEFAULT_SCHEMA, " tupleDivideByNumber" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) / CAST(x AS BIGINT)))" },
84
+ {DEFAULT_SCHEMA, " tupleModulo" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) % CAST(x AS BIGINT)))" },
85
+ {DEFAULT_SCHEMA, " tupleModuloByNumber" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( apply(a, (x) -> CAST(apply(b, x -> CAST(x AS BIGINT))[1] as BIGINT) % CAST(x AS BIGINT)))" },
86
+ {DEFAULT_SCHEMA, " tupleConcat" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( list_concat(a, b))" },
87
87
// -- String matching macros
88
88
{DEFAULT_SCHEMA, " match" , {" string" , " token" }, {{nullptr , nullptr }}, R"( string LIKE token)" },
89
89
// -- Array macros
90
- {DEFAULT_SCHEMA, " arrayExists" , {" needle" , " haystack" }, {{nullptr , nullptr }}, R"( haystack @> ARRAY[needle])" },
91
- {DEFAULT_SCHEMA, " arrayMap" , {" e " , " arr" }, {{nullptr , nullptr }}, R"( array_transform(arr, e -> (e * e) ))" },
90
+ {DEFAULT_SCHEMA, " arrayExists" , {" needle" , " haystack" , nullptr }, {{nullptr , nullptr }}, R"( haystack @> ARRAY[needle])" },
91
+ {DEFAULT_SCHEMA, " arrayMap" , {" x " , " arr" , nullptr }, {{nullptr , nullptr }}, R"( array_transform(arr, x ))" },
92
92
// Date and Time Functions
93
93
{DEFAULT_SCHEMA, " toYear" , {" date_expression" , nullptr }, {{nullptr , nullptr }}, R"( EXTRACT(YEAR FROM date_expression))" },
94
94
{DEFAULT_SCHEMA, " toMonth" , {" date_expression" , nullptr }, {{nullptr , nullptr }}, R"( EXTRACT(MONTH FROM date_expression))" },
@@ -119,10 +119,32 @@ static DefaultMacro chsql_macros[] = {
119
119
// IP Address Functions
120
120
{DEFAULT_SCHEMA, " IPv4NumToString" , {" num" , nullptr }, {{nullptr , nullptr }}, R"( CONCAT(CAST((num >> 24) & 255 AS VARCHAR), '.', CAST((num >> 16) & 255 AS VARCHAR), '.', CAST((num >> 8) & 255 AS VARCHAR), '.', CAST(num & 255 AS VARCHAR)))" },
121
121
{DEFAULT_SCHEMA, " IPv4StringToNum" , {" ip" , nullptr }, {{nullptr , nullptr }}, R"( CAST(SPLIT_PART(ip, '.', 1) AS INTEGER) * 256 * 256 * 256 + CAST(SPLIT_PART(ip, '.', 2) AS INTEGER) * 256 * 256 + CAST(SPLIT_PART(ip, '.', 3) AS INTEGER) * 256 + CAST(SPLIT_PART(ip, '.', 4) AS INTEGER))" },
122
+ // -- JSON Macros
123
+ {DEFAULT_SCHEMA, " JSONExtract" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( json_extract(json, key))" },
124
+ {DEFAULT_SCHEMA, " JSONExtractString" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( CAST(json_extract(json, key) AS VARCHAR))" },
125
+ {DEFAULT_SCHEMA, " JSONExtractUInt" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( CAST(json_extract(json, key) AS UINTEGER))" },
126
+ {DEFAULT_SCHEMA, " JSONExtractInt" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( CAST(json_extract(json, key) AS INT32))" },
127
+ {DEFAULT_SCHEMA, " JSONExtractFloat" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( CAST(json_extract(json, key) AS DOUBLE))" },
128
+ {DEFAULT_SCHEMA, " JSONExtractRaw" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( json_extract(json, key))" },
129
+ {DEFAULT_SCHEMA, " JSONHas" , {" json" , " key" , nullptr }, {{nullptr , nullptr }}, R"( json_extract(json, key) IS NOT NULL)" },
130
+ {DEFAULT_SCHEMA, " JSONLength" , {" json" , nullptr }, {{nullptr , nullptr }}, R"( json_array_length(json))" },
131
+ {DEFAULT_SCHEMA, " JSONType" , {" json" , " path" , nullptr }, {{nullptr , nullptr }}, R"( CASE WHEN path IS NULL THEN json_each(json) ELSE json_each(json,path) END)" },
132
+ {DEFAULT_SCHEMA, " JSONExtractKeys" , {" json" , nullptr }, {{nullptr , nullptr }}, R"( json_object_keys(json))" },
133
+ {DEFAULT_SCHEMA, " JSONExtractValues" , {" json" , nullptr }, {{nullptr , nullptr }}, R"( json_each_text(json))" },
134
+ // -- Compare Macros
135
+ {DEFAULT_SCHEMA, " equals" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a = b))" },
136
+ {DEFAULT_SCHEMA, " notEquals" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a <> b))" },
137
+ {DEFAULT_SCHEMA, " less" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a < b))" },
138
+ {DEFAULT_SCHEMA, " greater" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a > b))" },
139
+ {DEFAULT_SCHEMA, " lessOrEquals" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a <= b))" },
140
+ {DEFAULT_SCHEMA, " greaterOrEquals" , {" a" , " b" , nullptr }, {{nullptr , nullptr }}, R"( (a >= b))" },
122
141
// -- Misc macros
123
142
{DEFAULT_SCHEMA, " generateUUIDv4" , {nullptr }, {{nullptr , nullptr }}, R"( toString(uuid()))" },
124
143
{DEFAULT_SCHEMA, " parseURL" , {" url" , " part" , nullptr }, {{nullptr , nullptr }}, R"( CASE part WHEN 'protocol' THEN REGEXP_EXTRACT(url, '^(\w+)://') WHEN 'domain' THEN REGEXP_EXTRACT(url, '://([^/:]+)') WHEN 'port' THEN REGEXP_EXTRACT(url, ':(\d+)') WHEN 'path' THEN REGEXP_EXTRACT(url, '://[^/]+(/.+?)(\?|#|$)') WHEN 'query' THEN REGEXP_EXTRACT(url, '\?([^#]+)') WHEN 'fragment' THEN REGEXP_EXTRACT(url, '#(.+)$') END)" },
125
144
{DEFAULT_SCHEMA, " bitCount" , {" num" , nullptr }, {{nullptr , nullptr }}, R"( BIT_COUNT(num))" },
145
+ // Dictionary Emulation using MAP VARIABLES
146
+ {DEFAULT_SCHEMA, " dictGet" , {" dict" ," attr" , nullptr }, {{nullptr , nullptr }}, R"( getvariable(dict)[attr][1])" },
147
+ // -- End Macro
126
148
{nullptr , nullptr , {nullptr }, {{nullptr , nullptr }}, nullptr }};
127
149
128
150
// To add a new table SQL macro, add a new macro to this array!
@@ -142,8 +164,23 @@ static DefaultMacro chsql_macros[] = {
142
164
// clang-format off
143
165
static const DefaultTableMacro chsql_table_macros[] = {
144
166
{DEFAULT_SCHEMA, " numbers" , {" x" , nullptr }, {{" z" , " 0" }, {nullptr , nullptr }}, R"( SELECT * as number FROM generate_series(z,x-1);)" },
145
- {DEFAULT_SCHEMA, " ch_scan" , {" query" , " server" }, {{" format" , " JSONEachRow" }, {" user" , " play" }, {nullptr , nullptr }}, R"( SELECT * FROM read_json_auto(concat(server, '/?default_format=', format, '&user=', user, '&query=', query)))" },
146
- {DEFAULT_SCHEMA, " url" , {" url" , " format" }, {{nullptr , nullptr }}, R"( WITH "JSON" as (SELECT * FROM read_json_auto(url)), "PARQUET" as (SELECT * FROM read_parquet(url)), "CSV" as (SELECT * FROM read_csv_auto(url)), "BLOB" as (SELECT * FROM read_blob(url)), "TEXT" as (SELECT * FROM read_text(url)) FROM query_table(format))" },
167
+ {DEFAULT_SCHEMA, " url" , {" url" , " format" , nullptr }, {{nullptr , nullptr }}, R"( WITH "JSON" as (SELECT * FROM read_json_auto(url)), "PARQUET" as (SELECT * FROM read_parquet(url)), "CSV" as (SELECT * FROM read_csv_auto(url)), "BLOB" as (SELECT * FROM read_blob(url)), "TEXT" as (SELECT * FROM read_text(url)) FROM query_table(format))" },
168
+ {DEFAULT_SCHEMA, " ch_scan" , {" query" , " server" , nullptr }, {{" format" , " JSONEachRow" }, {" user" , " play" }, {nullptr , nullptr }}, R"(
169
+ WITH
170
+ "json" AS (SELECT * FROM read_json_auto(concat(server, '/?default_format=jsoneachrow&user=', user, '&query=', query))),
171
+ "parquet" AS (SELECT * FROM read_parquet(concat(server, '/?default_format=parquet&user=', user, '&query=', query))),
172
+ "csv" AS (SELECT * FROM read_csv_auto(concat(server, '/?default_format=csv&user=', user, '&query=', query))),
173
+ "blob" AS (SELECT * FROM read_blob(concat(server, '/?default_format=blob&user=', user, '&query=', query))),
174
+ "text" AS (SELECT * FROM read_text(concat(server, '/?default_format=text&user=', user, '&query=', query)))
175
+ FROM query_table(CASE
176
+ WHEN LOWER(format) LIKE 'json%' THEN 'json'
177
+ WHEN LOWER(format) LIKE 'csv%' THEN 'csv'
178
+ WHEN LOWER(format) = 'parquet' THEN 'parquet'
179
+ WHEN LOWER(format) = 'blob' THEN 'blob'
180
+ WHEN LOWER(format) = 'text' THEN 'text'
181
+ ELSE 'json'
182
+ END)
183
+ )" },
147
184
{nullptr , nullptr , {nullptr }, {{nullptr , nullptr }}, nullptr }
148
185
};
149
186
// clang-format on
0 commit comments