ClickHouse-Encoder

 view release on metacpan or  search on metacpan

t/types.t  view on Meta::CPAN

    );
    my $bin = $enc->encode([[99.99]]);
    my $off = skip_header($bin);
    is(unpack('l<', substr($bin, $off, 4)), 9999, 'Decimal(9,2) 99.99 = 9999');
}

# Test Decimal128
{
    my $enc = ClickHouse::Encoder->new(
        columns => [['v', 'Decimal128(2)']],
    );
    my $bin = $enc->encode([[123.45]]);
    my $off = skip_header($bin);
    my $lo = unpack('q<', substr($bin, $off, 8));
    my $hi = unpack('q<', substr($bin, $off+8, 8));
    is($lo, 12345, 'Decimal128(2) low part');
    is($hi, 0, 'Decimal128(2) high part');
}

# Test Decimal128 negative
{
    my $enc = ClickHouse::Encoder->new(
        columns => [['v', 'Decimal128(2)']],
    );
    my $bin = $enc->encode([[-123.45]]);
    my $off = skip_header($bin);
    my $lo = unpack('q<', substr($bin, $off, 8));
    my $hi = unpack('q<', substr($bin, $off+8, 8));
    is($lo, -12345, 'Decimal128(2) negative low part');
    is($hi, -1, 'Decimal128(2) negative high part (sign extension)');
}

# Test Nullable(Decimal32)
{
    my $enc = ClickHouse::Encoder->new(
        columns => [['v', 'Nullable(Decimal32(2))']],
    );
    my $bin = $enc->encode([[123.45], [undef]]);
    ok(defined $bin, 'Nullable(Decimal32) encodes');
}

# Test Array(Decimal64)
{
    my $enc = ClickHouse::Encoder->new(
        columns => [['v', 'Array(Decimal64(2))']],
    );
    my $bin = $enc->encode([[[1.23, 4.56]]]);
    ok(defined $bin, 'Array(Decimal64) encodes');
}

# Test UTF-8 String
{
    use utf8;
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'String']]);
    my $utf8_str = "Привет мир 日本語 🎉";
    my $bin = $enc->encode([[$utf8_str]]);
    ok(defined $bin, 'UTF-8 string encodes');

    my $off = skip_header($bin);
    my ($len, $off2) = read_varint($bin, $off);
    my $decoded = substr($bin, $off2, $len);
    utf8::decode($decoded);
    is($decoded, $utf8_str, 'UTF-8 string content preserved');
}

# Test UTF-8 FixedString (truncation on byte boundary)
{
    use utf8;
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'FixedString(6)']]);
    # "Привет" is 12 bytes in UTF-8, should truncate to 6 bytes
    my $bin = $enc->encode([["Привет"]]);
    my $off = skip_header($bin);
    is(length(substr($bin, $off)), 6, 'UTF-8 FixedString truncates by bytes');
}

# Test empty rows
{
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'UInt32']]);
    my $bin = $enc->encode([]);
    ok(defined $bin, 'empty rows encodes');
    my ($ncols, $off) = read_varint($bin, 0);
    my ($nrows, $off2) = read_varint($bin, $off);
    is($nrows, 0, 'empty rows count is 0');
}

# Test Tuple error handling
{
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'Tuple(UInt8, UInt8)']]);
    eval { $enc->encode([['not a tuple']]) };
    like($@, qr/Expected arrayref or hashref for Tuple/, 'Tuple with scalar croaks');
}

# Test Date with string
{
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'Date']]);
    my $bin = $enc->encode([['1970-01-01'], ['2000-01-01'], ['2024-06-15']]);
    my $off = skip_header($bin);
    is(unpack('v', substr($bin, $off, 2)), 0, 'Date 1970-01-01 = 0');
    is(unpack('v', substr($bin, $off+2, 2)), 10957, 'Date 2000-01-01 = 10957');
    is(unpack('v', substr($bin, $off+4, 2)), 19889, 'Date 2024-06-15 = 19889');
}

# Test Date with integer (days since epoch)
{
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'Date']]);
    my $bin = $enc->encode([[0], [10957]]);
    my $off = skip_header($bin);
    is(unpack('v', substr($bin, $off, 2)), 0, 'Date numeric 0');
    is(unpack('v', substr($bin, $off+2, 2)), 10957, 'Date numeric 10957');
}

# Test Date32 with string (supports wider range including negative)
{
    my $enc = ClickHouse::Encoder->new(columns => [['v', 'Date32']]);
    my $bin = $enc->encode([['1970-01-01'], ['1900-01-01']]);
    my $off = skip_header($bin);
    is(unpack('l<', substr($bin, $off, 4)), 0, 'Date32 1970-01-01 = 0');
    # 1900-01-01 is before epoch, should be negative
    my $days_1900 = unpack('l<', substr($bin, $off+4, 4));
    ok($days_1900 < 0, 'Date32 1900-01-01 is negative');
}

# Test DateTime with string



( run in 0.993 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )