mirror of https://github.com/citusdata/citus.git
Add extra foreach convenience macros (#3117)
This completely hides `ListCell` to the user of the loop Example usage: ```c WorkerNode *workerNode = NULL; foreach_ptr(workerNode, workerNodeList) { // Do stuff with workerNode } ``` Instead of: ```c ListCell *workerNodeCell = NULL; foreach(cell, workerNodeList) { WorkerNode *workerNode = lfirst(workerNodeCell); // Do stuff with workerNode } ```pull/3122/head
parent
54de466876
commit
a5010e5b17
|
@ -181,7 +181,7 @@ LockTruncatedRelationMetadataInWorkers(TruncateStmt *truncateStatement)
|
||||||
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
||||||
DistTableCacheEntry *cacheEntry = NULL;
|
DistTableCacheEntry *cacheEntry = NULL;
|
||||||
List *referencingTableList = NIL;
|
List *referencingTableList = NIL;
|
||||||
ListCell *referencingTableCell = NULL;
|
Oid referencingRelationId = InvalidOid;
|
||||||
|
|
||||||
if (!IsDistributedTable(relationId))
|
if (!IsDistributedTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -199,9 +199,8 @@ LockTruncatedRelationMetadataInWorkers(TruncateStmt *truncateStatement)
|
||||||
Assert(cacheEntry != NULL);
|
Assert(cacheEntry != NULL);
|
||||||
|
|
||||||
referencingTableList = cacheEntry->referencingRelationsViaForeignKey;
|
referencingTableList = cacheEntry->referencingRelationsViaForeignKey;
|
||||||
foreach(referencingTableCell, referencingTableList)
|
foreach_oid(referencingRelationId, referencingTableList)
|
||||||
{
|
{
|
||||||
Oid referencingRelationId = lfirst_oid(referencingTableCell);
|
|
||||||
distributedRelationList = list_append_unique_oid(distributedRelationList,
|
distributedRelationList = list_append_unique_oid(distributedRelationList,
|
||||||
referencingRelationId);
|
referencingRelationId);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +227,7 @@ LockTruncatedRelationMetadataInWorkers(TruncateStmt *truncateStatement)
|
||||||
static void
|
static void
|
||||||
AcquireDistributedLockOnRelations(List *relationIdList, LOCKMODE lockMode)
|
AcquireDistributedLockOnRelations(List *relationIdList, LOCKMODE lockMode)
|
||||||
{
|
{
|
||||||
ListCell *relationIdCell = NULL;
|
Oid relationId = InvalidOid;
|
||||||
List *workerNodeList = ActivePrimaryNodeList(NoLock);
|
List *workerNodeList = ActivePrimaryNodeList(NoLock);
|
||||||
const char *lockModeText = LockModeToLockModeText(lockMode);
|
const char *lockModeText = LockModeToLockModeText(lockMode);
|
||||||
|
|
||||||
|
@ -241,10 +240,8 @@ AcquireDistributedLockOnRelations(List *relationIdList, LOCKMODE lockMode)
|
||||||
|
|
||||||
BeginOrContinueCoordinatedTransaction();
|
BeginOrContinueCoordinatedTransaction();
|
||||||
|
|
||||||
foreach(relationIdCell, relationIdList)
|
foreach_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId = lfirst_oid(relationIdCell);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only acquire distributed lock on relation if
|
* We only acquire distributed lock on relation if
|
||||||
* the relation is sync'ed between mx nodes.
|
* the relation is sync'ed between mx nodes.
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "distributed/citus_clauses.h"
|
#include "distributed/citus_clauses.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/deparse_shard_query.h"
|
#include "distributed/deparse_shard_query.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/multi_logical_optimizer.h"
|
#include "distributed/multi_logical_optimizer.h"
|
||||||
#include "distributed/multi_logical_planner.h"
|
#include "distributed/multi_logical_planner.h"
|
||||||
|
@ -1061,7 +1062,7 @@ DeferErrorIfUnsupportedTableCombination(Query *queryTree)
|
||||||
{
|
{
|
||||||
List *rangeTableList = queryTree->rtable;
|
List *rangeTableList = queryTree->rtable;
|
||||||
List *joinTreeTableIndexList = NIL;
|
List *joinTreeTableIndexList = NIL;
|
||||||
ListCell *joinTreeTableIndexCell = NULL;
|
int joinTreeTableIndex = 0;
|
||||||
bool unsupportedTableCombination = false;
|
bool unsupportedTableCombination = false;
|
||||||
char *errorDetail = NULL;
|
char *errorDetail = NULL;
|
||||||
|
|
||||||
|
@ -1071,13 +1072,12 @@ DeferErrorIfUnsupportedTableCombination(Query *queryTree)
|
||||||
*/
|
*/
|
||||||
ExtractRangeTableIndexWalker((Node *) queryTree->jointree, &joinTreeTableIndexList);
|
ExtractRangeTableIndexWalker((Node *) queryTree->jointree, &joinTreeTableIndexList);
|
||||||
|
|
||||||
foreach(joinTreeTableIndexCell, joinTreeTableIndexList)
|
foreach_int(joinTreeTableIndex, joinTreeTableIndexList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Join tree's range table index starts from 1 in the query tree. But,
|
* Join tree's range table index starts from 1 in the query tree. But,
|
||||||
* list indexes start from 0.
|
* list indexes start from 0.
|
||||||
*/
|
*/
|
||||||
int joinTreeTableIndex = lfirst_int(joinTreeTableIndexCell);
|
|
||||||
int rangeTableListIndex = joinTreeTableIndex - 1;
|
int rangeTableListIndex = joinTreeTableIndex - 1;
|
||||||
|
|
||||||
RangeTblEntry *rangeTableEntry =
|
RangeTblEntry *rangeTableEntry =
|
||||||
|
|
|
@ -765,8 +765,8 @@ UpdateNodeLocation(int32 nodeId, char *newNodeName, int32 newNodePort)
|
||||||
Datum
|
Datum
|
||||||
master_initialize_node_metadata(PG_FUNCTION_ARGS)
|
master_initialize_node_metadata(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
ListCell *workerNodeCell = NULL;
|
|
||||||
List *workerNodes = NIL;
|
List *workerNodes = NIL;
|
||||||
|
WorkerNode *workerNode = NULL;
|
||||||
|
|
||||||
CheckCitusVersion(ERROR);
|
CheckCitusVersion(ERROR);
|
||||||
|
|
||||||
|
@ -779,9 +779,8 @@ master_initialize_node_metadata(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
workerNodes = ParseWorkerNodeFileAndRename();
|
workerNodes = ParseWorkerNodeFileAndRename();
|
||||||
|
|
||||||
foreach(workerNodeCell, workerNodes)
|
foreach_ptr(workerNode, workerNodes)
|
||||||
{
|
{
|
||||||
WorkerNode *workerNode = (WorkerNode *) lfirst(workerNodeCell);
|
|
||||||
bool nodeAlreadyExists = false;
|
bool nodeAlreadyExists = false;
|
||||||
NodeMetadata nodeMetadata = DefaultNodeMetadata();
|
NodeMetadata nodeMetadata = DefaultNodeMetadata();
|
||||||
nodeMetadata.nodeRack = workerNode->workerRack;
|
nodeMetadata.nodeRack = workerNode->workerRack;
|
||||||
|
|
|
@ -20,6 +20,51 @@
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* foreach_ptr -
|
||||||
|
* a convenience macro which loops through a pointer list without needing a
|
||||||
|
* ListCell, just a declared pointer variable to store the pointer of the
|
||||||
|
* cell in.
|
||||||
|
*
|
||||||
|
* How it works:
|
||||||
|
* - A ListCell is declared with the name {var}Cell and used throughout the
|
||||||
|
* for loop using ## to concat.
|
||||||
|
* - To assign to var it needs to be done in the condition of the for loop,
|
||||||
|
* because we cannot use the initializer since a ListCell* variable is
|
||||||
|
* declared there.
|
||||||
|
* - || true is used to always enter the loop when cell is not null even if
|
||||||
|
* var is NULL.
|
||||||
|
*/
|
||||||
|
#define foreach_ptr(var, l) \
|
||||||
|
for (ListCell *(var ## Cell) = list_head(l); \
|
||||||
|
(var ## Cell) != NULL && (((var) = lfirst(var ## Cell)) || true); \
|
||||||
|
var ## Cell = lnext(var ## Cell))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* foreach_int -
|
||||||
|
* a convenience macro which loops through an int list without needing a
|
||||||
|
* ListCell, just a declared int variable to store the int of the cell in.
|
||||||
|
* For explanation of how it works see foreach_ptr.
|
||||||
|
*/
|
||||||
|
#define foreach_int(var, l) \
|
||||||
|
for (ListCell *(var ## Cell) = list_head(l); \
|
||||||
|
(var ## Cell) != NULL && (((var) = lfirst_int(var ## Cell)) || true); \
|
||||||
|
var ## Cell = lnext(var ## Cell))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* foreach_oid -
|
||||||
|
* a convenience macro which loops through an oid list without needing a
|
||||||
|
* ListCell, just a declared Oid variable to store the oid of the cell in.
|
||||||
|
* For explanation of how it works see foreach_ptr.
|
||||||
|
*/
|
||||||
|
#define foreach_oid(var, l) \
|
||||||
|
for (ListCell *(var ## Cell) = list_head(l); \
|
||||||
|
(var ## Cell) != NULL && (((var) = lfirst_oid(var ## Cell)) || true); \
|
||||||
|
var ## Cell = lnext(var ## Cell))
|
||||||
|
|
||||||
|
|
||||||
/* utility functions declaration shared within this module */
|
/* utility functions declaration shared within this module */
|
||||||
extern List * SortList(List *pointerList,
|
extern List * SortList(List *pointerList,
|
||||||
int (*ComparisonFunction)(const void *, const void *));
|
int (*ComparisonFunction)(const void *, const void *));
|
||||||
|
|
Loading…
Reference in New Issue