Skip to content

Commit 0bf3ae8

Browse files
committed
Directly modify foreign tables.
postgres_fdw can now sent an UPDATE or DELETE statement directly to the foreign server in simple cases, rather than sending a SELECT FOR UPDATE statement and then updating or deleting rows one-by-one. Etsuro Fujita, reviewed by Rushabh Lathia, Shigeru Hanada, Kyotaro Horiguchi, Albe Laurenz, Thom Brown, and me.
1 parent 3422fec commit 0bf3ae8

File tree

21 files changed

+1515
-125
lines changed

21 files changed

+1515
-125
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,69 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root,
13141314
returningList, retrieved_attrs);
13151315
}
13161316

1317+
/*
1318+
* deparse remote UPDATE statement
1319+
*
1320+
* The statement text is appended to buf, and we also create an integer List
1321+
* of the columns being retrieved by RETURNING (if any), which is returned
1322+
* to *retrieved_attrs.
1323+
*/
1324+
void
1325+
deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
1326+
Index rtindex, Relation rel,
1327+
List *targetlist,
1328+
List *targetAttrs,
1329+
List *remote_conds,
1330+
List **params_list,
1331+
List *returningList,
1332+
List **retrieved_attrs)
1333+
{
1334+
RelOptInfo *baserel = root->simple_rel_array[rtindex];
1335+
deparse_expr_cxt context;
1336+
int nestlevel;
1337+
bool first;
1338+
ListCell *lc;
1339+
1340+
/* Set up context struct for recursion */
1341+
context.root = root;
1342+
context.foreignrel = baserel;
1343+
context.buf = buf;
1344+
context.params_list = params_list;
1345+
1346+
appendStringInfoString(buf, "UPDATE ");
1347+
deparseRelation(buf, rel);
1348+
appendStringInfoString(buf, " SET ");
1349+
1350+
/* Make sure any constants in the exprs are printed portably */
1351+
nestlevel = set_transmission_modes();
1352+
1353+
first = true;
1354+
foreach(lc, targetAttrs)
1355+
{
1356+
int attnum = lfirst_int(lc);
1357+
TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
1358+
1359+
if (!first)
1360+
appendStringInfoString(buf, ", ");
1361+
first = false;
1362+
1363+
deparseColumnRef(buf, rtindex, attnum, root, false);
1364+
appendStringInfoString(buf, " = ");
1365+
deparseExpr((Expr *) tle->expr, &context);
1366+
}
1367+
1368+
reset_transmission_modes(nestlevel);
1369+
1370+
if (remote_conds)
1371+
{
1372+
appendStringInfo(buf, " WHERE ");
1373+
appendConditions(remote_conds, &context);
1374+
}
1375+
1376+
deparseReturningList(buf, root, rtindex, rel, false,
1377+
returningList, retrieved_attrs);
1378+
}
1379+
13171380
/*
13181381
* deparse remote DELETE statement
13191382
*
@@ -1336,6 +1399,43 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root,
13361399
returningList, retrieved_attrs);
13371400
}
13381401

1402+
/*
1403+
* deparse remote DELETE statement
1404+
*
1405+
* The statement text is appended to buf, and we also create an integer List
1406+
* of the columns being retrieved by RETURNING (if any), which is returned
1407+
* to *retrieved_attrs.
1408+
*/
1409+
void
1410+
deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root,
1411+
Index rtindex, Relation rel,
1412+
List *remote_conds,
1413+
List **params_list,
1414+
List *returningList,
1415+
List **retrieved_attrs)
1416+
{
1417+
RelOptInfo *baserel = root->simple_rel_array[rtindex];
1418+
deparse_expr_cxt context;
1419+
1420+
/* Set up context struct for recursion */
1421+
context.root = root;
1422+
context.foreignrel = baserel;
1423+
context.buf = buf;
1424+
context.params_list = params_list;
1425+
1426+
appendStringInfoString(buf, "DELETE FROM ");
1427+
deparseRelation(buf, rel);
1428+
1429+
if (remote_conds)
1430+
{
1431+
appendStringInfo(buf, " WHERE ");
1432+
appendConditions(remote_conds, &context);
1433+
}
1434+
1435+
deparseReturningList(buf, root, rtindex, rel, false,
1436+
returningList, retrieved_attrs);
1437+
}
1438+
13391439
/*
13401440
* Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE.
13411441
*/

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