From 96325b1916f07965ff9e9137ea5e0bc0fc760b37 Mon Sep 17 00:00:00 2001 From: Laurent Dami Date: Fri, 4 Jul 2014 11:25:37 +0200 Subject: [PATCH] test case for RT#96878 : inserting into a contentless FTS table OK without bind values NOK with bind values ("constraint failed") In the end, it's not really a bug, but rather a matter of usage pattern --- MANIFEST | 1 + t/rt_96878_fts_contentless_table.t | 58 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 t/rt_96878_fts_contentless_table.t diff --git a/MANIFEST b/MANIFEST index 3c64cec..a69fb5e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -105,6 +105,7 @@ t/rt_77724_primary_key_with_a_whitespace.t t/rt_78833_utf8_flag_for_column_names.t t/rt_81536_multi_column_primary_key_info.t t/rt_88228_sqlite_3_8_0_crash.t +t/rt_96878_fts_contentless_table.t typemap util/getsqlite.pl xt/meta.t diff --git a/t/rt_96878_fts_contentless_table.t b/t/rt_96878_fts_contentless_table.t new file mode 100644 index 0000000..b64cf10 --- /dev/null +++ b/t/rt_96878_fts_contentless_table.t @@ -0,0 +1,58 @@ +#!/usr/bin/perl + +# In a contentless FTS table, the columns are hidden from the schema, +# and therefore SQLite has no information to infer column types, so +# these are typed as SQLITE_NULL ... and this type conflicts with the +# constraint on the 'docid' column. So we have to explicitly type that +# column, using a CAST expression or a call to bind_param(). + +# TMP HACK +use lib ".."; +use lib "../blib/arch"; +use lib "../lib"; + + +use strict; +BEGIN { + $| = 1; + $^W = 1; +} + +use t::lib::Test; +use Test::More; +use DBI qw/SQL_INTEGER/; +plan tests => 8; +use Test::NoWarnings; + +my $dbh = connect_ok(RaiseError => 1, AutoCommit => 1); + +# $dbh->trace(15); + +my $sql = q{CREATE VIRTUAL TABLE foo USING fts4 (content="", a, b)}; +ok( $dbh->do($sql), 'CREATE TABLE' ); + + +ok($dbh->do("INSERT INTO foo(docid, a, b) VALUES(1, 'a', 'b')"), + "insert without bind"); + +# The following yields a constraint error because docid is improperly typed +# $dbh->do("INSERT INTO foo(docid, a, b) VALUES(?, ?, ?)", {}, qw/2 aa bb/); + +# This works, thanks to the cast expression +ok($dbh->do("INSERT INTO foo(docid, a, b) VALUES(CAST(? AS INTEGER), ?, ?)", + {}, qw/2 aa bb/), + "insert with bind and cast"); + +# This also works, thanks to the bind_param() call +my $sth = $dbh->prepare("INSERT INTO foo(docid, a, b) VALUES(?, ?, ?)"); +$sth->bind_param(1, 3, SQL_INTEGER); +$sth->bind_param(2, "aaa"); +$sth->bind_param(3, "bbb"); +ok($sth->execute(), + "insert with bind_param and explicit type "); + +# Check that all terms were properly inserted +ok( $dbh->do("CREATE VIRTUAL TABLE foo_aux USING fts4aux(foo)"), 'FTS4AUX'); +my $data = $dbh->selectcol_arrayref("select term from foo_aux where col='*'"); +is_deeply ([sort @$data], [qw/a aa aaa b bb bbb/], "terms properly indexed"); +