Skip to content

Commit 50a2c9f

Browse files
author
Commitfest Bot
committed
[CF 5379] v5 - Fix bug with accessing to temporary tables of other sessions
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5379 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CAJDiXghdFcZ8=nh4G69te7iRr3Q0uFyXxb3ZdG09_GTNZXwH0g@mail.gmail.com Author(s): Daniil Davydov
2 parents 039bfc4 + e483d14 commit 50a2c9f

File tree

5 files changed

+55
-23
lines changed

5 files changed

+55
-23
lines changed

src/backend/catalog/namespace.c

+36-20
Original file line numberDiff line numberDiff line change
@@ -499,28 +499,44 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
499499
*/
500500
if (relation->relpersistence == RELPERSISTENCE_TEMP)
501501
{
502-
if (!OidIsValid(myTempNamespace))
503-
relId = InvalidOid; /* this probably can't happen? */
504-
else
505-
{
506-
if (relation->schemaname)
507-
{
508-
Oid namespaceId;
502+
Oid namespaceId;
509503

510-
namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
504+
if (relation->schemaname)
505+
{
506+
namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
511507

508+
/*
509+
* If the user has specified an existing temporary schema
510+
* owned by another user.
511+
*/
512+
if (OidIsValid(namespaceId) && namespaceId != myTempNamespace)
513+
{
512514
/*
513-
* For missing_ok, allow a non-existent schema name to
514-
* return InvalidOid.
515+
* We don't allow users to access temp tables of other
516+
* sessions except for the case of dropping tables.
515517
*/
516-
if (namespaceId != myTempNamespace)
518+
if (!(flags & RVR_OTHER_TEMP_OK))
517519
ereport(ERROR,
518-
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
519-
errmsg("temporary tables cannot specify a schema name")));
520+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
521+
errmsg("could not access temporary relations of other sessions")));
520522
}
523+
}
524+
else
525+
{
526+
namespaceId = myTempNamespace;
521527

522-
relId = get_relname_relid(relation->relname, myTempNamespace);
528+
/*
529+
* If this table was recognized as temporary, it means that we
530+
* found it because backend's temporary namespace was specified
531+
* in search_path. Thus, MyTempNamespace must contain valid oid.
532+
*/
533+
Assert(OidIsValid(namespaceId));
523534
}
535+
536+
if (missing_ok && !OidIsValid(namespaceId))
537+
relId = InvalidOid;
538+
else
539+
relId = get_relname_relid(relation->relname, namespaceId);
524540
}
525541
else if (relation->schemaname)
526542
{
@@ -3553,21 +3569,19 @@ get_namespace_oid(const char *nspname, bool missing_ok)
35533569
RangeVar *
35543570
makeRangeVarFromNameList(const List *names)
35553571
{
3556-
RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3572+
RangeVar *rel;
35573573

35583574
switch (list_length(names))
35593575
{
35603576
case 1:
3561-
rel->relname = strVal(linitial(names));
3577+
rel = makeRangeVar(NULL, strVal(linitial(names)), -1);
35623578
break;
35633579
case 2:
3564-
rel->schemaname = strVal(linitial(names));
3565-
rel->relname = strVal(lsecond(names));
3580+
rel = makeRangeVar(strVal(linitial(names)), strVal(lsecond(names)), -1);
35663581
break;
35673582
case 3:
3583+
rel = makeRangeVar(strVal(lsecond(names)), strVal(lthird(names)), -1);
35683584
rel->catalogname = strVal(linitial(names));
3569-
rel->schemaname = strVal(lsecond(names));
3570-
rel->relname = strVal(lthird(names));
35713585
break;
35723586
default:
35733587
ereport(ERROR,
@@ -3774,6 +3788,8 @@ GetTempNamespaceProcNumber(Oid namespaceId)
37743788
return INVALID_PROC_NUMBER; /* no such namespace? */
37753789
if (strncmp(nspname, "pg_temp_", 8) == 0)
37763790
result = atoi(nspname + 8);
3791+
else if (strcmp(nspname, "pg_temp") == 0)
3792+
result = MyProcNumber;
37773793
else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
37783794
result = atoi(nspname + 14);
37793795
else

src/backend/commands/tablecmds.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,8 @@ RemoveRelations(DropStmt *drop)
16231623
state.heapOid = InvalidOid;
16241624
state.partParentOid = InvalidOid;
16251625

1626-
relOid = RangeVarGetRelidExtended(rel, lockmode, RVR_MISSING_OK,
1626+
relOid = RangeVarGetRelidExtended(rel, lockmode,
1627+
RVR_MISSING_OK | RVR_OTHER_TEMP_OK,
16271628
RangeVarCallbackForDropRelation,
16281629
&state);
16291630

src/backend/nodes/makefuncs.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,14 @@ makeRangeVar(char *schemaname, char *relname, int location)
478478
r->schemaname = schemaname;
479479
r->relname = relname;
480480
r->inh = true;
481-
r->relpersistence = RELPERSISTENCE_PERMANENT;
482481
r->alias = NULL;
483482
r->location = location;
484483

484+
if (r->schemaname && strncmp(r->schemaname, "pg_temp", 7) == 0)
485+
r->relpersistence = RELPERSISTENCE_TEMP;
486+
else
487+
r->relpersistence = RELPERSISTENCE_PERMANENT;
488+
485489
return r;
486490
}
487491

src/backend/parser/gram.y

+10-1
Original file line numberDiff line numberDiff line change
@@ -19421,7 +19421,11 @@ makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner)
1942119421
break;
1942219422
}
1942319423

19424-
r->relpersistence = RELPERSISTENCE_PERMANENT;
19424+
if (r->schemaname && strncmp(r->schemaname, "pg_temp", 7) == 0)
19425+
r->relpersistence = RELPERSISTENCE_TEMP;
19426+
else
19427+
r->relpersistence = RELPERSISTENCE_PERMANENT;
19428+
1942519429
r->location = position;
1942619430

1942719431
return r;
@@ -19461,6 +19465,11 @@ makeRangeVarFromQualifiedName(char *name, List *namelist, int location,
1946119465
break;
1946219466
}
1946319467

19468+
if (r->schemaname && strncmp(r->schemaname, "pg_temp", 7) == 0)
19469+
r->relpersistence = RELPERSISTENCE_TEMP;
19470+
else
19471+
r->relpersistence = RELPERSISTENCE_PERMANENT;
19472+
1946419473
return r;
1946519474
}
1946619475

src/include/catalog/namespace.h

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ typedef enum RVROption
7272
RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */
7373
RVR_NOWAIT = 1 << 1, /* error if relation cannot be locked */
7474
RVR_SKIP_LOCKED = 1 << 2, /* skip if relation cannot be locked */
75+
RVR_OTHER_TEMP_OK = 1 << 3 /* don't error if relation is temp relation of
76+
other session (needed for DROP command) */
7577
} RVROption;
7678

7779
typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId,

0 commit comments

Comments
 (0)