[DBD::Pg] 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.
dbdpg-commits-gENoVmVU/[email protected] Fri, 2 Jan 2015 23:58:50 +0000
| Newsgroups | gmane.comp.db.postgresql.dbdpg.cvs |
|---|---|
| Message-ID | <[email protected]> |
Committed by Greg Sabino Mullane <greg-O9fzpki4YnJWk0Htik3J/[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