[DBD::Pg 2/2] Ensure that number-colon-number is always ignored as a potential placeholder. Should allow array[1:2] to start working as expected again.
dbdpg-commits-gENoVmVU/[email protected] Sun, 18 May 2014 15:31:29 +0000
| Newsgroups | gmane.comp.db.postgresql.dbdpg.cvs |
|---|---|
| Message-ID | <[email protected]> |
Committed by Greg Sabino Mullane <greg-O9fzpki4YnJWk0Htik3J/[email protected]> Subject: [DBD::Pg 2/2] Ensure that number-colon-number is always ignored as a potential placeholder. Should allow array[1:2] to start working as expected again. --- dbdimp.c | 34 ++++++++++++++++++++++++++-------- t/12placeholders.t | 13 +++++++++++-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/dbdimp.c b/dbdimp.c index bfc8a44..476eae7 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -1699,6 +1699,8 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char unsigned char ch; /* The current character being checked */ + unsigned char oldch; /* The previous character */ + char quote; /* Current quote or comment character: used only in those two blocks */ bool found; /* Simple boolean */ @@ -1754,7 +1756,7 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char /* Start everyone at the start of the string */ currpos = sectionstart = 0; - ch = 1; + ch = oldch = 1; while (1) { @@ -1763,6 +1765,9 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char break; } + /* Store the old character in case we need to look backwards */ + oldch = ch; + /* Put the current letter into ch, and advance statement to the next character */ ch = *statement++; @@ -1771,12 +1776,14 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char /* Quick short-circuit for uninteresting characters */ if ( - (ch < 34 && ch != 0) || (ch > 63 && ch != 91) || - (ch!=34 && ch!=39 && /* simple quoting */ - ch!=45 && ch!=47 && /* comment */ - ch!=36 && /* dollar quoting or placeholder */ - ch!=58 && ch!=63 && /* placeholder */ - ch!=91 && /* array slice */ + (ch < 34 && ch != 0) + || (ch > 63 && ch != 91) /* > @ABC... but not [ */ + || + (ch!=34 && ch!=39 && /* " ' simple quoting */ + ch!=45 && ch!=47 && /* - / comment */ + ch!=36 && /* $ dollar quoting or placeholder */ + ch!=58 && ch!=63 && /* : ? placeholder */ + ch!=91 && /* [ array slice */ ch!=0 /* end of the string (create segment) */ ) ) { @@ -1982,8 +1989,9 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char if ('?' == ch) { placeholder_type = 1; } - /* Colon style, but skip two colons in a row (e.g. myval::float) */ + /* Colon style */ else if (':' == ch && ! imp_sth->nocolons) { + /* Skip two colons in a row (e.g. myval::float) */ if (':' == *statement) { /* Might as well skip _all_ consecutive colons */ while(':' == *statement) { @@ -1992,6 +2000,16 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * imp_sth, int version, char } continue; } + /* Skip number-colon-number */ + if (isDIGIT(oldch) && isDIGIT(*statement)) { + /* Eat until we don't see a number */ + while (isDIGIT(*statement)) { + ++statement; + ++currpos; + } + continue; + } + /* Only allow colon placeholders if they start with alphanum */ if (isALNUM(*statement)) { while(isALNUM(*statement)) { ++statement; diff --git a/t/12placeholders.t b/t/12placeholders.t index 386f02f..c81bd43 100644 --- a/t/12placeholders.t +++ b/t/12placeholders.t @@ -17,7 +17,7 @@ my $dbh = connect_database(); if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 250; +plan tests => 251; my $t='Connect to database for placeholder testing'; isnt ($dbh, undef, $t); @@ -555,13 +555,22 @@ like ($@, qr{unbound placeholder}, $t); $t=q{Value of placeholder_nocolons defaults to 0}; is ($dbh->{pg_placeholder_nocolons}, 0, $t); -$t='Without placeholder_nocolons, queries with array slices fail'; +$t='Simple array slices do not get picked up as placeholders'; $SQL = q{SELECT argh[1:2] FROM dbd_pg_test_geom WHERE id = ?}; eval { $sth = $dbh->prepare($SQL); $sth->execute(1); $sth->finish(); }; +is ($@, q{}, $t); + +$t='Without placeholder_nocolons, queries with array slices fail'; +$SQL = q{SELECT argh[1 :2] FROM dbd_pg_test_geom WHERE id = ?}; +eval { + $sth = $dbh->prepare($SQL); + $sth->execute(1); + $sth->finish(); +}; like ($@, qr{Cannot mix placeholder styles}, $t); $t='Use of statement level placeholder_nocolons allows use of ? placeholders while ignoring :'; -- 1.8.4