From 7add0abece9b800479c1988204ef84dfbca0d71a Mon Sep 17 00:00:00 2001 From: Nga Tran Date: Fri, 18 Jul 2025 16:51:18 -0400 Subject: [PATCH] Add serialization and deserialization tests for all tpc-ch queries --- Cargo.lock | 146 ++++++++++++++------------ Cargo.toml | 6 +- tests/round_trip_physical_plan.rs | 142 +++++++++++++++++++++++++ tpch/data/tpch_customer_small.parquet | Bin 0 -> 7733 bytes tpch/data/tpch_lineitem_small.parquet | Bin 0 -> 11069 bytes tpch/data/tpch_nation_small.parquet | Bin 0 -> 4364 bytes tpch/data/tpch_orders_small.parquet | Bin 0 -> 7219 bytes tpch/data/tpch_part_small.parquet | Bin 0 -> 4356 bytes tpch/data/tpch_partsupp_small.parquet | Bin 0 -> 5457 bytes tpch/data/tpch_region_small.parquet | Bin 0 -> 2831 bytes tpch/data/tpch_supplier_small.parquet | Bin 0 -> 6973 bytes 11 files changed, 224 insertions(+), 70 deletions(-) create mode 100644 tests/round_trip_physical_plan.rs create mode 100644 tpch/data/tpch_customer_small.parquet create mode 100644 tpch/data/tpch_lineitem_small.parquet create mode 100644 tpch/data/tpch_nation_small.parquet create mode 100644 tpch/data/tpch_orders_small.parquet create mode 100644 tpch/data/tpch_part_small.parquet create mode 100644 tpch/data/tpch_partsupp_small.parquet create mode 100644 tpch/data/tpch_region_small.parquet create mode 100644 tpch/data/tpch_supplier_small.parquet diff --git a/Cargo.lock b/Cargo.lock index e3f8d34..5ad39a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -294,6 +294,7 @@ dependencies = [ "arrow-schema", "flatbuffers", "lz4_flex", + "zstd", ] [[package]] @@ -403,7 +404,7 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06575e6a9673580f52661c92107baabffbf41e2141373441cbcdc47cb733003c" dependencies = [ - "bzip2", + "bzip2 0.5.2", "flate2", "futures-core", "memchr", @@ -708,6 +709,15 @@ dependencies = [ "bzip2-sys", ] +[[package]] +name = "bzip2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea8dcd42434048e4f7a304411d9273a411f647446c1234a65ce0554923f4cff" +dependencies = [ + "libbz2-rs-sys", +] + [[package]] name = "bzip2-sys" version = "0.1.13+1.0.8" @@ -1034,15 +1044,14 @@ dependencies = [ [[package]] name = "datafusion" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6cb8c2c81eada072059983657d6c9caf3fddefc43b4a65551d243253254a96" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "arrow-ipc", "arrow-schema", "async-trait", "bytes", - "bzip2", + "bzip2 0.6.0", "chrono", "datafusion-catalog", "datafusion-catalog-listing", @@ -1069,6 +1078,7 @@ dependencies = [ "datafusion-sql", "flate2", "futures", + "hex", "itertools 0.14.0", "log", "object_store", @@ -1088,8 +1098,7 @@ dependencies = [ [[package]] name = "datafusion-catalog" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7be8d1b627843af62e447396db08fe1372d882c0eb8d0ea655fd1fbc33120ee" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1114,8 +1123,7 @@ dependencies = [ [[package]] name = "datafusion-catalog-listing" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ab16c5ae43f65ee525fc493ceffbc41f40dee38b01f643dfcfc12959e92038" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1137,15 +1145,16 @@ dependencies = [ [[package]] name = "datafusion-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d56b2ac9f476b93ca82e4ef5fb00769c8a3f248d12b4965af7e27635fa7e12" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", "arrow-ipc", "base64 0.22.1", + "chrono", "half", "hashbrown 0.14.5", + "hex", "indexmap 2.10.0", "libc", "log", @@ -1161,8 +1170,7 @@ dependencies = [ [[package]] name = "datafusion-common-runtime" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16015071202d6133bc84d72756176467e3e46029f3ce9ad2cb788f9b1ff139b2" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "futures", "log", @@ -1172,14 +1180,13 @@ dependencies = [ [[package]] name = "datafusion-datasource" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b77523c95c89d2a7eb99df14ed31390e04ab29b43ff793e562bdc1716b07e17b" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-compression", "async-trait", "bytes", - "bzip2", + "bzip2 0.6.0", "chrono", "datafusion-common", "datafusion-common-runtime", @@ -1208,8 +1215,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-csv" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d25c5e2c0ebe8434beeea997b8e88d55b3ccc0d19344293f2373f65bc524fc" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1233,8 +1239,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-json" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc6959e1155741ab35369e1dc7673ba30fc45ed568fad34c01b7cb1daeb4d4c" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1258,8 +1263,7 @@ dependencies = [ [[package]] name = "datafusion-datasource-parquet" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a6afdfe358d70f4237f60eaef26ae5a1ce7cb2c469d02d5fc6c7fd5d84e58b" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1275,8 +1279,10 @@ dependencies = [ "datafusion-physical-expr-common", "datafusion-physical-optimizer", "datafusion-physical-plan", + "datafusion-pruning", "datafusion-session", "futures", + "hex", "itertools 0.14.0", "log", "object_store", @@ -1289,14 +1295,12 @@ dependencies = [ [[package]] name = "datafusion-doc" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bcd8a3e3e3d02ea642541be23d44376b5d5c37c2938cce39b3873cdf7186eea" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" [[package]] name = "datafusion-execution" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670da1d45d045eee4c2319b8c7ea57b26cf48ab77b630aaa50b779e406da476a" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "dashmap", @@ -1314,10 +1318,10 @@ dependencies = [ [[package]] name = "datafusion-expr" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a577f64bdb7e2cc4043cd97f8901d8c504711fde2dbcb0887645b00d7c660b" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", + "async-trait", "chrono", "datafusion-common", "datafusion-doc", @@ -1335,8 +1339,7 @@ dependencies = [ [[package]] name = "datafusion-expr-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b7916806ace3e9f41884f230f7f38ebf0e955dfbd88266da1826f29a0b9a6a" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "datafusion-common", @@ -1348,8 +1351,7 @@ dependencies = [ [[package]] name = "datafusion-functions" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb31c9dc73d3e0c365063f91139dc273308f8a8e124adda9898db8085d68357" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "arrow-buffer", @@ -1377,8 +1379,7 @@ dependencies = [ [[package]] name = "datafusion-functions-aggregate" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb72c6940697eaaba9bd1f746a697a07819de952b817e3fb841fb75331ad5d4" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", @@ -1398,8 +1399,7 @@ dependencies = [ [[package]] name = "datafusion-functions-aggregate-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fdc54656659e5ecd49bf341061f4156ab230052611f4f3609612a0da259696" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", @@ -1411,8 +1411,7 @@ dependencies = [ [[package]] name = "datafusion-functions-nested" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad94598e3374938ca43bca6b675febe557e7a14eb627d617db427d70d65118b" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "arrow-ord", @@ -1422,6 +1421,7 @@ dependencies = [ "datafusion-expr", "datafusion-functions", "datafusion-functions-aggregate", + "datafusion-functions-aggregate-common", "datafusion-macros", "datafusion-physical-expr-common", "itertools 0.14.0", @@ -1432,8 +1432,7 @@ dependencies = [ [[package]] name = "datafusion-functions-table" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2fc6c2946da5cab8364fb28b5cac3115f0f3a87960b235ed031c3f7e2e639b" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1448,8 +1447,7 @@ dependencies = [ [[package]] name = "datafusion-functions-window" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5746548a8544870a119f556543adcd88fe0ba6b93723fe78ad0439e0fbb8b4" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "datafusion-common", @@ -1466,8 +1464,7 @@ dependencies = [ [[package]] name = "datafusion-functions-window-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbe9404382cda257c434f22e13577bee7047031dfdb6216dd5e841b9465e6fe" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "datafusion-common", "datafusion-physical-expr-common", @@ -1476,8 +1473,7 @@ dependencies = [ [[package]] name = "datafusion-macros" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dce50e3b637dab0d25d04d2fe79dfdca2b257eabd76790bffd22c7f90d700c8" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "datafusion-expr", "quote", @@ -1487,13 +1483,13 @@ dependencies = [ [[package]] name = "datafusion-optimizer" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cfaacf06445dc3bbc1e901242d2a44f2cae99a744f49f3fefddcee46240058" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "chrono", "datafusion-common", "datafusion-expr", + "datafusion-expr-common", "datafusion-physical-expr", "indexmap 2.10.0", "itertools 0.14.0", @@ -1506,8 +1502,7 @@ dependencies = [ [[package]] name = "datafusion-physical-expr" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1908034a89d7b2630898e06863583ae4c00a0dd310c1589ca284195ee3f7f8a6" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", @@ -1528,8 +1523,7 @@ dependencies = [ [[package]] name = "datafusion-physical-expr-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b7a12dd59ea07614b67dbb01d85254fbd93df45bcffa63495e11d3bdf847df" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", @@ -1542,8 +1536,7 @@ dependencies = [ [[package]] name = "datafusion-physical-optimizer" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4371cc4ad33978cc2a8be93bd54a232d3f2857b50401a14631c0705f3f910aae" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "datafusion-common", @@ -1553,6 +1546,7 @@ dependencies = [ "datafusion-physical-expr", "datafusion-physical-expr-common", "datafusion-physical-plan", + "datafusion-pruning", "itertools 0.14.0", "log", "recursive", @@ -1561,8 +1555,7 @@ dependencies = [ [[package]] name = "datafusion-physical-plan" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc47bc33025757a5c11f2cd094c5b6b5ed87f46fa33c023e6fdfa25fcbfade23" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "ahash", "arrow", @@ -1591,8 +1584,7 @@ dependencies = [ [[package]] name = "datafusion-proto" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f5d9acd7d96e3bf2a7bb04818373cab6e51de0356e3694b94905fee7b4e8b6" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "chrono", @@ -1607,19 +1599,34 @@ dependencies = [ [[package]] name = "datafusion-proto-common" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ecb5ec152c4353b60f7a5635489834391f7a291d2b39a4820cd469e318b78e" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "datafusion-common", "prost", ] +[[package]] +name = "datafusion-pruning" +version = "48.0.0" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" +dependencies = [ + "arrow", + "arrow-schema", + "datafusion-common", + "datafusion-datasource", + "datafusion-expr-common", + "datafusion-physical-expr", + "datafusion-physical-expr-common", + "datafusion-physical-plan", + "itertools 0.14.0", + "log", +] + [[package]] name = "datafusion-session" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7485da32283985d6b45bd7d13a65169dcbe8c869e25d01b2cfbc425254b4b49" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "async-trait", @@ -1642,8 +1649,7 @@ dependencies = [ [[package]] name = "datafusion-sql" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a466b15632befddfeac68c125f0260f569ff315c6831538cbb40db754134e0df" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "arrow", "bigdecimal", @@ -1659,8 +1665,7 @@ dependencies = [ [[package]] name = "datafusion-substrait" version = "48.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f3973b1a4f6e9ee7fd99a22d58e1c06e6723a28dc911a60df575974c8339aa" +source = "git+https://github.com/apache/datafusion?rev=a45a4c44317ce32f432cbeb8647e6555c93e998f#a45a4c44317ce32f432cbeb8647e6555c93e998f" dependencies = [ "async-recursion", "async-trait", @@ -2851,6 +2856,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "libbz2-rs-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775bf80d5878ab7c2b1080b5351a48b2f737d9f6f8b383574eebcc22be0dfccb" + [[package]] name = "libc" version = "0.2.174" @@ -3244,6 +3255,7 @@ dependencies = [ "num-bigint", "object_store", "paste", + "ring", "seq-macro", "simdutf8", "snap", @@ -4340,9 +4352,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "substrait" -version = "0.56.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13de2e20128f2a018dab1cfa30be83ae069219a65968c6f89df66ad124de2397" +checksum = "de6d24c270c6c672a86c183c3a8439ba46c1936f93cf7296aa692de3b0ff0228" dependencies = [ "heck", "pbjson", diff --git a/Cargo.toml b/Cargo.toml index 132d092..7482dcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,9 +44,9 @@ async-trait = "0.1.88" async-stream = "0.3" bytes = "1.5" clap = { version = "4.4", features = ["derive"] } -datafusion = "48.0.0" -datafusion-proto = "48.0.0" -datafusion-substrait = "48.0.0" +datafusion = { git = "https://github.com/apache/datafusion", rev = "a45a4c44317ce32f432cbeb8647e6555c93e998f" } +datafusion-proto = { git = "https://github.com/apache/datafusion", rev = "a45a4c44317ce32f432cbeb8647e6555c93e998f" } +datafusion-substrait = { git = "https://github.com/apache/datafusion", rev = "a45a4c44317ce32f432cbeb8647e6555c93e998f" } env_logger = "0.11" futures = "0.3" itertools = "0.14" diff --git a/tests/round_trip_physical_plan.rs b/tests/round_trip_physical_plan.rs new file mode 100644 index 0000000..ea31839 --- /dev/null +++ b/tests/round_trip_physical_plan.rs @@ -0,0 +1,142 @@ +use anyhow::Result; +use datafusion::common::DataFusionError; +use datafusion::physical_plan::ExecutionPlan; +use datafusion::prelude::{ParquetReadOptions, SessionContext}; +use datafusion_proto::physical_plan::{AsExecutionPlan, DefaultPhysicalExtensionCodec}; +use datafusion_proto::protobuf::PhysicalPlanNode; +use std::sync::Arc; + +/// Helper function to create physical plan and its version after serialization and deserialization +async fn physical_plan_before_after_serde( + sql: &str, + ctx: &SessionContext, +) -> Result<(Arc, Arc), DataFusionError> { + // Build physical plan from sql + let plan = ctx.sql(sql).await?.create_physical_plan().await?; + + let codec = DefaultPhysicalExtensionCodec {}; + + // Serialize the physical plan + let proto: PhysicalPlanNode = + PhysicalPlanNode::try_from_physical_plan(plan.clone(), &codec).expect("to proto"); + + // Deserialize the physical plan + let runtime = ctx.runtime_env(); + let de_plan: Arc = proto + .try_into_physical_plan(ctx, runtime.as_ref(), &codec) + .expect("from proto"); + + Ok((plan, de_plan)) +} + +/// Perform a serde (serialize and deserialize) roundtrip for the specified sql's physical plan, and assert that +async fn assert_serde_roundtrip(sql: &str, ctx: &SessionContext) -> Result<(), DataFusionError> { + let (plan, de_plan) = physical_plan_before_after_serde(sql, ctx).await?; + + // Assert that the physical plan is identical after serialization and deserialization + assert_eq!(format!("{plan:?}"), format!("{de_plan:?}")); + + Ok(()) +} + +/// Helper function to create a SessionContext with TPC-H tables registered from parquet files +async fn tpch_context() -> Result { + let ctx = SessionContext::new(); + + // TPC-H table definitions with their corresponding parquet file paths + let tables = [ + ("customer", "tpch/data/tpch_customer_small.parquet"), + ("lineitem", "tpch/data/tpch_lineitem_small.parquet"), + ("nation", "tpch/data/tpch_nation_small.parquet"), + ("orders", "tpch/data/tpch_orders_small.parquet"), + ("part", "tpch/data/tpch_part_small.parquet"), + ("partsupp", "tpch/data/tpch_partsupp_small.parquet"), + ("region", "tpch/data/tpch_region_small.parquet"), + ("supplier", "tpch/data/tpch_supplier_small.parquet"), + ]; + + // Register all TPC-H tables + for (table_name, file_path) in &tables { + ctx.register_parquet(*table_name, *file_path, ParquetReadOptions::default()) + .await?; + } + + // Create the revenue0 view required for query 15 + let revenue0_sql = "CREATE VIEW revenue0 (supplier_no, total_revenue) AS SELECT l_suppkey, sum(l_extendedprice * (1 - l_discount)) FROM lineitem WHERE l_shipdate >= date '1996-08-01' AND l_shipdate < date '1996-08-01' + interval '3' month GROUP BY l_suppkey"; + ctx.sql(revenue0_sql).await?.collect().await?; + + Ok(ctx) +} + +/// Helper function to get TPC-H query SQL from the repository +fn get_tpch_query_sql(query: usize) -> Result, DataFusionError> { + use std::fs; + + if !(1..=22).contains(&query) { + return Err(DataFusionError::External( + format!("Invalid TPC-H query number: {query}").into(), + )); + } + + let filename = format!("tpch/queries/q{query}.sql"); + let contents = fs::read_to_string(&filename).map_err(|e| { + DataFusionError::External(format!("Failed to read query file {filename}: {e}").into()) + })?; + + Ok(contents + .split(';') + .map(|s| s.trim()) + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()) + .collect()) +} + +/// Test that we are able to build the physical plan and its version after serialization and deserialization +#[tokio::test] +async fn test_serialize_deserialize_tpch_queries() -> Result<()> { + // Create context with TPC-H tables from parquet files + let ctx = tpch_context().await?; + + // repeat to run all 22 queries + for query in 1..=22 { + // run all statements in the query + let sql = get_tpch_query_sql(query)?; + for stmt in sql { + // Skip empty statements and comment-only statements + let trimmed = stmt.trim(); + if trimmed.is_empty() { + continue; + } + // Skip statements that are only comments + if trimmed + .lines() + .all(|line| line.trim().is_empty() || line.trim().starts_with("--")) + { + continue; + } + + // Ensure we are able to build the physical plan and its version after serialization and deserialization + physical_plan_before_after_serde(&stmt, &ctx).await?; + } + } + + Ok(()) +} + +// Test compare the result of the physical plan before and after serialization and deserialization +#[tokio::test] +async fn test_round_trip_tpch_queries() -> Result<(), DataFusionError> { + // Create context with TPC-H tables + let ctx = tpch_context().await?; + + // Verify q3, q5, q10, q12 pass the round trip + // todo: after bug https://github.com/apache/datafusion/issues/16772 is fixed, test with all 22 queries + for query in [3, 5, 10, 12] { + let sql = get_tpch_query_sql(query)?; + for stmt in sql { + assert_serde_roundtrip(&stmt, &ctx).await?; + } + } + + Ok(()) +} diff --git a/tpch/data/tpch_customer_small.parquet b/tpch/data/tpch_customer_small.parquet new file mode 100644 index 0000000000000000000000000000000000000000..3d5f73ef3a066e4e3e8efe9aaadc70a75f40b1b5 GIT binary patch literal 7733 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 JS^VMb{{yYVPG0~3 literal 0 HcmV?d00001 diff --git a/tpch/data/tpch_nation_small.parquet b/tpch/data/tpch_nation_small.parquet new file mode 100644 index 0000000000000000000000000000000000000000..99da99594cf89425a6e603f1be6a7bc5bf916085 GIT binary patch literal 4364 zcmd5AZERat^}fVT?A95{mgm`Os=Y>yaXQD?PTV$Ks_xoxl9$F#>^63sQkC~{ZNKDw zxbGv0Df=;mU=;cT398acQ`v?zB>o_z3c(N9(3n&)KD7ViH-aC41nMS)IQQAf^3@`S z5ZvTkzkANP=lh)JWC@p&tcU$s7yE!&V52O08ln3PLVXNk`h2Jhpc}vg;05Rb=mqcr z_yLXp90dpf^Z`5t@F{?PfPp^W6i9Q|Go4Qsv2ivP14aF858E>o@@-Q>z77itqUa%5 zpgz0O1$&h7_HwV_o0HM+y>s_Q;-McQaNuq?`>1Q%f%lkLFL2_8*<6Xoe&*6I=fEs#ZD|qo@OXcOPNQgVhZO4Vcm&)}ip3H;wZI;6 zQyJaKBxG=^8!pmC!$=qC8fGKAvq7DrYi~9VVu5Ag#dbEjd*_DLH>Me1FU`Y)5c|ug zw)1c=@Taeh11r}M>UEXGIY}@{%~91BS5tIBBu*L*R zob&%=U?N69A`vX`O|SQz8j5k2q7vO^mj)($V3GHysRlY*b4z%9<$ASTCrKVU0% zgISxdsZOn?0G^sEQRA4~o(tk>Gr;-l3z=r(q1x^A}u889PQ50i84AhmHot_H`X8^58VGaLv;3010|A8duq5oRH z2^qe6Vww4|P)gn(J6HY9z`H0u@O=1Yve_;#&8wI$KFS=;!9UU{%@xH z`pq@4hrMw8TgmSDyNv(Fz^{=|eG?H<34e&<=davKo^03e72q4W<01O;vB`4r7el&X z8>X&U`7iP1Qd?SDV_MiK-1gANwtu$2yA{}S9Qh!7~ zU8pl>p|o=Mk@DS9Bz)&@6PnBXW@MqH~)MH5vq6w@I#?nYv=%{{87i<(Wr8XgKSM9>iH38zs{e|V2%wksG7zTydfu{-hs6Y>2!@3(La z#wTLC=v3~9kEzj~a0I~sM^ss$qpV}JtLK3yc*hfYttWD`d+5;D!~v1PkC^aosk>a* z@w@FpSMU)N`KUMYS}*u;aQ@SG^g%2-pzu&1K8~rY>o3QGUw=CC^iu#xN~XU?1L9z{7B}rVv$jEBFv%TkSQw)pW1IWIH`UFX@ifY#l^v#1>@17C@2? zujiLy++MX{z@Zx3_H#>cPn9^OO zeJVeJvu@f=0xvTY;(cRSRYX%TTQrN!mSCF3CN%-RE?6*#C^nUd!_P2eWw@h#H!(g= zX($xHrP5;MTzl$;9{E2**BSVNi*XTvu8SB?;7lFQU|h%9x{J$X_Ru#eGPgsYFJ{|k z*j*_uoyT|+!#((ezQ%~r`J zp7Lu#rEIOvOghy{Ql)ZuEnR~<386CS2&r!)4!li5J zq_~nvuZ)+{((E$WiWQ-fP88OP%0d<^Vx^p@R!X2dNBwZ*%9d3FUr1|yzg}wVlkD22 zZ&oYm_3BEYCeNvx9siP|rh@+^^>H?dsrl=xl|sknq$o?X+wM+Is5py?c@0`#V#q+Tvs7p5Yr7wftsVSoK+P`n`uG4 z(Hh(&m6?{LO^&zgYE_l=LQ_mlxHXes!%jXsvB~RhEq`pMR&Gf&2UKR3Z!N6lfp2~i z<0|c+4qqOgX_I9w*sw^qX}9U1A2F7fpr2{`6_;J)97XQ5Hr%4v*>r6uR+N14GF*DT zPDcTpGPpsJSfZQTuk-=q1-gmqWNWn|gD+`wb!8o|Z|kGu0#y} og}A0*!k>QjnAB{JxdWB!3{0*)O2hOU-_9>e!r$gg@PCkh0&q02<^TWy literal 0 HcmV?d00001 diff --git a/tpch/data/tpch_orders_small.parquet b/tpch/data/tpch_orders_small.parquet new file mode 100644 index 0000000000000000000000000000000000000000..79e043137caf69fefe02d04ba574e3520bf00639 GIT binary patch literal 7219 zcmcgxe{3699e?NA$+=6~q^&($OX0UpKWI!t6Ga+`@4GwK zKa&+0yX4)y_rBlv{qgyJ-}^o#bM%7GX0|X@2E0ysYn9J?8r?&`Z2&b(p!gtv%-8voPf5;Pvnu z@M1p+(|{8W z%kD9Z&nf(h;ny4}?XyueC`SRAIR_B~+OD7ul&Q1FLeL!;pGOGW*RJ6+_tq(b{MTL- z|MC^$=AZkJZ}${>>FEn7{ng#Xh0nN%aqcGcj~jxdv5lieBj5#Eq6YO&cF7c z$triE{f;0Zs2@9}?hNe#?N$B{7&Md@F&fdNo`oW>uQ@2y6=T1fw zvBb%V4w&)}O(x=#m@zOkb8;eaW(KTs+1w4mv}n>CWK|Y$_ui_zcNiG|0_ez>A}~$7ZkL1_=j` z{>IU)ji6_xbodC5wj=h~9=o9m+a>E;(~u;nsHk$8RRyW2P>RU&B`RB%1*xov6^bcH z#TAFL6qsL;MBaIzZcMJ{p&Z5Cy>qV?v;v`W}c`${QrBP6Lwk)u#Vr7`hNFqmB7_*@I%oZjH z)-&uXlLOYW!dv%Ej01BnC-R`6#Iph;4tBpZDf4H`yn;QGd5Xy~LQy$%QI>4-HdUv7F5cAkP`HlIzUs{(A?$XnAMf5#Zn4>^Fsf*atugEP(ACCyPwZ zdJ)}1k6WIwsRIXl-|+oGiSf2IW=>f2$0Mpw%

oq#$CYB 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 H|BwFy6@>Ld literal 0 HcmV?d00001 diff --git a/tpch/data/tpch_partsupp_small.parquet b/tpch/data/tpch_partsupp_small.parquet new file mode 100644 index 0000000000000000000000000000000000000000..711d58dda74935b8b86e6ef552629073927ba510 GIT binary patch literal 5457 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 WeB`*d!WV_=fAkpq+P4{gO#LTL&k$Vz literal 0 HcmV?d00001 diff --git a/tpch/data/tpch_region_small.parquet b/tpch/data/tpch_region_small.parquet new file mode 100644 index 0000000000000000000000000000000000000000..5e00a1f6da1d9c9bf4e278f8e0c3f789fa7c5589 GIT binary patch literal 2831 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 KuJ_=7oc#|;d|#CS literal 0 HcmV?d00001