ClickHouse-Encoder

 view release on metacpan or  search on metacpan

t/parse-create-table.t  view on Meta::CPAN

        ['name',    'String'],
        ['ts',      'DateTime'],
        ['payload', 'Nullable(String)'],
        ['tags',    'Array(LowCardinality(String))'],
    ], 'columns parsed as [name, type], modifiers stripped from type');
}

# Types with internal commas (Decimal, named Tuple) must not be split.
{
    my $ddl = 'CREATE TABLE t ('
            . '`price` Decimal(18, 4), '
            . '`pair` Tuple(a Int32, b String), '
            . '`m` Map(String, Array(Int64))'
            . ') ENGINE = Memory';
    my $p = ClickHouse::Encoder->parse_create_table($ddl);
    is_deeply($p->{columns}, [
        ['price', 'Decimal(18, 4)'],
        ['pair',  'Tuple(a Int32, b String)'],
        ['m',     'Map(String, Array(Int64))'],
    ], 'paren-aware column split keeps nested commas intact');
    is($p->{engine}, 'Memory', 'engine with no other clauses');
}

# No database qualifier -> database is undef, table still set.
{
    my $p = ClickHouse::Encoder->parse_create_table(
        'CREATE TABLE bare (`x` Int32) ENGINE = Memory');
    is($p->{database}, undef, 'unqualified name -> undef database');
    is($p->{table},    'bare', 'unqualified table name');
}

# IF NOT EXISTS and backtick-quoted qualified name.
{
    my $p = ClickHouse::Encoder->parse_create_table(
        'CREATE TABLE IF NOT EXISTS `my-db`.`my tbl` '
      . '(`c` Int32) ENGINE = Memory');
    is($p->{database}, 'my-db',  'backtick database with hyphen');
    is($p->{table},    'my tbl', 'backtick table with space');
}

# Identifiers containing a literal backtick: CH's SHOW CREATE TABLE (and
# format_create_table) backslash-escape it as \` inside the quotes, so
# the parser must decode that escape rather than treat it as the end of
# the quoted region.
{
    my $sql = ClickHouse::Encoder->format_create_table(
        table   => 'tbl',
        columns => [['we`ird', 'Int32'], ['ok', 'String']],
        engine  => 'Memory',
    );
    my $p = ClickHouse::Encoder->parse_create_table($sql);
    is_deeply($p->{columns}, [['we`ird', 'Int32'], ['ok', 'String']],
              'backtick-in-name round-trips format -> parse');
}

# The doubled-backtick escape form is also accepted on input.
{
    my $p = ClickHouse::Encoder->parse_create_table(
        'CREATE TABLE t (`a``b` Int32) ENGINE = Memory');
    is_deeply($p->{columns}, [['a`b', 'Int32']],
              'doubled-backtick escape decoded on input');
}

# CREATE OR REPLACE TABLE and CREATE TEMPORARY TABLE header variants.
{
    my $p = ClickHouse::Encoder->parse_create_table(
        'CREATE OR REPLACE TABLE t (`x` Int32) ENGINE = Memory');
    is($p->{table}, 't', 'CREATE OR REPLACE TABLE header parsed');

    my $q = ClickHouse::Encoder->parse_create_table(
        'CREATE TEMPORARY TABLE tmp (`y` String) ENGINE = Memory');
    is($q->{table}, 'tmp', 'CREATE TEMPORARY TABLE header parsed');
}

# Round-trip: parse -> schema_diff against a changed shape -> ALTERs.
{
    my $p = ClickHouse::Encoder->parse_create_table(
        'CREATE TABLE t (`a` Int32, `b` String) ENGINE = Memory');
    my $diff = ClickHouse::Encoder->schema_diff(
        $p->{columns}, [['a', 'Int64'], ['c', 'DateTime']]);
    my $sql = ClickHouse::Encoder->apply_schema_diff($diff, table => 't');
    is_deeply($sql, [
        'alter table `t` drop column `b`',
        'alter table `t` modify column `a` Int64',
        'alter table `t` add column `c` DateTime',
    ], 'parsed columns feed straight into schema_diff + apply_schema_diff');
}

# Error paths.
{
    local $@;
    eval { ClickHouse::Encoder->parse_create_table(undef) };
    like($@, qr/input required/, 'undef input croaks');
    eval { ClickHouse::Encoder->parse_create_table('SELECT 1') };
    like($@, qr/no create table header/, 'non-DDL input croaks');
    eval { ClickHouse::Encoder->parse_create_table('CREATE TABLE t') };
    like($@, qr/no column list/, 'missing column block croaks');
    eval { ClickHouse::Encoder->parse_create_table(
        'CREATE TABLE t (`a` Int32') };
    like($@, qr/unbalanced column list/,
         'column block with no closing paren croaks');
}

done_testing();



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