Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e7dcfd0

Browse files
committed
Apply Tcl_Init() to the "hold" interpreter created by pltcl.
You might think this is unnecessary since that interpreter is never used to run code --- but it turns out that's wrong. As of Tcl 8.5, the "clock" command (alone among builtin Tcl commands) is partially implemented by loaded-on-demand Tcl code, which means that it fails if there's not unknown-command support, and also that it's impossible to run it directly in a safe interpreter. The way they get around the latter is that Tcl_CreateSlave() automatically sets up an alias command that forwards any execution of "clock" in a safe slave interpreter to its parent interpreter. Thus, when attempting to execute "clock" in trusted pltcl, the command actually executes in the "hold" interpreter, where it will fail if unknown-command support hasn't been introduced by sourcing the standard init.tcl script, which is done by Tcl_Init(). (This is a pretty dubious design decision on the Tcl boys' part, if you ask me ... but they didn't.) Back-patch all the way. It's not clear that anyone would try to use ancient versions of pltcl with a recent Tcl, but it's not clear they wouldn't, either. Also add a regression test using "clock", in branches that have regression test support for pltcl. Per recent trouble report from Kyle Bateman.
1 parent 56cbb61 commit e7dcfd0

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

src/pl/tcl/expected/pltcl_setup.out

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,23 @@ CREATE OPERATOR CLASS tcl_int4_ops
495495
OPERATOR 4 @>=,
496496
OPERATOR 5 @>,
497497
FUNCTION 1 tcl_int4cmp(int4,int4) ;
498+
--
499+
-- Test usage of Tcl's "clock" command. In recent Tcl versions this
500+
-- command fails without working "unknown" support, so it's a good canary
501+
-- for initialization problems.
502+
--
503+
create function tcl_date_week(int4,int4,int4) returns text as $$
504+
return [clock format [clock scan "$2/$3/$1"] -format "%U"]
505+
$$ language pltcl immutable;
506+
select tcl_date_week(2010,1,24);
507+
tcl_date_week
508+
---------------
509+
04
510+
(1 row)
511+
512+
select tcl_date_week(2001,10,24);
513+
tcl_date_week
514+
---------------
515+
42
516+
(1 row)
517+

src/pl/tcl/pltcl.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* pltcl.c - PostgreSQL support for Tcl as
33
* procedural language (PL)
44
*
5-
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.129 2009/12/31 19:41:37 tgl Exp $
5+
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.130 2010/01/25 01:58:13 tgl Exp $
66
*
77
**********************************************************************/
88

@@ -304,9 +304,12 @@ _PG_init(void)
304304
************************************************************/
305305
if ((pltcl_hold_interp = Tcl_CreateInterp()) == NULL)
306306
elog(ERROR, "could not create \"hold\" interpreter");
307+
if (Tcl_Init(pltcl_hold_interp) == TCL_ERROR)
308+
elog(ERROR, "could not initialize \"hold\" interpreter");
307309

308310
/************************************************************
309-
* Create the two interpreters
311+
* Create the two slave interpreters. Note: Tcl automatically does
312+
* Tcl_Init on the normal slave, and it's not wanted for the safe slave.
310313
************************************************************/
311314
if ((pltcl_norm_interp =
312315
Tcl_CreateSlave(pltcl_hold_interp, "norm", 0)) == NULL)

src/pl/tcl/sql/pltcl_setup.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,15 @@ CREATE OPERATOR CLASS tcl_int4_ops
542542
OPERATOR 4 @>=,
543543
OPERATOR 5 @>,
544544
FUNCTION 1 tcl_int4cmp(int4,int4) ;
545+
546+
--
547+
-- Test usage of Tcl's "clock" command. In recent Tcl versions this
548+
-- command fails without working "unknown" support, so it's a good canary
549+
-- for initialization problems.
550+
--
551+
create function tcl_date_week(int4,int4,int4) returns text as $$
552+
return [clock format [clock scan "$2/$3/$1"] -format "%U"]
553+
$$ language pltcl immutable;
554+
555+
select tcl_date_week(2010,1,24);
556+
select tcl_date_week(2001,10,24);

0 commit comments

Comments
 (0)