libpgtcl doesn't use UTF encoding of TCL

Started by PostgreSQL Bugs Listover 24 years ago21 messageshackersbugs
Jump to latest
#1PostgreSQL Bugs List
pgsql-bugs@postgresql.org
hackersbugs

Eugene Faukin (elf@solvo.ru) reports a bug with a severity of 2
The lower the number the more severe it is.

Short Description
libpgtcl doesn't use UTF encoding of TCL

Long Description
Modern versions of the TCL (8.2 at least) use UTF encoding to internal
storage of the text. libpgtcl uses TCL functions to insert strings directly
into TCL internal structure without any conversion.

Sample Code
I can suggest you next patch I use for myself:

diff -uNr postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c
--- postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c   Wed Apr 12 21:17:11 2000
+++ postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c        Thu Nov 16 20:26:37 2000
@@ -431,6 +431,7 @@
        Pg_ConnectionId *connid;
        PGconn     *conn;
        PGresult   *result;
+       Tcl_DString putString;

if (argc != 3)
{
@@ -449,7 +450,9 @@
return TCL_ERROR;
}

-       result = PQexec(conn, argv[2]);
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);

/* Transfer any notify events from libpq to Tcl event queue. */
PgNotifyTransferEvents(connid);
@@ -535,6 +538,7 @@
char *arrVar;
char nameBuffer[256];
const char *appendstr;
+ Tcl_DString retString;

        if (argc < 3 || argc > 5)
        {
@@ -685,11 +689,24 @@
                }
 #ifdef TCL_ARRAYS
                for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i)));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
 #else
                for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQgetvalue(result, tupno, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            PQgetvalue(result, tupno, i),
+                                            -1, &retString);
+               
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
 #endif
+               Tcl_DStringFree(&retString);
                return TCL_OK;
        }
        else if (strcmp(opt, "-tupleArray") == 0)
@@ -707,21 +724,35 @@
                }
                for (i = 0; i < PQnfields(result); i++)
                {
-                       if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                   Tcl_ExternalToUtfDString(NULL, 
 #ifdef TCL_ARRAYS
-                                                       tcl_value(PQgetvalue(result, tupno, i)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
 #else
-                                                       PQgetvalue(result, tupno, i),
+                                            PQgetvalue(result, tupno, i),
 #endif
-                                                       TCL_LEAVE_ERR_MSG) == NULL)
-                               return TCL_ERROR;
+                                            -1, &retString);
+
+                   if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                                   Tcl_DStringValue(&retString),
+                                   TCL_LEAVE_ERR_MSG) == NULL)
+                   {
+                       Tcl_DStringFree(&retString);
+                       return TCL_ERROR;
+                   }
                }
+               Tcl_DStringFree(&retString);
                return TCL_OK;
        }
        else if (strcmp(opt, "-attributes") == 0)
        {
                for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQfname(result, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL, PQfname(result, i),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+                   Tcl_DStringFree(&retString);
+               }
                return TCL_OK;
        }
        else if (strcmp(opt, "-lAttributes") == 0)
@@ -1274,6 +1305,8 @@
                                column,
                                ncols;
        Tcl_DString headers;
+       Tcl_DString retString;
+       Tcl_DString putString;
        char            buffer[2048];
        struct info_s
        {
@@ -1292,7 +1325,11 @@
        if (conn == (PGconn *) NULL)
                return TCL_ERROR;
-       if ((result = PQexec(conn, argv[2])) == 0)
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);
+
+       if (result == 0)
        {
                /* error occurred sending the query */
                Tcl_SetResult(interp, PQerrorMessage(conn), TCL_VOLATILE);
@@ -1340,13 +1377,21 @@
                Tcl_SetVar2(interp, argv[3], ".tupno", buffer, 0);
                for (column = 0; column < ncols; column++)
-                       Tcl_SetVar2(interp, argv[3], info[column].cname,
+               {
+                   Tcl_ExternalToUtfDString(NULL,
 #ifdef TCL_ARRAYS
-                                               tcl_value(PQgetvalue(result, tupno, column)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno,
+                                                                 column)),
 #else
-                                               PQgetvalue(result, tupno, column),
+                                            PQgetvalue(result, tupno, column),
 #endif
-                                               0);
+                                            -1, &retString);
+
+                   Tcl_SetVar2(interp, argv[3], info[column].cname,
+                               Tcl_DStringValue(&retString), 0);
+                   Tcl_DStringFree(&retString);
+               }

Tcl_SetVar2(interp, argv[3], ".command", "update", 0);

No file was uploaded with this report

#2Bruce Momjian
bruce@momjian.us
In reply to: PostgreSQL Bugs List (#1)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

Do you have any idea how this will work with earlier TCL versions? When
was Tcl_UtfToExternalDString added to TCL?

Eugene Faukin (elf@solvo.ru) reports a bug with a severity of 2
The lower the number the more severe it is.

Short Description
libpgtcl doesn't use UTF encoding of TCL

Long Description
Modern versions of the TCL (8.2 at least) use UTF encoding to internal
storage of the text. libpgtcl uses TCL functions to insert strings directly
into TCL internal structure without any conversion.

Sample Code
I can suggest you next patch I use for myself:

diff -uNr postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c
--- postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c   Wed Apr 12 21:17:11 2000
+++ postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c        Thu Nov 16 20:26:37 2000
@@ -431,6 +431,7 @@
Pg_ConnectionId *connid;
PGconn     *conn;
PGresult   *result;
+       Tcl_DString putString;

if (argc != 3)
{
@@ -449,7 +450,9 @@
return TCL_ERROR;
}

-       result = PQexec(conn, argv[2]);
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);

/* Transfer any notify events from libpq to Tcl event queue. */
PgNotifyTransferEvents(connid);
@@ -535,6 +538,7 @@
char *arrVar;
char nameBuffer[256];
const char *appendstr;
+ Tcl_DString retString;

if (argc < 3 || argc > 5)
{
@@ -685,11 +689,24 @@
}
#ifdef TCL_ARRAYS
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i)));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
#else
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQgetvalue(result, tupno, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            PQgetvalue(result, tupno, i),
+                                            -1, &retString);
+               
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
#endif
+               Tcl_DStringFree(&retString);
return TCL_OK;
}
else if (strcmp(opt, "-tupleArray") == 0)
@@ -707,21 +724,35 @@
}
for (i = 0; i < PQnfields(result); i++)
{
-                       if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                   Tcl_ExternalToUtfDString(NULL, 
#ifdef TCL_ARRAYS
-                                                       tcl_value(PQgetvalue(result, tupno, i)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
#else
-                                                       PQgetvalue(result, tupno, i),
+                                            PQgetvalue(result, tupno, i),
#endif
-                                                       TCL_LEAVE_ERR_MSG) == NULL)
-                               return TCL_ERROR;
+                                            -1, &retString);
+
+                   if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                                   Tcl_DStringValue(&retString),
+                                   TCL_LEAVE_ERR_MSG) == NULL)
+                   {
+                       Tcl_DStringFree(&retString);
+                       return TCL_ERROR;
+                   }
}
+               Tcl_DStringFree(&retString);
return TCL_OK;
}
else if (strcmp(opt, "-attributes") == 0)
{
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQfname(result, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL, PQfname(result, i),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+                   Tcl_DStringFree(&retString);
+               }
return TCL_OK;
}
else if (strcmp(opt, "-lAttributes") == 0)
@@ -1274,6 +1305,8 @@
column,
ncols;
Tcl_DString headers;
+       Tcl_DString retString;
+       Tcl_DString putString;
char            buffer[2048];
struct info_s
{
@@ -1292,7 +1325,11 @@
if (conn == (PGconn *) NULL)
return TCL_ERROR;
-       if ((result = PQexec(conn, argv[2])) == 0)
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);
+
+       if (result == 0)
{
/* error occurred sending the query */
Tcl_SetResult(interp, PQerrorMessage(conn), TCL_VOLATILE);
@@ -1340,13 +1377,21 @@
Tcl_SetVar2(interp, argv[3], ".tupno", buffer, 0);
for (column = 0; column < ncols; column++)
-                       Tcl_SetVar2(interp, argv[3], info[column].cname,
+               {
+                   Tcl_ExternalToUtfDString(NULL,
#ifdef TCL_ARRAYS
-                                               tcl_value(PQgetvalue(result, tupno, column)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno,
+                                                                 column)),
#else
-                                               PQgetvalue(result, tupno, column),
+                                            PQgetvalue(result, tupno, column),
#endif
-                                               0);
+                                            -1, &retString);
+
+                   Tcl_SetVar2(interp, argv[3], info[column].cname,
+                               Tcl_DStringValue(&retString), 0);
+                   Tcl_DStringFree(&retString);
+               }

Tcl_SetVar2(interp, argv[3], ".command", "update", 0);

No file was uploaded with this report

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#3Reinhard Max
max@suse.de
In reply to: Bruce Momjian (#2)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

When was Tcl_UtfToExternalDString added to TCL?

According to Tcl's changelog files, it was added in 1997 for Tcl 8.1
wich was released in 1999.

cu
Reinhard Max

Maintainer of the Tcl/Tk and PostgreSQL packages for SuSE Linux

#4Bruce Momjian
bruce@momjian.us
In reply to: Reinhard Max (#3)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Can't we probe the TCL version in the code and handle it that way?

When was Tcl_UtfToExternalDString added to TCL?

According to Tcl's changelog files, it was added in 1997 for Tcl 8.1
wich was released in 1999.

Shame. I think we could have required Tcl 8.X but clearly we can't be
requring >= 8.1. I have 8.0 here and I am sure many do as well.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Reinhard Max (#3)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch. We really don't want to give up
backwards compatibility just yet.

regards, tom lane

#6Eugene Fokin
elf@solvo.ru
In reply to: Tom Lane (#5)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, Jul 18, 2001 at 02:53:22PM -0400, Tom Lane wrote:

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch. We really don't want to give up
backwards compatibility just yet.

Thank you, gentlemans :-)
I will be interest with this result too.

--
Eugene Faukin
SOLVO Ltd. Company

#7Bruce Momjian
bruce@momjian.us
In reply to: Eugene Fokin (#6)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, Jul 18, 2001 at 02:53:22PM -0400, Tom Lane wrote:

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch. We really don't want to give up
backwards compatibility just yet.

Thank you, gentlemans :-)
I will be interest with this result too.

I believe $tcl_version is what you want to use to test.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#8Reinhard Max
max@suse.de
In reply to: Tom Lane (#5)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Tom Lane wrote:

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch.

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

Can anybody tell me, if that TCL_ARRAYS stuff is still good for
something? If I could remove it, TCL_UTF8 would be less complex at
some places, because I'd only have to cover two instead of four cases.

BTW, I think the proposed Patch doesn't go far enough as it assumes
the database (client) encoding is identical to the system encoding by
using NULL as the first argument for Tcl_UtfToExternalDString and
Tcl_ExternalToUtfDString. I think it should instead either use the
database's encoding for the conversion to be correct or set
PostgreSQL's client encoding to UNICODE so that no conversion would be
needed. Unfortunately, I don't have the time to do that at the moment.

We really don't want to give up backwards compatibility just yet.

How far do you want it to be backwards compatible? If >= 8.0 is OK,
I'll possibly overwork libpq later this year to use Tcl's object
interface. I expect at least some performance gain out of this.

cu
Reinhard

#9Reinhard Max
max@suse.de
In reply to: Tom Lane (#5)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Tom Lane wrote:

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch.

Here it is, but I consider it still incomplete and I have not done
exhaustive testing. Some more occurrences of PQexec and PQgetvalue
need to be wrapped up with UTF8 conversion, but I'll not have the time
to do it for the next 1-2 weeks.

cu
Reinhard

Attachments:

pgtcl-utf8.patchtext/plain; charset=US-ASCII; name=pgtcl-utf8.patchDownload+123-4
#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Reinhard Max (#8)
hackersbugs
Re: [BUGS] libpgtcl doesn't use UTF encoding of TCL

Reinhard Max <max@suse.de> writes:

[ concerning libpgtcl ]
We really don't want to give up backwards compatibility just yet.

How far do you want it to be backwards compatible? If >= 8.0 is OK,
I'll possibly overwork libpq later this year to use Tcl's object
interface. I expect at least some performance gain out of this.

That's been on the to-do list for awhile, but we haven't really faced up
to the question of whether Tcl 7.* compatibility is still important to
retain. I can see three plausible paths:

1. Drop 7.* compatibility, rework code to use 8.0 object interfaces.

2. Rework code to use object interfaces #if TCL >= 8.0, else not.

3. Build a separate, new implementation that's only for Tcl >= 8.0,
but leave the old code available as a separate library.

My guess is that #2 would uglify the code to the point of
unmaintainability --- but I haven't really looked to see how extensive
the changes might be; perhaps it'd be workable. #3 would create a
different sort of maintainability issue, namely updating two parallel
sets of code when there were common bugs. Probably the old code would
get dropped at some future time anyway, so that ultimately #3 becomes
#1.

I don't have a strong opinion about what to do. I've cc'd this to
pgsql-interfaces, maybe we can get some comments there. Does anyone
still use/care about Tcl 7.* ?

regards, tom lane

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Reinhard Max (#8)
hackersbugs
libpgtcl and TCL_ARRAYS

Reinhard Max <max@suse.de> writes:

Can anybody tell me, if that TCL_ARRAYS stuff is still good for
something? If I could remove it, TCL_UTF8 would be less complex at
some places, because I'd only have to cover two instead of four cases.

TCL_ARRAYS is a kluge in my humble opinion, but we haven't really
settled on something better --- in particular, the challenge is to
fix it without breaking other things. See the mailing list archives
for prior discussions, notably the thread starting at

http://fts.postgresql.org/db/mw/msg.html?mid=40589

Unless you want to tackle the problem of providing a replacement
feature, I'd recommend just adding the extra code :-(

regards, tom lane

#12Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#10)
hackersbugs
Re: [BUGS] libpgtcl doesn't use UTF encoding of TCL

My guess is that #2 would uglify the code to the point of
unmaintainability --- but I haven't really looked to see how extensive
the changes might be; perhaps it'd be workable. #3 would create a
different sort of maintainability issue, namely updating two parallel
sets of code when there were common bugs. Probably the old code would
get dropped at some future time anyway, so that ultimately #3 becomes
#1.

I don't have a strong opinion about what to do. I've cc'd this to
pgsql-interfaces, maybe we can get some comments there. Does anyone
still use/care about Tcl 7.* ?

BSD/OS still ships with 7.5 but I have requested 8.0 in the next
release. Let's see what happens. BSD/OS is usually up on the newer
stuff so it is strange they have held back. I think part of the problem
is that everyone is not happy with how TCL went with 8.1+ so many have
held back on upgrading and are still on 7.5 or 8.0.5. My guess is
considering the number of platforms we support that we will have to keep
7.5 perhaps another year. Part of the problem is that we haven't had
any complaints about the 7.5-supported functionality.

I have 8.0.5 custom-installed here. I agree dropping 7.5 support is the
only reasonable option rather than ifdef or separate files.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#13Bruce Momjian
bruce@momjian.us
In reply to: Reinhard Max (#8)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Tom Lane wrote:

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch.

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

Is the TCL_UTF8 some variable that gets set at tcl runtime? I hope so.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#14Peter Eisentraut
peter_e@gmx.net
In reply to: Reinhard Max (#8)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

Reinhard Max writes:

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

No, please add a configure check for Tcl_UtfToExternalDString or some
other function representative of this interface..

--
Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter

#15Reinhard Max
max@suse.de
In reply to: Peter Eisentraut (#14)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Fri, 20 Jul 2001, Peter Eisentraut wrote:

Reinhard Max writes:

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

No, please add a configure check for Tcl_UtfToExternalDString or
some other function representative of this interface..

Why make simple things complicated?
Tcl changed it's internal string representation starting with release
8.1 . It is not an interface one can decide whether to use it or not.
Every extension that imports or exports strings and gets compiled for
Tcl >= 8.1 has to make sure that they are UTF8 regardless, if it uses
the Tcl_*Utf*DString functions or something else. So I consider it
sufficient to define TCL_UTF8 if Tcl's Version is >= 8.1 as I did in
the patch that was attached to my last mail.

cu
Reinhard

#16Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#13)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Tom Lane wrote:

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch.

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

Is the TCL_UTF8 some variable that gets set at tcl runtime? I hope so.

I now realize we can't have this configure at runtime. It has to read
the tcl include file for the version it is about to be linked to.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#17Bruce Momjian
bruce@momjian.us
In reply to: Reinhard Max (#15)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Fri, 20 Jul 2001, Peter Eisentraut wrote:

Reinhard Max writes:

OK, I'll pack the new stuff inside #ifdef TCL_UTF8 and define that if
the Tcl version is 8.1 or greater.

No, please add a configure check for Tcl_UtfToExternalDString or
some other function representative of this interface..

Why make simple things complicated?
Tcl changed it's internal string representation starting with release
8.1 . It is not an interface one can decide whether to use it or not.
Every extension that imports or exports strings and gets compiled for
Tcl >= 8.1 has to make sure that they are UTF8 regardless, if it uses
the Tcl_*Utf*DString functions or something else. So I consider it
sufficient to define TCL_UTF8 if Tcl's Version is >= 8.1 as I did in
the patch that was attached to my last mail.

I think he is OK checking the TCL version. It is pretty common to check
the TCL include file for symbols and handle things that way. Do we test
any other TCL include defines from configure?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#18Tatsuo Ishii
t-ishii@sra.co.jp
In reply to: PostgreSQL Bugs List (#1)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

Hum. Why don't you enable --enable-multibyte and
--enable-unicode-conversion and set client_encoding to UNICODE? That
would do a conversion from/to UTF-8 for Tcl 8.x (x > 9) clients?
--
Tatsuo Ishii

Show quoted text

Eugene Faukin (elf@solvo.ru) reports a bug with a severity of 2
The lower the number the more severe it is.

Short Description
libpgtcl doesn't use UTF encoding of TCL

Long Description
Modern versions of the TCL (8.2 at least) use UTF encoding to internal
storage of the text. libpgtcl uses TCL functions to insert strings directly
into TCL internal structure without any conversion.

Sample Code
I can suggest you next patch I use for myself:

diff -uNr postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c
--- postgresql-7.0.2.orig/src/interfaces/libpgtcl/pgtclCmds.c   Wed Apr 12 21:17:11 2000
+++ postgresql-7.0.2/src/interfaces/libpgtcl/pgtclCmds.c        Thu Nov 16 20:26:37 2000
@@ -431,6 +431,7 @@
Pg_ConnectionId *connid;
PGconn     *conn;
PGresult   *result;
+       Tcl_DString putString;

if (argc != 3)
{
@@ -449,7 +450,9 @@
return TCL_ERROR;
}

-       result = PQexec(conn, argv[2]);
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);

/* Transfer any notify events from libpq to Tcl event queue. */
PgNotifyTransferEvents(connid);
@@ -535,6 +538,7 @@
char *arrVar;
char nameBuffer[256];
const char *appendstr;
+ Tcl_DString retString;

if (argc < 3 || argc > 5)
{
@@ -685,11 +689,24 @@
}
#ifdef TCL_ARRAYS
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i)));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
#else
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQgetvalue(result, tupno, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL,
+                                            PQgetvalue(result, tupno, i),
+                                            -1, &retString);
+               
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+               }
#endif
+               Tcl_DStringFree(&retString);
return TCL_OK;
}
else if (strcmp(opt, "-tupleArray") == 0)
@@ -707,21 +724,35 @@
}
for (i = 0; i < PQnfields(result); i++)
{
-                       if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                   Tcl_ExternalToUtfDString(NULL, 
#ifdef TCL_ARRAYS
-                                                       tcl_value(PQgetvalue(result, tupno, i)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno, i)),
#else
-                                                       PQgetvalue(result, tupno, i),
+                                            PQgetvalue(result, tupno, i),
#endif
-                                                       TCL_LEAVE_ERR_MSG) == NULL)
-                               return TCL_ERROR;
+                                            -1, &retString);
+
+                   if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+                                   Tcl_DStringValue(&retString),
+                                   TCL_LEAVE_ERR_MSG) == NULL)
+                   {
+                       Tcl_DStringFree(&retString);
+                       return TCL_ERROR;
+                   }
}
+               Tcl_DStringFree(&retString);
return TCL_OK;
}
else if (strcmp(opt, "-attributes") == 0)
{
for (i = 0; i < PQnfields(result); i++)
-                       Tcl_AppendElement(interp, PQfname(result, i));
+               {
+                   Tcl_ExternalToUtfDString(NULL, PQfname(result, i),
+                                            -1, &retString);
+                   Tcl_AppendElement(interp, Tcl_DStringValue(&retString));
+                   Tcl_DStringFree(&retString);
+               }
return TCL_OK;
}
else if (strcmp(opt, "-lAttributes") == 0)
@@ -1274,6 +1305,8 @@
column,
ncols;
Tcl_DString headers;
+       Tcl_DString retString;
+       Tcl_DString putString;
char            buffer[2048];
struct info_s
{
@@ -1292,7 +1325,11 @@
if (conn == (PGconn *) NULL)
return TCL_ERROR;
-       if ((result = PQexec(conn, argv[2])) == 0)
+       Tcl_UtfToExternalDString(NULL, argv[2], -1, &putString);
+       result = PQexec(conn, Tcl_DStringValue(&putString));
+       Tcl_DStringFree(&putString);
+
+       if (result == 0)
{
/* error occurred sending the query */
Tcl_SetResult(interp, PQerrorMessage(conn), TCL_VOLATILE);
@@ -1340,13 +1377,21 @@
Tcl_SetVar2(interp, argv[3], ".tupno", buffer, 0);
for (column = 0; column < ncols; column++)
-                       Tcl_SetVar2(interp, argv[3], info[column].cname,
+               {
+                   Tcl_ExternalToUtfDString(NULL,
#ifdef TCL_ARRAYS
-                                               tcl_value(PQgetvalue(result, tupno, column)),
+                                            tcl_value(PQgetvalue(result,
+                                                                 tupno,
+                                                                 column)),
#else
-                                               PQgetvalue(result, tupno, column),
+                                            PQgetvalue(result, tupno, column),
#endif
-                                               0);
+                                            -1, &retString);
+
+                   Tcl_SetVar2(interp, argv[3], info[column].cname,
+                               Tcl_DStringValue(&retString), 0);
+                   Tcl_DStringFree(&retString);
+               }

Tcl_SetVar2(interp, argv[3], ".command", "update", 0);

No file was uploaded with this report

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

#19Eugene Fokin
elf@solvo.ru
In reply to: Tatsuo Ishii (#18)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Sun, Jul 22, 2001 at 08:10:32PM +0900, Tatsuo Ishii wrote:

Hum. Why don't you enable --enable-multibyte and
--enable-unicode-conversion and set client_encoding to UNICODE? That
would do a conversion from/to UTF-8 for Tcl 8.x (x > 9) clients?

You're right. Probably, this way correct enough too :-)
Thank you for suggest.
But, I think, patching the libpgtcl has not to be superfluous.

--
Eugene Faukin
SOLVO Ltd. Company

#20Bruce Momjian
bruce@momjian.us
In reply to: Reinhard Max (#9)
hackersbugs
Re: libpgtcl doesn't use UTF encoding of TCL

On Wed, 18 Jul 2001, Tom Lane wrote:

Reinhard Max <max@suse.de> writes:

On Wed, 18 Jul 2001, Bruce Momjian wrote:

Do you have any idea how this will work with earlier TCL versions?

It won't. If pgtcl is supposed to still be able to compile with older
versions of Tcl, the changes have to be made a compile time option.

Please do that and resubmit the patch.

Here it is, but I consider it still incomplete and I have not done
exhaustive testing. Some more occurrences of PQexec and PQgetvalue
need to be wrapped up with UTF8 conversion, but I'll not have the time
to do it for the next 1-2 weeks.

cu
Reinhard

I have a patch here that handles all the TCL/UTF issues. Would you let
me know if it is OK?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Attachments:

/bjm/difftext/plainDownload+74-11
#21Reinhard Max
max@suse.de
In reply to: Bruce Momjian (#20)
hackersbugs