Skip Menu |

This queue is for tickets about the SQL-Statement CPAN distribution.

Report information
The Basics
Id: 6082
Status: resolved
Worked: 2 hours (120 min)
Priority: 0/
Queue: SQL-Statement

People
Owner: JZUCKER [...] cpan.org
Requestors: Dan [...] DWright.Org
Cc:
AdminCc:

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



Subject: Parser can't handle mixture of parens / no parens.
I don't know if this is a bug in SQL::Parser, or SQL::Statement, but I have found while using DBD::AnyData, when you try a query like either of these: SELECT item1, item2, item3 from table1 WHERE (item4 = 'a') AND item5 = 'b'; SELECT item1, item2, item3 from table1 WHERE (item4 = 'a' OR item4 ='b') AND item5 = 'b'; It ignores the item5 = 'b' portion of the query completely. Additionally, if you try this: SELECT item1, item2, item3 from table1 WHERE item5 = 'b' AND (item4 = 'a') It will give you a 'Bad predicate' error. Here is a stack trace from a time when I saw the 'BAD PREDICATE' message: SQL ERROR: Bad predicate: ''! SQL::Parser::do_err('SQL::Parser=HASH(0x8e9976c)', 'Bad predicate: \'\'!') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 1128 SQL::Parser::PREDICATE('SQL::Parser=HASH(0x8e9976c)', '') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 992 SQL::Parser::non_parens_search('SQL::Parser=HASH(0x8e9976c)', '', 'ARRAY(0xa2cddb0)') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 976 SQL::Parser::non_parens_search('SQL::Parser=HASH(0x8e9976c)', '~0~ OR transaction_code = ?2?', 'ARRAY(0xa2cddb0)') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 976 SQL::Parser::non_parens_search('SQL::Parser=HASH(0x8e9976c)', 'statement_category = ?0? AND transaction_code = ?1? OR transacti...', 'ARRAY(0xa2cddb0)') called at/usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 951 SQL::Parser::parens_search('SQL::Parser=HASH(0x8e9976c)', 'statement_category = ?0? AND (transaction_code = ?1? OR transact...', 'ARRAY(0xa2cddb0)') called at/usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 816 SQL::Parser::SEARCH_CONDITION('SQL::Parser=HASH(0x8e9976c)', 'statement_category = ?0? AND (transaction_code = ?1? OR transact...') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 315 SQL::Parser::SELECT('SQL::Parser=HASH(0x8e9976c)', 'SELECT transaction_code,type,statement_category FROM billi ng_tra...') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Parser.pm line 87 SQL::Parser::parse('SQL::Parser=HASH(0x8e9976c)', ' SELECT transaction_code, type, statement_category FROM bil ling_...') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Statement.pm line 98 SQL::Statement::prepare('DBD::AnyData::Statement=HASH(0xa28bee8)', ' SELECT transaction_code, type, statement_ category FROM billing_...', 'SQL::Parser=HASH(0x8e9976c)') called at /usr/local/lib/perl5/site_perl/5.6.1/SQL/Statement.pm line 82 SQL::Statement::new('DBD::AnyData::Statement', ' SELECT transaction_code, type, statement_category FROM billin g_...', 'SQL::Parser=HASH(0x8e9976c)') called at /usr/local/lib/perl5/site_perl/5.6.1/DBD/AnyData.pm line 148 eval {...} called at /usr/local/lib/perl5/site_perl/5.6.1/DBD/AnyData.pm line 148 DBD::AnyData::db::prepare('DBI::db=HASH(0x8c22700)', ' SELECT transaction_code, type, statement_category FROM billing_...')
Thanks for finding this Dan. It's fixed now in version 1.09 (it was a silly quotemeta bug in SQL::Parser). Here's a sample script that tests the cases you mentioned: #!perl -w $|=1; use strict; use Data::Dumper; #use lib qw( ./SQL-Statement/SQL-Statement-1.09/lib ); use DBI; my $dbh=DBI->connect('DBI:AnyData:'); my($populate,$query)=split /~\n+/,join '', <DATA>; $dbh->do($_) for split /\n/, $populate; for my $q(split /\n/,$query) { my $dq = $q; $dq =~ s/.*?(WHERE.*)/$1/; print "\n$dq\n"; my $sth = $dbh->prepare($q); $sth->execute; while (my $r=$sth->fetch) { print join(', ', @$r),"\n"; } } __DATA__ CREATE TABLE t1 (c1 TEXT, c2 TEXT, c3 TEXT) INSERT INTO t1 VALUES (1,'a','b') INSERT INTO t1 VALUES (2,'b','b') INSERT INTO t1 VALUES (3,'a','Z') INSERT INTO t1 VALUES (4,'Z','b') ~ SELECT * FROM t1 SELECT * FROM t1 WHERE c3='b' AND (c2='a') SELECT * FROM t1 WHERE (c2='a') AND c3='b' SELECT * FROM t1 WHERE (c2='a' OR c2='b') AND c3='b' -- Jeff