@@ -98,6 +98,10 @@ static SimpleEcontextStackEntry *simple_econtext_stack = NULL;
9898 *
9999 * The evaluation state trees (cast_exprstate) are managed in the same way as
100100 * simple expressions (i.e., we assume cast expressions are always simple).
101+ *
102+ * As with simple expressions, DO blocks don't use the shared hash table but
103+ * must have their own. This isn't ideal, but we don't want to deal with
104+ * multiple simple_eval_estates within a DO block.
101105 */
102106typedef struct /* lookup key for cast info */
103107{
@@ -118,8 +122,8 @@ typedef struct/* cast_hash table entry */
118122LocalTransactionId cast_lxid ;
119123}plpgsql_CastHashEntry ;
120124
121- static MemoryContext cast_hash_context = NULL ;
122- static HTAB * cast_hash = NULL ;
125+ static MemoryContext shared_cast_context = NULL ;
126+ static HTAB * shared_cast_hash = NULL ;
123127
124128/************************************************************
125129 * Local function forward declarations
@@ -283,7 +287,9 @@ static char *format_preparedparamsdata(PLpgSQL_execstate *estate,
283287 * difference that this code is aware of is that for a DO block, we want
284288 * to use a private simple_eval_estate, which is created and passed in by
285289 * the caller. For regular functions, pass NULL, which implies using
286- * shared_simple_eval_estate.
290+ * shared_simple_eval_estate. (When using a private simple_eval_estate,
291+ * we must also use a private cast hashtable, but that's taken care of
292+ * within plpgsql_estate_setup.)
287293 * ----------
288294 */
289295Datum
@@ -3286,6 +3292,8 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
32863292ReturnSetInfo * rsi ,
32873293EState * simple_eval_estate )
32883294{
3295+ HASHCTL ctl ;
3296+
32893297/* this link will be restored at exit from plpgsql_call_handler */
32903298func -> cur_estate = estate ;
32913299
@@ -3333,11 +3341,44 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
33333341estate -> paramLI -> parserSetupArg = NULL ;/* filled during use */
33343342estate -> paramLI -> numParams = estate -> ndatums ;
33353343
3336- /* set up for use of appropriate simple-expression EState */
3344+ /* set up for use of appropriate simple-expression EStateand cast hash */
33373345if (simple_eval_estate )
3346+ {
33383347estate -> simple_eval_estate = simple_eval_estate ;
3348+ /* Private cast hash just lives in function's main context */
3349+ memset (& ctl ,0 ,sizeof (ctl ));
3350+ ctl .keysize = sizeof (plpgsql_CastHashKey );
3351+ ctl .entrysize = sizeof (plpgsql_CastHashEntry );
3352+ ctl .hcxt = CurrentMemoryContext ;
3353+ estate -> cast_hash = hash_create ("PLpgSQL private cast cache" ,
3354+ 16 ,/* start small and extend */
3355+ & ctl ,
3356+ HASH_ELEM |HASH_BLOBS |HASH_CONTEXT );
3357+ estate -> cast_hash_context = CurrentMemoryContext ;
3358+ }
33393359else
3360+ {
33403361estate -> simple_eval_estate = shared_simple_eval_estate ;
3362+ /* Create the session-wide cast-info hash table if we didn't already */
3363+ if (shared_cast_hash == NULL )
3364+ {
3365+ shared_cast_context = AllocSetContextCreate (TopMemoryContext ,
3366+ "PLpgSQL cast info" ,
3367+ ALLOCSET_DEFAULT_MINSIZE ,
3368+ ALLOCSET_DEFAULT_INITSIZE ,
3369+ ALLOCSET_DEFAULT_MAXSIZE );
3370+ memset (& ctl ,0 ,sizeof (ctl ));
3371+ ctl .keysize = sizeof (plpgsql_CastHashKey );
3372+ ctl .entrysize = sizeof (plpgsql_CastHashEntry );
3373+ ctl .hcxt = shared_cast_context ;
3374+ shared_cast_hash = hash_create ("PLpgSQL cast cache" ,
3375+ 16 ,/* start small and extend */
3376+ & ctl ,
3377+ HASH_ELEM |HASH_BLOBS |HASH_CONTEXT );
3378+ }
3379+ estate -> cast_hash = shared_cast_hash ;
3380+ estate -> cast_hash_context = shared_cast_context ;
3381+ }
33413382
33423383estate -> eval_tuptable = NULL ;
33433384estate -> eval_processed = 0 ;
@@ -6014,32 +6055,12 @@ get_cast_hashentry(PLpgSQL_execstate *estate,
60146055LocalTransactionId curlxid ;
60156056MemoryContext oldcontext ;
60166057
6017- /* Create the session-wide cast-info hash table if we didn't already */
6018- if (cast_hash == NULL )
6019- {
6020- HASHCTL ctl ;
6021-
6022- cast_hash_context = AllocSetContextCreate (TopMemoryContext ,
6023- "PLpgSQL cast info" ,
6024- ALLOCSET_DEFAULT_MINSIZE ,
6025- ALLOCSET_DEFAULT_INITSIZE ,
6026- ALLOCSET_DEFAULT_MAXSIZE );
6027- memset (& ctl ,0 ,sizeof (ctl ));
6028- ctl .keysize = sizeof (plpgsql_CastHashKey );
6029- ctl .entrysize = sizeof (plpgsql_CastHashEntry );
6030- ctl .hcxt = cast_hash_context ;
6031- cast_hash = hash_create ("PLpgSQL cast cache" ,
6032- 16 ,/* start small and extend */
6033- & ctl ,
6034- HASH_ELEM |HASH_BLOBS |HASH_CONTEXT );
6035- }
6036-
60376058/* Look for existing entry */
60386059cast_key .srctype = srctype ;
60396060cast_key .dsttype = dsttype ;
60406061cast_key .srctypmod = srctypmod ;
60416062cast_key .dsttypmod = dsttypmod ;
6042- cast_entry = (plpgsql_CastHashEntry * )hash_search (cast_hash ,
6063+ cast_entry = (plpgsql_CastHashEntry * )hash_search (estate -> cast_hash ,
60436064 (void * )& cast_key ,
60446065HASH_FIND ,NULL );
60456066
@@ -6124,15 +6145,15 @@ get_cast_hashentry(PLpgSQL_execstate *estate,
61246145cast_expr = (Node * )expression_planner ((Expr * )cast_expr );
61256146
61266147/* Now copy the tree into cast_hash_context */
6127- MemoryContextSwitchTo (cast_hash_context );
6148+ MemoryContextSwitchTo (estate -> cast_hash_context );
61286149
61296150cast_expr = copyObject (cast_expr );
61306151}
61316152
61326153MemoryContextSwitchTo (oldcontext );
61336154
61346155/* Now we can fill in a hashtable entry. */
6135- cast_entry = (plpgsql_CastHashEntry * )hash_search (cast_hash ,
6156+ cast_entry = (plpgsql_CastHashEntry * )hash_search (estate -> cast_hash ,
61366157 (void * )& cast_key ,
61376158HASH_ENTER ,& found );
61386159Assert (!found );/* wasn't there a moment ago */
@@ -6154,7 +6175,9 @@ get_cast_hashentry(PLpgSQL_execstate *estate,
61546175 * executions. (We will leak some memory intra-transaction if that
61556176 * happens a lot, but we don't expect it to.) It's okay to update the
61566177 * hash table with the new tree because all plpgsql functions within a
6157- * given transaction share the same simple_eval_estate.
6178+ * given transaction share the same simple_eval_estate. (Well, regular
6179+ * functions do; DO blocks have private simple_eval_estates, and private
6180+ * cast hash tables to go with them.)
61586181 */
61596182curlxid = MyProc -> lxid ;
61606183if (cast_entry -> cast_lxid != curlxid || cast_entry -> cast_in_use )