mirror of https://github.com/citusdata/citus.git
introduce list compat macros
Pass the list to lnext API lnext API now expects the list as well. The commit on Postgres that introduced the change: 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164 lnext_compat and list_delete_cell_compat macros are introduced so that we can use these macros in the codebase without having to use #if directives in the codebase. Related commit on postgres: 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164 Command to search in postgres: git log --all --grep="list_delete_cell" add ListCellAndListWrapper When iterating a list in separate function calls, we need both the list and the current cell starting from PG13, therefore ListCellAndListWrapper is added to store both as a wrapper. Use ListCellAndListWrapper in foreign key test udfs As we iterate a list in these udfs using a functionContext, we need to use the wrapper to be able to access both the list and the current cell.pull/3900/head
parent
8ce8683ac4
commit
0819b79631
|
@ -753,18 +753,20 @@ static List *
|
|||
RemoveOptionFromList(List *optionList, char *optionName)
|
||||
{
|
||||
ListCell *optionCell = NULL;
|
||||
#if PG_VERSION_NUM < PG_VERSION_13
|
||||
ListCell *previousCell = NULL;
|
||||
|
||||
#endif
|
||||
foreach(optionCell, optionList)
|
||||
{
|
||||
DefElem *option = (DefElem *) lfirst(optionCell);
|
||||
|
||||
if (strncmp(option->defname, optionName, NAMEDATALEN) == 0)
|
||||
{
|
||||
return list_delete_cell(optionList, optionCell, previousCell);
|
||||
return list_delete_cell_compat(optionList, optionCell, previousCell);
|
||||
}
|
||||
|
||||
#if PG_VERSION_NUM < PG_VERSION_13
|
||||
previousCell = optionCell;
|
||||
#endif
|
||||
}
|
||||
|
||||
return optionList;
|
||||
|
@ -1423,7 +1425,7 @@ ColumnCoercionPaths(TupleDesc destTupleDescriptor, TupleDesc inputTupleDescripto
|
|||
ConversionPathForTypes(inputTupleType, destTupleType,
|
||||
&coercePaths[columnIndex]);
|
||||
|
||||
currentColumnName = lnext(currentColumnName);
|
||||
currentColumnName = lnext_compat(columnNameList, currentColumnName);
|
||||
|
||||
if (currentColumnName == NULL)
|
||||
{
|
||||
|
|
|
@ -75,6 +75,7 @@ int NextPlacementId = 0;
|
|||
static List * GetTableReplicaIdentityCommand(Oid relationId);
|
||||
static Datum WorkerNodeGetDatum(WorkerNode *workerNode, TupleDesc tupleDescriptor);
|
||||
|
||||
|
||||
/* exports for SQL callable functions */
|
||||
PG_FUNCTION_INFO_V1(master_get_table_metadata);
|
||||
PG_FUNCTION_INFO_V1(master_get_table_ddl_events);
|
||||
|
@ -221,8 +222,10 @@ master_get_table_ddl_events(PG_FUNCTION_ARGS)
|
|||
/* allocate DDL statements, and then save position in DDL statements */
|
||||
List *tableDDLEventList = GetTableDDLEvents(relationId, includeSequenceDefaults);
|
||||
tableDDLEventCell = list_head(tableDDLEventList);
|
||||
|
||||
functionContext->user_fctx = tableDDLEventCell;
|
||||
ListCellAndListWrapper* wrapper = palloc0(sizeof(ListCellAndListWrapper));
|
||||
wrapper->list = tableDDLEventList;
|
||||
wrapper->listCell = tableDDLEventCell;
|
||||
functionContext->user_fctx = wrapper;
|
||||
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
|
@ -235,13 +238,13 @@ master_get_table_ddl_events(PG_FUNCTION_ARGS)
|
|||
*/
|
||||
functionContext = SRF_PERCALL_SETUP();
|
||||
|
||||
tableDDLEventCell = (ListCell *) functionContext->user_fctx;
|
||||
if (tableDDLEventCell != NULL)
|
||||
ListCellAndListWrapper* wrapper = (ListCellAndListWrapper *) functionContext->user_fctx;
|
||||
if (wrapper->listCell != NULL)
|
||||
{
|
||||
char *ddlStatement = (char *) lfirst(tableDDLEventCell);
|
||||
char *ddlStatement = (char *) lfirst(wrapper->listCell);
|
||||
text *ddlStatementText = cstring_to_text(ddlStatement);
|
||||
|
||||
functionContext->user_fctx = lnext(tableDDLEventCell);
|
||||
wrapper->listCell = lnext_compat(wrapper->list, wrapper->listCell);
|
||||
|
||||
SRF_RETURN_NEXT(functionContext, PointerGetDatum(ddlStatementText));
|
||||
}
|
||||
|
|
|
@ -370,18 +370,20 @@ RemoveLocalNodeFromWorkerList(List *workerNodeList)
|
|||
int32 localGroupId = GetLocalGroupId();
|
||||
|
||||
ListCell *workerNodeCell = NULL;
|
||||
#if PG_VERSION_NUM < PG_VERSION_13
|
||||
ListCell *prev = NULL;
|
||||
#endif
|
||||
foreach(workerNodeCell, workerNodeList)
|
||||
{
|
||||
WorkerNode *workerNode = (WorkerNode *) lfirst(workerNodeCell);
|
||||
if (workerNode->groupId == localGroupId)
|
||||
{
|
||||
return list_delete_cell(workerNodeList, workerNodeCell, prev);
|
||||
return list_delete_cell_compat(workerNodeList, workerNodeCell, prev);
|
||||
}
|
||||
|
||||
prev = workerNodeCell;
|
||||
}
|
||||
|
||||
#if PG_VERSION_NUM < PG_VERSION_13
|
||||
prev = workerNodeCell;
|
||||
#endif
|
||||
return workerNodeList;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
#include "fmgr.h"
|
||||
#include "funcapi.h"
|
||||
|
||||
#include "distributed/listutils.h"
|
||||
#include "distributed/metadata_cache.h"
|
||||
|
||||
#include "distributed/version_compat.h"
|
||||
|
||||
/* these functions are only exported in the regression tests */
|
||||
PG_FUNCTION_INFO_V1(get_referencing_relation_id_list);
|
||||
|
@ -47,10 +48,12 @@ get_referencing_relation_id_list(PG_FUNCTION_ARGS)
|
|||
MemoryContextSwitchTo(functionContext->multi_call_memory_ctx);
|
||||
List *refList = list_copy(
|
||||
cacheEntry->referencingRelationsViaForeignKey);
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
|
||||
ListCellAndListWrapper* wrapper = palloc0(sizeof(ListCellAndListWrapper));
|
||||
foreignRelationCell = list_head(refList);
|
||||
functionContext->user_fctx = foreignRelationCell;
|
||||
wrapper->list = refList;
|
||||
wrapper->listCell = foreignRelationCell;
|
||||
functionContext->user_fctx = wrapper;
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -61,12 +64,12 @@ get_referencing_relation_id_list(PG_FUNCTION_ARGS)
|
|||
*/
|
||||
functionContext = SRF_PERCALL_SETUP();
|
||||
|
||||
foreignRelationCell = (ListCell *) functionContext->user_fctx;
|
||||
if (foreignRelationCell != NULL)
|
||||
ListCellAndListWrapper* wrapper = (ListCellAndListWrapper *) functionContext->user_fctx;
|
||||
if (wrapper->listCell != NULL)
|
||||
{
|
||||
Oid refId = lfirst_oid(foreignRelationCell);
|
||||
Oid refId = lfirst_oid(wrapper->listCell);
|
||||
|
||||
functionContext->user_fctx = lnext(foreignRelationCell);
|
||||
wrapper->listCell = lnext_compat(wrapper->list, wrapper->listCell);
|
||||
|
||||
SRF_RETURN_NEXT(functionContext, PointerGetDatum(refId));
|
||||
}
|
||||
|
@ -102,10 +105,12 @@ get_referenced_relation_id_list(PG_FUNCTION_ARGS)
|
|||
MemoryContext oldContext =
|
||||
MemoryContextSwitchTo(functionContext->multi_call_memory_ctx);
|
||||
List *refList = list_copy(cacheEntry->referencedRelationsViaForeignKey);
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
|
||||
foreignRelationCell = list_head(refList);
|
||||
functionContext->user_fctx = foreignRelationCell;
|
||||
ListCellAndListWrapper* wrapper = palloc0(sizeof(ListCellAndListWrapper));
|
||||
wrapper->list = refList;
|
||||
wrapper->listCell = foreignRelationCell;
|
||||
functionContext->user_fctx = wrapper;
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -116,12 +121,13 @@ get_referenced_relation_id_list(PG_FUNCTION_ARGS)
|
|||
*/
|
||||
functionContext = SRF_PERCALL_SETUP();
|
||||
|
||||
foreignRelationCell = (ListCell *) functionContext->user_fctx;
|
||||
if (foreignRelationCell != NULL)
|
||||
{
|
||||
Oid refId = lfirst_oid(foreignRelationCell);
|
||||
ListCellAndListWrapper* wrapper = (ListCellAndListWrapper *) functionContext->user_fctx;
|
||||
|
||||
functionContext->user_fctx = lnext(foreignRelationCell);
|
||||
if (wrapper->listCell != NULL)
|
||||
{
|
||||
Oid refId = lfirst_oid(wrapper->listCell);
|
||||
|
||||
wrapper->listCell = lnext_compat(wrapper->list, wrapper->listCell);
|
||||
|
||||
SRF_RETURN_NEXT(functionContext, PointerGetDatum(refId));
|
||||
}
|
||||
|
|
|
@ -18,8 +18,20 @@
|
|||
#include "nodes/pg_list.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/hsearch.h"
|
||||
#include "distributed/version_compat.h"
|
||||
|
||||
|
||||
/*
|
||||
* ListCellAndListWrapper stores a list and list cell.
|
||||
* This struct is used for functionContext. When iterating a list
|
||||
* in separate function calls, we need both the list and the current cell.
|
||||
* Therefore this wrapper stores both of them.
|
||||
*/
|
||||
typedef struct ListCellAndListWrapper {
|
||||
List *list;
|
||||
ListCell *listCell;
|
||||
} ListCellAndListWrapper;
|
||||
|
||||
/*
|
||||
* foreach_ptr -
|
||||
* a convenience macro which loops through a pointer list without needing a
|
||||
|
@ -39,7 +51,7 @@
|
|||
for (ListCell *(var ## CellDoNotUse) = list_head(l); \
|
||||
(var ## CellDoNotUse) != NULL && \
|
||||
(((var) = lfirst(var ## CellDoNotUse)) || true); \
|
||||
var ## CellDoNotUse = lnext(var ## CellDoNotUse))
|
||||
var ## CellDoNotUse = lnext_compat(l, var ## CellDoNotUse))
|
||||
|
||||
|
||||
/*
|
||||
|
@ -52,7 +64,7 @@
|
|||
for (ListCell *(var ## CellDoNotUse) = list_head(l); \
|
||||
(var ## CellDoNotUse) != NULL && \
|
||||
(((var) = lfirst_int(var ## CellDoNotUse)) || true); \
|
||||
var ## CellDoNotUse = lnext(var ## CellDoNotUse))
|
||||
var ## CellDoNotUse = lnext_compat(l, var ## CellDoNotUse))
|
||||
|
||||
|
||||
/*
|
||||
|
@ -65,7 +77,7 @@
|
|||
for (ListCell *(var ## CellDoNotUse) = list_head(l); \
|
||||
(var ## CellDoNotUse) != NULL && \
|
||||
(((var) = lfirst_oid(var ## CellDoNotUse)) || true); \
|
||||
var ## CellDoNotUse = lnext(var ## CellDoNotUse))
|
||||
var ## CellDoNotUse = lnext_compat(l, var ## CellDoNotUse))
|
||||
|
||||
|
||||
/* utility functions declaration shared within this module */
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
#include "optimizer/optimizer.h"
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
#define lnext_compat(l, r) lnext(l, r)
|
||||
#define list_delete_cell_compat(l,c,p) list_delete_cell(l,c)
|
||||
#else /* pre PG13 */
|
||||
#define lnext_compat(l, r) lnext(r)
|
||||
#define list_delete_cell_compat(l,c,p) list_delete_cell(l,c,p)
|
||||
#endif
|
||||
#if PG_VERSION_NUM >= PG_VERSION_12
|
||||
|
||||
#define MakeSingleTupleTableSlotCompat MakeSingleTupleTableSlot
|
||||
|
|
Loading…
Reference in New Issue