From 480541c4f2bae7929a0529c1ea5871a868ac2a64 Mon Sep 17 00:00:00 2001 From: Jelte Fennema-Nio Date: Wed, 25 Oct 2023 14:20:07 +0200 Subject: [PATCH v6 3/3] Even more convenient macros With this change you don't even have to declare the iterator variable manually anymore. This has the advantage that it is scoped to the loop. --- src/backend/executor/execExpr.c | 4 +-- src/backend/executor/nodeSubplan.c | 7 ---- src/backend/replication/logical/relation.c | 1 - src/backend/replication/logical/tablesync.c | 3 +- src/backend/replication/pgoutput/pgoutput.c | 1 - src/include/nodes/pg_list.h | 37 ++++++++++++--------- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 08255a28454..e06886a7334 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -216,8 +216,6 @@ ExecInitQual(List *qual, PlanState *parent) ExprState *state; ExprEvalStep scratch = {0}; List *adjust_jumps = NIL; - Expr *node; - int jump; /* short-circuit (here and in ExecQual) for empty restriction list */ if (qual == NIL) @@ -251,7 +249,7 @@ ExecInitQual(List *qual, PlanState *parent) scratch.resvalue = &state->resvalue; scratch.resnull = &state->resnull; - foreach_ptr(node, qual) + foreach_ptr(Expr, node, qual) { /* first evaluate expression */ ExecInitExprRec(node, state, &state->resvalue, &state->resnull); diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 62465510701..904c7a0a14d 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -307,7 +307,6 @@ ExecScanSubPlan(SubPlanState *node, Datum rowresult; bool rownull; int col; - int paramid; if (subLinkType == EXISTS_SUBLINK) { @@ -478,8 +477,6 @@ ExecScanSubPlan(SubPlanState *node, } else if (subLinkType == MULTIEXPR_SUBLINK) { - int paramid; - /* We don't care about function result, but set the setParams */ foreach_int(paramid, subplan->setParam) { @@ -604,7 +601,6 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) { int col = 1; bool isnew; - int paramid; /* * Load up the Params representing the raw sub-select outputs, then @@ -878,8 +874,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) if (subplan->setParam != NIL && subplan->parParam == NIL && subplan->subLinkType != CTE_SUBLINK) { - int paramid; - foreach_int(paramid, subplan->setParam) { ParamExecData *prm = &(estate->es_param_exec_vals[paramid]); @@ -903,7 +897,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) List *oplist, *lefttlist, *righttlist; - OpExpr *opexpr; /* We need a memory context to hold the hash table(s) */ sstate->hashtablecxt = diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 7c5f27a88be..41834a25545 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -746,7 +746,6 @@ static Oid FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) { List *idxlist = RelationGetIndexList(localrel); - Oid idxoid; foreach_oid(idxoid, idxlist) { diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index 381c97fc97b..7de4551555d 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -416,7 +416,6 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn) TimestampTz last_start_time; }; static HTAB *last_start_times = NULL; - SubscriptionRelState *rstate; bool started_tx = false; bool should_exit = false; @@ -453,7 +452,7 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn) /* * Process all tables that are being synchronized. */ - foreach_ptr(rstate, table_states_not_ready) + foreach_ptr(SubscriptionRelState, rstate, table_states_not_ready) { if (rstate->state == SUBREL_STATE_SYNCDONE) { diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 81f6f700a46..e806ed19780 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -2229,7 +2229,6 @@ cleanup_rel_sync_cache(TransactionId xid, bool is_commit) { HASH_SEQ_STATUS hash_seq; RelationSyncEntry *entry; - TransactionId streamed_txn; Assert(RelationSyncCache != NULL); diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index d3403c63aa9..28836187c90 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -453,12 +453,16 @@ for_each_cell_setup(const List *lst, const ListCell *initcell) return r; } -#define foreach_internal(var, lst, func) \ - for (ForEachState var##__state = {(lst), 0}; \ - (var##__state.l != NIL && \ - var##__state.i < var##__state.l->length && \ - (var = func(&var##__state.l->elements[var##__state.i]), true)); \ - var##__state.i++) +#define foreach_internal(type, pointer, var, lst, func) \ + for (type pointer var = 0, pointer var##__outerloop = (type pointer) 1; \ + var##__outerloop; \ + var##__outerloop = 0) \ + for (ForEachState var##__state = {(lst), 0}; \ + (var##__state.l != NIL && \ + var##__state.i < var##__state.l->length && \ + (var = func(&var##__state.l->elements[var##__state.i]), true)); \ + var##__state.i++) + /* * Convenience macros that loop through a list of pointers/ints/oids/xids @@ -473,10 +477,10 @@ for_each_cell_setup(const List *lst, const ListCell *initcell) * * The caveats for foreach() apply equally here. */ -#define foreach_ptr(var, lst) foreach_internal(var, lst, lfirst) -#define foreach_int(var, lst) foreach_internal(var, lst, lfirst_int) -#define foreach_oid(var, lst) foreach_internal(var, lst, lfirst_oid) -#define foreach_xid(var, lst) foreach_internal(var, lst, lfirst_xid) +#define foreach_ptr(type, var, lst) foreach_internal(type, *, var, lst, lfirst) +#define foreach_int(var, lst) foreach_internal(int, , var, lst, lfirst_int) +#define foreach_oid(var, lst) foreach_internal(Oid, , var, lst, lfirst_oid) +#define foreach_xid(var, lst) foreach_internal(TransactionId, , var, lst, lfirst_xid) /* @@ -485,11 +489,14 @@ for_each_cell_setup(const List *lst, const ListCell *initcell) * the element is of the specified node type (using its nodeTag()). */ #define foreach_node(type, var, lst) \ - for (ForEachState var##__state = {(lst), 0}; \ - (var##__state.l != NIL && \ - var##__state.i < var##__state.l->length && \ - (var = lfirst_node(type, &var##__state.l->elements[var##__state.i]), true));\ - var##__state.i++) + for (type * var = 0, *var##__outerloop = (type *) 1; \ + var##__outerloop; \ + var##__outerloop = 0) \ + for (ForEachState var##__state = {(lst), 0}; \ + (var##__state.l != NIL && \ + var##__state.i < var##__state.l->length && \ + (var = lfirst_node(type, &var##__state.l->elements[var##__state.i]), true));\ + var##__state.i++) /* * forboth - -- 2.34.1