From 8f8741d1b75d68e8e2883ea85229a97d5c5604e3 Mon Sep 17 00:00:00 2001 From: SATO Kentaro Date: Tue, 14 Mar 2017 00:20:56 +0900 Subject: [PATCH] fix zero-length BLOB value is retrieved as undef --- dbdimp.c | 3 ++- t/20_blobs.t | 29 ++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/dbdimp.c b/dbdimp.c index e287d73..c35e1f0 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -1176,7 +1176,8 @@ sqlite_st_fetch(SV *sth, imp_sth_t *imp_sth) case SQLITE_BLOB: sqlite_trace(sth, imp_sth, 5, form("fetch column %d as blob", i)); len = sqlite3_column_bytes(imp_sth->stmt, i); - sv_setpvn(AvARRAY(av)[i], sqlite3_column_blob(imp_sth->stmt, i), len); + val = (char*)sqlite3_column_blob(imp_sth->stmt, i); + sv_setpvn(AvARRAY(av)[i], len ? val : "", len); SvUTF8_off(AvARRAY(av)[i]); break; default: diff --git a/t/20_blobs.t b/t/20_blobs.t index dbd5b6a..28830d0 100644 --- a/t/20_blobs.t +++ b/t/20_blobs.t @@ -10,7 +10,7 @@ BEGIN { } use t::lib::SQLiteTest; -use Test::More tests => 10; +use Test::More tests => 17; use Test::NoWarnings; use DBI ':sql_types'; @@ -42,7 +42,7 @@ $dbh->{sqlite_handle_binary_nulls} = 1; ok( $dbh->do(<<'END_SQL'), 'CREATE TABLE' ); CREATE TABLE one ( id INTEGER NOT NULL, - name BLOB (128) NOT NULL + name BLOB (128) ) END_SQL @@ -58,20 +58,31 @@ for ( my $i = 0; $i < 128; $i++ ) { # Insert a row into the test table SCOPE: { - my $sth = $dbh->prepare("INSERT INTO one VALUES ( 1, ? )"); + my $sth = $dbh->prepare("INSERT INTO one VALUES ( ?, ? )"); isa_ok( $sth, 'DBI::st' ); - ok( $sth->bind_param(1, $blob, SQL_BLOB), '->bind_param' ); + ok( $sth->bind_param(1, 1), '->bind_param' ); + ok( $sth->bind_param(2, $blob, SQL_BLOB), '->bind_param' ); + ok( $sth->execute, '->execute' ); + + ok( $sth->bind_param(1, 2), '->bind_param' ); + ok( $sth->bind_param(2, '', SQL_BLOB), '->bind_param' ); + ok( $sth->execute, '->execute' ); + + ok( $sth->bind_param(1, 3), '->bind_param' ); + ok( $sth->bind_param(2, undef, SQL_BLOB), '->bind_param' ); ok( $sth->execute, '->execute' ); } # Now, try SELECT'ing the row out. SCOPE: { - my $sth = $dbh->prepare("SELECT * FROM one WHERE id = 1"); + my $sth = $dbh->prepare("SELECT * FROM one ORDER BY id"); isa_ok( $sth, 'DBI::st' ); ok( $sth->execute, '->execute' ); - ok( - $sth->fetchrow_arrayref->[1] eq $blob, - 'Got the blob back ok', - ); + my $rows = $sth->fetchall_arrayref; + is_deeply( $rows, [ + [ 1, $blob ], + [ 2, '' ], + [ 3, undef ], + ], 'Got the blob back ok' ); ok( $sth->finish, '->finish' ); }