2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; version 2 of the License.
6
# This program is distributed in the hope that it will be useful, but
7
# WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# General Public License for more details.
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
16
package GenTest::Transform::ConvertLiteralsToSubqueries;
19
@ISA = qw(GenTest GenTest::Transform);
24
use GenTest::Transform;
25
use GenTest::Constants;
30
my ($class, $orig_query, $executor) = @_;
33
if ($initialized != 1) {
34
my $dbh = $executor->dbh();
35
$dbh->do("CREATE DATABASE IF NOT EXISTS literals");
36
$dbh->do("CREATE TABLE IF NOT EXISTS literals.integers (i1 INTEGER NOT NULL PRIMARY KEY)");
37
foreach my $i (-128..256) {
38
$dbh->do("INSERT IGNORE INTO literals.integers VALUES ($i)");
41
$dbh->do("CREATE TABLE IF NOT EXISTS literals.strings (s1 VARCHAR(255) NOT NULL PRIMARY KEY)");
46
# We skip LIMIT queries because LIMIT N can not be converted into LIMIT ( SELECT ... )
47
return STATUS_WONT_HANDLE if $orig_query =~ m{LIMIT}sio;
48
return STATUS_WONT_HANDLE if $orig_query =~ m{GROUP BY \d}sio;
49
return STATUS_WONT_HANDLE if $orig_query =~ m{ORDER BY \d}sio;
51
my @transformed_queries;
54
my $new_integer_query = $orig_query;
57
# We do not want to match "integers" in parts of dates, times, etc.
58
# Thus only using those that are followed by certain characters or space.
59
if ( $new_integer_query =~ m{\s+(\d+)(\s|\)|,|;)} ) {
60
$new_integer_query =~ s{\s+(\d+)}{
61
push @integer_literals, $1;
62
" (SELECT i1 FROM literals.integers WHERE i1 = $1 ) ";
66
if ($new_integer_query ne $orig_query) {
67
push @transformed_queries, [
68
"INSERT IGNORE INTO literals.integers VALUES ".join(",", map { "($_)" } @integer_literals).";",
69
$new_integer_query." /* TRANSFORM_OUTCOME_UNORDERED_MATCH */"
75
my $new_string_query = $orig_query;
78
$new_string_query =~ s{\s+'(.+?)'}{
79
push @string_literals, $1;
80
" (SELECT s1 FROM literals.strings WHERE s1 = '$1' ) ";
83
if ($new_string_query ne $orig_query) {
84
push @transformed_queries, [
85
"INSERT IGNORE INTO literals.strings VALUES ".join(",", map { "('$_')" } @string_literals).";",
86
$new_string_query." /* TRANSFORM_OUTCOME_UNORDERED_MATCH */"
91
if ($#transformed_queries > -1) {
92
return \@transformed_queries;
94
return STATUS_WONT_HANDLE;