Committed by =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <[email protected]>
Subject: [DBD::Pg 2/8] Add support for UTF-8 statement strings
---
dbdimp.c | 5 ++++-
dbdimp.h | 4 ++--
t/30unicode.t | 58 ++++++++++++++++++++++++++++++++++++----------------------
3 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/dbdimp.c b/dbdimp.c
index fed72bd..59e2f61 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -1530,13 +1530,16 @@ SV * pg_db_pg_notifies (SV * dbh, imp_dbh_t * imp_dbh)
/* ================================================================== */
-int dbd_st_prepare (SV * sth, imp_sth_t * imp_sth, char * statement, SV *
attribs)
+int dbd_st_prepare_sv (SV * sth, imp_sth_t * imp_sth, SV * statement_sv, SV *
attribs)
{
dTHX;
D_imp_dbh_from_sth;
STRLEN mypos=0, wordstart, newsize; /* Used to find and set firstword */
SV **svp; /* To help parse the arguments */
+ statement_sv = pg_rightgraded_sv(aTHX_ statement_sv,
imp_dbh->client_encoding_utf8);
+ char *statement = SvPV_nolen(statement_sv);
+
if (TSTART_slow) TRC(DBILOGFP, "%sBegin dbd_st_prepare (statement:
%s)\n", THEADER_slow, statement);
if ('\0' == *statement)
diff --git a/dbdimp.h b/dbdimp.h
index abc082a..5e4f72f 100644
--- a/dbdimp.h
+++ b/dbdimp.h
@@ -158,8 +158,8 @@ int dbd_st_STORE_attrib (SV * sth, imp_sth_t * imp_sth, SV
* keysv, SV * valuesv
#define dbd_discon_all pg_discon_all
int dbd_discon_all (SV * drh, imp_drh_t * imp_drh);
-#define dbd_st_prepare pg_st_prepare
-int dbd_st_prepare (SV * sth, imp_sth_t * imp_sth, char * statement, SV *
attribs);
+#define dbd_st_prepare_sv pg_st_prepare_sv
+int dbd_st_prepare_sv (SV * sth, imp_sth_t * imp_sth, SV * statement_sv, SV *
attribs);
#define dbd_bind_ph pg_bind_ph
int dbd_bind_ph (SV * sth, imp_sth_t * imp_sth, SV * ph_name, SV * newvalue,
IV sql_type, SV * attribs, int is_inout, IV maxlen);
diff --git a/t/30unicode.t b/t/30unicode.t
index ad45fc5..bec7d12 100644
--- a/t/30unicode.t
+++ b/t/30unicode.t
@@ -9,7 +9,7 @@ use strict;
use warnings;
use utf8;
use charnames ':full';
-use Encode;
+use Encode qw(encode_utf8);
use Test::More;
use lib 't','.';
require 'dbdpg_test_setup.pl';
@@ -29,33 +29,47 @@ my $name_d = my $name_u = "\N{LATIN CAPITAL LETTER E WITH
ACUTE}milie du Ch\N{LA
utf8::downgrade($name_d);
utf8::upgrade($name_u);
+# Before 5.12.0 the text to the left of => gets to be SvUTF8() under use utf8;
+# even if it's plain ASCII. This would confuse what we test for below.
foreach (
- [upgraded => text => $name_u],
- [downgraded => text => $name_d],
+ [upgraded => 'text' => $name_u],
+ [downgraded => 'text' => $name_d],
[upgraded => 'text[]' => [$name_u]],
[downgraded => 'text[]' => [$name_d]],
[mixed => 'text[]' => [$name_d,$name_u]],
) {
my ($state, $type, $value) = @$_;
- $dbh->{pg_enable_utf8} = 1;
-
- my $SQL = "SELECT ?::$type";
- my $sth = $dbh->prepare($SQL);
- $sth->execute($value);
- my $result = $sth->fetchall_arrayref->[0][0];
- $t = "Fetching $state UTF-8 $type from the database returns proper value";
- is_deeply ($result, $value, $t);
- $t = "Fetching $state UTF-8 $type from the database returns string with
UTF-8 flag on";
- ok (utf8::is_utf8($_), $t) for (ref $result ? @{$result} : $result);
-
- $dbh->{pg_enable_utf8} = 0;
- $sth->execute($value);
- $result = $sth->fetchall_arrayref->[0][0];
- $t = "Fetching $state UTF-8 $type from the database returns proper string
(pg_enable_utf8=0)";
- utf8::encode($_) for (ref $value ? @{$value} : $value);
- is_deeply ($result, $value, $t);
- $t = "Fetching $state UTF-8 $type from the database returns string with
UTF-8 flag off (pg_enable_utf8=0)";
- ok (!utf8::is_utf8($result), $t) for (ref $result ? @{$result} : $result);
+ foreach (
+ [placeholder => "SELECT ?::$type", $value],
+ (($type eq 'text') ? (
+ [interpolated => "SELECT '$value'::$type"],
+ ):()),
+ ) {
+ foreach my $enable_utf8 (1, 0) {
+ my ($qtype, $sql, @args) = @$_;
+ my $desc = "$state UTF-8 $qtype $type
(pg_enable_utf8=$enable_utf8)";
+ is(utf8::is_utf8($sql), ($state eq 'upgraded'), "$desc query has
correct flag")
+ if $qtype eq 'interpolated';
+ if ($state ne 'mixed') {
+ foreach my $arg (map { ref($_) ? @{$_} : $_ } @args) {
+ is(utf8::is_utf8($arg), ($state eq 'upgraded'), "$desc arg
has correct flag")
+ }
+ }
+ $dbh->{pg_enable_utf8} = $enable_utf8;
+
+ my $sth = $dbh->prepare($sql);
+ $sth->execute(@args);
+ my $result = $sth->fetchall_arrayref->[0][0];
+ my $return_value =
+ $enable_utf8 ? $value :
+ ref $value ? [ map encode_utf8($_), @{$value} ] :
+ encode_utf8($value);
+ $t = "$desc returns proper value";
+ is_deeply ($result, $return_value, $t);
+ $t = "$desc returns string with correct UTF-8 flag ";
+ is(utf8::is_utf8($_), !!$enable_utf8, $t) for (ref $result ?
@{$result} : $result);
+ }
+ }
}
$t = 'Generated string is not utf8';
--
1.8.4