HAWQ-1772. Add new functions
diff --git a/depends/dbcommon/src/dbcommon/function/func-kind.h b/depends/dbcommon/src/dbcommon/function/func-kind.h
index 36402ac..c4c81fc 100644
--- a/depends/dbcommon/src/dbcommon/function/func-kind.h
+++ b/depends/dbcommon/src/dbcommon/function/func-kind.h
@@ -191,12 +191,13 @@
BIGINT_TO_TEXT,
FLOAT_TO_TEXT,
DOUBLE_TO_TEXT,
+ DECIMAL_TO_TEXT,
+ DATE_TO_TEXT,
BOOL_TO_TEXT,
TEXT_TO_CHAR,
INT_TO_CHAR,
DOUBLE_TO_TIMESTAMP,
INTERVAL_TO_TEXT,
-
// date/time related functions
DATE_TO_TIMESTAMP,
TIMESTAMP_TO_DATE,
@@ -334,7 +335,19 @@
TEXT_TO_BIGINT,
TEXT_TO_FLOAT,
TEXT_TO_DOUBLE,
-
+ CHAR_TO_BYTEA,
+ SMALLINT_TO_BYTEA,
+ INT_TO_BYTEA,
+ BIGINT_TO_BYTEA,
+ FLOAT_TO_BYTEA,
+ DOUBLE_TO_BYTEA,
+ TEXT_TO_BYTEA,
+ DATE_TO_BYTEA,
+ TIME_TO_BYTEA,
+ TIMESTAMP_TO_BYTEA,
+ TIMESTAMPTZ_TO_BYTEA,
+ INTERVAL_TO_BYTEA,
+ DECIMAL_TO_BYTEA,
SMALLINT_TO_BOOLEAN,
INT_TO_BOOLEAN,
BIGINT_TO_BOOLEAN,
@@ -343,7 +356,6 @@
BOOLEAN_TO_BIGINT,
TEXT_TO_DECIMAL,
TO_NUMBER,
-
// random()
RANDOMF,
diff --git a/depends/dbcommon/src/dbcommon/function/func.cc b/depends/dbcommon/src/dbcommon/function/func.cc
index 06ae53e..47b1f06 100644
--- a/depends/dbcommon/src/dbcommon/function/func.cc
+++ b/depends/dbcommon/src/dbcommon/function/func.cc
@@ -325,6 +325,7 @@
FuncEntryArray.push_back({FLOAT_TO_TEXT, "float_to_text", STRINGID, {FLOATID}, float4_to_text});
FuncEntryArray.push_back({DOUBLE_TO_TEXT, "double_to_text", STRINGID, {DOUBLEID}, float8_to_text});
FuncEntryArray.push_back({DECIMAL_TO_TEXT, "decimal_to_text", STRINGID, {DECIMALNEWID}, decimal_to_text});
+ FuncEntryArray.push_back({DATE_TO_TEXT, "date_to_text", STRINGID, {DATEID}, date_to_text});
FuncEntryArray.push_back({BOOL_TO_TEXT, "bool_to_text", STRINGID, {BOOLEANID}, bool_to_text});
FuncEntryArray.push_back({TEXT_TO_CHAR, "text_to_char", TINYINTID, {STRINGID}, text_to_char});
FuncEntryArray.push_back({INT_TO_CHAR, "int4_to_char", TINYINTID, {INTID}, int4_to_char});
@@ -462,9 +463,6 @@
FuncEntryArray.push_back({TEXT_TO_BIGINT, "text_bigint", BIGINTID, {STRINGID}, text_to_int8});
FuncEntryArray.push_back({TEXT_TO_FLOAT, "text_float", FLOATID, {STRINGID}, text_to_float4});
FuncEntryArray.push_back({TEXT_TO_DOUBLE, "text_double", DOUBLEID, {STRINGID}, text_to_float8});
- FuncEntryArray.push_back{TEXT_TO_DECIMAL, "text_decimal", DECIMALNEWID, {STRINGID}, textToDecimal});
- FuncEntryArray.push_back({TO_NUMBER, "to_number", DECIMALNEWID, {STRINGID, STRINGID}, toNumber});
- FuncEntryArray.push_back({INTERVAL_TO_TEXT, "interval_text", STRINGID, {INTERVALID}, intervalToText});
FuncEntryArray.push_back({BOOLEAN_TO_SMALLINT, "boolean_smallint", SMALLINTID, {BOOLEANID}, bool_to_int2});
FuncEntryArray.push_back({BOOLEAN_TO_INT, "boolean_int", INTID, {BOOLEANID}, bool_to_int4});
@@ -472,21 +470,36 @@
FuncEntryArray.push_back({SMALLINT_TO_BOOLEAN, "smallint_boolean", BOOLEANID, {SMALLINTID}, int2_to_bool});
FuncEntryArray.push_back({INT_TO_BOOLEAN, "int_boolean", BOOLEANID, {INTID}, int4_to_bool});
FuncEntryArray.push_back({BIGINT_TO_BOOLEAN, "bigint_boolean", BOOLEANID, {BIGINTID}, int8_to_bool});
- // clang-format on
+ FuncEntryArray.push_back({CHAR_TO_BYTEA, "char_bytea", BINARYID, {TINYINTID}, charToBytea});
+ FuncEntryArray.push_back({SMALLINT_TO_BYTEA, "smallint_bytea", BINARYID, {SMALLINTID}, int2ToBytea});
+ FuncEntryArray.push_back({INT_TO_BYTEA, "int_bytea", BINARYID, {INTID}, int4ToBytea});
+ FuncEntryArray.push_back({BIGINT_TO_BYTEA, "bigint_bytea", BINARYID, {BIGINTID}, int8ToBytea});
+ FuncEntryArray.push_back({FLOAT_TO_BYTEA, "float_bytea", BINARYID, {FLOATID}, float4ToBytea});
+ FuncEntryArray.push_back({DOUBLE_TO_BYTEA, "double_bytea", BINARYID, {DOUBLEID}, float8ToBytea});
+ FuncEntryArray.push_back({TEXT_TO_BYTEA, "text_bytea", BINARYID, {STRINGID}, textToBytea});
+ FuncEntryArray.push_back({DATE_TO_BYTEA, "date_bytea", BINARYID, {DATEID}, dateToBytea});
+ FuncEntryArray.push_back({TIME_TO_BYTEA, "time_bytea", BINARYID, {TIMEID}, timeToBytea});
+ FuncEntryArray.push_back({TIMESTAMP_TO_BYTEA, "timestamp_bytea", BINARYID, {TIMESTAMPID}, timestampToBytea});
+ FuncEntryArray.push_back({TIMESTAMPTZ_TO_BYTEA, "timestamptz_bytea", BINARYID, {TIMESTAMPTZID}, timestampToBytea});
+ FuncEntryArray.push_back({INTERVAL_TO_BYTEA, "interval_bytea", BINARYID, {INTERVALID}, intervalToBytea});
+ FuncEntryArray.push_back({DECIMAL_TO_BYTEA, "decimal_bytea", BINARYID, {DECIMALNEWID}, decimalToBytea});
+ FuncEntryArray.push_back({TEXT_TO_DECIMAL, "text_decimal", DECIMALNEWID, {STRINGID}, textToDecimal});
+ FuncEntryArray.push_back({TO_NUMBER, "to_number", DECIMALNEWID, {STRINGID, STRINGID}, toNumber});
+ FuncEntryArray.push_back({INTERVAL_TO_TEXT, "interval_text", STRINGID, {INTERVALID}, intervalToText});
+// clang-format on
- std::sort(FuncEntryArray.begin(), FuncEntryArray.end(),
- [](const FuncEntry &a, const FuncEntry &b) {
- return a.funcId < b.funcId;
- });
+std::sort(
+ FuncEntryArray.begin(), FuncEntryArray.end(),
+ [](const FuncEntry &a, const FuncEntry &b) { return a.funcId < b.funcId; });
- //
- // Check if the function table is continuous
- //
- for (uint64_t i = 0; i < FuncEntryArray.size(); ++i) {
- if (i != FuncEntryArray[i].funcId) {
- assert(false && "function table is not ordered");
- std::terminate();
- }
+//
+// Check if the function table is continuous
+//
+for (uint64_t i = 0; i < FuncEntryArray.size(); ++i) {
+ if (i != FuncEntryArray[i].funcId) {
+ assert(false && "function table is not ordered");
+ std::terminate();
+ }
}
//
diff --git a/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.cc b/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.cc
index 7a0b20b..4ab2638 100644
--- a/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.cc
+++ b/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.cc
@@ -19,12 +19,14 @@
#include "dbcommon/function/typecast-texttonum-func.h"
+#include <arpa/inet.h>
#include <algorithm>
#include <cmath>
#include <limits>
#include <stack>
#include <string>
#include <typeinfo>
+#include <vector>
#include "dbcommon/common/vector-transformer.h"
#include "dbcommon/common/vector.h"
@@ -34,8 +36,10 @@
#include "dbcommon/function/arithmetic-function.h"
#include "dbcommon/function/decimal-function.h"
#include "dbcommon/function/function.h"
+#include "dbcommon/nodes/datum.h"
#include "dbcommon/type/decimal.h"
#include "dbcommon/type/type-util.h"
+#include "dbcommon/utils/int-util.h"
#include "dbcommon/utils/macro.h"
#include "dbcommon/utils/string-util.h"
#include "dbcommon/utils/timezone-util.h"
@@ -564,6 +568,320 @@
return text_to_Float<double>(params, size);
}
+template <typename TP>
+struct Hton {
+ typedef int32_t returnType;
+ int32_t operator()(TP in) { return 0; }
+};
+
+template <>
+struct Hton<uint16_t> {
+ typedef uint16_t returnType;
+ uint16_t operator()(uint16_t in) {
+ uint16_t n16 = htons(static_cast<uint16_t>(in));
+ return n16;
+ }
+};
+
+template <>
+struct Hton<uint32_t> {
+ typedef uint32_t returnType;
+ uint32_t operator()(uint32_t in) {
+ uint32_t n32 = htonl(static_cast<uint32_t>(in));
+ return n32;
+ }
+};
+
+template <typename TP>
+inline uint32_t serializeInt(ByteBuffer *pbuf, TP in) {
+ uint32_t lenBefore = pbuf->size();
+ uint32_t lenAdd = sizeof(TP);
+ pbuf->resize(lenBefore + lenAdd);
+ typename Hton<TP>::returnType n = Hton<TP>()(in);
+ memcpy(pbuf->data() + lenBefore, reinterpret_cast<char *>(&n), lenAdd);
+ return lenAdd;
+}
+
+template <>
+inline uint32_t serializeInt(ByteBuffer *pbuf, uint64_t in) {
+ uint32_t n32;
+ uint32_t lenAdd = 0;
+ n32 = static_cast<uint32_t>(in >> 32);
+ lenAdd += serializeInt(pbuf, n32);
+ n32 = static_cast<uint32_t>(in);
+ lenAdd += serializeInt(pbuf, n32);
+ return lenAdd;
+}
+
+Datum charToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int8_t in) -> text {
+ uint32_t lenBefore = buf.size();
+ uint32_t lenAdd = sizeof(int8_t);
+ buf.resize(lenBefore + lenAdd);
+ memcpy(buf.data() + lenBefore, reinterpret_cast<char *>(&in), lenAdd);
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int8_t>(params, size, numToBytea);
+}
+
+Datum int2ToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int16_t in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(in));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int16_t>(params, size, numToBytea);
+}
+
+Datum int4ToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int32_t in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint32_t>(in));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int32_t>(params, size, numToBytea);
+}
+
+Datum int8ToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int64_t in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint64_t>(in));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int64_t>(params, size, numToBytea);
+}
+
+Datum float4ToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, float in) -> text {
+ union {
+ float f;
+ uint32_t i;
+ } swap;
+ swap.f = in;
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, swap.i);
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, float>(params, size, numToBytea);
+}
+
+Datum float8ToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, double in) -> text {
+ union {
+ double f;
+ uint64_t i;
+ } swap;
+ swap.f = in;
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, swap.i);
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, double>(params, size, numToBytea);
+}
+
+Datum textToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto textCastBytea = [](ByteBuffer &buf, text in) -> text {
+ uint32_t lenBefore = buf.size();
+ buf.resize(lenBefore + in.length);
+ memcpy(buf.data() + lenBefore, in.val, in.length);
+ return text(nullptr, in.length);
+ };
+ return one_param_bind<text, text>(params, size, textCastBytea);
+}
+
+Datum dateToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int32_t in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint32_t>(in - 10957));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int32_t>(params, size, numToBytea);
+}
+
+Datum timeToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int64_t in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint64_t>(in));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int64_t>(params, size, numToBytea);
+}
+
+Datum timestampToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, Timestamp in) -> text {
+ int64_t second =
+ in.second * 1000000 + in.nanosecond / 1000 - 10957 * 24 * 3600000000;
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint64_t>(second));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, Timestamp>(params, size, numToBytea);
+}
+
+Datum intervalToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, IntervalVar in) -> text {
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint64_t>(in.timeOffset));
+ lenAdd += serializeInt(&buf, static_cast<uint32_t>(in.day));
+ lenAdd += serializeInt(&buf, static_cast<uint32_t>(in.month));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, IntervalVar>(params, size, numToBytea);
+}
+
+Datum decimalToBytea(Datum *params, uint64_t size) {
+ auto decimalToText = [](std::string &buf, DecimalVar val) -> uint64_t {
+ uint64_t len = 0, scale = 0;
+ __uint128_t unsigned_val;
+ __int128_t srcVal = val.highbits;
+ srcVal = (srcVal << 64) + val.lowbits;
+
+ uint64_t low_min = 0;
+ int64_t high_min = INT64_MIN;
+ __int128_t MIN = INT64_MIN;
+ MIN = (MIN << 64) + low_min;
+
+ bool isNegative = srcVal < 0;
+ if (isNegative) {
+ if (srcVal == MIN) {
+ unsigned_val = -(srcVal + 1);
+ unsigned_val++;
+ } else {
+ unsigned_val = -srcVal;
+ }
+ } else {
+ unsigned_val = srcVal;
+ }
+ auto numOfDigit = getNumOfDigit<__uint128_t>(unsigned_val);
+ if (srcVal == 0) {
+ numOfDigit = 1 + val.scale;
+ }
+ if (val.scale == 0) {
+ len += (numOfDigit + isNegative);
+ } else {
+ len += (numOfDigit + 1 + isNegative);
+ }
+ buf.clear();
+ buf.resize(len);
+ char *ret = const_cast<char *>(buf.data() + len);
+ do {
+ auto old = unsigned_val;
+ unsigned_val = unsigned_val / 10;
+ *--ret = old - unsigned_val * 10 + '0';
+ scale++;
+ } while (unsigned_val > 0 && scale != val.scale);
+
+ if (val.scale != 0) {
+ *--ret = '.';
+ do {
+ auto old = unsigned_val;
+ unsigned_val = unsigned_val / 10;
+ *--ret = old - unsigned_val * 10 + '0';
+ } while (unsigned_val > 0);
+ }
+ if (isNegative) {
+ *--ret = '-';
+ }
+ return len;
+ };
+
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [&decimalToText](ByteBuffer &buf, DecimalVar in) -> text {
+ struct oldDes {
+ int32_t ndigits; /* # of digits in digits[] - can be 0! */
+ int32_t weight; /* weight of first digit */
+ int32_t sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
+ int32_t dscale; /* display scale */
+ } oldVar;
+ // std::string decimalStr =
+ // DecimalType::toString(in.highbits, in.lowbits, in.scale);
+ std::string decimalStr;
+ uint64_t strLength = decimalToText(decimalStr, in);
+ const char *frontPtr = decimalStr.data();
+ const char *endPtr = frontPtr + strLength;
+ const char *dotPtr = nullptr;
+ if (*frontPtr == '-') {
+ oldVar.sign = 0x4000;
+ ++frontPtr;
+ } else {
+ oldVar.sign = 0x0000;
+ }
+ for (const char *ptemp = frontPtr; *ptemp != '\0'; ++ptemp) {
+ if (*ptemp == '.') {
+ dotPtr = ptemp;
+ break;
+ }
+ }
+ std::vector<int16_t> numVec(0);
+ numVec.reserve(50);
+ const char *pendTmp = dotPtr ? dotPtr : endPtr;
+ const char *ptemp = frontPtr;
+ int32_t rest = (pendTmp - ptemp) % 4;
+ if (rest == 3) {
+ int16_t val =
+ (ptemp[0] - '0') * 100 + (ptemp[1] - '0') * 10 + (ptemp[2] - '0');
+ numVec.push_back(val);
+ ptemp += 3;
+ } else if (rest == 2) {
+ int16_t val = (ptemp[0] - '0') * 10 + (ptemp[1] - '0');
+ numVec.push_back(val);
+ ptemp += 2;
+ } else if (rest == 1) {
+ int16_t val = ptemp[0] - '0';
+ numVec.push_back(val);
+ ptemp += 1;
+ }
+ for (; pendTmp - ptemp >= 4; ptemp += 4) {
+ int16_t val = (ptemp[0] - '0') * 1000 + (ptemp[1] - '0') * 100 +
+ (ptemp[2] - '0') * 10 + (ptemp[3] - '0');
+ numVec.push_back(val);
+ }
+ oldVar.weight = numVec.size() - 1;
+ oldVar.dscale = 0;
+ if (dotPtr) {
+ oldVar.dscale = endPtr - dotPtr - 1;
+ for (ptemp = dotPtr + 1; endPtr - ptemp >= 4; ptemp += 4) {
+ int16_t val = (ptemp[0] - '0') * 1000 + (ptemp[1] - '0') * 100 +
+ (ptemp[2] - '0') * 10 + (ptemp[3] - '0');
+ numVec.push_back(val);
+ }
+ rest = endPtr - ptemp;
+ if (rest == 3) {
+ int16_t val = (ptemp[0] - '0') * 1000 + (ptemp[1] - '0') * 100 +
+ (ptemp[2] - '0') * 10;
+ numVec.push_back(val);
+ } else if (rest == 2) {
+ int16_t val = (ptemp[0] - '0') * 1000 + (ptemp[1] - '0') * 100;
+ numVec.push_back(val);
+ } else if (rest == 1) {
+ int16_t val = (ptemp[0] - '0') * 1000;
+ numVec.push_back(val);
+ }
+ }
+ oldVar.ndigits = numVec.size();
+ uint32_t lenAdd = 0;
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(oldVar.ndigits));
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(oldVar.weight));
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(oldVar.sign));
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(oldVar.dscale));
+ for (int16_t i = 0; i < oldVar.ndigits; ++i)
+ lenAdd += serializeInt(&buf, static_cast<uint16_t>(numVec[i]));
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, DecimalVar>(params, size, numToBytea);
+}
+
Datum intervalToText(Datum *params, uint64_t size) {
auto inttotext = [](char *&ptr, uint32_t val) {
if (val == 0) {
@@ -688,4 +1006,17 @@
return one_param_bind<text, IntervalVar>(params, size, intervalCastText);
}
+Datum charToBytea(Datum *params, uint64_t size) {
+ assert(size == 2 && "invalid input");
+ auto numToBytea = [](ByteBuffer &buf, int8_t in) -> text {
+ uint32_t lenBefore = buf.size();
+ uint32_t lenAdd = sizeof(int8_t);
+ buf.resize(lenBefore + lenAdd);
+ memcpy(buf.data() + lenBefore, reinterpret_cast<char *>(&in), lenAdd);
+ return text(nullptr, lenAdd);
+ };
+ return one_param_bind<text, int8_t>(params, size, numToBytea);
+}
+
+
} // namespace dbcommon
diff --git a/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.h b/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.h
index ac24e63..eda857d 100644
--- a/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.h
+++ b/depends/dbcommon/src/dbcommon/function/typecast-texttonum-func.h
@@ -31,9 +31,21 @@
Datum text_to_int8(Datum *params, uint64_t size);
Datum text_to_float4(Datum *params, uint64_t size);
Datum text_to_float8(Datum *params, uint64_t size);
+Datum int2ToBytea(Datum *params, uint64_t size);
+Datum int4ToBytea(Datum *params, uint64_t size);
+Datum int8ToBytea(Datum *params, uint64_t size);
+Datum float4ToBytea(Datum *params, uint64_t size);
+Datum float8ToBytea(Datum *params, uint64_t size);
+Datum textToBytea(Datum *params, uint64_t size);
+Datum dateToBytea(Datum *params, uint64_t size);
+Datum timeToBytea(Datum *params, uint64_t size);
+Datum timestampToBytea(Datum *params, uint64_t size);
+Datum intervalToBytea(Datum *params, uint64_t size);
+Datum decimalToBytea(Datum *params, uint64_t size);
Datum textToDecimal(Datum *params, uint64_t size);
Datum toNumber(Datum *params, uint64_t size);
Datum intervalToText(Datum *params, uint64_t size);
+Datum charToBytea(Datum *params, uint64_t size);
} // namespace dbcommon
diff --git a/depends/dbcommon/test/unit/function/test-typecast-texttonum-func.cc b/depends/dbcommon/test/unit/function/test-typecast-texttonum-func.cc
index 7d81e12..e225954 100644
--- a/depends/dbcommon/test/unit/function/test-typecast-texttonum-func.cc
+++ b/depends/dbcommon/test/unit/function/test-typecast-texttonum-func.cc
@@ -105,6 +105,96 @@
ERRCODE_INVALID_TEXT_REPRESENTATION}));
INSTANTIATE_TEST_CASE_P(
+ num_to_bytea, TestFunction,
+ ::testing::Values(
+ TestFunctionEntry{
+ FuncKind::CHAR_TO_BYTEA, "Vector: \\003 NULL", {"Vector: 3 NULL"}},
+ TestFunctionEntry{FuncKind::SMALLINT_TO_BYTEA,
+ "Vector: \\000{ NULL",
+ {"Vector: 123 NULL"}},
+ TestFunctionEntry{FuncKind::INT_TO_BYTEA,
+ "Vector: \\000\\000\\000{ NULL",
+ {"Vector: 123 NULL"}},
+ TestFunctionEntry{FuncKind::BIGINT_TO_BYTEA,
+ "Vector: \\000\\000\\000\\000\\000\\000\\000{ NULL",
+ {"Vector: 123 NULL"}},
+ TestFunctionEntry{FuncKind::FLOAT_TO_BYTEA,
+ "Vector: B\\366>\\372 NULL",
+ {"Vector: 123.123 NULL"}},
+ TestFunctionEntry{FuncKind::DOUBLE_TO_BYTEA,
+ "Vector: @^\\307\\337;dZ\\035 NULL",
+ {"Vector: 123.123 NULL"}},
+ TestFunctionEntry{FuncKind::TEXT_TO_BYTEA,
+ "Vector: 123hub7.;8knjn NULL",
+ {"Vector: 123hub7.;8knjn NULL"}},
+ TestFunctionEntry{FuncKind::DATE_TO_BYTEA,
+ "Vector: \\000\\000\\032\\034 NULL",
+ {"Vector: 2018-04-20 NULL"}},
+ TestFunctionEntry{FuncKind::TIME_TO_BYTEA,
+ "Vector: \\000\\000\\000\\011u\\013\\345P NULL",
+ {"Vector: 11:16:58.419536 NULL"}},
+ TestFunctionEntry{FuncKind::TIMESTAMP_TO_BYTEA,
+ "Vector: \\000\\002'\\203\\207Y\\245P NULL",
+ {"Vector: 2019-03-20 11:16:58.419536 NULL"}},
+ TestFunctionEntry{FuncKind::TIMESTAMPTZ_TO_BYTEA,
+ "Vector: \\000\\002'|\\322\\274\\205P NULL",
+ {"Vector: 2019-03-20 11:16:58.419536+08 NULL"}},
+ TestFunctionEntry{FuncKind::INTERVAL_TO_BYTEA,
+ "Vector: "
+ "\\000\\000\\000\\000\\000\\000\\000."
+ "\\000\\000\\000\\000\\000\\000\\000\\000 NULL",
+ {"Vector: 00:00:46 NULL"}},
+ TestFunctionEntry{
+ FuncKind::DECIMAL_TO_BYTEA,
+ "Vector: "
+ "\\000\\006\\000\\002@\\000\\000\\011\\000\\001\\011)"
+ "\\032\\205\\004\\322\\026.#( "
+ "\\000\\002\\000\\000\\000\\000\\000\\003\\000{\\004\\316 "
+ "\\000\\002\\000\\000\\000\\000\\000\\002\\000\\014\\004\\260 NULL",
+ {"Vector: -123456789.123456789 123.123 12.12 NULL"}}));
+
+INSTANTIATE_TEST_CASE_P(
+ text_to_Decimal, TestFunction,
+ ::testing::Values(
+ TestFunctionEntry{
+ FuncKind::TEXT_TO_DECIMAL,
+ "Vector: 922337203685.4775807 -9223372036854.775808 "
+ "1234.56 -0.00123456 1234.56 -0.00123456 NULL",
+ {"Vector: 922337203685.4775807 -9223372036854.775808 "
+ "1.23456e+3 -1.23456e-3 1.23456E+3 -1.23456E-3 NULL"}},
+ TestFunctionEntry{FuncKind::TEXT_TO_DECIMAL,
+ "Error",
+ {"Vector: -922337203i854775809 9223372036854l75808 "
+ "e33 1.23e2 1.2i3e2 1.23e2i2"},
+ ERRCODE_INVALID_TEXT_REPRESENTATION}));
+
+INSTANTIATE_TEST_CASE_P(
+ to_number, TestFunction,
+ ::testing::Values(
+ TestFunctionEntry{
+ FuncKind::TO_NUMBER,
+ "Vector: -34338492 -34338492.654878 -0.00001 -5.01 -5.01 0.01 0.0 "
+ "0 "
+ "-0.01 -564646.654564 -0.01 NULL",
+ {"Vector: -34,338,492 -34,338,492.654,878 0.00001- 5.01- 5.01- .01 "
+ ".0 "
+ "0 .01- <564646.654564> .-01 NULL",
+ "Vector: 99G999G999 99G999G999D999G999 9.999999S FM9.999999S "
+ "FM9.999999MI FM9.99 99999999.99999999 99.99 TH99.99S "
+ "999999.999999PR "
+ "S99.99 NULL"}},
+ TestFunctionEntry{FuncKind::TO_NUMBER,
+ "Error",
+ {"Vector: -34,338,492 -34,338,492.654,878 0.00001- "
+ "5.01- 5.01- .01 .0 "
+ "0 .01- <564646.654564> 111.11",
+ "Vector: 99G999G99Ss9 99G999G999D.999G999 "
+ "MIMI9.999999S FM9.99999PR9S "
+ "FM9.999999PLS FM9.99SPL 99999999.99999999PRS "
+ "99.9PR0 99.99SPR 999999.999999RN "
+ "99.99"},
+ ERRCODE_INVALID_TEXT_REPRESENTATION}));
+INSTANTIATE_TEST_CASE_P(
interval_to_text, TestFunction,
::testing::Values(TestFunctionEntry{
FuncKind::INTERVAL_TO_TEXT,