Committed by Greg Sabino Mullane <[email protected]>

Fix for named placeholders: we have to take into account both the length of the 
potential match and the length of the item we are searching for. Add more tests 
to confirm.

---
 dbdimp.c           |    8 +++++++-
 t/12placeholders.t |   30 +++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/dbdimp.c b/dbdimp.c
index 175ed97..84070d7 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -1911,7 +1911,13 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * 
imp_sth, int version, char
                        sectionsize = currpos-sectionstop;
                        /* Have we seen this placeholder yet? */
                        for (xint=1,thisph=imp_sth->ph; NULL != thisph; 
thisph=thisph->nextph,xint++) {
-                               if (0==strncmp(thisph->fooname, 
statement-sectionsize, sectionsize + 1)) {
+                               /*
+                                 Because we need to make sure :foobar does not 
match as a previous 
+                                  hit when seeing :foobar2, we always use the 
greater of the two lengths:
+                                  the length of the old name or the current 
name we are scanning
+                               */
+                               if (0==strncmp(thisph->fooname, 
statement-sectionsize,
+                                                          
strlen(thisph->fooname) > sectionsize ? strlen(thisph->fooname) : sectionsize)) 
{
                                        newseg->placeholder = xint;
                                        newseg->ph = thisph;
                                        break;
diff --git a/t/12placeholders.t b/t/12placeholders.t
index 1a89d91..e274243 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 => 240;
+plan tests => 243;
 
 my $t='Connect to database for placeholder testing';
 isnt ($dbh, undef, $t);
@@ -121,6 +121,25 @@ eval {
 };
 is ($@, q{}, $t);
 
+## Same, but fiddle with whitespace
+$sql = q{SELECT pname FROM dbd_pg_test WHERE pname = :foobar AND pname = 
:foobar2 AND pname = :foobar2};
+eval {
+       $sth = $dbh->prepare($sql);
+       $sth->bind_param(':foobar', 123);
+       $sth->bind_param(':foobar2', 456);
+       $sth->execute();
+};
+is ($@, q{}, $t);
+
+$sql = q{SELECT pname FROM dbd_pg_test WHERE pname = :foobar AND pname = 
:foobar AND pname = :foobar2 };
+eval {
+       $sth = $dbh->prepare($sql);
+       $sth->bind_param(':foobar', 123);
+       $sth->bind_param(':foobar2', 456);
+       $sth->execute();
+};
+is ($@, q{}, $t);
+
 $t='Execute with repeated named placeholders works';
 $sql = q{SELECT pname FROM dbd_pg_test WHERE pname = :foobar AND pname = 
:foobar };
 eval {
@@ -130,6 +149,15 @@ eval {
 };
 is ($@, q{}, $t);
 
+## Same thing, different whitespace
+$sql = q{SELECT pname FROM dbd_pg_test WHERE pname = :foobar AND pname = 
:foobar};
+eval {
+       $sth = $dbh->prepare($sql);
+       $sth->bind_param(':foobar', 123);
+       $sth->execute();
+};
+is ($@, q{}, $t);
+
 $t='Prepare with large number of parameters works';
 ## Test large number of placeholders
 $sql = 'SELECT 1 FROM dbd_pg_test WHERE id IN (' . '?,' x 300 . '?)';
-- 
1.7.1

Reply via email to