Committed by Greg Sabino Mullane <[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