Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion velox/docs/functions/spark/string.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ Unless specified otherwise, all functions return NULL if at least one of the arg

.. spark:function:: chr(n) -> varchar

Returns the Unicode code point ``n`` as a single character string.
Returns a utf8 string of single ASCII character. The ASCII character has the binary
equivalent of ``n``. If ``n < 0``, the result is an empty string. If ``n >= 256``,
the result is equivalent to chr(``n % 256``).

.. spark:function:: contains(left, right) -> boolean

Expand Down
16 changes: 14 additions & 2 deletions velox/functions/sparksql/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ struct AsciiFunction {
}
};

/// chr function
/// chr(n) -> string
/// Returns a utf8 string of single ASCII character. The ASCII character has
/// the binary equivalent of n. If n < 0, the result is an empty string. If n >=
/// 256, the result is equivalent to chr(n % 256).
template <typename T>
struct ChrFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);
Expand All @@ -40,8 +45,15 @@ struct ChrFunction {
if (ord < 0) {
result.resize(0);
} else {
result.resize(1);
*result.data() = ord;
ord = ord & 0xFF;
if (ord < 0x80) {
result.resize(1);
result.data()[0] = ord;
} else {
result.resize(2);
result.data()[0] = 0xC0 + (ord >> 6);
result.data()[1] = 0x80 + (ord & 0x3F);
}
}
return true;
}
Expand Down
13 changes: 9 additions & 4 deletions velox/functions/sparksql/tests/StringTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,16 @@ TEST_F(StringTest, Ascii) {
}

TEST_F(StringTest, Chr) {
EXPECT_EQ(chr(0), std::string("\0", 1));
EXPECT_EQ(chr(32), " ");
EXPECT_EQ(chr(-16), "");
EXPECT_EQ(chr(256), std::string("\0", 1));
EXPECT_EQ(chr(256 + 32), std::string(" ", 1));
EXPECT_EQ(chr(0), std::string("\0", 1));
EXPECT_EQ(chr(0x100), std::string("\0", 1));
EXPECT_EQ(chr(0x1100), std::string("\0", 1));
EXPECT_EQ(chr(0x20), "\x20");
EXPECT_EQ(chr(0x100 + 0x20), "\x20");
EXPECT_EQ(chr(0x80), "\xC2\x80");
EXPECT_EQ(chr(0x100 + 0x80), "\xC2\x80");
EXPECT_EQ(chr(0xFF), "\xC3\xBF");
EXPECT_EQ(chr(0x100 + 0xFF), "\xC3\xBF");
EXPECT_EQ(chr(std::nullopt), std::nullopt);
}

Expand Down