1 | #include "catch.hpp" |
2 | #include "test_helpers.hpp" |
3 | |
4 | using namespace duckdb; |
5 | using namespace std; |
6 | |
7 | TEST_CASE("Test scalar bitwise ops" , "[bitop]" ) { |
8 | unique_ptr<QueryResult> result; |
9 | DuckDB db(nullptr); |
10 | Connection con(db); |
11 | con.EnableQueryVerification(); |
12 | |
13 | // left shift |
14 | result = con.Query("SELECT 1 << 2, NULL << 2, 2 << NULL" ); |
15 | REQUIRE(CHECK_COLUMN(result, 0, {4})); |
16 | REQUIRE(CHECK_COLUMN(result, 1, {Value()})); |
17 | REQUIRE(CHECK_COLUMN(result, 2, {Value()})); |
18 | |
19 | // right shift |
20 | result = con.Query("SELECT 16 >> 2, 1 >> 2, NULL >> 2, 2 >> NULL" ); |
21 | REQUIRE(CHECK_COLUMN(result, 0, {4})); |
22 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
23 | REQUIRE(CHECK_COLUMN(result, 2, {Value()})); |
24 | REQUIRE(CHECK_COLUMN(result, 3, {Value()})); |
25 | |
26 | // bitwise and |
27 | result = con.Query("SELECT 1 & 1, 1 & 0, 0 & 0, NULL & 1, 1 & NULL" ); |
28 | REQUIRE(CHECK_COLUMN(result, 0, {1})); |
29 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
30 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
31 | REQUIRE(CHECK_COLUMN(result, 3, {Value()})); |
32 | REQUIRE(CHECK_COLUMN(result, 4, {Value()})); |
33 | |
34 | // bitwise or |
35 | result = con.Query("SELECT 1 | 1, 1 | 0, 0 | 0, NULL | 1, 1 | NULL" ); |
36 | REQUIRE(CHECK_COLUMN(result, 0, {1})); |
37 | REQUIRE(CHECK_COLUMN(result, 1, {1})); |
38 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
39 | REQUIRE(CHECK_COLUMN(result, 3, {Value()})); |
40 | REQUIRE(CHECK_COLUMN(result, 4, {Value()})); |
41 | |
42 | // bitwise xor |
43 | result = con.Query("SELECT 1 # 1, 1 # 0, 0 # 0, NULL # 1, 1 # NULL" ); |
44 | REQUIRE(CHECK_COLUMN(result, 0, {0})); |
45 | REQUIRE(CHECK_COLUMN(result, 1, {1})); |
46 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
47 | REQUIRE(CHECK_COLUMN(result, 3, {Value()})); |
48 | REQUIRE(CHECK_COLUMN(result, 4, {Value()})); |
49 | |
50 | // out of range shifts return 0 |
51 | result = con.Query("SELECT 1::TINYINT << -1::TINYINT, 1::TINYINT >> -1::TINYINT, 1::TINYINT << 12::TINYINT, " |
52 | "1::TINYINT >> 12::TINYINT" ); |
53 | REQUIRE(CHECK_COLUMN(result, 0, {0})); |
54 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
55 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
56 | REQUIRE(CHECK_COLUMN(result, 3, {0})); |
57 | result = con.Query("SELECT 1::SMALLINT << -1::SMALLINT, 1::SMALLINT >> -1::SMALLINT, 1::SMALLINT << 20::SMALLINT, " |
58 | "1::SMALLINT >> 20::SMALLINT" ); |
59 | REQUIRE(CHECK_COLUMN(result, 0, {0})); |
60 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
61 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
62 | REQUIRE(CHECK_COLUMN(result, 3, {0})); |
63 | result = con.Query("SELECT 1::INT << -1::INT, 1::INT >> -1::INT, 1::INT << 40::INT, 1::INT >> 40::INT" ); |
64 | REQUIRE(CHECK_COLUMN(result, 0, {0})); |
65 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
66 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
67 | REQUIRE(CHECK_COLUMN(result, 3, {0})); |
68 | result = con.Query("SELECT 1::BIGINT << -1::BIGINT, 1::BIGINT >> -1::BIGINT, 1::BIGINT << 1000::BIGINT, 1::BIGINT " |
69 | ">> 1000::BIGINT" ); |
70 | REQUIRE(CHECK_COLUMN(result, 0, {0})); |
71 | REQUIRE(CHECK_COLUMN(result, 1, {0})); |
72 | REQUIRE(CHECK_COLUMN(result, 2, {0})); |
73 | REQUIRE(CHECK_COLUMN(result, 3, {0})); |
74 | } |
75 | |
76 | TEST_CASE("Test bitwise ops with tables and different types" , "[bitop]" ) { |
77 | unique_ptr<QueryResult> result; |
78 | DuckDB db(nullptr); |
79 | Connection con(db); |
80 | con.EnableQueryVerification(); |
81 | |
82 | vector<string> types = {"TINYINT" , "SMALLINT" , "INTEGER" , "BIGINT" }; |
83 | for (auto &type : types) { |
84 | REQUIRE_NO_FAIL(con.Query("BEGIN TRANSACTION" )); |
85 | REQUIRE_NO_FAIL(con.Query("CREATE TABLE bitwise_test(i " + type + ", j " + type + ")" )); |
86 | REQUIRE_NO_FAIL(con.Query( |
87 | "INSERT INTO bitwise_test VALUES (1, 1), (1, 0), (0, 1), (0, 0), (1, NULL), (NULL, 1), (NULL, NULL)" )); |
88 | |
89 | result = con.Query("SELECT i << j, i >> j, i & j, i | j, i # j FROM bitwise_test" ); |
90 | REQUIRE(CHECK_COLUMN(result, 0, {2, 1, 0, 0, Value(), Value(), Value()})); |
91 | REQUIRE(CHECK_COLUMN(result, 1, {0, 1, 0, 0, Value(), Value(), Value()})); |
92 | REQUIRE(CHECK_COLUMN(result, 2, {1, 0, 0, 0, Value(), Value(), Value()})); |
93 | REQUIRE(CHECK_COLUMN(result, 3, {1, 1, 1, 0, Value(), Value(), Value()})); |
94 | REQUIRE(CHECK_COLUMN(result, 4, {0, 1, 1, 0, Value(), Value(), Value()})); |
95 | |
96 | REQUIRE_NO_FAIL(con.Query("ROLLBACK" )); |
97 | } |
98 | } |
99 | |
100 | TEST_CASE("Test invalid ops for bitwise operations" , "[bitop]" ) { |
101 | unique_ptr<QueryResult> result; |
102 | DuckDB db(nullptr); |
103 | Connection con(db); |
104 | con.EnableQueryVerification(); |
105 | |
106 | REQUIRE_FAIL(con.Query("SELECT 'hello' << 3" )); |
107 | REQUIRE_FAIL(con.Query("SELECT 3 << 'hello'" )); |
108 | REQUIRE_FAIL(con.Query("SELECT 2.0 << 1" )); |
109 | } |
110 | |