blob: 2412b07d8932e7ef01c01624284299c391b61fb1 [file] [log] [blame]
From 259ff80eb29c2c70e6afb77d266ce49cccbef223 Mon Sep 17 00:00:00 2001
From: Sven Klemm <sven@timescale.com>
Date: Sat, 19 Sep 2020 22:20:34 +0200
Subject: [PATCH] Add support for PG13 List implementation
PG13 changes the List implementation from a linked list to an array
while most of the API functions did not change a few them have slightly
different signature in PG13, additionally the list_make5 functions
got removed.
https://github.com/postgres/postgres/commit/1cff1b95ab
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
Fetch from: https://github.com/timescale/timescaledb/commit/b1a9c3b7b7d44ee78456931292655d52c252930d.patch
---
.clang-format | 1 +
src/bgw/scheduler.c | 12 ++++++------
src/cache.c | 10 ++++++++--
src/chunk_append/chunk_append.c | 2 +-
src/chunk_append/exec.c | 4 ++--
src/compat.h | 16 ++++++++++++++++
src/import/planner.c | 2 +-
src/plan_agg_bookend.c | 7 ++++---
src/plan_expand_hypertable.c | 13 +++++++++----
test/src/bgw/test_job_refresh.c | 3 ++-
tsl/src/continuous_aggs/create.c | 2 +-
tsl/src/debug.c | 15 ++++++++++-----
tsl/src/fdw/deparse.c | 6 +++---
.../nodes/decompress_chunk/decompress_chunk.c | 6 +++---
tsl/src/nodes/decompress_chunk/exec.c | 3 ++-
tsl/src/nodes/gapfill/planner.c | 11 +++++++----
16 files changed, 76 insertions(+), 37 deletions(-)
diff --git a/.clang-format b/.clang-format
index 5bb275cd..9aac7ef4 100644
--- a/.clang-format
+++ b/.clang-format
@@ -60,6 +60,7 @@ ForEachMacros:
- foreach
- forboth
- for_each_cell
+ - for_each_cell_compat
- for_both_cell
- forthree
IncludeBlocks: Preserve # separate include blocks will not be merged
diff --git a/src/bgw/scheduler.c b/src/bgw/scheduler.c
index 7a7e360c..2630ff9f 100644
--- a/src/bgw/scheduler.c
+++ b/src/bgw/scheduler.c
@@ -456,7 +456,7 @@ ts_update_scheduled_jobs_list(List *cur_jobs_list, MemoryContext mctx)
*/
terminate_and_cleanup_job(cur_sjob);
- cur_ptr = lnext(cur_ptr);
+ cur_ptr = lnext_compat(cur_jobs_list, cur_ptr);
continue;
}
if (cur_sjob->job.fd.id == new_sjob->job.fd.id)
@@ -472,15 +472,15 @@ ts_update_scheduled_jobs_list(List *cur_jobs_list, MemoryContext mctx)
if (cur_sjob->state == JOB_STATE_SCHEDULED)
scheduled_bgw_job_transition_state_to(new_sjob, JOB_STATE_SCHEDULED);
- cur_ptr = lnext(cur_ptr);
- new_ptr = lnext(new_ptr);
+ cur_ptr = lnext_compat(cur_jobs_list, cur_ptr);
+ new_ptr = lnext_compat(new_jobs, new_ptr);
}
else if (cur_sjob->job.fd.id > new_sjob->job.fd.id)
{
scheduled_bgw_job_transition_state_to(new_sjob, JOB_STATE_SCHEDULED);
/* Advance the new_job list until we catch up to cur_list */
- new_ptr = lnext(new_ptr);
+ new_ptr = lnext_compat(new_jobs, new_ptr);
}
}
@@ -489,7 +489,7 @@ ts_update_scheduled_jobs_list(List *cur_jobs_list, MemoryContext mctx)
{
ListCell *ptr;
- for_each_cell (ptr, cur_ptr)
+ for_each_cell_compat (ptr, cur_jobs_list, cur_ptr)
terminate_and_cleanup_job(lfirst(ptr));
}
@@ -498,7 +498,7 @@ ts_update_scheduled_jobs_list(List *cur_jobs_list, MemoryContext mctx)
/* Then there are more new jobs. Initialize all of them. */
ListCell *ptr;
- for_each_cell (ptr, new_ptr)
+ for_each_cell_compat (ptr, new_jobs, new_ptr)
scheduled_bgw_job_transition_state_to(lfirst(ptr), JOB_STATE_SCHEDULED);
}
diff --git a/src/cache.c b/src/cache.c
index cc6b2d07..3b53485a 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -7,6 +7,7 @@
#include <access/xact.h>
#include "cache.h"
+#include "compat.h"
/* List of pinned caches. A cache occurs once in this list for every pin
* taken */
@@ -105,7 +106,10 @@ ts_cache_pin(Cache *cache)
static void
remove_pin(Cache *cache, SubTransactionId subtxnid)
{
- ListCell *lc, *prev = NULL;
+ ListCell *lc;
+#if PG13_LT
+ ListCell *prev = NULL;
+#endif
foreach (lc, pinned_caches)
{
@@ -113,12 +117,14 @@ remove_pin(Cache *cache, SubTransactionId subtxnid)
if (cp->cache == cache && cp->subtxnid == subtxnid)
{
- pinned_caches = list_delete_cell(pinned_caches, lc, prev);
+ pinned_caches = list_delete_cell_compat(pinned_caches, lc, prev);
pfree(cp);
return;
}
+#if PG13_LT
prev = lc;
+#endif
}
/* should never reach here: there should always be a pin to remove */
diff --git a/src/chunk_append/chunk_append.c b/src/chunk_append/chunk_append.c
index fb1c87ff..ed91ff39 100644
--- a/src/chunk_append/chunk_append.c
+++ b/src/chunk_append/chunk_append.c
@@ -209,7 +209,7 @@ ts_chunk_append_path_create(PlannerInfo *root, RelOptInfo *rel, Hypertable *ht,
if (is_not_pruned)
{
merge_childs = lappend(merge_childs, child);
- flat = lnext(flat);
+ flat = lnext_compat(children, flat);
if (flat == NULL)
break;
}
diff --git a/src/chunk_append/exec.c b/src/chunk_append/exec.c
index 8f4dd5d6..84f79e23 100644
--- a/src/chunk_append/exec.c
+++ b/src/chunk_append/exec.c
@@ -344,8 +344,8 @@ initialize_runtime_exclusion(ChunkAppendState *state)
state->runtime_number_exclusions++;
}
- lc_clauses = lnext(lc_clauses);
- lc_constraints = lnext(lc_constraints);
+ lc_clauses = lnext_compat(state->filtered_ri_clauses, lc_clauses);
+ lc_constraints = lnext_compat(state->filtered_constraints, lc_constraints);
}
state->runtime_initialized = true;
diff --git a/src/compat.h b/src/compat.h
index d84f8754..51c1c181 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -358,4 +358,20 @@ get_vacuum_options(const VacuumStmt *stmt)
pg_b64_decode((src), (srclen), (dst), (dstlen))
#endif
+/* PG13 changes the List implementation from a linked list to an array
+ * while most of the API functions did not change a few them have slightly
+ * different signature in PG13, additionally the list_make5 functions
+ * got removed. */
+#if PG13_LT
+#define lnext_compat(l, lc) lnext((lc))
+#define list_delete_cell_compat(l, lc, prev) list_delete_cell((l), (lc), (prev))
+#define for_each_cell_compat(cell, list, initcell) for_each_cell ((cell), (initcell))
+#else
+#define lnext_compat(l, lc) lnext((l), (lc))
+#define list_delete_cell_compat(l, lc, prev) list_delete_cell((l), (lc))
+#define list_make5(x1, x2, x3, x4, x5) lappend(list_make4(x1, x2, x3, x4), x5)
+#define list_make5_oid(x1, x2, x3, x4, x5) lappend_oid(list_make4_oid(x1, x2, x3, x4), x5)
+#define for_each_cell_compat(cell, list, initcell) for_each_cell ((cell), (list), (initcell))
+#endif
+
#endif /* TIMESCALEDB_COMPAT_H */
diff --git a/src/import/planner.c b/src/import/planner.c
index 31a4889d..b907390d 100644
--- a/src/import/planner.c
+++ b/src/import/planner.c
@@ -196,7 +196,7 @@ ts_make_partial_grouping_target(struct PlannerInfo *root, PathTarget *grouping_t
struct List *non_group_cols;
struct List *non_group_exprs;
int i;
- struct ListCell *lc;
+ ListCell *lc;
partial_target = create_empty_pathtarget();
non_group_cols = NIL;
diff --git a/src/plan_agg_bookend.c b/src/plan_agg_bookend.c
index d4d06f5b..5394cf5d 100644
--- a/src/plan_agg_bookend.c
+++ b/src/plan_agg_bookend.c
@@ -696,13 +696,14 @@ build_first_last_path(PlannerInfo *root, FirstLastAggInfo *fl_info, Oid eqop, Oi
if (app->parent_reloid == rte->relid)
{
subroot->append_rel_list =
- list_delete_cell(subroot->append_rel_list, next, prev);
- next = prev != NULL ? prev->next : list_head(subroot->append_rel_list);
+ list_delete_cell_compat(subroot->append_rel_list, next, prev);
+ next = prev != NULL ? lnext_compat(subroot->append_rel_list, next) :
+ list_head(subroot->append_rel_list);
}
else
{
prev = next;
- next = next->next;
+ next = lnext_compat(subroot->append_rel_list, next);
}
}
}
diff --git a/src/plan_expand_hypertable.c b/src/plan_expand_hypertable.c
index 37282ce4..2b99c93b 100644
--- a/src/plan_expand_hypertable.c
+++ b/src/plan_expand_hypertable.c
@@ -581,7 +581,8 @@ process_quals(Node *quals, CollectQualCtx *ctx, bool is_outer_join)
ListCell *prev pg_attribute_unused() = NULL;
List *additional_quals = NIL;
- for (lc = list_head((List *) quals); lc != NULL; prev = lc, lc = lnext(lc))
+ for (lc = list_head((List *) quals); lc != NULL;
+ prev = lc, lc = lnext_compat((List *) quals, lc))
{
Expr *qual = lfirst(lc);
Relids relids = pull_varnos((Node *) qual);
@@ -611,7 +612,7 @@ process_quals(Node *quals, CollectQualCtx *ctx, bool is_outer_join)
* is called, so we can remove the functions from that directly
*/
#if PG12_LT
- quals = (Node *) list_delete_cell((List *) quals, lc, prev);
+ quals = (Node *) list_delete_cell_compat((List *) quals, lc, prev);
#endif
return quals;
}
@@ -663,7 +664,9 @@ process_quals(Node *quals, CollectQualCtx *ctx, bool is_outer_join)
static List *
remove_exclusion_fns(List *restrictinfo)
{
+#if PG13_LT
ListCell *prev = NULL;
+#endif
ListCell *lc = list_head(restrictinfo);
while (lc != NULL)
@@ -682,11 +685,13 @@ remove_exclusion_fns(List *restrictinfo)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("first parameter for chunks_in function needs to be record")));
- restrictinfo = list_delete_cell((List *) restrictinfo, lc, prev);
+ restrictinfo = list_delete_cell_compat((List *) restrictinfo, lc, prev);
return restrictinfo;
}
+#if PG13_LT
prev = lc;
- lc = lnext(lc);
+#endif
+ lc = lnext_compat(restrictinfo, lc);
}
return restrictinfo;
}
diff --git a/test/src/bgw/test_job_refresh.c b/test/src/bgw/test_job_refresh.c
index 51a3b0d7..d51415d4 100644
--- a/test/src/bgw/test_job_refresh.c
+++ b/test/src/bgw/test_job_refresh.c
@@ -13,6 +13,7 @@
#include <access/htup_details.h>
#include <utils/memutils.h>
+#include "compat.h"
#include "export.h"
#include "bgw/scheduler.h"
@@ -70,7 +71,7 @@ ts_test_job_refresh(PG_FUNCTION_ARGS)
memset(nulls, 0, sizeof(*nulls) * funcctx->tuple_desc->natts);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
- funcctx->user_fctx = lnext(lc);
+ funcctx->user_fctx = lnext_compat(cur_scheduled_jobs, lc);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
diff --git a/tsl/src/continuous_aggs/create.c b/tsl/src/continuous_aggs/create.c
index bdf4470a..f767dabb 100644
--- a/tsl/src/continuous_aggs/create.c
+++ b/tsl/src/continuous_aggs/create.c
@@ -1566,7 +1566,7 @@ fixup_userview_query_tlist(Query *userquery, List *tlist_aliases)
if (tle->resjunk)
continue;
tle->resname = pstrdup(strVal(lfirst(alist_item)));
- alist_item = lnext(alist_item);
+ alist_item = lnext_compat(tlist_aliases, alist_item);
if (alist_item == NULL)
break; /* done assigning aliases */
}
diff --git a/tsl/src/debug.c b/tsl/src/debug.c
index 697bfc0b..023097ee 100644
--- a/tsl/src/debug.c
+++ b/tsl/src/debug.c
@@ -168,7 +168,7 @@ append_func_expr(StringInfo buf, const Node *expr, const List *rtable)
foreach (l, e->args)
{
append_expr(buf, lfirst(l), rtable);
- if (lnext(l))
+ if (lnext_compat(e->args, l))
appendStringInfoString(buf, ", ");
}
appendStringInfoChar(buf, ')');
@@ -217,7 +217,7 @@ append_restrict_clauses(StringInfo buf, PlannerInfo *root, List *clauses)
RestrictInfo *c = lfirst(cell);
append_expr(buf, (Node *) c->clause, root->parse->rtable);
- if (lnext(cell))
+ if (lnext_compat(clauses, cell))
appendStringInfoString(buf, ", ");
}
}
@@ -270,7 +270,7 @@ append_pathkeys(StringInfo buf, const List *pathkeys, const List *rtable)
append_expr(buf, (Node *) mem->em_expr, rtable);
}
appendStringInfoChar(buf, ')');
- if (lnext(i))
+ if (lnext_compat(pathkeys, i))
appendStringInfoString(buf, ", ");
}
appendStringInfoChar(buf, ')');
@@ -601,7 +601,10 @@ tsl_debug_append_pruned_pathlist(StringInfo buf, PlannerInfo *root, RelOptInfo *
foreach (lc1, rel->pathlist)
{
Path *p1 = (Path *) lfirst(lc1);
- ListCell *lc2, *prev = NULL;
+ ListCell *lc2;
+#if PG13_LT
+ ListCell *prev = NULL;
+#endif
foreach (lc2, fdw_info->considered_paths)
{
@@ -610,11 +613,13 @@ tsl_debug_append_pruned_pathlist(StringInfo buf, PlannerInfo *root, RelOptInfo *
if (path_is_origin(p1, p2))
{
fdw_info->considered_paths =
- list_delete_cell(fdw_info->considered_paths, lc2, prev);
+ list_delete_cell_compat(fdw_info->considered_paths, lc2, prev);
fdw_utils_free_path(p2);
break;
}
+#if PG13_LT
prev = lc2;
+#endif
}
}
diff --git a/tsl/src/fdw/deparse.c b/tsl/src/fdw/deparse.c
index d90636b5..efd7debb 100644
--- a/tsl/src/fdw/deparse.c
+++ b/tsl/src/fdw/deparse.c
@@ -2211,7 +2211,7 @@ deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context)
{
deparseExpr(lfirst(lowlist_item), context);
appendStringInfoChar(buf, ':');
- lowlist_item = lnext(lowlist_item);
+ lowlist_item = lnext_compat(node->reflowerindexpr, lowlist_item);
}
deparseExpr(lfirst(uplist_item), context);
appendStringInfoChar(buf, ']');
@@ -2273,7 +2273,7 @@ deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context)
{
if (!first)
appendStringInfoString(buf, ", ");
- if (use_variadic && lnext(arg) == NULL)
+ if (use_variadic && lnext_compat(node->args, arg) == NULL)
appendStringInfoString(buf, "VARIADIC ");
deparseExpr((Expr *) lfirst(arg), context);
first = false;
@@ -2601,7 +2601,7 @@ deparseAggref(Aggref *node, deparse_expr_cxt *context)
first = false;
/* Add VARIADIC */
- if (use_variadic && lnext(arg) == NULL)
+ if (use_variadic && lnext_compat(node->args, arg) == NULL)
appendStringInfoString(buf, "VARIADIC ");
deparseExpr((Expr *) n, context);
diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c
index 90b6c7c3..1e36f5dc 100644
--- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c
+++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c
@@ -182,7 +182,7 @@ build_compressed_scan_pathkeys(SortInfo *sort_info, PlannerInfo *root, List *chu
for (lc = list_head(chunk_pathkeys);
lc != NULL && bms_num_members(segmentby_columns) < info->num_segmentby_columns;
- lc = lnext(lc))
+ lc = lnext_compat(chunk_pathkeys, lc))
{
PathKey *pk = lfirst(lc);
var = (Var *) ts_find_em_expr_for_rel(pk->pk_eclass, info->chunk_rel);
@@ -1210,7 +1210,7 @@ build_sortinfo(RelOptInfo *chunk_rel, CompressionInfo *info, List *pathkeys)
* we keep looping even if we found all segmentby columns in case a
* columns appears both in baserestrictinfo and in ORDER BY clause
*/
- for (; lc != NULL; lc = lnext(lc))
+ for (; lc != NULL; lc = lnext_compat(pathkeys, lc))
{
Assert(bms_num_members(segmentby_columns) <= info->num_segmentby_columns);
pk = lfirst(lc);
@@ -1250,7 +1250,7 @@ build_sortinfo(RelOptInfo *chunk_rel, CompressionInfo *info, List *pathkeys)
* loop over the rest of pathkeys
* this needs to exactly match the configured compress_orderby
*/
- for (pk_index = 1; lc != NULL; lc = lnext(lc), pk_index++)
+ for (pk_index = 1; lc != NULL; lc = lnext_compat(pathkeys, lc), pk_index++)
{
bool reverse = false;
pk = lfirst(lc);
diff --git a/tsl/src/nodes/decompress_chunk/exec.c b/tsl/src/nodes/decompress_chunk/exec.c
index 035f2de4..f58e6f6c 100644
--- a/tsl/src/nodes/decompress_chunk/exec.c
+++ b/tsl/src/nodes/decompress_chunk/exec.c
@@ -121,7 +121,8 @@ initialize_column_state(DecompressChunkState *state)
state->columns = palloc0(state->num_columns * sizeof(DecompressChunkColumnState));
- for (i = 0, lc = list_head(state->varattno_map); i < state->num_columns; lc = lnext(lc), i++)
+ for (i = 0, lc = list_head(state->varattno_map); i < state->num_columns;
+ lc = lnext_compat(state->varattno_map, lc), i++)
{
DecompressChunkColumnState *column = &state->columns[i];
column->attno = lfirst_int(lc);
diff --git a/tsl/src/nodes/gapfill/planner.c b/tsl/src/nodes/gapfill/planner.c
index 56bdffd5..765a14ce 100644
--- a/tsl/src/nodes/gapfill/planner.c
+++ b/tsl/src/nodes/gapfill/planner.c
@@ -295,8 +295,10 @@ gapfill_build_pathtarget(PathTarget *pt_upper, PathTarget *pt_path, PathTarget *
/*
* check arguments past first argument dont have Vars
*/
- for (lc_arg = lnext(list_head(context.call.window->args)); lc_arg != NULL;
- lc_arg = lnext(lc_arg))
+ for (lc_arg = lnext_compat(context.call.window->args,
+ list_head(context.call.window->args));
+ lc_arg != NULL;
+ lc_arg = lnext_compat(context.call.window->args, lc_arg))
{
if (contain_var_clause(lfirst(lc_arg)))
ereport(ERROR,
@@ -553,9 +555,10 @@ gapfill_adjust_window_targetlist(PlannerInfo *root, RelOptInfo *input_rel, RelOp
/*
* check arguments past first argument dont have Vars
*/
- for (lc_arg = lnext(list_head(context.call.window->args));
+ for (lc_arg = lnext_compat(context.call.window->args,
+ list_head(context.call.window->args));
lc_arg != NULL;
- lc_arg = lnext(lc_arg))
+ lc_arg = lnext_compat(context.call.window->args, lc_arg))
{
if (contain_var_clause(lfirst(lc_arg)))
ereport(ERROR,
--
2.29.2