diff --git a/Cargo.lock b/Cargo.lock index 5efd0bda67..14903e5588 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3757,7 +3757,7 @@ checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "datafusion" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "arrow-schema 58.3.0", @@ -3811,7 +3811,7 @@ dependencies = [ [[package]] name = "datafusion-catalog" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "datafusion-catalog-listing" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -3857,7 +3857,7 @@ dependencies = [ [[package]] name = "datafusion-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -3881,7 +3881,7 @@ dependencies = [ [[package]] name = "datafusion-common-runtime" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "futures", "log", @@ -3891,7 +3891,7 @@ dependencies = [ [[package]] name = "datafusion-datasource" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-compression", @@ -3925,7 +3925,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-arrow" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "arrow-ipc 58.3.0", @@ -3948,7 +3948,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-csv" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -3970,7 +3970,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-json" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -3993,7 +3993,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-parquet" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -4022,12 +4022,12 @@ dependencies = [ [[package]] name = "datafusion-doc" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" [[package]] name = "datafusion-execution" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "arrow-buffer 58.3.0", @@ -4049,7 +4049,7 @@ dependencies = [ [[package]] name = "datafusion-expr" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -4071,7 +4071,7 @@ dependencies = [ [[package]] name = "datafusion-expr-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4083,7 +4083,7 @@ dependencies = [ [[package]] name = "datafusion-functions" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "arrow-buffer 58.3.0", @@ -4114,7 +4114,7 @@ dependencies = [ [[package]] name = "datafusion-functions-aggregate" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -4135,7 +4135,7 @@ dependencies = [ [[package]] name = "datafusion-functions-aggregate-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -4147,7 +4147,7 @@ dependencies = [ [[package]] name = "datafusion-functions-nested" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "arrow-ord 58.3.0", @@ -4171,7 +4171,7 @@ dependencies = [ [[package]] name = "datafusion-functions-table" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "async-trait", @@ -4186,7 +4186,7 @@ dependencies = [ [[package]] name = "datafusion-functions-window" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4203,7 +4203,7 @@ dependencies = [ [[package]] name = "datafusion-functions-window-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "datafusion-common", "datafusion-physical-expr-common", @@ -4212,7 +4212,7 @@ dependencies = [ [[package]] name = "datafusion-macros" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "datafusion-doc", "quote", @@ -4222,7 +4222,7 @@ dependencies = [ [[package]] name = "datafusion-optimizer" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "chrono", @@ -4271,7 +4271,7 @@ dependencies = [ [[package]] name = "datafusion-physical-expr" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -4294,7 +4294,7 @@ dependencies = [ [[package]] name = "datafusion-physical-expr-adapter" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4308,7 +4308,7 @@ dependencies = [ [[package]] name = "datafusion-physical-expr-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -4324,7 +4324,7 @@ dependencies = [ [[package]] name = "datafusion-physical-optimizer" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4342,7 +4342,7 @@ dependencies = [ [[package]] name = "datafusion-physical-plan" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "ahash 0.8.12", "arrow 58.3.0", @@ -4373,7 +4373,7 @@ dependencies = [ [[package]] name = "datafusion-proto" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "chrono", @@ -4400,7 +4400,7 @@ dependencies = [ [[package]] name = "datafusion-proto-common" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4410,7 +4410,7 @@ dependencies = [ [[package]] name = "datafusion-pruning" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "datafusion-common", @@ -4426,7 +4426,7 @@ dependencies = [ [[package]] name = "datafusion-session" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "async-trait", "datafusion-common", @@ -4439,7 +4439,7 @@ dependencies = [ [[package]] name = "datafusion-sql" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "arrow 58.3.0", "bigdecimal 0.4.8", @@ -4457,7 +4457,7 @@ dependencies = [ [[package]] name = "datafusion-substrait" version = "53.1.0" -source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=4c8a6bf28347b346348136247eb67dfb933f1147#4c8a6bf28347b346348136247eb67dfb933f1147" +source = "git+https://github.com/GreptimeTeam/datafusion.git?rev=144225dd11e38960de75786fde69159cb27b8af3#144225dd11e38960de75786fde69159cb27b8af3" dependencies = [ "async-recursion", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 330b6f0640..7b3e9263d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -353,21 +353,21 @@ git = "https://github.com/GreptimeTeam/greptime-meter.git" rev = "5618e779cf2bb4755b499c630fba4c35e91898cb" [patch.crates-io] -datafusion = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-datasource = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-expr = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-expr-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-functions = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-functions-aggregate-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-functions-window-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-optimizer = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-physical-expr = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-physical-expr-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-physical-plan = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-proto = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-sql = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } -datafusion-substrait = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "4c8a6bf28347b346348136247eb67dfb933f1147" } +datafusion = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-datasource = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-expr = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-expr-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-functions = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-functions-aggregate-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-functions-window-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-optimizer = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-physical-expr = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-physical-expr-common = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-physical-plan = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-proto = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-sql = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } +datafusion-substrait = { git = "https://github.com/GreptimeTeam/datafusion.git", rev = "144225dd11e38960de75786fde69159cb27b8af3" } sqlparser = { git = "https://github.com/GreptimeTeam/sqlparser-rs.git", rev = "2aefa08a8d69c96eec2d6d6703598a009bba6e4c" } # on branch v0.61.x [profile.release] diff --git a/src/query/src/datafusion/json_expr_planner.rs b/src/query/src/datafusion/json_expr_planner.rs index e650ac102c..bbf5b4b8ff 100644 --- a/src/query/src/datafusion/json_expr_planner.rs +++ b/src/query/src/datafusion/json_expr_planner.rs @@ -20,21 +20,25 @@ use common_function::scalars::udf::create_udf; use datafusion_common::arrow::datatypes::DataType; use datafusion_common::{Column, DFSchema, Result, ScalarValue, TableReference}; use datafusion_expr::expr::{BinaryExpr, ScalarFunction}; -use datafusion_expr::planner::{ExprPlanner, PlannerResult, RawBinaryExpr}; -use datafusion_expr::{Expr, ExprSchemable, Operator, ScalarUDF}; +use datafusion_expr::planner::{ + ExprPlanner, PlannerResult, RawAggregateExpr, RawBinaryExpr, RawScalarExpr, RawWindowExpr, +}; +use datafusion_expr::type_coercion::functions::{UDFCoercionExt, fields_with_udf}; +use datafusion_expr::{Expr, ExprSchemable, Operator, ScalarUDF, WindowFunctionDefinition}; use datatypes::extension::json::is_json2_extension_type; -use either::Either; use sqlparser::ast::BinaryOperator; /// Rewrites JSON-aware SQL expressions into DataFusion expressions. /// -/// This planner handles two cases: +/// This planner handles three cases: /// - Rewrites compound identifiers on JSON extension columns into `json_get` function. /// For example, `select a.b.c` => `select json_get(a, "b.c")`. /// - Pushes an "expected type" argument into the `json_get` function when it participates in a /// binary operator. So that `json_get` knows the wanted data type when dealing with variant /// JSON values. /// For example, `select json_get(a, "b.c") + 1` => `select json_get(a, "b.c", NULL::Int64) + 1`. +/// - Infers the expected type from scalar, aggregate, and window function signatures. +/// For example, `select abs(a.b.c)` => `select abs(json_get(a, "b.c", NULL::Float64))`. #[derive(Debug)] pub(crate) struct JsonExprPlanner; @@ -50,9 +54,7 @@ impl ExprPlanner for JsonExprPlanner { mut right, } = expr; - if extract_untyped_json_get(&mut left).is_none() - && extract_untyped_json_get(&mut right).is_none() - { + if !is_untyped_json_get(&left) && !is_untyped_json_get(&right) { return Ok(PlannerResult::Original(RawBinaryExpr { op, left, right })); } @@ -62,17 +64,16 @@ impl ExprPlanner for JsonExprPlanner { let left_type = left.get_type(schema)?; let right_type = right.get_type(schema)?; - let left = push_json_get_type_arg(left, right_type)?; - let right = push_json_get_type_arg(right, left_type)?; - match (left, right) { - (Either::Left(left), Either::Left(right)) => { - Ok(PlannerResult::Original(RawBinaryExpr { op, left, right })) - } - (left, right) => Ok(PlannerResult::Planned(Expr::BinaryExpr(BinaryExpr::new( - Box::new(left.into_inner()), + let left_changed = push_json_get_type_arg(&mut left, &right_type)?; + let right_changed = push_json_get_type_arg(&mut right, &left_type)?; + if left_changed || right_changed { + Ok(PlannerResult::Planned(Expr::BinaryExpr(BinaryExpr::new( + Box::new(left), expr_op, - Box::new(right.into_inner()), - )))), + Box::new(right), + )))) + } else { + Ok(PlannerResult::Original(RawBinaryExpr { op, left, right })) } } @@ -101,31 +102,235 @@ impl ExprPlanner for JsonExprPlanner { ), ))) } + + /// Rewrites JSON2 arguments without taking over the final function planning. + /// + /// `Original` carries the possibly modified raw expression to subsequent planners and then + /// DataFusion's default function construction. Returning `Planned` would short-circuit both. + fn plan_scalar(&self, mut expr: RawScalarExpr) -> Result> { + push_function_arg_types(expr.func.as_ref(), &mut expr.args)?; + Ok(PlannerResult::Original(expr)) + } + + /// Rewrites JSON2 arguments while preserving subsequent aggregate planning. + fn plan_aggregate( + &self, + mut expr: RawAggregateExpr, + ) -> Result> { + push_function_arg_types(expr.func.as_ref(), &mut expr.args)?; + Ok(PlannerResult::Original(expr)) + } + + /// Rewrites JSON2 arguments while preserving subsequent window planning. + fn plan_window(&self, mut expr: RawWindowExpr) -> Result> { + match &expr.func_def { + WindowFunctionDefinition::AggregateUDF(func) => { + push_function_arg_types(func.as_ref(), &mut expr.args)?; + } + WindowFunctionDefinition::WindowUDF(func) => { + push_function_arg_types(func.as_ref(), &mut expr.args)?; + } + } + Ok(PlannerResult::Original(expr)) + } +} + +enum JsonGetTypeResolution { + Fallback, + Typed(Vec<(usize, DataType)>), +} + +/// Infers static output types for untyped `json_get` arguments from a function signature. +/// +/// DataFusion requires every expression to have one Arrow data type during planning. A JSON path +/// may contain heterogeneous values across rows, but it cannot expose those values as different +/// Arrow types in one result column. Preserving their runtime types would require a single +/// Variant-like data type and Variant-aware functions instead. Maybe we can wait for +/// https://github.com/apache/datafusion/issues/16116 +/// +/// This helper uses the function's coercion rules to select a supported output type, then appends +/// a typed NULL argument to each relevant `json_get`. The typed argument makes `json_get` project +/// compatible JSON values to that type and return NULL for incompatible values. Functions that +/// accept json_get's default `Utf8View` output keep the two-argument form so later rewrites can +/// still push down an outer cast. +fn push_function_arg_types(func: &F, args: &mut [Expr]) -> Result<()> +where + F: UDFCoercionExt, +{ + if !args.iter().any(is_untyped_json_get) { + return Ok(()); + } + + let fields = args.iter().map(function_arg_field).collect::>(); + match infer_json_get_types(func, args, &fields) { + JsonGetTypeResolution::Fallback => { + let Some(data_type) = fallback_json_get_type(func, args, &fields) else { + return Ok(()); + }; + for arg in args.iter_mut() { + if is_untyped_json_get(arg) { + let _ = push_json_get_type_arg(arg, &data_type)?; + } + } + } + JsonGetTypeResolution::Typed(types) => { + for (index, data_type) in types { + let _ = push_json_get_type_arg(&mut args[index], &data_type)?; + } + } + } + Ok(()) +} + +fn infer_json_get_types(func: &F, args: &[Expr], fields: &[Arc]) -> JsonGetTypeResolution +where + F: UDFCoercionExt, +{ + // Only untyped json_get arguments use Null placeholders; preserve every other known argument + // type. fields_with_udf performs contextual coercion rather than reverse inference from a + // signature alone. Numeric signatures may preserve all-Null inputs, while Comparable + // signatures may default them to Utf8. For example, retaining the Float64 peer in + // coalesce(json_get(...), 1.0) lets DataFusion resolve json_get to Float64 instead of Utf8. + // + // This is a best-effort probe: a failure does not mean the actual function call is invalid, so + // try concrete JSON types before leaving final validation to DataFusion's default planner. + let Ok(coerced) = fields_with_udf(fields, func) else { + return JsonGetTypeResolution::Fallback; + }; + + let mut inferred_types = Vec::with_capacity(coerced.len()); + for (index, (arg, field)) in args.iter().zip(coerced).enumerate() { + if !is_untyped_json_get(arg) || field.data_type().is_null() { + continue; + } + let Some(data_type) = json_get_output_type(field.data_type()) else { + return JsonGetTypeResolution::Fallback; + }; + inferred_types.push((index, data_type)); + } + if inferred_types.is_empty() { + JsonGetTypeResolution::Fallback + } else { + JsonGetTypeResolution::Typed(inferred_types) + } +} + +fn fallback_json_get_type(func: &F, args: &[Expr], fields: &[Arc]) -> Option +where + F: UDFCoercionExt, +{ + // Prefer json_get's default Utf8View type. If the function rejects strings but accepts numeric + // values, prefer Float64 so both integers and fractions remain usable. + let mut candidate_fields = fields.to_vec(); + for data_type in [ + DataType::Utf8View, + DataType::Float64, + DataType::Int64, + DataType::Boolean, + ] { + for (index, arg) in args.iter().enumerate() { + if is_untyped_json_get(arg) { + candidate_fields[index] = Arc::new( + fields[index] + .as_ref() + .clone() + .with_data_type(data_type.clone()), + ); + } + } + if fields_with_udf(&candidate_fields, func).is_ok() { + return Some(data_type); + } + } + None +} + +fn function_arg_field(expr: &Expr) -> Arc { + let data_type = if is_untyped_json_get(expr) { + DataType::Null + } else if let Some(data_type) = extract_json_get_type(expr) { + data_type + } else { + // Treat unresolved expressions as untyped NULL. This lets signatures such as `power` + // infer a JSON type, while functions such as `coalesce` can leave it untyped for default + // planning. This is only best-effort: overloaded or user-defined functions may select a + // different signature for NULL than for the expression's actual type. + // TODO(LFC): Use the input schema once DataFusion passes it to ExprPlanner::plan_*(). + expr.get_type(&DFSchema::empty()).unwrap_or(DataType::Null) + }; + Arc::new(Field::new("", data_type, true)) +} + +fn json_get_output_type(data_type: &DataType) -> Option { + let output_type = match data_type { + DataType::Boolean => DataType::Boolean, + data_type if data_type.is_integer() => DataType::Int64, + data_type if data_type.is_floating() => DataType::Float64, + DataType::Decimal128(_, _) | DataType::Decimal256(_, _) => DataType::Float64, + data_type if data_type.is_string() => DataType::Utf8View, + _ => return None, + }; + Some(output_type) +} + +macro_rules! is_untyped_json_get_func { + ($func:expr) => { + $func + .func + .name() + .eq_ignore_ascii_case(JsonGetWithType::NAME) + && $func.args.len() == 2 + }; +} + +macro_rules! is_typed_json_get_func { + ($func:expr) => { + $func + .func + .name() + .eq_ignore_ascii_case(JsonGetWithType::NAME) + && $func.args.len() == 3 + }; } fn extract_untyped_json_get(expr: &mut Expr) -> Option<&mut ScalarFunction> { match expr { - Expr::ScalarFunction(f) - if f.func.name().eq_ignore_ascii_case(JsonGetWithType::NAME) && f.args.len() == 2 => - { - Some(f) - } + Expr::ScalarFunction(f) if is_untyped_json_get_func!(f) => Some(f), _ => None, } } -fn push_json_get_type_arg(mut expr: Expr, mut data_type: DataType) -> Result> { - let Some(json_get) = extract_untyped_json_get(&mut expr) else { - return Ok(Either::Left(expr)); +fn extract_json_get_type(expr: &Expr) -> Option { + match expr { + Expr::ScalarFunction(f) if is_typed_json_get_func!(f) => f + .args + .get(2) + .and_then(|x| x.as_literal()) + .map(|x| x.data_type()), + _ => None, + } +} + +fn is_untyped_json_get(expr: &Expr) -> bool { + matches!( + expr, + Expr::ScalarFunction(f) if is_untyped_json_get_func!(f) + ) +} + +fn push_json_get_type_arg(expr: &mut Expr, data_type: &DataType) -> Result { + let Some(json_get) = extract_untyped_json_get(expr) else { + return Ok(false); }; + // The two-argument form already returns Utf8View. Keep it so JsonGetRewriter can still absorb + // a cast added by subsequent function coercion. if data_type.is_string() { - data_type = DataType::Utf8View; + return Ok(false); } - let with_type = ScalarValue::try_new_null(&data_type).map(|x| Expr::Literal(x, None))?; + let with_type = ScalarValue::try_new_null(data_type).map(|x| Expr::Literal(x, None))?; json_get.args.push(with_type); - - Ok(Either::Right(expr)) + Ok(true) } fn parse_sql_op(op: &BinaryOperator) -> Option { @@ -153,6 +358,11 @@ fn parse_sql_op(op: &BinaryOperator) -> Option { #[cfg(test)] mod tests { use arrow_schema::Fields; + use datafusion::functions_aggregate::count::count_udaf; + use datafusion::functions_aggregate::sum::sum_udaf; + use datafusion_expr::WindowFrame; + use datafusion_functions::core::coalesce; + use datafusion_functions::math::{abs, power}; use datatypes::extension::json::Json2ExtensionType; use super::*; @@ -281,4 +491,110 @@ mod tests { Ok(()) } + + #[test] + fn test_plan_functions() -> Result<()> { + let planner = JsonExprPlanner; + let json_get = || json_get_expr(Expr::Column(Column::new_unqualified("j")), "a.b"); + + let PlannerResult::Original(scalar) = planner.plan_scalar(RawScalarExpr { + func: abs(), + args: vec![json_get()], + })? + else { + unreachable!(); + }; + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&scalar.args[0]) + ); + + let PlannerResult::Original(scalar) = planner.plan_scalar(RawScalarExpr { + func: power(), + args: vec![ + json_get(), + Expr::Column(Column::new_unqualified("exponent")), + ], + })? + else { + unreachable!(); + }; + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&scalar.args[0]) + ); + + let PlannerResult::Original(aggregate) = planner.plan_aggregate(RawAggregateExpr { + func: sum_udaf(), + args: vec![json_get()], + distinct: false, + filter: None, + order_by: vec![], + null_treatment: None, + })? + else { + unreachable!(); + }; + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&aggregate.args[0]) + ); + + let PlannerResult::Original(count) = planner.plan_aggregate(RawAggregateExpr { + func: count_udaf(), + args: vec![json_get()], + distinct: false, + filter: None, + order_by: vec![], + null_treatment: None, + })? + else { + unreachable!(); + }; + assert_eq!(None, extract_json_get_type(&count.args[0])); + + let PlannerResult::Original(window) = planner.plan_window(RawWindowExpr { + func_def: WindowFunctionDefinition::AggregateUDF(sum_udaf()), + args: vec![json_get()], + partition_by: vec![], + order_by: vec![], + window_frame: WindowFrame::new(None), + filter: None, + null_treatment: None, + distinct: false, + })? + else { + unreachable!(); + }; + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&window.args[0]) + ); + Ok(()) + } + + #[test] + fn test_plan_function_with_mixed_json_get_types() -> Result<()> { + let planner = JsonExprPlanner; + let json_get = || json_get_expr(Expr::Column(Column::new_unqualified("j")), "a.b"); + let mut typed = json_get(); + push_json_get_type_arg(&mut typed, &DataType::Float64)?; + + let PlannerResult::Original(scalar) = planner.plan_scalar(RawScalarExpr { + func: coalesce(), + args: vec![json_get(), typed], + })? + else { + unreachable!(); + }; + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&scalar.args[0]) + ); + assert_eq!( + Some(DataType::Float64), + extract_json_get_type(&scalar.args[1]) + ); + Ok(()) + } } diff --git a/tests/cases/standalone/common/types/json/json2.result b/tests/cases/standalone/common/types/json/json2.result index 32fa31a76c..f1e5b0f0ad 100644 --- a/tests/cases/standalone/common/types/json/json2.result +++ b/tests/cases/standalone/common/types/json/json2.result @@ -328,19 +328,6 @@ select j.a.b + 1 from json2_table order by ts; | 11 | +------------------------------------------------------------+ -select abs(j.a.b) from json2_table order by ts; - -Error: 3000(PlanQuery), Failed to plan SQL: Error during planning: Function 'abs' expects NativeType::Numeric but received NativeType::String No function matches the given name and argument types 'abs(Utf8View)'. You might need to add explicit type casts. - Candidate functions: - abs(Numeric(1)) - --- "j.c" is of type "String", "abs" is expected to be all "null"s. -select abs(j.c) from json2_table order by ts; - -Error: 3000(PlanQuery), Failed to plan SQL: Error during planning: Function 'abs' expects NativeType::Numeric but received NativeType::String No function matches the given name and argument types 'abs(Utf8View)'. You might need to add explicit type casts. - Candidate functions: - abs(Numeric(1)) - select j.d from json2_table order by ts; +-----------------------------------+ diff --git a/tests/cases/standalone/common/types/json/json2.sql b/tests/cases/standalone/common/types/json/json2.sql index 090e1f4fd2..195b1de010 100644 --- a/tests/cases/standalone/common/types/json/json2.sql +++ b/tests/cases/standalone/common/types/json/json2.sql @@ -70,11 +70,6 @@ select json_get(j, '$.') from json2_table order by ts; select j.a.b + 1 from json2_table order by ts; -select abs(j.a.b) from json2_table order by ts; - --- "j.c" is of type "String", "abs" is expected to be all "null"s. -select abs(j.c) from json2_table order by ts; - select j.d from json2_table order by ts; drop table json2_table; diff --git a/tests/cases/standalone/common/types/json/json2_functions.result b/tests/cases/standalone/common/types/json/json2_functions.result new file mode 100644 index 0000000000..8d8561020f --- /dev/null +++ b/tests/cases/standalone/common/types/json/json2_functions.result @@ -0,0 +1,230 @@ +create table json2_function_table ( + ts timestamp time index, + j json2, + exponent double +) with ( + 'append_mode' = 'true', + 'sst_format' = 'flat' +); + +Affected Rows: 0 + +insert into json2_function_table values + (1, '{"metrics":{"value":1,"enabled":true},"label":"one","tags":["a"]}', 2), + (2, '{"metrics":{"value":-2.5,"enabled":false},"label":2,"tags":{"source":"b"}}', 2); + +Affected Rows: 2 + +admin flush_table('json2_function_table'); + ++-------------------------------------------+ +| ADMIN flush_table('json2_function_table') | ++-------------------------------------------+ +| 0 | ++-------------------------------------------+ + +insert into json2_function_table values + (3, '{"metrics":{"value":"three","enabled":"yes"},"label":true,"tags":[1,2]}', 2), + (4, '{"metrics":{"value":true},"label":{"name":"four"},"tags":"four"}', 2), + (5, '{"metrics":{"value":{"nested":5}},"label":["five"],"tags":null}', 2), + (6, '{"metrics":{"value":[6]},"label":null}', 2); + +Affected Rows: 4 + +admin flush_table('json2_function_table'); + ++-------------------------------------------+ +| ADMIN flush_table('json2_function_table') | ++-------------------------------------------+ +| 0 | ++-------------------------------------------+ + +admin compact_table('json2_function_table', 'swcs', '86400'); + ++--------------------------------------------------------------+ +| ADMIN compact_table('json2_function_table', 'swcs', '86400') | ++--------------------------------------------------------------+ +| 0 | ++--------------------------------------------------------------+ + +insert into json2_function_table values + (7, '{"metrics":{"value":null},"label":"seven","extra":7}', 2), + (8, '{"metrics":"opaque","label":8,"extra":false}', 2); + +Affected Rows: 2 + +admin flush_table('json2_function_table'); + ++-------------------------------------------+ +| ADMIN flush_table('json2_function_table') | ++-------------------------------------------+ +| 0 | ++-------------------------------------------+ + +insert into json2_function_table values + (9, '{"other":9,"label":{"name":"nine"}}', 2), + (10, '{"metrics":{"value":10},"label":"ten","extra":[10]}', 2); + +Affected Rows: 2 + +-- Arrow casts Boolean values to Float64 as true = 1.0 and false = 0.0. +select abs(j.metrics.value) as abs_value from json2_function_table order by ts; + ++-----------+ +| abs_value | ++-----------+ +| 1.0 | +| 2.5 | +| | +| 1.0 | +| | +| | +| | +| | +| | +| 10.0 | ++-----------+ + +select power(j.label, 2) * 2 as scaled_label from json2_function_table order by ts; + ++--------------+ +| scaled_label | ++--------------+ +| | +| 8.0 | +| 2.0 | +| | +| | +| | +| | +| 128.0 | +| | +| | ++--------------+ + +select power(j.metrics.value, exponent) as powered_value from json2_function_table order by ts; + ++---------------+ +| powered_value | ++---------------+ +| 1.0 | +| 6.25 | +| | +| 1.0 | +| | +| | +| | +| | +| | +| 100.0 | ++---------------+ + +select coalesce(j.metrics.value, exponent) as value_or_exponent from json2_function_table order by ts; + ++-------------------+ +| value_or_exponent | ++-------------------+ +| 1.0 | +| -2.5 | +| 2.0 | +| 1.0 | +| 2.0 | +| 2.0 | +| 2.0 | +| 2.0 | +| 2.0 | +| 10.0 | ++-------------------+ + +select coalesce( + j.metrics.value, + j.label::double +) as mixed_value from json2_function_table order by ts; + ++-------------+ +| mixed_value | ++-------------+ +| 1.0 | +| -2.5 | +| 1.0 | +| 1.0 | +| | +| | +| | +| 8.0 | +| | +| 10.0 | ++-------------+ + +select ts, j.label as label, signum(j.metrics.value) as value_sign +from json2_function_table +order by ts; + ++-------------------------+-----------------+------------+ +| ts | label | value_sign | ++-------------------------+-----------------+------------+ +| 1970-01-01T00:00:00.001 | one | 1.0 | +| 1970-01-01T00:00:00.002 | 2 | -1.0 | +| 1970-01-01T00:00:00.003 | true | | +| 1970-01-01T00:00:00.004 | {"name":"four"} | 1.0 | +| 1970-01-01T00:00:00.005 | ["five"] | | +| 1970-01-01T00:00:00.006 | | | +| 1970-01-01T00:00:00.007 | seven | | +| 1970-01-01T00:00:00.008 | 8 | | +| 1970-01-01T00:00:00.009 | {"name":"nine"} | | +| 1970-01-01T00:00:00.010 | ten | 1.0 | ++-------------------------+-----------------+------------+ + +select ts, j.label as label +from json2_function_table +where iszero(j.metrics.value) = false +order by ts; + ++-------------------------+-----------------+ +| ts | label | ++-------------------------+-----------------+ +| 1970-01-01T00:00:00.001 | one | +| 1970-01-01T00:00:00.002 | 2 | +| 1970-01-01T00:00:00.004 | {"name":"four"} | +| 1970-01-01T00:00:00.010 | ten | ++-------------------------+-----------------+ + +select count(j.metrics.value) as value_count from json2_function_table; + ++-------------+ +| value_count | ++-------------+ +| 7 | ++-------------+ + +select sum(j.metrics.value) as value_sum from json2_function_table; + ++-----------+ +| value_sum | ++-----------+ +| 9.5 | ++-----------+ + +select lag(j.metrics.value) over (order by ts) as previous_value +from json2_function_table +order by ts; + ++----------------+ +| previous_value | ++----------------+ +| | +| 1 | +| -2.5 | +| three | +| true | +| {"nested":5} | +| [6] | +| | +| | +| | ++----------------+ + +drop table json2_function_table; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/types/json/json2_functions.sql b/tests/cases/standalone/common/types/json/json2_functions.sql new file mode 100644 index 0000000000..3dcced0557 --- /dev/null +++ b/tests/cases/standalone/common/types/json/json2_functions.sql @@ -0,0 +1,67 @@ +create table json2_function_table ( + ts timestamp time index, + j json2, + exponent double +) with ( + 'append_mode' = 'true', + 'sst_format' = 'flat' +); + +insert into json2_function_table values + (1, '{"metrics":{"value":1,"enabled":true},"label":"one","tags":["a"]}', 2), + (2, '{"metrics":{"value":-2.5,"enabled":false},"label":2,"tags":{"source":"b"}}', 2); + +admin flush_table('json2_function_table'); + +insert into json2_function_table values + (3, '{"metrics":{"value":"three","enabled":"yes"},"label":true,"tags":[1,2]}', 2), + (4, '{"metrics":{"value":true},"label":{"name":"four"},"tags":"four"}', 2), + (5, '{"metrics":{"value":{"nested":5}},"label":["five"],"tags":null}', 2), + (6, '{"metrics":{"value":[6]},"label":null}', 2); + +admin flush_table('json2_function_table'); + +admin compact_table('json2_function_table', 'swcs', '86400'); + +insert into json2_function_table values + (7, '{"metrics":{"value":null},"label":"seven","extra":7}', 2), + (8, '{"metrics":"opaque","label":8,"extra":false}', 2); + +admin flush_table('json2_function_table'); + +insert into json2_function_table values + (9, '{"other":9,"label":{"name":"nine"}}', 2), + (10, '{"metrics":{"value":10},"label":"ten","extra":[10]}', 2); + +-- Arrow casts Boolean values to Float64 as true = 1.0 and false = 0.0. +select abs(j.metrics.value) as abs_value from json2_function_table order by ts; + +select power(j.label, 2) * 2 as scaled_label from json2_function_table order by ts; + +select power(j.metrics.value, exponent) as powered_value from json2_function_table order by ts; + +select coalesce(j.metrics.value, exponent) as value_or_exponent from json2_function_table order by ts; + +select coalesce( + j.metrics.value, + j.label::double +) as mixed_value from json2_function_table order by ts; + +select ts, j.label as label, signum(j.metrics.value) as value_sign +from json2_function_table +order by ts; + +select ts, j.label as label +from json2_function_table +where iszero(j.metrics.value) = false +order by ts; + +select count(j.metrics.value) as value_count from json2_function_table; + +select sum(j.metrics.value) as value_sum from json2_function_table; + +select lag(j.metrics.value) over (order by ts) as previous_value +from json2_function_table +order by ts; + +drop table json2_function_table;