1 | #include "catch.hpp" |
2 | #include "test_helpers.hpp" |
3 | |
4 | using namespace duckdb; |
5 | using namespace std; |
6 | |
7 | /* Test Case disclaimer |
8 | * |
9 | * Assertions built using the Domain Testing technique |
10 | * at: https://bbst.courses/wp-content/uploads/2018/01/Kaner-Intro-to-Domain-Testing-2018.pdf |
11 | * |
12 | */ |
13 | TEST_CASE("Prefix test" , "[function]" ) { |
14 | unique_ptr<QueryResult> result; |
15 | DuckDB db(nullptr); |
16 | Connection con(db); |
17 | con.EnableQueryVerification(); |
18 | |
19 | SECTION("Early out prefix" ) { |
20 | result = con.Query("SELECT prefix('abcd', 'a')" ); |
21 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
22 | result = con.Query("SELECT prefix('abcd', 'ab')" ); |
23 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
24 | result = con.Query("SELECT prefix('abcd', 'abc')" ); |
25 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
26 | result = con.Query("SELECT prefix('abcd', 'abcd')" ); |
27 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
28 | result = con.Query("SELECT prefix('abcd', 'b')" ); |
29 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
30 | } |
31 | |
32 | SECTION("Inlined string" ) { |
33 | result = con.Query("SELECT prefix('abcdefgh', 'a')" ); |
34 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
35 | result = con.Query("SELECT prefix('abcdefgh', 'ab')" ); |
36 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
37 | result = con.Query("SELECT prefix('abcdefgh', 'abc')" ); |
38 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
39 | result = con.Query("SELECT prefix('abcdefgh', 'abcd')" ); |
40 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
41 | result = con.Query("SELECT prefix('abcdefgh', 'abcde')" ); |
42 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
43 | result = con.Query("SELECT prefix('abcdefgh', 'b')" ); |
44 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
45 | } |
46 | |
47 | SECTION("Stored pointer string" ) { |
48 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'a')" ); |
49 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
50 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'ab')" ); |
51 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
52 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'abc')" ); |
53 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
54 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'abcd')" ); |
55 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
56 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'abcde')" ); |
57 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
58 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'b')" ); |
59 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
60 | |
61 | result = con.Query("SELECT prefix('abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwx')" ); |
62 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
63 | } |
64 | |
65 | SECTION("Empty string and prefix" ) { |
66 | result = con.Query("SELECT prefix('', 'aaa')" ); |
67 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
68 | |
69 | result = con.Query("SELECT prefix('aaa', '')" ); |
70 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
71 | } |
72 | |
73 | SECTION("Issue #572 alloc exception on empty table" ) { |
74 | REQUIRE_NO_FAIL(con.Query("CREATE TABLE t0(c0 VARCHAR)" )); |
75 | REQUIRE_NO_FAIL(con.Query("SELECT * FROM t0 WHERE PREFIX(t0.c0, '')" )); |
76 | } |
77 | |
78 | SECTION("Prefix test with UTF8" ) { |
79 | // átomo (atom) |
80 | result = con.Query("SELECT prefix('\xc3\xa1tomo', '\xc3\xa1')" ); |
81 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
82 | result = con.Query("SELECT prefix('\xc3\xa1tomo', 'á')" ); |
83 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
84 | result = con.Query("SELECT prefix('\xc3\xa1tomo', 'a')" ); |
85 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
86 | |
87 | // olá mundo (hello world) |
88 | result = con.Query("SELECT prefix('ol\xc3\xa1 mundo', 'ol\xc3\xa1')" ); |
89 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
90 | result = con.Query("SELECT prefix('ol\xc3\xa1 mundo', 'olá')" ); |
91 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
92 | result = con.Query("SELECT prefix('ol\xc3\xa1 mundo', 'ola')" ); |
93 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
94 | |
95 | //ñeft |
96 | result = con.Query("SELECT prefix('\xc3\xb1\x65\x66\x74', '\xc3\xb1')" ); |
97 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
98 | result = con.Query("SELECT prefix('\xc3\xb1\x65\x66\x74', 'ñ')" ); |
99 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
100 | result = con.Query("SELECT prefix('\xc3\xb1\x65\x66\x74', 'ñeft')" ); |
101 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
102 | result = con.Query("SELECT prefix('\xc3\xb1\x65\x66\x74', 'neft')" ); |
103 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
104 | |
105 | // two ñ three ₡ four 🦆 end |
106 | string str_utf8 = "'two \xc3\xb1 three \xE2\x82\xA1 four \xF0\x9F\xA6\x86 end'" ; |
107 | |
108 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two \xc3\xb1')" ); |
109 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
110 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ')" ); |
111 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
112 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two n')" ); |
113 | REQUIRE(CHECK_COLUMN(result, 0, {false})); |
114 | |
115 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ three')" ); |
116 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
117 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ three \xE2\x82\xA1')" ); |
118 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
119 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ three \xE2\x82\xA1 four \xF0\x9F\xA6\x86')" ); |
120 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
121 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ three \xE2\x82\xA1 four \xF0\x9F\xA6\x86 end')" ); |
122 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
123 | result = con.Query("SELECT prefix(" + str_utf8 + ", 'two ñ three ₡ four 🦆 end')" ); |
124 | REQUIRE(CHECK_COLUMN(result, 0, {true})); |
125 | } |
126 | } |
127 | |