Skip Menu |

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

Report information
The Basics
Id: 81060
Status: resolved
Priority: 0/
Queue: SQLite-VirtualTable

People
Owner: Nobody in particular
Requestors: BENBOOTH [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.06
Fixed in: (no value)



Subject: SQLite::VirtualTable not usable from within DBD::SQLite
Trying to use SQLite::VirtualTable's perlvtab.so library from within DBD::SQLite causes strange things to happen. I attached a testcase which fails with the following output: Can't make DBI com handle for DBD::SQLite::st: unknown package. However, the DBD::SQLite::st package is defined. If I run the test script in the perl debugger and single step through it, I get this: Usage: Term::ReadLine::Gnu::Var::_rl_fetch_iostream(id). I think what's happening is that there is already a perl interpreter loaded, but when perlvtab.so is loaded by DBD::SQLite, it attempts to re-initialize the perl interpreter. I noticed the following lines in perlvtab.c: PERL_SYS_INIT3(&ac, &av, &env); perl_construct(my_perl); perl_parse(my_perl, xs_init, ac, av, env); perl_run(my_perl); If perlvtab.so is run from within a context where there is already a perl interpreter loaded, it should simply use that interpreter and not attempt to re-initialize. This could be done with some kind of check before initializing perl again to make sure it's not already running. I think that might fix this problem.
Here are the test files.
Subject: test
Download test
application/octet-stream 6b

Message body not shown because it is not plain text.

Subject: test.pl
#!/usr/bin/env perl use DBI; use strict; use warnings; my $dbh = DBI->connect("dbi:SQLite::memory:", undef, undef, { RaiseError=>1, PrintError=>1, }); # load the virtual table extension $dbh->sqlite_enable_load_extension(1); $dbh->sqlite_load_extension('perlvtab.so'); my $sth = $dbh->prepare('create virtual table test using perl ("SQLite::VirtualTable::CSV","test");'); $sth->execute; my $sth2 = $dbh->prepare('select * from test;'); $sth2->execute;
I fixed the bug and have attached the patch to perlvtab.c. The problem was that perlvtab.c wasn't using Perl_get_context() PERL_SET_CONTEXT to switch between the main perl context and the SQLite::VirtualTable context. Here is a page with more information: http://perldoc.perl.org/perlembed.html#Maintaining-multiple-interpreter-instances The patch should allow SQLite::VirtualTable to be used in conjunction with DBD::SQLite.
Subject: perlvtab.patch
--- /Users/bbooth/Downloads/SQLite-VirtualTable-0.06/perlvtab.c 2012-10-18 17:08:41.000000000 -0700 +++ perlvtab.c 2012-11-13 11:23:34.000000000 -0800 @@ -4,9 +4,6 @@ #include "perl.h" #include "XSUB.h" -#include <unistd.h> -extern char **environ; - #define NEED_newRV_noinc #define NEED_sv_2pv_nolen #include "ppport.h" @@ -15,11 +12,20 @@ SQLITE_EXTENSION_INIT1 #ifdef MULTIPLICITY -# define my_dTHX(a) pTHXx = ((PerlInterpreter*)(a)) +# define my_dTHX(a) \ + PerlInterpreter *main_perl = Perl_get_context(); \ + pTHXx = ((PerlInterpreter*)(a)); \ + PERL_SET_CONTEXT(my_perl); +# define my_dTHX_end \ + if (main_perl != NULL) \ + PERL_SET_CONTEXT(main_perl); #else # define my_dTHX(a) dNOOP +# define my_dTHX_end dNOOP #endif +extern char **environ; + typedef struct _perl_vtab { sqlite3_vtab base; SV *sv; @@ -139,7 +145,8 @@ FREETMPS; LEAVE; - + my_dTHX_end; + return rc; } @@ -192,6 +199,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -232,6 +240,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -308,6 +317,7 @@ FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -349,6 +359,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -464,6 +475,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -506,6 +518,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -540,6 +553,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -603,6 +617,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -674,6 +689,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -721,6 +737,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -769,6 +786,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -804,6 +822,7 @@ cleanup: FREETMPS; LEAVE; + my_dTHX_end; return rc; } @@ -847,15 +866,26 @@ int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { +#ifdef MULTIPLICITY + PerlInterpreter *main_perl = Perl_get_context(); +#endif PerlInterpreter *my_perl = perl_alloc(); int ac = 3; char **av = argv; char **env = environ; PERL_SYS_INIT3(&ac, &av, &env); +#ifdef MULTIPLICITY + PERL_SET_CONTEXT(my_perl); +#endif perl_construct(my_perl); perl_parse(my_perl, xs_init, ac, av, env); perl_run(my_perl); +#ifdef MULTIPLICITY + if (main_perl != NULL) + PERL_SET_CONTEXT(main_perl); +#endif + SQLITE_EXTENSION_INIT2(pApi) sqlite3_create_module(db, "perl", &perlModule, my_perl);
fixed in 0.07