Skip to content

Commit a5f91fe

Browse files
committed
Fix overly-enthusiastic parenthesis unroller (RT#99503)
1 parent 187f46d commit a5f91fe

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

Changes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
Revision history for SQL::Abstract
22

3+
- Fix overly-enthusiastic parenthesis unroller (RT#99503)
4+
35
revision 1.80 2014-10-05
46
----------------------------
57
- Fix erroneous behavior of is_literal_value($) wrt { -ident => ... }

Makefile.PL

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ requires 'Exporter' => '5.57';
2222
requires 'MRO::Compat' => '0.12';
2323
requires 'Moo' => '1.004002';
2424
requires 'Hash::Merge' => '0.12';
25+
requires 'Text::Balanced' => '2.00';
2526

2627
test_requires "Test::More" => '0.88';
2728
test_requires "Test::Exception" => '0.31';

lib/SQL/Abstract.pm

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,8 +1242,29 @@ sub _where_field_IN {
12421242
# adding them back in the corresponding method
12431243
sub _open_outer_paren {
12441244
my ($self, $sql) = @_;
1245-
$sql = $1 while $sql =~ /^ \s* \( (.*) \) \s* $/xs;
1246-
return $sql;
1245+
1246+
while ( my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs ) {
1247+
1248+
# there are closing parens inside, need the heavy duty machinery
1249+
# to reevaluate the extraction starting from $sql (full reevaluation)
1250+
if ( $inner =~ /\)/ ) {
1251+
require Text::Balanced;
1252+
1253+
my (undef, $remainder) = do {
1254+
# idiotic design - writes to $@ but *DOES NOT* throw exceptions
1255+
local $@;
1256+
Text::Balanced::extract_bracketed( $sql, '()', qr/\s*/ );
1257+
};
1258+
1259+
# the entire expression needs to be a balanced bracketed thing
1260+
# (after an extract no remainder sans trailing space)
1261+
last if defined $remainder and $remainder =~ /\S/;
1262+
}
1263+
1264+
$sql = $inner;
1265+
}
1266+
1267+
$sql;
12471268
}
12481269

12491270

t/05in_between.t

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ my @in_between_tests = (
174174
bind => [],
175175
test => '-in multi-line subquery test',
176176
},
177+
178+
# check that the outer paren opener is not too agressive
179+
# note: this syntax *is not legal* on SQLite (maybe others)
180+
# see end of https://rt.cpan.org/Ticket/Display.html?id=99503
181+
{
182+
where => { foo => { -in => \ '(SELECT 1) UNION (SELECT 2)' } },
183+
stmt => 'WHERE foo IN ( (SELECT 1) UNION (SELECT 2) )',
184+
bind => [],
185+
test => '-in paren-opening works on balanced pairs only',
186+
},
187+
177188
{
178189
where => {
179190
customer => { -in => \[

0 commit comments

Comments
 (0)