Skip Menu |

This queue is for tickets about the DBD-SQLite CPAN distribution.

Report information
The Basics
Id: 15711
Status: resolved
Priority: 0/
Queue: DBD-SQLite

People
Owner: Nobody in particular
Requestors: nate [...] verse.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.09
Fixed in: (no value)



Subject: User defined functions cannot return blob values (patch)
User defined functions cannot currently return values that contain NUL's. Effectively, this means that they cannot return blobs. The problem is that dbdimp.c:sqlite_db_set_result() presumes that anything that is not a number is text, and sets the return value with sqlite3_result_text(). This causes bad results for NUL containing values. I've attached a patch that sets the value as a blob if it contains NUL's. While this works for my purposes, I don't know enough about the internals to know if this is a good general solution. A better approach might be to allow the function to explicitly set a return type. Patch attached.
--- dbdimp.c.orig 2005-11-10 19:27:55.000000000 -0700 +++ dbdimp.c 2005-11-10 20:03:14.000000000 -0700 @@ -707,7 +713,13 @@ sqlite3_result_double( context, SvNV(result)); } else { s = SvPV(result, len); - sqlite3_result_text( context, s, len, SQLITE_TRANSIENT ); + if (memchr(s, 0, len)) { + /* if the result contains NUL(s) treat it as a blob */ + sqlite3_result_blob(context, s, len, SQLITE_TRANSIENT ); + } + else { + sqlite3_result_text( context, s, len, SQLITE_TRANSIENT ); + } } }
This should just work. Can you provide a test case? [guest - Fri Nov 11 12:42:20 2005]: Show quoted text
> User defined functions cannot currently return values that contain > NUL's. Effectively, this means that they cannot return blobs. > > The problem is that dbdimp.c:sqlite_db_set_result() presumes that > anything that is not a number is text, and sets the return value > with sqlite3_result_text(). This causes bad results for NUL > containing values. > > I've attached a patch that sets the value as a blob if it contains > NUL's. While this works for my purposes, I don't know enough about > the internals to know if this is a good general solution. A better > approach might be to allow the function to explicitly set a return > type. > > Patch attached.
From: nate [...] verse.com
[MSERGEANT - Mon Dec 5 11:48:39 2005]: Show quoted text
> This should just work. Can you provide a test case?
I just tried 1.11, and indeed this appears to work out of the box. I also tried a fresh compile of 1.09 and can reconfirm that it does fail there. So something else that was changed in 1.10 or 1.11 must have fixed this as a side effect. Attached is a patch to the test suite. With this patch, the test suite passes on 1.11 and fails on 1.09.
--- ../DBD-SQLite-1.09/t/08create_function.t 2004-07-21 14:50:45.000000000 -0600 +++ t/08create_function.t 2005-12-05 09:49:24.000000000 -0700 @@ -1,5 +1,5 @@ use Test; -BEGIN { plan tests => 18 } +BEGIN { plan tests => 19 } use DBI; sub now { @@ -44,6 +44,10 @@ return $_[0]; } +sub return_blob { + return "bl" . "\x00" . "ob"; +} + my $dbh = DBI->connect("dbi:SQLite:dbname=foo", "", "", { PrintError => 0 } ); ok($dbh); @@ -111,4 +115,8 @@ $result = $dbh->selectrow_arrayref( "SELECT noop(1.1)" ); ok( $result && $result->[0] == 1.1 ); +$dbh->func( "return_blob", 0, \&return_blob, "create_function" ); +$result = $dbh->selectrow_arrayref( "SELECT return_blob()" ); +ok( $result && $result->[0] eq return_blob() ); + $dbh->disconnect;