1#include "catch.hpp"
2#include "test_helpers.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7TEST_CASE("Test correct behavior of various string functions under complex unicode characters", "[function]") {
8 unique_ptr<QueryResult> result;
9 DuckDB db(nullptr);
10 Connection con(db);
11 con.EnableQueryVerification();
12
13 // length with grapheme clusters
14 result = con.Query("SELECT length('S̈a')");
15 REQUIRE(CHECK_COLUMN(result, 0, {2}));
16 result = con.Query("SELECT length('🤦🏼‍♂️')");
17 REQUIRE(CHECK_COLUMN(result, 0, {1}));
18 result = con.Query("SELECT length('🤦🏼‍♂️ L🤦🏼‍♂️R 🤦🏼‍♂️')");
19 REQUIRE(CHECK_COLUMN(result, 0, {7}));
20
21 // strlen returns size in bytes
22 result = con.Query("SELECT strlen('🤦🏼‍♂️')");
23 REQUIRE(CHECK_COLUMN(result, 0, {17}));
24 result = con.Query("SELECT strlen('S̈a')");
25 REQUIRE(CHECK_COLUMN(result, 0, {4}));
26
27 // reverse with grapheme clusters
28 result = con.Query("SELECT REVERSE('S̈a︍')");
29 REQUIRE(CHECK_COLUMN(result, 0, {"a︍S̈"}));
30 result = con.Query("SELECT REVERSE('Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢')");
31 REQUIRE(CHECK_COLUMN(result, 0, {"A̴̵̜̰͔ͫ͗͢Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍"}));
32 result = con.Query("SELECT REVERSE('🤦🏼‍♂️')");
33 REQUIRE(CHECK_COLUMN(result, 0, {"🤦🏼‍♂️"}));
34 result = con.Query("SELECT REVERSE('🤦🏼‍♂️ L🤦🏼‍♂️R 🤦🏼‍♂️')");
35 REQUIRE(CHECK_COLUMN(result, 0, {"🤦🏼‍♂️ R🤦🏼‍♂️L 🤦🏼‍♂️"}));
36 result = con.Query("SELECT REVERSE('MotörHead')");
37 REQUIRE(CHECK_COLUMN(result, 0, {"daeHrötoM"}));
38
39 // substring with grapheme clusters
40 result = con.Query("SELECT substring('🤦🏼‍♂️🤦🏼‍♂️🤦🏼‍♂️', 1, 1)");
41 REQUIRE(CHECK_COLUMN(result, 0, {"🤦🏼‍♂️"}));
42 result = con.Query("SELECT substring('S̈a︍', 2, 1)");
43 REQUIRE(CHECK_COLUMN(result, 0, {"a"}));
44 result = con.Query("SELECT substring('test: 🤦🏼‍♂️hello🤦🏼‍♂️ world', 7, 7)");
45 REQUIRE(CHECK_COLUMN(result, 0, {"🤦🏼‍♂️hello🤦🏼‍♂️"}));
46 result = con.Query("SELECT substring('S̈a', 1, 1)");
47 REQUIRE(CHECK_COLUMN(result, 0, {"S̈"}));
48}
49