| 1 | #include "catch.hpp" |
| 2 | #include "test_helpers.hpp" |
| 3 | |
| 4 | #include "duckdb.hpp" |
| 5 | |
| 6 | #include "dbgen.hpp" |
| 7 | |
| 8 | using namespace duckdb; |
| 9 | using namespace std; |
| 10 | |
| 11 | TEST_CASE("Test filter and projection of nested struct" , "[nested]" ) { |
| 12 | DuckDB db(nullptr); |
| 13 | Connection con(db); |
| 14 | unique_ptr<QueryResult> result; |
| 15 | con.EnableQueryVerification(); |
| 16 | |
| 17 | REQUIRE_NO_FAIL(con.Query("CREATE TABLE struct_data (g INTEGER, e INTEGER)" )); |
| 18 | REQUIRE_NO_FAIL( |
| 19 | con.Query("INSERT INTO struct_data VALUES (1, 1), (1, 2), (2, 3), (2, 4), (2, 5), (3, 6), (5, NULL)" )); |
| 20 | |
| 21 | // all the wrong ways of holding this |
| 22 | REQUIRE_FAIL(con.Query("SELECT STRUCT_PACK() FROM struct_data" )); |
| 23 | REQUIRE_FAIL(con.Query("SELECT STRUCT_PACK(e+1) FROM struct_data" )); |
| 24 | REQUIRE_FAIL(con.Query("SELECT STRUCT_PACK(a := e, a := g) FROM struct_data" )); |
| 25 | REQUIRE_FAIL(con.Query("SELECT STRUCT_PACK(e, e) FROM struct_data" )); |
| 26 | |
| 27 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(e, 'e') FROM struct_data" )); |
| 28 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(e) FROM struct_data" )); |
| 29 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT('e') FROM struct_data" )); |
| 30 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT() FROM struct_data" )); |
| 31 | |
| 32 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), 'zz') FROM struct_data" )); |
| 33 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g)) FROM struct_data" )); |
| 34 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), g) FROM struct_data" )); |
| 35 | REQUIRE_FAIL(con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), '42) FROM struct_data" )); |
| 36 | |
| 37 | REQUIRE_FAIL(con.Query("CREATE TABLE test AS SELECT e, STRUCT_PACK(e) FROM struct_data" )); |
| 38 | |
| 39 | result = con.Query("SELECT STRUCT_PACK(a := 42, b := 43)" ); |
| 40 | REQUIRE(CHECK_COLUMN(result, 0, |
| 41 | {Value::STRUCT({make_pair("a" , Value::INTEGER(42)), make_pair("b" , Value::INTEGER(43))})})); |
| 42 | |
| 43 | result = con.Query("SELECT e, STRUCT_PACK(e) FROM struct_data ORDER BY e LIMIT 2" ); |
| 44 | REQUIRE(CHECK_COLUMN(result, 0, {Value(), 1})); |
| 45 | REQUIRE(CHECK_COLUMN( |
| 46 | result, 1, {Value::STRUCT({make_pair("e" , Value())}), Value::STRUCT({make_pair("e" , Value::INTEGER(1))})})); |
| 47 | |
| 48 | result = con.Query("SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), 'xx') as ee FROM struct_data" ); |
| 49 | REQUIRE(CHECK_COLUMN(result, 0, {1, 2, 3, 4, 5, 6, Value()})); |
| 50 | REQUIRE(CHECK_COLUMN(result, 1, {1, 2, 3, 4, 5, 6, Value()})); |
| 51 | |
| 52 | result = |
| 53 | con.Query("SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), 'xx') as s FROM struct_data WHERE e > 4" ); |
| 54 | REQUIRE(CHECK_COLUMN(result, 0, {5, 6})); |
| 55 | REQUIRE(CHECK_COLUMN(result, 1, {5, 6})); |
| 56 | |
| 57 | result = con.Query( |
| 58 | "SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), 'xx') as s FROM struct_data WHERE e IS NULL" ); |
| 59 | REQUIRE(CHECK_COLUMN(result, 0, {Value()})); |
| 60 | REQUIRE(CHECK_COLUMN(result, 1, {Value()})); |
| 61 | |
| 62 | result = con.Query("SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e/2), 'xx') as s FROM struct_data WHERE e > 4" ); |
| 63 | REQUIRE(CHECK_COLUMN(result, 0, {5, 6})); |
| 64 | REQUIRE(CHECK_COLUMN(result, 1, {2, 3})); |
| 65 | |
| 66 | result = con.Query("SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e/2), 'xx')*2 as s FROM struct_data WHERE e > 4" ); |
| 67 | REQUIRE(CHECK_COLUMN(result, 0, {5, 6})); |
| 68 | REQUIRE(CHECK_COLUMN(result, 1, {4, 6})); |
| 69 | |
| 70 | result = con.Query( |
| 71 | "SELECT e, STRUCT_EXTRACT(STRUCT_PACK(xx := e, yy := g), 'xx') as ee FROM struct_data ORDER BY e DESC" ); |
| 72 | REQUIRE(CHECK_COLUMN(result, 0, {6, 5, 4, 3, 2, 1, Value()})); |
| 73 | REQUIRE(CHECK_COLUMN(result, 1, {6, 5, 4, 3, 2, 1, Value()})); |
| 74 | |
| 75 | result = con.Query("SELECT e, STRUCT_EXTRACT(STRUCT_PACK(a := e, b := ROWID, c := 42), 'c') as ee FROM struct_data " |
| 76 | "ORDER BY ROWID" ); |
| 77 | REQUIRE(CHECK_COLUMN(result, 0, {1, 2, 3, 4, 5, 6, Value()})); |
| 78 | REQUIRE(CHECK_COLUMN(result, 1, {42, 42, 42, 42, 42, 42, 42})); |
| 79 | |
| 80 | result = con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(a := 42, b := 43), 'a') FROM struct_data" ); |
| 81 | REQUIRE(CHECK_COLUMN(result, 0, {42, 42, 42, 42, 42, 42, 42})); |
| 82 | |
| 83 | result = con.Query("SELECT STRUCT_EXTRACT(STRUCT_PACK(a := 42, b := 43), 'a') s" ); |
| 84 | REQUIRE(CHECK_COLUMN(result, 0, {42})); |
| 85 | |
| 86 | result = con.Query("SELECT STRUCT_EXTRACT(STRUCT_EXTRACT(STRUCT_PACK(a := STRUCT_PACK(x := 'asdf', y := NULL), b " |
| 87 | ":= 43), 'a'), 'x') s" ); |
| 88 | REQUIRE(CHECK_COLUMN(result, 0, {"asdf" })); |
| 89 | } |
| 90 | |
| 91 | TEST_CASE("Test packing and unpacking lineitem into structs" , "[nested][.]" ) { |
| 92 | DuckDB db(nullptr); |
| 93 | Connection con(db); |
| 94 | unique_ptr<QueryResult> result; |
| 95 | // con.EnableQueryVerification(); // FIXME something odd happening here |
| 96 | |
| 97 | auto sf = 0.01; |
| 98 | |
| 99 | tpch::dbgen(sf, db, DEFAULT_SCHEMA, "_org" ); |
| 100 | REQUIRE_NO_FAIL(con.Query( |
| 101 | "CREATE VIEW lineitem AS SELECT STRUCT_EXTRACT(struct, 'orderkey') l_orderkey, STRUCT_EXTRACT(struct, " |
| 102 | "'partkey') l_partkey, STRUCT_EXTRACT(struct, 'suppkey') l_suppkey, STRUCT_EXTRACT(struct, 'linenumber') " |
| 103 | "l_linenumber, STRUCT_EXTRACT(struct, 'quantity') l_quantity, STRUCT_EXTRACT(struct, 'extendedprice') " |
| 104 | "l_extendedprice, STRUCT_EXTRACT(struct, 'discount') l_discount, STRUCT_EXTRACT(struct, 'tax') l_tax, " |
| 105 | "STRUCT_EXTRACT(struct, 'returnflag') l_returnflag, STRUCT_EXTRACT(struct, 'linestatus') l_linestatus, " |
| 106 | "STRUCT_EXTRACT(struct, 'shipdate') l_shipdate, STRUCT_EXTRACT(struct, 'commitdate') l_commitdate, " |
| 107 | "STRUCT_EXTRACT(struct, 'receiptdate') l_receiptdate, STRUCT_EXTRACT(struct, 'shipinstruct') l_shipinstruct, " |
| 108 | "STRUCT_EXTRACT(struct, 'shipmode') l_shipmode, STRUCT_EXTRACT(struct, 'comment') l_comment FROM (SELECT " |
| 109 | "STRUCT_PACK(quantity := l_quantity , extendedprice := l_extendedprice , discount := l_discount , tax := l_tax " |
| 110 | ", returnflag := l_returnflag , linestatus := l_linestatus , shipdate := l_shipdate , commitdate := " |
| 111 | "l_commitdate , receiptdate := l_receiptdate , shipinstruct := l_shipinstruct , shipmode := l_shipmode , " |
| 112 | "comment := l_comment , orderkey := l_orderkey , partkey := l_partkey , suppkey := l_suppkey , linenumber := " |
| 113 | "l_linenumber) struct FROM lineitem_org) structs" )); |
| 114 | |
| 115 | result = con.Query(tpch::get_query(1)); |
| 116 | COMPARE_CSV(result, tpch::get_answer(sf, 1), true); |
| 117 | } |
| 118 | |