Thread

  1. libpgtcl doesn't use UTF encoding of TCL

    PostgreSQL Bugs List <pgsql-bugs@postgresql.org> — 2001-07-18T08:18:23Z

    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
    
    
    
  2. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-18T15:24:41Z

    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
    
    
  3. Re: libpgtcl doesn't use UTF encoding of TCL

    Reinhard Max <max@suse.de> — 2001-07-18T16:14:59Z

    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
    
    
    
  4. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-18T16:22:14Z

    > 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
    
    
  5. Re: libpgtcl doesn't use UTF encoding of TCL

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-07-18T18:53:22Z

    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
    
    
  6. Re: libpgtcl doesn't use UTF encoding of TCL

    Eugene Fokin <elf@solvo.ru> — 2001-07-19T06:26:59Z

    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
    
    
  7. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-19T10:28:16Z

    > 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
    
    
  8. Re: libpgtcl doesn't use UTF encoding of TCL

    Reinhard Max <max@suse.de> — 2001-07-19T10:44:30Z

    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
    
    
    
    
  9. Re: libpgtcl doesn't use UTF encoding of TCL

    Reinhard Max <max@suse.de> — 2001-07-19T14:05:35Z

    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
    
  10. Re: [BUGS] libpgtcl doesn't use UTF encoding of TCL

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-07-19T17:40:47Z

    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
    
    
  11. libpgtcl and TCL_ARRAYS

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-07-19T18:58:40Z

    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
    
    
  12. Re: [BUGS] libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-20T14:08:33Z

    > 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
    
    
  13. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-20T14:10:04Z

    > 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
    
    
  14. Re: libpgtcl doesn't use UTF encoding of TCL

    Peter Eisentraut <peter_e@gmx.net> — 2001-07-20T14:22:08Z

    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
    
    
    
  15. Re: libpgtcl doesn't use UTF encoding of TCL

    Reinhard Max <max@suse.de> — 2001-07-20T15:09:03Z

    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
    
    
    
  16. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-20T15:16:16Z

    > > 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
    
    
  17. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-20T15:17:26Z

    > 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
    
    
  18. Re: libpgtcl doesn't use UTF encoding of TCL

    Tatsuo Ishii <t-ishii@sra.co.jp> — 2001-07-22T11:10:32Z

    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
    
    > 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
    > 
    
    
  19. Re: libpgtcl doesn't use UTF encoding of TCL

    Eugene Fokin <elf@solvo.ru> — 2001-07-23T07:23:50Z

    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
    
    
  20. Re: libpgtcl doesn't use UTF encoding of TCL

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-09-05T16:52:37Z

    > 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
    
  21. Re: libpgtcl doesn't use UTF encoding of TCL

    Reinhard Max <max@suse.de> — 2001-09-06T09:43:12Z

    Hi Bruce,
    
    On Wed, 5 Sep 2001, Bruce Momjian wrote:
    
    > I have a patch here that handles all the TCL/UTF issues.
    > Would you let me know if it is OK?
    
    I think, it isn't really a clean fix. It only works, if your
    database's encoding and Tcl's system encoding are identical. If the
    database uses a different encoding than Tcl, you still end up with
    wrong characters. Also, the configure switch (if needed at all)
    should IMHO be a disable switch, because the conversion is mandatory
    for Tcl >= 8.1 unless someone really knows that he won't have any
    8-Bit characters in his database. So less people would get bitten, if
    UTF conversion was enabled by default for Tcl >= 8.1 .
    
    Besides these flaws, I think the patch could be simpler and avoid the
    UTF_BEGIN and UTF_END macros if UTF_U2E and UTF_E2U were (maybe
    inlined) functions and defined like this (untested):
    
    char* UTF_U2E(CONST char * source)
    {
    	static Tcl_DString *destPtr = NULL;
    
    	if (destPtr == NULL) {
    		destPtr = (Tcl_DString *) malloc(sizeof(Tcl_DString));
    	} else {
    		Tcl_DStringFree(destPtr);
    	}
    	return Tcl_UtfToExternalDString(NULL, source, -1, destPtr);
    }
    
    
    See also the mail, I sent to pgsql-patches last Tuesday on the same
    topic.
    
    In addition to my suggestion there to require the database to be
    UNICODE for Tcl >= 8.1, I just had another Idea how it could be solved
    cleanly:
    
    What about making --enable-unicode-conversion mandatory when
    PostgreSQL gets compiled with Tcl support and changing PgTcl and
    PL/Tcl to set their client encoding to UNICODE at _runtime_ when they
    find themselfes running with a Tcl interpreter that needs UTF-8 (i.e.
    Tcl >= 8.1)?
    
    Going this way, we could even retain binary compatibility for PgTcl
    and PL/Tcl with Tcl versions prior and after Tcl's move to UTF-8.
    
    One Question remains here: Do --enable-multibyte and
    --enable-unicode-conversion have any downsides (besides a larger
    executable), if they are compiled in, but not used?
    
    cu
    	Reinhard