@@ -178,7 +178,6 @@ static List *overrideStack = NIL;
178
178
* committed its creation, depending on whether myTempNamespace is valid.
179
179
*/
180
180
static Oid myTempNamespace = InvalidOid ;
181
-
182
181
static Oid myTempToastNamespace = InvalidOid ;
183
182
184
183
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId ;
@@ -193,6 +192,7 @@ char *namespace_search_path = NULL;
193
192
/* Local functions */
194
193
static void recomputeNamespacePath (void );
195
194
static void InitTempTableNamespace (void );
195
+ static Oid GetTempTableNamespace (void );
196
196
static void RemoveTempRelations (Oid tempNamespaceId );
197
197
static void RemoveTempRelationsCallback (int code , Datum arg );
198
198
static void NamespaceCallback (Datum arg , int cacheid , uint32 hashvalue );
@@ -460,9 +460,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
460
460
if (strcmp (newRelation -> schemaname , "pg_temp" ) == 0 )
461
461
{
462
462
/* Initialize temp namespace if first time through */
463
- if (!OidIsValid (myTempNamespace ))
464
- InitTempTableNamespace ();
465
- return myTempNamespace ;
463
+ return GetTempTableNamespace ();
466
464
}
467
465
/* use exact schema given */
468
466
namespaceId = get_namespace_oid (newRelation -> schemaname , false);
@@ -471,9 +469,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
471
469
else if (newRelation -> relpersistence == RELPERSISTENCE_TEMP )
472
470
{
473
471
/* Initialize temp namespace if first time through */
474
- if (!OidIsValid (myTempNamespace ))
475
- InitTempTableNamespace ();
476
- return myTempNamespace ;
472
+ return GetTempTableNamespace ();
477
473
}
478
474
else
479
475
{
@@ -482,8 +478,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
482
478
if (activeTempCreationPending )
483
479
{
484
480
/* Need to initialize temp namespace */
485
- InitTempTableNamespace ();
486
- return myTempNamespace ;
481
+ return GetTempTableNamespace ();
487
482
}
488
483
namespaceId = activeCreationNamespace ;
489
484
if (!OidIsValid (namespaceId ))
@@ -2921,9 +2916,7 @@ LookupCreationNamespace(const char *nspname)
2921
2916
if (strcmp (nspname , "pg_temp" ) == 0 )
2922
2917
{
2923
2918
/* Initialize temp namespace if first time through */
2924
- if (!OidIsValid (myTempNamespace ))
2925
- InitTempTableNamespace ();
2926
- return myTempNamespace ;
2919
+ return GetTempTableNamespace ();
2927
2920
}
2928
2921
2929
2922
namespaceId = get_namespace_oid (nspname , false);
@@ -2986,9 +2979,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
2986
2979
if (strcmp (schemaname , "pg_temp" ) == 0 )
2987
2980
{
2988
2981
/* Initialize temp namespace if first time through */
2989
- if (!OidIsValid (myTempNamespace ))
2990
- InitTempTableNamespace ();
2991
- return myTempNamespace ;
2982
+ return GetTempTableNamespace ();
2992
2983
}
2993
2984
/* use exact schema given */
2994
2985
namespaceId = get_namespace_oid (schemaname , false);
@@ -3001,8 +2992,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
3001
2992
if (activeTempCreationPending )
3002
2993
{
3003
2994
/* Need to initialize temp namespace */
3004
- InitTempTableNamespace ();
3005
- return myTempNamespace ;
2995
+ return GetTempTableNamespace ();
3006
2996
}
3007
2997
namespaceId = activeCreationNamespace ;
3008
2998
if (!OidIsValid (namespaceId ))
@@ -3254,16 +3244,28 @@ int
3254
3244
GetTempNamespaceBackendId (Oid namespaceId )
3255
3245
{
3256
3246
int result ;
3257
- char * nspname ;
3247
+ char * nspname ,
3248
+ * addlevel ;
3258
3249
3259
3250
/* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3260
3251
nspname = get_namespace_name (namespaceId );
3261
3252
if (!nspname )
3262
3253
return InvalidBackendId ; /* no such namespace? */
3263
3254
if (strncmp (nspname , "pg_temp_" , 8 ) == 0 )
3264
- result = atoi (nspname + 8 );
3255
+ {
3256
+ /* check for session id */
3257
+ if ((addlevel = strstr (nspname + 8 , "_" )) != NULL )
3258
+ result = atoi (addlevel + 1 );
3259
+ else
3260
+ result = atoi (nspname + 8 );
3261
+ }
3265
3262
else if (strncmp (nspname , "pg_toast_temp_" , 14 ) == 0 )
3266
- result = atoi (nspname + 14 );
3263
+ {
3264
+ if ((addlevel = strstr (nspname + 14 , "_" )) != NULL )
3265
+ result = atoi (addlevel + 1 );
3266
+ else
3267
+ result = atoi (nspname + 14 );
3268
+ }
3267
3269
else
3268
3270
result = InvalidBackendId ;
3269
3271
pfree (nspname );
@@ -3309,8 +3311,11 @@ void
3309
3311
SetTempNamespaceState (Oid tempNamespaceId , Oid tempToastNamespaceId )
3310
3312
{
3311
3313
/* Worker should not have created its own namespaces ... */
3312
- Assert (myTempNamespace == InvalidOid );
3313
- Assert (myTempToastNamespace == InvalidOid );
3314
+ if (!ActiveSession )
3315
+ {
3316
+ Assert (myTempNamespace == InvalidOid );
3317
+ Assert (myTempToastNamespace == InvalidOid );
3318
+ }
3314
3319
Assert (myTempNamespaceSubID == InvalidSubTransactionId );
3315
3320
3316
3321
/* Assign same namespace OIDs that leader has */
@@ -3830,6 +3835,24 @@ recomputeNamespacePath(void)
3830
3835
list_free (oidlist );
3831
3836
}
3832
3837
3838
+ static Oid
3839
+ GetTempTableNamespace (void )
3840
+ {
3841
+ if (ActiveSession )
3842
+ {
3843
+ if (!OidIsValid (ActiveSession -> tempNamespace ))
3844
+ InitTempTableNamespace ();
3845
+ else
3846
+ myTempNamespace = ActiveSession -> tempNamespace ;
3847
+ }
3848
+ else
3849
+ {
3850
+ if (!OidIsValid (myTempNamespace ))
3851
+ InitTempTableNamespace ();
3852
+ }
3853
+ return myTempNamespace ;
3854
+ }
3855
+
3833
3856
/*
3834
3857
* InitTempTableNamespace
3835
3858
* Initialize temp table namespace on first use in a particular backend
@@ -3841,8 +3864,6 @@ InitTempTableNamespace(void)
3841
3864
Oid namespaceId ;
3842
3865
Oid toastspaceId ;
3843
3866
3844
- Assert (!OidIsValid (myTempNamespace ));
3845
-
3846
3867
/*
3847
3868
* First, do permission check to see if we are authorized to make temp
3848
3869
* tables. We use a nonstandard error message here since "databasename:
@@ -3881,7 +3902,12 @@ InitTempTableNamespace(void)
3881
3902
(errcode (ERRCODE_READ_ONLY_SQL_TRANSACTION ),
3882
3903
errmsg ("cannot create temporary tables during a parallel operation" )));
3883
3904
3884
- snprintf (namespaceName , sizeof (namespaceName ), "pg_temp_%d" , MyBackendId );
3905
+ if (ActiveSession )
3906
+ snprintf (namespaceName , sizeof (namespaceName ), "pg_temp_%d_%u" ,
3907
+ ActiveSession -> id , MyBackendId );
3908
+ else
3909
+ snprintf (namespaceName , sizeof (namespaceName ), "pg_temp_%d" ,
3910
+ MyBackendId );
3885
3911
3886
3912
namespaceId = get_namespace_oid (namespaceName , true);
3887
3913
if (!OidIsValid (namespaceId ))
@@ -3913,8 +3939,12 @@ InitTempTableNamespace(void)
3913
3939
* it. (We assume there is no need to clean it out if it does exist, since
3914
3940
* dropping a parent table should make its toast table go away.)
3915
3941
*/
3916
- snprintf (namespaceName , sizeof (namespaceName ), "pg_toast_temp_%d" ,
3917
- MyBackendId );
3942
+ if (ActiveSession )
3943
+ snprintf (namespaceName , sizeof (namespaceName ), "pg_toast_temp_%d_%u" ,
3944
+ ActiveSession -> id , MyBackendId );
3945
+ else
3946
+ snprintf (namespaceName , sizeof (namespaceName ), "pg_toast_temp_%u" ,
3947
+ MyBackendId );
3918
3948
3919
3949
toastspaceId = get_namespace_oid (namespaceName , true);
3920
3950
if (!OidIsValid (toastspaceId ))
@@ -3945,6 +3975,11 @@ InitTempTableNamespace(void)
3945
3975
*/
3946
3976
MyProc -> tempNamespaceId = namespaceId ;
3947
3977
3978
+ if (ActiveSession )
3979
+ {
3980
+ ActiveSession -> tempNamespace = namespaceId ;
3981
+ ActiveSession -> tempToastNamespace = toastspaceId ;
3982
+ }
3948
3983
/* It should not be done already. */
3949
3984
AssertState (myTempNamespaceSubID == InvalidSubTransactionId );
3950
3985
myTempNamespaceSubID = GetCurrentSubTransactionId ();
@@ -3974,6 +4009,11 @@ AtEOXact_Namespace(bool isCommit, bool parallel)
3974
4009
{
3975
4010
myTempNamespace = InvalidOid ;
3976
4011
myTempToastNamespace = InvalidOid ;
4012
+ if (ActiveSession )
4013
+ {
4014
+ ActiveSession -> tempNamespace = InvalidOid ;
4015
+ ActiveSession -> tempToastNamespace = InvalidOid ;
4016
+ }
3977
4017
baseSearchPathValid = false; /* need to rebuild list */
3978
4018
3979
4019
/*
@@ -4121,13 +4161,16 @@ RemoveTempRelations(Oid tempNamespaceId)
4121
4161
static void
4122
4162
RemoveTempRelationsCallback (int code , Datum arg )
4123
4163
{
4124
- if (OidIsValid (myTempNamespace )) /* should always be true */
4164
+ Oid tempNamespace = ActiveSession ?
4165
+ ActiveSession -> tempNamespace : myTempNamespace ;
4166
+
4167
+ if (OidIsValid (tempNamespace )) /* should always be true */
4125
4168
{
4126
4169
/* Need to ensure we have a usable transaction. */
4127
4170
AbortOutOfAnyTransaction ();
4128
4171
StartTransactionCommand ();
4129
4172
4130
- RemoveTempRelations (myTempNamespace );
4173
+ RemoveTempRelations (tempNamespace );
4131
4174
4132
4175
CommitTransactionCommand ();
4133
4176
}
@@ -4137,10 +4180,19 @@ RemoveTempRelationsCallback(int code, Datum arg)
4137
4180
* Remove all temp tables from the temporary namespace.
4138
4181
*/
4139
4182
void
4140
- ResetTempTableNamespace (void )
4183
+ ResetTempTableNamespace (Oid npc )
4141
4184
{
4142
- if (OidIsValid (myTempNamespace ))
4143
- RemoveTempRelations (myTempNamespace );
4185
+ if (OidIsValid (npc ))
4186
+ {
4187
+ AbortOutOfAnyTransaction ();
4188
+ StartTransactionCommand ();
4189
+ RemoveTempRelations (npc );
4190
+ CommitTransactionCommand ();
4191
+ }
4192
+ else
4193
+ /* global */
4194
+ if (OidIsValid (myTempNamespace ))
4195
+ RemoveTempRelations (myTempNamespace );
4144
4196
}
4145
4197
4146
4198
0 commit comments