Committed by Greg Sabino Mullane <[email protected]>
Add a call to $dbh->{pg_placeholder_escapes} = 0 as an
emergency measure in case the new backslash escape system breaks something.
It is very unlikely to do so - and this will probably be removed entirely
after a few versions.
---
Pg.pm | 1 +
dbdimp.c | 21 +++++++++++++++++----
dbdimp.h | 1 +
t/12placeholders.t | 14 ++++++++++++--
4 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/Pg.pm b/Pg.pm
index 703f882..948db96 100644
--- a/Pg.pm
+++ b/Pg.pm
@@ -1584,6 +1584,7 @@ use 5.008001;
pg_pid => undef,
pg_placeholder_dollaronly => undef,
pg_placeholder_nocolons => undef,
+ pg_placeholder_escapes => undef,
pg_port => undef,
pg_prepare_now => undef,
pg_protocol => undef,
diff --git a/dbdimp.c b/dbdimp.c
index c90d561..543b7c5 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -237,6 +237,7 @@ int dbd_db_login6 (SV * dbh, imp_dbh_t * imp_dbh, char *
dbname, char * uid, cha
imp_dbh->done_begin = DBDPG_FALSE;
imp_dbh->dollaronly = DBDPG_FALSE;
imp_dbh->nocolons = DBDPG_FALSE;
+ imp_dbh->ph_escaped = DBDPG_TRUE;
imp_dbh->expand_array = DBDPG_TRUE;
imp_dbh->txn_read_only = DBDPG_FALSE;
imp_dbh->pid_number = getpid();
@@ -970,6 +971,14 @@ int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV
* keysv, SV * valuesv
}
break;
+ case 22: /* pg_placeholder_escaped */
+
+ if (strEQ("pg_placeholder_escaped", key)) {
+ imp_dbh->ph_escaped = newval ? DBDPG_TRUE : DBDPG_FALSE;
+ retval = 1;
+ }
+ break;
+
case 23: /* pg_placeholder_nocolons */
if (strEQ("pg_placeholder_nocolons", key)) {
@@ -1979,15 +1988,19 @@ static void pg_st_split_statement (pTHX_ imp_sth_t *
imp_sth, int version, char
continue;
}
- /* If this placeholder is escaped, we rewrite the string to
remove the
- backslash, and move on as if there is no placeholder */
- if ('\\' == oldch) {
+ /*
+ If this placeholder is escaped, we rewrite the string to
remove the
+ backslash, and move on as if there is no placeholder.
+ The use of $dbh->{pg_placeholder_escaped} = 0 is left as an
emergency measure.
+ It will probably be removed at some point.
+ */
+ if ('\\' == oldch && imp_dbh->ph_escaped) {
/* copy the placeholder-like character but ignore the
backslash */
unsigned char *p = statement-2;
while(*p++) {
*(p-1) = *p;
}
- /* We need to adjust these items because we just
rewrote statement! */
+ /* We need to adjust these items because we just
rewrote 'statement'! */
statement--;
currpos--;
ch = *statement;
diff --git a/dbdimp.h b/dbdimp.h
index 5bddc3a..06af917 100644
--- a/dbdimp.h
+++ b/dbdimp.h
@@ -37,6 +37,7 @@ struct imp_dbh_st {
bool done_begin; /* have we done a begin? (e.g. are we in a
transaction?) */
bool dollaronly; /* only consider $1, $2 ... as valid
placeholders */
bool nocolons; /* do not consider :1, :2 ... as valid
placeholders */
+ bool ph_escaped; /* allow backslash to escape placeholders */
bool expand_array; /* transform arrays from the db into Perl
arrays? Default is 1 */
bool txn_read_only; /* are we in read-only mode? Set with
$dbh->{ReadOnly} */
diff --git a/t/12placeholders.t b/t/12placeholders.t
index cfd7164..254903d 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 => 253;
+plan tests => 254;
my $t='Connect to database for placeholder testing';
isnt ($dbh, undef, $t);
@@ -867,7 +867,17 @@ eval {
is($@, '', $t);
$sth->finish();
-## pg_placeholder_escaping = 1;
+## This is an emergency hatch only. Hopefully will never be used in the wild!
+$dbh->{pg_placeholder_escaped} = 0;
+$t = q{Basic placeholder escaping fails when pg_placeholder_escaped is set to
false};
+$SQL = qq{SELECT count(*) FROM dbd_pg_test WHERE pname \\?\\? ?};
+$sth = $dbh->prepare($SQL);
+eval {
+ $count = $sth->execute('foobar');
+};
+like($@, qr{execute}, $t);
+$sth->finish();
+
## Begin custom type testing
--
1.8.4