Skip to content

Commit b88ef20

Browse files
committed
postgres_fdw: Refactor deparsing code for locking clauses.
The upcoming patch to allow join pushdown in postgres_fdw needs to use this code multiple times, which requires moving it to deparse.c. That seems like a good idea anyway, so do that now both on general principle and to simplify the future patch. Inspired by a patch by Shigeru Hanada and Ashutosh Bapat, but I did it a little differently than what that patch did.
1 parent fbe5a3f commit b88ef20

File tree

3 files changed

+64
-49
lines changed

3 files changed

+64
-49
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
#include "catalog/pg_type.h"
4646
#include "commands/defrem.h"
4747
#include "nodes/nodeFuncs.h"
48+
#include "nodes/plannodes.h"
4849
#include "optimizer/clauses.h"
50+
#include "optimizer/prep.h"
4951
#include "optimizer/var.h"
5052
#include "parser/parsetree.h"
5153
#include "utils/builtins.h"
@@ -807,6 +809,64 @@ deparseTargetList(StringInfo buf,
807809
appendStringInfoString(buf, "NULL");
808810
}
809811

812+
/*
813+
* Deparse the appropriate locking clause (FOR SELECT or FOR SHARE) for a
814+
* given relation.
815+
*/
816+
void
817+
deparseLockingClause(StringInfo buf, PlannerInfo *root, RelOptInfo *rel)
818+
{
819+
/*
820+
* Add FOR UPDATE/SHARE if appropriate. We apply locking during the
821+
* initial row fetch, rather than later on as is done for local tables.
822+
* The extra roundtrips involved in trying to duplicate the local
823+
* semantics exactly don't seem worthwhile (see also comments for
824+
* RowMarkType).
825+
*
826+
* Note: because we actually run the query as a cursor, this assumes that
827+
* DECLARE CURSOR ... FOR UPDATE is supported, which it isn't before 8.3.
828+
*/
829+
if (rel->relid == root->parse->resultRelation &&
830+
(root->parse->commandType == CMD_UPDATE ||
831+
root->parse->commandType == CMD_DELETE))
832+
{
833+
/* Relation is UPDATE/DELETE target, so use FOR UPDATE */
834+
appendStringInfoString(buf, " FOR UPDATE");
835+
}
836+
else
837+
{
838+
PlanRowMark *rc = get_plan_rowmark(root->rowMarks, rel->relid);
839+
840+
if (rc)
841+
{
842+
/*
843+
* Relation is specified as a FOR UPDATE/SHARE target, so handle
844+
* that. (But we could also see LCS_NONE, meaning this isn't a
845+
* target relation after all.)
846+
*
847+
* For now, just ignore any [NO] KEY specification, since (a) it's
848+
* not clear what that means for a remote table that we don't have
849+
* complete information about, and (b) it wouldn't work anyway on
850+
* older remote servers. Likewise, we don't worry about NOWAIT.
851+
*/
852+
switch (rc->strength)
853+
{
854+
case LCS_NONE:
855+
/* No locking needed */
856+
break;
857+
case LCS_FORKEYSHARE:
858+
case LCS_FORSHARE:
859+
appendStringInfoString(buf, " FOR SHARE");
860+
break;
861+
case LCS_FORNOKEYUPDATE:
862+
case LCS_FORUPDATE:
863+
appendStringInfoString(buf, " FOR UPDATE");
864+
break;
865+
}
866+
}
867+
}
868+
}
869+
810870
/*
811871
* Deparse WHERE clauses in given list of RestrictInfos and append them to buf.
812872
*

contrib/postgres_fdw/postgres_fdw.c

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,55 +1013,8 @@ postgresGetForeignPlan(PlannerInfo *root,
10131013
if (best_path->path.pathkeys)
10141014
appendOrderByClause(&sql, root, baserel, best_path->path.pathkeys);
10151015

1016-
/*
1017-
* Add FOR UPDATE/SHARE if appropriate. We apply locking during the
1018-
* initial row fetch, rather than later on as is done for local tables.
1019-
* The extra roundtrips involved in trying to duplicate the local
1020-
* semantics exactly don't seem worthwhile (see also comments for
1021-
* RowMarkType).
1022-
*
1023-
* Note: because we actually run the query as a cursor, this assumes that
1024-
* DECLARE CURSOR ... FOR UPDATE is supported, which it isn't before 8.3.
1025-
*/
1026-
if (baserel->relid == root->parse->resultRelation &&
1027-
(root->parse->commandType == CMD_UPDATE ||
1028-
root->parse->commandType == CMD_DELETE))
1029-
{
1030-
/* Relation is UPDATE/DELETE target, so use FOR UPDATE */
1031-
appendStringInfoString(&sql, " FOR UPDATE");
1032-
}
1033-
else
1034-
{
1035-
PlanRowMark *rc = get_plan_rowmark(root->rowMarks, baserel->relid);
1036-
1037-
if (rc)
1038-
{
1039-
/*
1040-
* Relation is specified as a FOR UPDATE/SHARE target, so handle
1041-
* that. (But we could also see LCS_NONE, meaning this isn't a
1042-
* target relation after all.)
1043-
*
1044-
* For now, just ignore any [NO] KEY specification, since (a) it's
1045-
* not clear what that means for a remote table that we don't have
1046-
* complete information about, and (b) it wouldn't work anyway on
1047-
* older remote servers. Likewise, we don't worry about NOWAIT.
1048-
*/
1049-
switch (rc->strength)
1050-
{
1051-
case LCS_NONE:
1052-
/* No locking needed */
1053-
break;
1054-
case LCS_FORKEYSHARE:
1055-
case LCS_FORSHARE:
1056-
appendStringInfoString(&sql, " FOR SHARE");
1057-
break;
1058-
case LCS_FORNOKEYUPDATE:
1059-
case LCS_FORUPDATE:
1060-
appendStringInfoString(&sql, " FOR UPDATE");
1061-
break;
1062-
}
1063-
}
1064-
}
1016+
/* Add any necessary FOR UPDATE/SHARE. */
1017+
deparseLockingClause(&sql, root, baserel);
10651018

10661019
/*
10671020
* Build the fdw_private list that will be available to the executor.

contrib/postgres_fdw/postgres_fdw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ extern void deparseSelectSql(StringInfo buf,
8888
RelOptInfo *baserel,
8989
Bitmapset *attrs_used,
9090
List **retrieved_attrs);
91+
extern void deparseLockingClause(StringInfo buf,
92+
PlannerInfo *root, RelOptInfo *rel);
9193
extern void appendWhereClause(StringInfo buf,
9294
PlannerInfo *root,
9395
RelOptInfo *baserel,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy