File: rt_99748.t

package info (click to toggle)
libdbd-sqlite3-perl 1.76-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,004 kB
  • sloc: ansic: 167,715; perl: 1,788; pascal: 277; makefile: 9
file content (151 lines) | stat: -rw-r--r-- 4,483 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use strict;
use warnings;
use lib "t/lib";
use SQLiteTest qw/connect_ok $sqlite_call has_sqlite/;
use Test::More;
use if -d ".git", "Test::FailWarnings";

# tests that the MATCH operator does not allow code injection
my @interpolation_attempts = (
  '@{[die -1]}',
  '(foobar',      # will die - incorrect regex
  '(?{die 999})', # will die - Eval-group not allowed at runtime
  '$foobar',
  '$self->{row_ix}',
  '$main::ARGV[ die 999 ]',
  '@main::ARGV',
  '$0',
  '$self',
 );

# sample data
our $perl_rows = [
  [1, 2, 'three'],
  [4, undef, 'six'  ],
  [7, 8, undef ],
  [10, undef, '}'],
  [11, undef,  '\}'],
  [12, undef,  "data\nhas\tspaces"],
];

my $dbh = connect_ok( RaiseError => 1, AutoCommit => 1 );

# create a regular table so that we can compare results with the virtual table
$dbh->do("CREATE TABLE rtb(a INT, b INT, c TEXT)");
my $sth = $dbh->prepare("INSERT INTO rtb(a, b, c) VALUES (?, ?, ?)");
$sth->execute(@$_) foreach @$perl_rows;

# create the virtual table
ok $dbh->$sqlite_call(create_module =>
                        perl => "DBD::SQLite::VirtualTable::PerlData"),
   "create_module";
ok $dbh->do(<<""), "create vtable";
  CREATE VIRTUAL TABLE vtb USING perl(a INT, b INT, c TEXT,
                                      arrayrefs="main::perl_rows")

# run same tests on both the regular and the virtual table
test_table($dbh, 'rtb');
test_table($dbh, 'vtb');

# the match operator only works on the virtual table
test_match_operator($dbh, 'vtb');

sub test_table {
  my ($dbh, $table) = @_;

  my $sql = "SELECT rowid, * FROM $table";
  my $res = $dbh->selectall_arrayref($sql, {Slice => {}});
  is scalar(@$res), scalar(@$perl_rows), "$sql: got 3 rows";
  is $res->[0]{a}, 1, 'got 1 in a';
  is $res->[0]{b}, 2, 'got undef in b';

  $sql  = "SELECT a FROM $table WHERE b < 8 ORDER BY a";
  $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [1], "got 1 in a";

  $sql = "SELECT rowid FROM $table WHERE c = 'six'";
  $res = $dbh->selectall_arrayref($sql, {Slice => {}});
  is_deeply $res, [{rowid => 2}], $sql;

  $sql = "SELECT a FROM $table WHERE b IS NULL ORDER BY a";
  $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [4, 10, 11, 12], $sql;

  $sql = "SELECT a FROM $table WHERE b IS NOT NULL ORDER BY a";
  $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [1, 7], $sql;

  $sql = "SELECT a FROM $table WHERE c IS NULL ORDER BY a";
  $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [7], $sql;

  $sql = "SELECT a FROM $table WHERE c IS NOT NULL ORDER BY a";
  $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [1, 4, 10, 11, 12], $sql;

  $sql = "SELECT a FROM $table WHERE c = ?";
  $res = $dbh->selectcol_arrayref($sql, {}, '}');
  is_deeply $res, [10], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '\}');
  is_deeply $res, [11], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '\\');
  is_deeply $res, [], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '{');
  is_deeply $res, [], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, undef);
  is_deeply $res, [], $sql;

  if (has_sqlite('3.6.19')) {
    $sql = "SELECT a FROM $table WHERE c IS ?";
    $res = $dbh->selectcol_arrayref($sql, {}, undef);
    is_deeply $res, [7], $sql;

    $sql = "SELECT a FROM $table WHERE c IS NOT ? order by a";
    $res = $dbh->selectcol_arrayref($sql, {}, undef);
    is_deeply $res, [1, 4, 10, 11, 12], $sql;
  }
}

sub test_match_operator {
  my ($dbh, $table) = @_;

  my $sql = "SELECT c FROM $table WHERE c MATCH '^.i' ORDER BY c";
  my $res = $dbh->selectcol_arrayref($sql);
  is_deeply $res, [qw/six/], $sql;

  $sql = "SELECT c FROM $table WHERE c MATCH ? ORDER BY c";
  is_deeply $dbh->selectcol_arrayref($sql, {}, $_) => [], $_
    foreach @interpolation_attempts;

  $sql = "SELECT a FROM $table WHERE c MATCH ?";
  $res = $dbh->selectcol_arrayref($sql, {}, '}');
  is_deeply $res, [10, 11], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '\}');
  is_deeply $res, [10, 11], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '\\\\}');
  is_deeply $res, [11], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '\\\\');
  is_deeply $res, [11], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, "\n");
  is_deeply $res, [12], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, "\t");
  is_deeply $res, [12], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '{');
  is_deeply $res, [], $sql;

  $res = $dbh->selectcol_arrayref($sql, {}, '$x[$y]');
  is_deeply $res, [], $sql;

}

done_testing;