From 259ff80eb29c2c70e6afb77d266ce49cccbef223 Mon Sep 17 00:00:00 2001 From: Sven Klemm 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 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 #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 #include +#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