Add DateTime64 support

This commit is contained in:
slvrtrn 2023-09-04 20:49:29 +02:00
parent 8483d1c701
commit 4f4640ec90
5 changed files with 364 additions and 186 deletions

View File

@ -46,6 +46,8 @@ public class PreparedStatementsTest {
testDecimalTypes(conn);
testMiscTypes(conn);
testDateTypes(conn);
testUnusualDateTime64Scales(conn);
testDateTimeTimezones(conn);
conn.close();
} catch (Exception e) {
e.printStackTrace();
@ -59,21 +61,21 @@ public class PreparedStatementsTest {
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "i8"), rs.getInt("i8"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "i16"), rs.getInt("i16"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "i32"), rs.getInt("i32"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "i64"), rs.getLong("i64"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "i128"), rs.getString("i128"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "i256"), rs.getString("i256"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "ui8"), rs.getInt("ui8"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "ui16"), rs.getInt("ui16"));
System.out.printf("Type: %s, value: %d\n", getMysqlType(rs, "ui32"), rs.getLong("ui32"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "ui64"), rs.getString("ui64"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "ui128"), rs.getString("ui128"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "ui256"), rs.getString("ui256"));
System.out.printf("Type: %s, value: %f\n", getMysqlType(rs, "f32"), rs.getFloat("f32"));
System.out.printf("Type: %s, value: %f\n", getMysqlType(rs, "f64"), rs.getFloat("f64"));
System.out.printf("Type: %s, value: %b\n", getMysqlType(rs, "b"), rs.getBoolean("b"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "i8"), rs.getInt("i8"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "i16"), rs.getInt("i16"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "i32"), rs.getInt("i32"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "i64"), rs.getLong("i64"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "i128"), rs.getString("i128"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "i256"), rs.getString("i256"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "ui8"), rs.getInt("ui8"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "ui16"), rs.getInt("ui16"));
System.out.printf("%s, value: %d\n", getMysqlType(rs, "ui32"), rs.getLong("ui32"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "ui64"), rs.getString("ui64"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "ui128"), rs.getString("ui128"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "ui256"), rs.getString("ui256"));
System.out.printf("%s, value: %f\n", getMysqlType(rs, "f32"), rs.getFloat("f32"));
System.out.printf("%s, value: %f\n", getMysqlType(rs, "f64"), rs.getFloat("f64"));
System.out.printf("%s, value: %b\n", getMysqlType(rs, "b"), rs.getBoolean("b"));
}
System.out.println();
}
@ -84,10 +86,10 @@ public class PreparedStatementsTest {
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "s"), rs.getString("s"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "sn"), rs.getString("sn"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "lc"), rs.getString("lc"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "nlc"), rs.getString("nlc"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "s"), rs.getString("s"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "sn"), rs.getString("sn"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "lc"), rs.getString("lc"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "nlc"), rs.getString("nlc"));
}
System.out.println();
}
@ -98,16 +100,12 @@ public class PreparedStatementsTest {
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d32"),
rs.getBigDecimal("d32").toPlainString());
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d64"),
rs.getBigDecimal("d64").toPlainString());
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d128_native"),
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d32"), rs.getBigDecimal("d32").toPlainString());
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d64"), rs.getBigDecimal("d64").toPlainString());
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d128_native"),
rs.getBigDecimal("d128_native").toPlainString());
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d128_text"),
rs.getString("d128_text"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d256"),
rs.getString("d256"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d128_text"), rs.getString("d128_text"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d256"), rs.getString("d256"));
}
System.out.println();
}
@ -118,12 +116,41 @@ public class PreparedStatementsTest {
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d"), rs.getDate("d"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "d32"), rs.getDate("d32"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "dt"), rs.getTimestamp("dt"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "dt64_3"), rs.getString("dt64_3"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "dt64_6"), rs.getString("dt64_6"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "dt64_9"), rs.getString("dt64_9"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d"), rs.getDate("d"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "d32"), rs.getDate("d32"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt"), rs.getTimestamp("dt"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_3"), rs.getTimestamp("dt64_3"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_6"), rs.getTimestamp("dt64_6"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_9"), rs.getTimestamp("dt64_9"));
}
System.out.println();
}
private static void testUnusualDateTime64Scales(Connection conn) throws SQLException {
System.out.println("### testUnusualDateTime64Scales");
ResultSet rs = conn.prepareStatement("SELECT * FROM ps_unusual_datetime64_scales").executeQuery();
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_0"), rs.getTimestamp("dt64_0"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_1"), rs.getTimestamp("dt64_1"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_2"), rs.getTimestamp("dt64_2"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_4"), rs.getTimestamp("dt64_4"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_5"), rs.getTimestamp("dt64_5"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_7"), rs.getTimestamp("dt64_7"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_8"), rs.getTimestamp("dt64_8"));
}
System.out.println();
}
private static void testDateTimeTimezones(Connection conn) throws SQLException {
System.out.println("### testDateTimeTimezones");
ResultSet rs = conn.prepareStatement("SELECT * FROM ps_datetime_timezones").executeQuery();
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt"), rs.getTimestamp("dt"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "dt64_3"), rs.getTimestamp("dt64_3"));
}
System.out.println();
}
@ -134,16 +161,17 @@ public class PreparedStatementsTest {
int rowNum = 1;
while (rs.next()) {
System.out.printf("Row #%d\n", rowNum++);
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "a"), rs.getString("a"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "u"), rs.getString("u"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "t"), rs.getString("t"));
System.out.printf("Type: %s, value: %s\n", getMysqlType(rs, "m"), rs.getString("m"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "a"), rs.getString("a"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "u"), rs.getString("u"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "t"), rs.getString("t"));
System.out.printf("%s, value: %s\n", getMysqlType(rs, "m"), rs.getString("m"));
}
System.out.println();
}
private static MysqlType getMysqlType(ResultSet rs, String columnLabel) throws SQLException {
private static String getMysqlType(ResultSet rs, String columnLabel) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
return MysqlType.getByJdbcType(meta.getColumnType(rs.findColumn(columnLabel)));
return String.format("%s type is %s", columnLabel,
MysqlType.getByJdbcType(meta.getColumnType(rs.findColumn(columnLabel))));
}
}

View File

@ -7,6 +7,8 @@
#include "Columns/ColumnLowCardinality.h"
#include "Columns/ColumnVector.h"
#include "Columns/ColumnsDateTime.h"
#include "Core/DecimalFunctions.h"
#include "DataTypes/DataTypeDateTime64.h"
#include "DataTypes/DataTypeLowCardinality.h"
#include "DataTypes/DataTypeNullable.h"
#include "DataTypes/DataTypesNumber.h"
@ -74,46 +76,66 @@ namespace MySQLProtocol
payload_size += 8;
break;
case TypeIndex::Date: {
UInt16 value = assert_cast<const ColumnVector<UInt16> &>(*col).getData()[row_num];
if (value == 0)
{
payload_size += 1; // length only, no other fields
}
else
{
payload_size += 5;
}
break;
}
case TypeIndex::Date32: {
Int32 value = assert_cast<const ColumnVector<Int32> &>(*col).getData()[row_num];
if (value == 0)
{
payload_size += 1; // length only, no other fields
}
else
{
payload_size += 5;
}
break;
}
case TypeIndex::DateTime: {
UInt32 value = assert_cast<const ColumnVector<UInt32> &>(*col).getData()[row_num];
if (value == 0)
{
payload_size += 1; // length only, no other fields
}
else
{
LocalDateTime ldt = LocalDateTime(value, DateLUT::instance(getDateTimeTimezone(*data_type)));
if (ldt.second() == 0 && ldt.minute() == 0 && ldt.hour() == 0)
{
payload_size += 5;
}
else
bool has_time = !(ldt.hour() == 0 && ldt.minute() == 0 && ldt.second() == 0);
if (has_time)
{
payload_size += 8;
}
else
{
payload_size += 5;
}
break;
}
case TypeIndex::DateTime64: {
const auto * date_time_type = typeid_cast<const DataTypeDateTime64 *>(data_type.get());
UInt32 scale = date_time_type->getScale();
static constexpr UInt32 MaxScale = DecimalUtils::max_precision<DateTime64>;
scale = scale > MaxScale ? MaxScale : scale;
const auto dt64 = assert_cast<const ColumnDateTime64 &>(*col).getData()[row_num];
auto components = DecimalUtils::split(dt64, scale);
using T = typename DateTime64::NativeType;
if (dt64.value < 0 && components.fractional)
{
components.fractional
= DecimalUtils::scaleMultiplier<T>(scale) + (components.whole ? T(-1) : T(1)) * components.fractional;
--components.whole;
}
if (scale > 6)
{
// MySQL Timestamp has max scale of 6
components.fractional /= static_cast<int>(pow(10, scale - 6));
}
LocalDateTime ldt = LocalDateTime(components.whole, DateLUT::instance(getDateTimeTimezone(*data_type)));
bool has_microseconds = components.fractional != 0;
bool has_time = !(ldt.hour() == 0 && ldt.minute() == 0 && ldt.second() == 0);
if (has_microseconds)
{
payload_size += 12;
}
else if (has_time)
{
payload_size += 8;
}
else
{
payload_size += 5;
}
break;
}
@ -199,8 +221,6 @@ namespace MySQLProtocol
}
case TypeIndex::Date: {
UInt16 value = assert_cast<const ColumnVector<UInt16> &>(*col).getData()[row_num];
if (value != 0)
{
LocalDate ld = LocalDate(DayNum(value));
buffer.write(static_cast<char>(4)); // bytes_following
auto year = ld.year();
@ -209,17 +229,10 @@ namespace MySQLProtocol
buffer.write(reinterpret_cast<const char *>(&year), 2);
buffer.write(reinterpret_cast<const char *>(&month), 1);
buffer.write(reinterpret_cast<const char *>(&day), 1);
}
else
{
buffer.write(static_cast<char>(0));
}
break;
}
case TypeIndex::Date32: {
Int32 value = assert_cast<const ColumnVector<Int32> &>(*col).getData()[row_num];
if (value != 0)
{
LocalDate ld = LocalDate(ExtendedDayNum(value));
buffer.write(static_cast<char>(4)); // bytes_following
auto year = ld.year();
@ -228,18 +241,12 @@ namespace MySQLProtocol
buffer.write(reinterpret_cast<const char *>(&year), 2);
buffer.write(reinterpret_cast<const char *>(&month), 1);
buffer.write(reinterpret_cast<const char *>(&day), 1);
}
else
{
buffer.write(static_cast<char>(0));
}
break;
}
case TypeIndex::DateTime: {
UInt32 value = assert_cast<const ColumnVector<UInt32> &>(*col).getData()[row_num];
if (value != 0)
{
LocalDateTime ldt = LocalDateTime(value, DateLUT::instance(getDateTimeTimezone(*data_type)));
String timezone = getDateTimeTimezone(*data_type);
LocalDateTime ldt = LocalDateTime(value, DateLUT::instance(timezone));
int year = ldt.year();
int month = ldt.month();
int day = ldt.day();
@ -258,14 +265,89 @@ namespace MySQLProtocol
buffer.write(reinterpret_cast<const char *>(&minute), 1);
buffer.write(reinterpret_cast<const char *>(&second), 1);
}
break;
}
case TypeIndex::DateTime64: {
const auto * date_time_type = typeid_cast<const DataTypeDateTime64 *>(data_type.get());
UInt32 scale = date_time_type->getScale();
static constexpr UInt32 MaxScale = DecimalUtils::max_precision<DateTime64>;
scale = scale > MaxScale ? MaxScale : scale;
const auto dt64 = assert_cast<const ColumnDateTime64 &>(*col).getData()[row_num];
auto components = DecimalUtils::split(dt64, scale);
using T = typename DateTime64::NativeType;
if (dt64.value < 0 && components.fractional)
{
components.fractional
= DecimalUtils::scaleMultiplier<T>(scale) + (components.whole ? T(-1) : T(1)) * components.fractional;
--components.whole;
}
if (components.fractional != 0)
{
if (scale > 6)
{
// MySQL Timestamp has max scale of 6
components.fractional /= static_cast<int>(pow(10, scale - 6));
}
else
{
buffer.write(static_cast<char>(0));
// fractional == 1 is a different microsecond value depending on the scale
// Scale 1 = 100 000
// Scale 2 = 010 000
// Scale 3 = 001 000
// Scale 4 = 000 100
// Scale 5 = 000 010
// Scale 6 = 000 001
components.fractional *= static_cast<int>(pow(10, 6 - scale));
}
}
String timezone = getDateTimeTimezone(*data_type);
std::cout << "Timezone is " << timezone << std::endl;
LocalDateTime ldt = LocalDateTime(components.whole, DateLUT::instance(timezone));
auto year = ldt.year();
auto month = ldt.month();
auto day = ldt.day();
auto hour = ldt.hour();
auto minute = ldt.minute();
auto second = ldt.second();
bool has_time = !(hour == 0 && minute == 0 && second == 0);
bool has_microseconds = components.fractional != 0;
if (has_microseconds)
{
buffer.write(static_cast<char>(11)); // bytes_following
buffer.write(reinterpret_cast<const char *>(&year), 2);
buffer.write(reinterpret_cast<const char *>(&month), 1);
buffer.write(reinterpret_cast<const char *>(&day), 1);
buffer.write(reinterpret_cast<const char *>(&hour), 1);
buffer.write(reinterpret_cast<const char *>(&minute), 1);
buffer.write(reinterpret_cast<const char *>(&second), 1);
buffer.write(reinterpret_cast<const char *>(&components.fractional), 4);
}
else if (has_time)
{
buffer.write(static_cast<char>(7)); // bytes_following
buffer.write(reinterpret_cast<const char *>(&year), 2);
buffer.write(reinterpret_cast<const char *>(&month), 1);
buffer.write(reinterpret_cast<const char *>(&day), 1);
buffer.write(reinterpret_cast<const char *>(&hour), 1);
buffer.write(reinterpret_cast<const char *>(&minute), 1);
buffer.write(reinterpret_cast<const char *>(&second), 1);
}
else
{
buffer.write(static_cast<char>(4)); // bytes_following
buffer.write(reinterpret_cast<const char *>(&year), 2);
buffer.write(reinterpret_cast<const char *>(&month), 1);
buffer.write(reinterpret_cast<const char *>(&day), 1);
}
break;
}
default:
writeLengthEncodedString(serialized[i], buffer);
break;

View File

@ -211,6 +211,10 @@ namespace MySQLProtocol
column_type = ColumnType::MYSQL_TYPE_DATETIME;
flags = ColumnDefinitionFlags::BINARY_FLAG;
break;
case TypeIndex::DateTime64:
column_type = ColumnType::MYSQL_TYPE_DATETIME;
flags = ColumnDefinitionFlags::BINARY_FLAG;
break;
case TypeIndex::Decimal32:
case TypeIndex::Decimal64:
column_type = ColumnType::MYSQL_TYPE_DECIMAL;

View File

@ -1,81 +1,114 @@
### testSimpleDataTypes
Row #1
Type: TINYINT, value: -128
Type: SMALLINT, value: -32768
Type: INT, value: -2147483648
Type: BIGINT, value: -9223372036854775808
Type: CHAR, value: -170141183460469231731687303715884105728
Type: CHAR, value: -57896044618658097711785492504343953926634992332820282019728792003956564819968
Type: TINYINT, value: 120
Type: SMALLINT, value: 1234
Type: INT, value: 51234
Type: BIGINT, value: 421342
Type: CHAR, value: 15324355
Type: CHAR, value: 41345135123432
Type: FLOAT, value: -0.796896
Type: DOUBLE, value: -0.113259
Type: BIT, value: true
i8 type is TINYINT, value: -128
i16 type is SMALLINT, value: -32768
i32 type is INT, value: -2147483648
i64 type is BIGINT, value: -9223372036854775808
i128 type is CHAR, value: -170141183460469231731687303715884105728
i256 type is CHAR, value: -57896044618658097711785492504343953926634992332820282019728792003956564819968
ui8 type is TINYINT, value: 120
ui16 type is SMALLINT, value: 1234
ui32 type is INT, value: 51234
ui64 type is BIGINT, value: 421342
ui128 type is CHAR, value: 15324355
ui256 type is CHAR, value: 41345135123432
f32 type is FLOAT, value: -0.796896
f64 type is DOUBLE, value: -0.113259
b type is BIT, value: true
Row #2
Type: TINYINT, value: 127
Type: SMALLINT, value: 32767
Type: INT, value: 2147483647
Type: BIGINT, value: 9223372036854775807
Type: CHAR, value: 170141183460469231731687303715884105727
Type: CHAR, value: 57896044618658097711785492504343953926634992332820282019728792003956564819967
Type: TINYINT, value: 255
Type: SMALLINT, value: 65535
Type: INT, value: 4294967295
Type: BIGINT, value: 18446744073709551615
Type: CHAR, value: 340282366920938463463374607431768211455
Type: CHAR, value: 115792089237316195423570985008687907853269984665640564039457584007913129639935
Type: FLOAT, value: 1.234000
Type: DOUBLE, value: 3.352451
Type: BIT, value: false
i8 type is TINYINT, value: 127
i16 type is SMALLINT, value: 32767
i32 type is INT, value: 2147483647
i64 type is BIGINT, value: 9223372036854775807
i128 type is CHAR, value: 170141183460469231731687303715884105727
i256 type is CHAR, value: 57896044618658097711785492504343953926634992332820282019728792003956564819967
ui8 type is TINYINT, value: 255
ui16 type is SMALLINT, value: 65535
ui32 type is INT, value: 4294967295
ui64 type is BIGINT, value: 18446744073709551615
ui128 type is CHAR, value: 340282366920938463463374607431768211455
ui256 type is CHAR, value: 115792089237316195423570985008687907853269984665640564039457584007913129639935
f32 type is FLOAT, value: 1.234000
f64 type is DOUBLE, value: 3.352451
b type is BIT, value: false
### testStringTypes
Row #1
Type: CHAR, value: 42
Type: CHAR, value: null
Type: CHAR, value: test
Type: CHAR, value: null
s type is CHAR, value: 42
sn type is CHAR, value: null
lc type is CHAR, value: test
nlc type is CHAR, value: null
Row #2
Type: CHAR, value: foo
Type: CHAR, value: bar
Type: CHAR, value: qaz
Type: CHAR, value: qux
s type is CHAR, value: foo
sn type is CHAR, value: bar
lc type is CHAR, value: qaz
nlc type is CHAR, value: qux
### testDecimalTypes
Row #1
Type: DECIMAL, value: -1.55
Type: DECIMAL, value: 6.03
Type: DECIMAL, value: 5
Type: CHAR, value: -1224124.23423
Type: CHAR, value: -54342.3
d32 type is DECIMAL, value: -1.55
d64 type is DECIMAL, value: 6.03
d128_native type is DECIMAL, value: 5
d128_text type is CHAR, value: -1224124.23423
d256 type is CHAR, value: -54342.3
Row #2
Type: DECIMAL, value: 1234567.89
Type: DECIMAL, value: 123456789123456.789
Type: DECIMAL, value: 12345678912345678912.1234567891
Type: CHAR, value: 1234567.8912345678912345678911234567891
Type: CHAR, value: 12345678912345678912345678911234567891234567891234567891.12345678911234567891
d32 type is DECIMAL, value: 1234567.89
d64 type is DECIMAL, value: 123456789123456.789
d128_native type is DECIMAL, value: 12345678912345678912.1234567891
d128_text type is CHAR, value: 1234567.8912345678912345678911234567891
d256 type is CHAR, value: 12345678912345678912345678911234567891234567891234567891.12345678911234567891
### testMiscTypes
Row #1
Type: CHAR, value: []
Type: CHAR, value: 9a0ccc06-2578-4861-8534-631c9d40f3f7
Type: CHAR, value: (0,'')
Type: CHAR, value: {}
a type is CHAR, value: []
u type is CHAR, value: 9a0ccc06-2578-4861-8534-631c9d40f3f7
t type is CHAR, value: (0,'')
m type is CHAR, value: {}
Row #2
Type: CHAR, value: ['foo','bar']
Type: CHAR, value: 5da5038d-788f-48c6-b510-babb41c538d3
Type: CHAR, value: (42,'qaz')
Type: CHAR, value: {'qux':144,'text':255}
a type is CHAR, value: ['foo','bar']
u type is CHAR, value: 5da5038d-788f-48c6-b510-babb41c538d3
t type is CHAR, value: (42,'qaz')
m type is CHAR, value: {'qux':144,'text':255}
### testDateTypes
Row #1
Type: DATE, value: 2149-06-06
Type: DATE, value: 2178-04-16
Type: TIMESTAMP, value: 2106-02-07 06:28:15.0
Type: CHAR, value: 2106-02-07 06:28:15.123
Type: CHAR, value: 2106-02-07 06:28:15.123456
Type: CHAR, value: 2106-02-07 06:28:15.123456789
d type is DATE, value: 1970-01-01
d32 type is DATE, value: 1900-01-01
dt type is TIMESTAMP, value: 1970-01-01 01:00:00.0
dt64_3 type is TIMESTAMP, value: 1900-01-01 00:00:00.0
dt64_6 type is TIMESTAMP, value: 1900-01-01 00:00:00.000001
dt64_9 type is TIMESTAMP, value: 1900-01-01 00:00:00.0
Row #2
d type is DATE, value: 2149-06-06
d32 type is DATE, value: 2178-04-16
dt type is TIMESTAMP, value: 2106-02-07 06:28:15.0
dt64_3 type is TIMESTAMP, value: 2106-02-07 06:28:15.123
dt64_6 type is TIMESTAMP, value: 2106-02-07 06:28:15.123456
dt64_9 type is TIMESTAMP, value: 2106-02-07 06:28:15.123456
### testUnusualDateTime64Scales
Row #1
dt64_0 type is TIMESTAMP, value: 2022-04-13 03:17:45.0
dt64_1 type is TIMESTAMP, value: 2022-04-13 03:17:45.1
dt64_2 type is TIMESTAMP, value: 2022-04-13 03:17:45.12
dt64_4 type is TIMESTAMP, value: 2022-04-13 03:17:45.1234
dt64_5 type is TIMESTAMP, value: 2022-04-13 03:17:45.12345
dt64_7 type is TIMESTAMP, value: 2022-04-13 03:17:45.123456
dt64_8 type is TIMESTAMP, value: 2022-04-13 03:17:45.123456
Row #2
dt64_0 type is TIMESTAMP, value: 2022-04-13 03:17:45.0
dt64_1 type is TIMESTAMP, value: 2022-04-13 03:17:45.1
dt64_2 type is TIMESTAMP, value: 2022-04-13 03:17:45.01
dt64_4 type is TIMESTAMP, value: 2022-04-13 03:17:45.0001
dt64_5 type is TIMESTAMP, value: 2022-04-13 03:17:45.00001
dt64_7 type is TIMESTAMP, value: 2022-04-13 03:17:45.0
dt64_8 type is TIMESTAMP, value: 2022-04-13 03:17:45.0
### testDateTimeTimezones
Row #1
dt type is TIMESTAMP, value: 1970-01-01 01:00:00.0
dt64_3 type is TIMESTAMP, value: 1969-12-31 16:00:00.0
Row #2
dt type is TIMESTAMP, value: 2022-09-04 20:31:05.0
dt64_3 type is TIMESTAMP, value: 2022-09-04 20:31:05.022

View File

@ -83,4 +83,35 @@ INSERT INTO ps_date_types
VALUES ('2149-06-06', '2178-04-16', '2106-02-07 06:28:15',
'2106-02-07 06:28:15.123',
'2106-02-07 06:28:15.123456',
'2106-02-07 06:28:15.123456789');
'2106-02-07 06:28:15.123456789'),
('1970-01-01', '1900-01-01', '1970-01-01 00:00:00',
'1900-01-01 00:00:00.001',
'1900-01-01 00:00:00.000001',
'1900-01-01 00:00:00.000000001');;
CREATE TABLE ps_unusual_datetime64_scales
(
dt64_0 DateTime64(0, 'UTC'),
dt64_1 DateTime64(1, 'UTC'),
dt64_2 DateTime64(2, 'UTC'),
dt64_4 DateTime64(4, 'UTC'),
dt64_5 DateTime64(5, 'UTC'),
dt64_7 DateTime64(7, 'UTC'),
dt64_8 DateTime64(8, 'UTC')
) ENGINE MergeTree ORDER BY dt64_0;
INSERT INTO ps_unusual_datetime64_scales
VALUES ('2022-04-13 03:17:45',
'2022-04-13 03:17:45.1',
'2022-04-13 03:17:45.12',
'2022-04-13 03:17:45.1234',
'2022-04-13 03:17:45.12345',
'2022-04-13 03:17:45.1234567',
'2022-04-13 03:17:45.12345678'),
('2022-04-13 03:17:45',
'2022-04-13 03:17:45.1',
'2022-04-13 03:17:45.01',
'2022-04-13 03:17:45.0001',
'2022-04-13 03:17:45.00001',
'2022-04-13 03:17:45.0000001',
'2022-04-13 03:17:45.00000001');