Repository navigation
Open
Description
I'm attempting to use array columns in Perl, but it seems like the ODBC driver might be missing some configuration to support transparent array handling. Here's a test script showing the issue:
#!/usr/bin/perl -w
use v5.28;
use strict;
use warnings;
use utf8;
use DBI;
use Test::More;
my $dbh = DBI->connect('dbi:ODBC:Server=clickhouse;Database=default;Driver=ClickHouse', '', '', {
PrintError => 0,
RaiseError => 1,
AutoCommit => 1,
});
END { $dbh->disconnect if $dbh }
$dbh->do(q{
CREATE TABLE IF NOT EXISTS posts (
id INT PRIMARY KEY,
tags Array(TEXT) NOT NULL DEFAULT '[]'
) ENGINE=MergeTree
});
# Try just inserting an array.
eval {
$dbh->do(
'INSERT INTO posts VALUES (?, ?)',
undef, 1, [qw(clickhouse perl)],
);
};
is $@, undef, 'Should have inserted an array';
# Try using an explicit bind param.
my $sth = $dbh->prepare('INSERT INTO posts VALUES (?, ?)');
$sth->bind_param(1, 1);
local $@ = undef;
eval { $sth-> bind_param(2, [qw(clickhouse perl)], { TYPE => DBI::SQL_ARRAY}) };
is $@, undef, 'Should bound an array column';
# local $@ = undef;
# $sth->execute;
# is $@, undef, 'Should have inserted a bound array';
# Insert some tags to select.
$dbh->do(
q{INSERT INTO posts VALUES (?, array('clickhouse', 'perl'))},
undef, 1,
);
# Select the tags column.
my $tags = $dbh->selectcol_arrayref(
'SELECT tags FROM posts WHERE id = ?',
undef, 1,
)->[0];
# It is a string and not an array.
is_deeply $tags, [qw(clickhouse perl)], 'Should have selected an array';
# Try binding again.
$sth = $dbh->prepare('SELECT tags FROM posts WHERE id = ?');
local $@;
eval { $sth->bind_col(1, \$tags, { TYPE => DBI::SQL_ARRAY}) };
is $@, undef, 'Should have inserted an array';
# local $@ = undef;
# $sth->execute;
# is_deeply $tags, [qw(clickhouse perl)], 'Should have selected a bound array';
done_testing;And the output:
array.t ..
not ok 1 - Should have inserted an array
not ok 2 - Should bound an array column
# Failed test 'Should have inserted an array'
# at try.pl line 32.
# got: 'Cannot bind a plain reference at /usr/lib/perl5/x86_64-linux-gnu-thread-multi/DBI.pm line 1630.
# '
# expected: undef
# Failed test 'Should bound an array column'
# at try.pl line 39.
# got: 'cannot bind to non-existent field 2 at try.pl line 38.
# '
# expected: undef
not ok 3 - Should have selected an array
not ok 4 - Should have inserted an array
1..4
# Failed test 'Should have selected an array'
# at try.pl line 56.
# Structures begin differing at:
# $got = '['clickhouse','perl']'
# $expected = ARRAY(0x555556231aa0)
# Failed test 'Should have inserted an array'
# at try.pl line 62.
# got: 'cannot bind to non-existent field 1 at try.pl line 61.
# '
# expected: undef
# Looks like you failed 4 tests of 4.
Dubious, test returned 4 (wstat 1024, 0x400)
Failed 4/4 subtests
Test Summary Report
-------------------
try.pl (Wstat: 1024 (exited 4) Tests: 4 Failed: 4)
Failed tests: 1-4
Non-zero exit status: 4
Files=1, Tests=4, 0 wallclock secs ( 0.01 usr 0.01 sys + 0.13 cusr 0.00 csys = 0.15 CPU)
Result: FAIL
Metadata
Metadata
Assignees
Labels
No labels
Activity
Get all tests passing for ClickHouse
Get all tests passing for ClickHouse
Get all tests passing for ClickHouse
slabko commentedon Apr 18, 2026
@theory which other databases support DBI::SQL_ARRAY? From what I can find, none of the ODBC drivers support this type and instead fall back to VARCHAR.
theory commentedon Apr 18, 2026
Looks like none of the four ODBC drivers that Sqitch uses support it (ClickeHouse, Exasol, Snowflake, Vertica). But I think that of those four only ClickHouse has array columns. For now Sqitch feeds each item as a separate placeholder to the
array()constructor, but it would be very nice to be able to use a single placeholder, and I suspect more efficient.