diff options
36 files changed, 178 insertions, 92 deletions
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 index 3321f226f3e..b366e40cff0 100644 --- a/config/c-compiler.m4 +++ b/config/c-compiler.m4 @@ -178,6 +178,33 @@ fi])# PGAC_C_STATIC_ASSERT +# PGAC_C_TYPEOF +# ------------- +# Check if the C compiler understands typeof or a variant. Define +# HAVE_TYPEOF if so, and define 'typeof' to the actual key word. +# +AC_DEFUN([PGAC_C_TYPEOF], +[AC_CACHE_CHECK(for typeof, pgac_cv_c_typeof, +[pgac_cv_c_typeof=no +for pgac_kw in typeof __typeof__ decltype; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], +[int x = 0; +$pgac_kw(x) y; +y = x; +return y;])], +[pgac_cv_c_typeof=$pgac_kw]) + test "$pgac_cv_c_typeof" != no && break +done]) +if test "$pgac_cv_c_typeof" != no; then + AC_DEFINE(HAVE_TYPEOF, 1, + [Define to 1 if your compiler understands `typeof' or something similar.]) + if test "$pgac_cv_c_typeof" != typeof; then + AC_DEFINE(typeof, $pgac_cv_c_typeof, [Define to how the compiler spells `typeof'.]) + fi +fi])# PGAC_C_TYPEOF + + + # PGAC_C_TYPES_COMPATIBLE # ----------------------- # Check if the C compiler understands __builtin_types_compatible_p, diff --git a/configure b/configure index 4b8229e959f..3c92cabb924 100755 --- a/configure +++ b/configure @@ -11668,6 +11668,46 @@ if test x"$pgac_cv__static_assert" = xyes ; then $as_echo "#define HAVE__STATIC_ASSERT 1" >>confdefs.h fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeof" >&5 +$as_echo_n "checking for typeof... " >&6; } +if ${pgac_cv_c_typeof+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_cv_c_typeof=no +for pgac_kw in typeof __typeof__ decltype; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +int x = 0; +$pgac_kw(x) y; +y = x; +return y; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_c_typeof=$pgac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$pgac_cv_c_typeof" != no && break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_c_typeof" >&5 +$as_echo "$pgac_cv_c_typeof" >&6; } +if test "$pgac_cv_c_typeof" != no; then + +$as_echo "#define HAVE_TYPEOF 1" >>confdefs.h + + if test "$pgac_cv_c_typeof" != typeof; then + +$as_echo "#define typeof \$pgac_cv_c_typeof" >>confdefs.h + + fi +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_types_compatible_p" >&5 $as_echo_n "checking for __builtin_types_compatible_p... " >&6; } if ${pgac_cv__types_compatible+:} false; then : diff --git a/configure.in b/configure.in index 6c742141711..d7c501af6a5 100644 --- a/configure.in +++ b/configure.in @@ -1330,6 +1330,7 @@ AC_C_FLEXIBLE_ARRAY_MEMBER PGAC_C_SIGNED PGAC_C_FUNCNAME_SUPPORT PGAC_C_STATIC_ASSERT +PGAC_C_TYPEOF PGAC_C_TYPES_COMPATIBLE PGAC_C_BUILTIN_BSWAP32 PGAC_C_BUILTIN_BSWAP64 diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index d8efdb5ed3d..46c207c86c8 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -1082,11 +1082,11 @@ index_register(Oid heap, memcpy(newind->il_info, indexInfo, sizeof(IndexInfo)); /* expressions will likely be null, but may as well copy it */ - newind->il_info->ii_Expressions = (List *) + newind->il_info->ii_Expressions = copyObject(indexInfo->ii_Expressions); newind->il_info->ii_ExpressionsState = NIL; /* predicate will likely be null, but may as well copy it */ - newind->il_info->ii_Predicate = (List *) + newind->il_info->ii_Predicate = copyObject(indexInfo->ii_Predicate); newind->il_info->ii_PredicateState = NULL; /* no exclusion constraints at bootstrap time, so no need to copy */ diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index ab59be84552..0158eda5917 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1470,7 +1470,7 @@ BeginCopy(ParseState *pstate, * function and is executed repeatedly. (See also the same hack in * DECLARE CURSOR and PREPARE.) XXX FIXME someday. */ - rewritten = pg_analyze_and_rewrite((RawStmt *) copyObject(raw_query), + rewritten = pg_analyze_and_rewrite(copyObject(raw_query), pstate->p_sourcetext, NULL, 0); /* check that we got back something we can work with */ diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 3daffc894a1..20cb64661a6 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -315,7 +315,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, * and is executed repeatedly. (See also the same hack in EXPLAIN and * PREPARE.) */ - rewritten = QueryRewrite((Query *) copyObject(query)); + rewritten = QueryRewrite(copyObject(query)); /* SELECT should never rewrite to more or less than one SELECT query */ if (list_length(rewritten) != 1) diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 7366fc74bec..d7c199f3144 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -1869,7 +1869,7 @@ EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, Oid opfamoid, OperatorFamilyRelationId, opfamoid); command->d.opfam.operators = operators; command->d.opfam.procedures = procedures; - command->parsetree = copyObject(stmt); + command->parsetree = (Node *) copyObject(stmt); currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList, command); @@ -1902,7 +1902,7 @@ EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid, OperatorClassRelationId, opcoid); command->d.createopc.operators = operators; command->d.createopc.procedures = procedures; - command->parsetree = copyObject(stmt); + command->parsetree = (Node *) copyObject(stmt); currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList, command); @@ -1937,7 +1937,7 @@ EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts); memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts); command->d.atscfg.ndicts = ndicts; - command->parsetree = copyObject(stmt); + command->parsetree = (Node *) copyObject(stmt); currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList, command); @@ -1967,7 +1967,7 @@ EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt) command->type = SCT_AlterDefaultPrivileges; command->d.defprivs.objtype = stmt->action->objtype; command->in_extension = creating_extension; - command->parsetree = copyObject(stmt); + command->parsetree = (Node *) copyObject(stmt); currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList, command); diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index a9246109774..dc6d43ec6d6 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -352,7 +352,7 @@ EvaluateParams(PreparedStatement *pstmt, List *params, * We have to run parse analysis for the expressions. Since the parser is * not cool about scribbling on its input, copy first. */ - params = (List *) copyObject(params); + params = copyObject(params); pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; @@ -554,7 +554,7 @@ FetchPreparedStatementTargetList(PreparedStatement *stmt) tlist = CachedPlanGetTargetList(stmt->plansource); /* Copy into caller's context in case plan gets invalidated */ - return (List *) copyObject(tlist); + return copyObject(tlist); } /* diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 7d76f567a8e..35e25db7dca 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -373,7 +373,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) * Var node twice. copyObject will expand any multiply-referenced subtree * into multiple copies. */ - viewParse = (Query *) copyObject(viewParse); + viewParse = copyObject(viewParse); /* Create a dummy ParseState for addRangeTableEntryForRelation */ pstate = make_parsestate(NULL); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index c23d5c52851..1c88d601bd1 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -43,7 +43,7 @@ /* Copy a field that is a pointer to some kind of Node or Node tree */ #define COPY_NODE_FIELD(fldname) \ - (newnode->fldname = copyObject(from->fldname)) + (newnode->fldname = copyObjectImpl(from->fldname)) /* Copy a field that is a pointer to a Bitmapset */ #define COPY_BITMAPSET_FIELD(fldname) \ @@ -4507,7 +4507,7 @@ _copyDropSubscriptionStmt(const DropSubscriptionStmt *from) */ #define COPY_NODE_CELL(new, old) \ (new) = (ListCell *) palloc(sizeof(ListCell)); \ - lfirst(new) = copyObject(lfirst(old)); + lfirst(new) = copyObjectImpl(lfirst(old)); static List * _copyList(const List *from) @@ -4610,13 +4610,13 @@ _copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from) /* - * copyObject + * copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h * * Create a copy of a Node tree or list. This is a "deep" copy: all * substructure is copied too, recursively. */ void * -copyObject(const void *from) +copyObjectImpl(const void *from) { void *retval; diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index c2b72d410af..a5d19f9b1c5 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -4004,9 +4004,9 @@ adjust_rowcompare_for_index(RowCompareExpr *clause, matching_cols); rc->inputcollids = list_truncate(list_copy(clause->inputcollids), matching_cols); - rc->largs = list_truncate((List *) copyObject(clause->largs), + rc->largs = list_truncate(copyObject(clause->largs), matching_cols); - rc->rargs = list_truncate((List *) copyObject(clause->rargs), + rc->rargs = list_truncate(copyObject(clause->rargs), matching_cols); return (Expr *) rc; } diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index aafec58281b..d357479829f 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -1275,7 +1275,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) foreach(l, uniq_exprs) { - Node *uniqexpr = lfirst(l); + Expr *uniqexpr = lfirst(l); TargetEntry *tle; tle = tlist_member(uniqexpr, newtlist); @@ -1318,7 +1318,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) groupColPos = 0; foreach(l, uniq_exprs) { - Node *uniqexpr = lfirst(l); + Expr *uniqexpr = lfirst(l); TargetEntry *tle; tle = tlist_member(uniqexpr, newtlist); @@ -4318,7 +4318,7 @@ process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) /* No, so add it */ nlp = makeNode(NestLoopParam); nlp->paramno = pitem->paramId; - nlp->paramval = copyObject(phv); + nlp->paramval = (Var *) copyObject(phv); root->curOuterParams = lappend(root->curOuterParams, nlp); } } diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index b4ac224a7a8..53aefbd1a3d 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -2306,8 +2306,8 @@ process_implied_equality(PlannerInfo *root, clause = make_opclause(opno, BOOLOID, /* opresulttype */ false, /* opretset */ - (Expr *) copyObject(item1), - (Expr *) copyObject(item2), + copyObject(item1), + copyObject(item2), InvalidOid, collation); @@ -2369,8 +2369,8 @@ build_implied_join_equality(Oid opno, clause = make_opclause(opno, BOOLOID, /* opresulttype */ false, /* opretset */ - (Expr *) copyObject(item1), - (Expr *) copyObject(item2), + copyObject(item1), + copyObject(item2), InvalidOid, collation); diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index c3fbf3cdf82..55657360fc3 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -369,11 +369,11 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, subroot->outer_params = NULL; subroot->init_plans = NIL; - subroot->parse = parse = (Query *) copyObject(root->parse); + subroot->parse = parse = copyObject(root->parse); IncrementVarSublevelsUp((Node *) parse, 1, 1); /* append_rel_list might contain outer Vars? */ - subroot->append_rel_list = (List *) copyObject(root->append_rel_list); + subroot->append_rel_list = copyObject(root->append_rel_list); IncrementVarSublevelsUp((Node *) subroot->append_rel_list, 1, 1); /* There shouldn't be any OJ info to translate, as yet */ Assert(subroot->join_info_list == NIL); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index fa7a5f84277..f99257b5993 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1157,7 +1157,7 @@ inheritance_planner(PlannerInfo *root) * executor doesn't need to see the modified copies --- we can just * pass it the original rowMarks list.) */ - subroot->rowMarks = (List *) copyObject(root->rowMarks); + subroot->rowMarks = copyObject(root->rowMarks); /* * The append_rel_list likewise might contain references to subquery @@ -1179,7 +1179,7 @@ inheritance_planner(PlannerInfo *root) AppendRelInfo *appinfo2 = (AppendRelInfo *) lfirst(lc2); if (bms_is_member(appinfo2->child_relid, modifiableARIindexes)) - appinfo2 = (AppendRelInfo *) copyObject(appinfo2); + appinfo2 = copyObject(appinfo2); subroot->append_rel_list = lappend(subroot->append_rel_list, appinfo2); diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 5930747eba4..4e3f6ee960f 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -111,10 +111,10 @@ static Var *search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist, Index newvarno, int rtoffset); -static Var *search_indexed_tlist_for_non_var(Node *node, +static Var *search_indexed_tlist_for_non_var(Expr *node, indexed_tlist *itlist, Index newvarno); -static Var *search_indexed_tlist_for_sortgroupref(Node *node, +static Var *search_indexed_tlist_for_sortgroupref(Expr *node, Index sortgroupref, indexed_tlist *itlist, Index newvarno); @@ -1440,7 +1440,7 @@ fix_param_node(PlannerInfo *root, Param *p) elog(ERROR, "unexpected PARAM_MULTIEXPR ID: %d", p->paramid); return copyObject(list_nth(params, colno - 1)); } - return copyObject(p); + return (Node *) copyObject(p); } /* @@ -1727,7 +1727,7 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset) if (tle->ressortgroupref != 0 && !IsA(tle->expr, Var)) { newexpr = (Node *) - search_indexed_tlist_for_sortgroupref((Node *) tle->expr, + search_indexed_tlist_for_sortgroupref(tle->expr, tle->ressortgroupref, subplan_itlist, OUTER_VAR); @@ -1810,7 +1810,7 @@ convert_combining_aggrefs(Node *node, void *context) */ child_agg->args = NIL; child_agg->aggfilter = NULL; - parent_agg = (Aggref *) copyObject(child_agg); + parent_agg = copyObject(child_agg); child_agg->args = orig_agg->args; child_agg->aggfilter = orig_agg->aggfilter; @@ -2054,7 +2054,7 @@ search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist, * so there's a correctness reason not to call it unless that's set. */ static Var * -search_indexed_tlist_for_non_var(Node *node, +search_indexed_tlist_for_non_var(Expr *node, indexed_tlist *itlist, Index newvarno) { TargetEntry *tle; @@ -2095,7 +2095,7 @@ search_indexed_tlist_for_non_var(Node *node, * And it's also faster than search_indexed_tlist_for_non_var. */ static Var * -search_indexed_tlist_for_sortgroupref(Node *node, +search_indexed_tlist_for_sortgroupref(Expr *node, Index sortgroupref, indexed_tlist *itlist, Index newvarno) @@ -2229,7 +2229,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) /* See if the PlaceHolderVar has bubbled up from a lower plan node */ if (context->outer_itlist && context->outer_itlist->has_ph_vars) { - newvar = search_indexed_tlist_for_non_var((Node *) phv, + newvar = search_indexed_tlist_for_non_var((Expr *) phv, context->outer_itlist, OUTER_VAR); if (newvar) @@ -2237,7 +2237,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) } if (context->inner_itlist && context->inner_itlist->has_ph_vars) { - newvar = search_indexed_tlist_for_non_var((Node *) phv, + newvar = search_indexed_tlist_for_non_var((Expr *) phv, context->inner_itlist, INNER_VAR); if (newvar) @@ -2252,7 +2252,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) /* Try matching more complex expressions too, if tlists have any */ if (context->outer_itlist && context->outer_itlist->has_non_vars) { - newvar = search_indexed_tlist_for_non_var(node, + newvar = search_indexed_tlist_for_non_var((Expr *) node, context->outer_itlist, OUTER_VAR); if (newvar) @@ -2260,7 +2260,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) } if (context->inner_itlist && context->inner_itlist->has_non_vars) { - newvar = search_indexed_tlist_for_non_var(node, + newvar = search_indexed_tlist_for_non_var((Expr *) node, context->inner_itlist, INNER_VAR); if (newvar) @@ -2344,7 +2344,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) /* See if the PlaceHolderVar has bubbled up from a lower plan node */ if (context->subplan_itlist->has_ph_vars) { - newvar = search_indexed_tlist_for_non_var((Node *) phv, + newvar = search_indexed_tlist_for_non_var((Expr *) phv, context->subplan_itlist, context->newvarno); if (newvar) @@ -2380,7 +2380,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) /* Try matching more complex expressions too, if tlist has any */ if (context->subplan_itlist->has_non_vars) { - newvar = search_indexed_tlist_for_non_var(node, + newvar = search_indexed_tlist_for_non_var((Expr *) node, context->subplan_itlist, context->newvarno); if (newvar) diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 6fa65406624..db0e5b31e2e 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -125,7 +125,7 @@ assign_param_for_var(PlannerInfo *root, Var *var) } /* Nope, so make a new one */ - var = (Var *) copyObject(var); + var = copyObject(var); var->varlevelsup = 0; pitem = makeNode(PlannerParamItem); @@ -224,7 +224,7 @@ assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) } /* Nope, so make a new one */ - phv = (PlaceHolderVar *) copyObject(phv); + phv = copyObject(phv); if (phv->phlevelsup != 0) { IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0); @@ -316,7 +316,7 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg) * It does not seem worthwhile to try to match duplicate outer aggs. Just * make a new slot every time. */ - agg = (Aggref *) copyObject(agg); + agg = copyObject(agg); IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0); Assert(agg->agglevelsup == 0); @@ -358,7 +358,7 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp) * It does not seem worthwhile to try to match duplicate outer aggs. Just * make a new slot every time. */ - grp = (GroupingFunc *) copyObject(grp); + grp = copyObject(grp); IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0); Assert(grp->agglevelsup == 0); @@ -491,7 +491,7 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, * same sub-Query node, but the planner wants to scribble on the Query. * Try to clean this up when we do querytree redesign... */ - subquery = (Query *) copyObject(orig_subquery); + subquery = copyObject(orig_subquery); /* * If it's an EXISTS subplan, we might be able to simplify it. @@ -568,7 +568,7 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, List *paramIds; /* Make a second copy of the original subquery */ - subquery = (Query *) copyObject(orig_subquery); + subquery = copyObject(orig_subquery); /* and re-simplify */ simple_exists = simplify_EXISTS_query(root, subquery); Assert(simple_exists); @@ -1431,7 +1431,7 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, * Copy the subquery so we can modify it safely (see comments in * make_subplan). */ - subselect = (Query *) copyObject(subselect); + subselect = copyObject(subselect); /* * See if the subquery can be simplified based on the knowledge that it's diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 048815d7b07..348c6b791f4 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -1592,7 +1592,7 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte) * Need a modifiable copy of the VALUES list to hack on, just in case it's * multiply referenced. */ - values_list = (List *) copyObject(linitial(rte->values_lists)); + values_list = copyObject(linitial(rte->values_lists)); /* * The VALUES RTE can't contain any Vars of level zero, let alone any that @@ -2128,7 +2128,7 @@ pullup_replace_vars_callback(Var *var, varattno); /* Make a copy of the tlist item to return */ - newnode = copyObject(tle->expr); + newnode = (Node *) copyObject(tle->expr); /* Insert PlaceHolderVar if needed */ if (rcon->need_phvs) diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 824af3f54cb..de47153bace 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -180,7 +180,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist) var->varno == result_relation) continue; /* don't need it */ - if (tlist_member((Node *) var, tlist)) + if (tlist_member((Expr *) var, tlist)) continue; /* already got it */ tle = makeTargetEntry((Expr *) var, diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index d88738ec7cb..e327e66f6b9 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -1274,7 +1274,7 @@ generate_append_tlist(List *colTypes, List *colCollations, static List * generate_setop_grouplist(SetOperationStmt *op, List *targetlist) { - List *grouplist = (List *) copyObject(op->groupClauses); + List *grouplist = copyObject(op->groupClauses); ListCell *lg; ListCell *lt; @@ -1879,7 +1879,7 @@ adjust_appendrel_attrs_mutator(Node *node, rte = rt_fetch(appinfo->parent_relid, context->root->parse->rtable); - fields = (List *) copyObject(appinfo->translated_vars); + fields = copyObject(appinfo->translated_vars); rowexpr = makeNode(RowExpr); rowexpr->args = fields; rowexpr->row_typeid = var->vartype; diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index 5728f70c8b0..09523853d0c 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -51,7 +51,7 @@ static bool split_pathtarget_walker(Node *node, * equal() to the given expression. Result is NULL if no such member. */ TargetEntry * -tlist_member(Node *node, List *targetlist) +tlist_member(Expr *node, List *targetlist) { ListCell *temp; @@ -72,12 +72,12 @@ tlist_member(Node *node, List *targetlist) * involving binary-compatible sort operations. */ TargetEntry * -tlist_member_ignore_relabel(Node *node, List *targetlist) +tlist_member_ignore_relabel(Expr *node, List *targetlist) { ListCell *temp; while (node && IsA(node, RelabelType)) - node = (Node *) ((RelabelType *) node)->arg; + node = ((RelabelType *) node)->arg; foreach(temp, targetlist) { @@ -139,7 +139,7 @@ add_to_flat_tlist(List *tlist, List *exprs) foreach(lc, exprs) { - Node *expr = (Node *) lfirst(lc); + Expr *expr = (Expr *) lfirst(lc); if (!tlist_member(expr, tlist)) { @@ -762,7 +762,7 @@ apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target) if (expr && IsA(expr, Var)) tle = tlist_member_match_var((Var *) expr, tlist); else - tle = tlist_member((Node *) expr, tlist); + tle = tlist_member(expr, tlist); /* * Complain if noplace for the sortgrouprefs label, or if we'd @@ -999,7 +999,7 @@ split_pathtarget_at_srfs(PlannerInfo *root, foreach(lcx, input_srfs) { - Node *srf = (Node *) lfirst(lcx); + Expr *srf = (Expr *) lfirst(lcx); if (list_member(prev_level_tlist, srf)) add_new_column_to_pathtarget(ntarget, copyObject(srf)); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 25699fbc4aa..f6025225be4 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -2548,7 +2548,7 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt) * in the IntoClause because that's where intorel_startup() can * conveniently get it from. */ - stmt->into->viewQuery = copyObject(query); + stmt->into->viewQuery = (Node *) copyObject(query); } /* represent the command as a utility Query */ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 20865c0ee00..9d53a29ad27 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -15599,7 +15599,7 @@ TableFuncTypeName(List *columns) { FunctionParameter *p = (FunctionParameter *) linitial(columns); - result = (TypeName *) copyObject(p->argType); + result = copyObject(p->argType); } else result = SystemTypeName("record"); diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 47ca685b568..4f391d2d411 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -348,7 +348,7 @@ transformJoinUsingClause(ParseState *pstate, /* Now create the lvar = rvar join condition */ e = makeSimpleA_Expr(AEXPR_OP, "=", - copyObject(lvar), copyObject(rvar), + (Node *) copyObject(lvar), (Node *) copyObject(rvar), -1); /* Prepare to combine into an AND clause, if multiple join columns */ diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index d3ed073cee2..323be23bca6 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -1255,7 +1255,7 @@ transformAExprIn(ParseState *pstate, A_Expr *a) /* ROW() op ROW() is handled specially */ cmp = make_row_comparison_op(pstate, a->name, - (List *) copyObject(((RowExpr *) lexpr)->args), + copyObject(((RowExpr *) lexpr)->args), ((RowExpr *) rexpr)->args, a->location); } diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 2eea258d28d..2c19e0cbf58 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -1804,7 +1804,7 @@ addRangeTableEntryForJoin(ParseState *pstate, rte->joinaliasvars = aliasvars; rte->alias = alias; - eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL); + eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL); numaliases = list_length(eref->colnames); /* fill in any unspecified alias columns */ diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 673276a9d3d..1ae43dc25dc 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -167,7 +167,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) * We must not scribble on the passed-in CreateStmt, so copy it. (This is * overkill, but easy.) */ - stmt = (CreateStmt *) copyObject(stmt); + stmt = copyObject(stmt); /* Set up pstate */ pstate = make_parsestate(NULL); @@ -2107,7 +2107,7 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) * We must not scribble on the passed-in IndexStmt, so copy it. (This is * overkill, but easy.) */ - stmt = (IndexStmt *) copyObject(stmt); + stmt = copyObject(stmt); /* Set up pstate */ pstate = make_parsestate(NULL); @@ -2521,7 +2521,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, * We must not scribble on the passed-in AlterTableStmt, so copy it. (This * is overkill, but easy.) */ - stmt = (AlterTableStmt *) copyObject(stmt); + stmt = copyObject(stmt); /* Caller is responsible for locking the relation */ rel = relation_open(relid, NoLock); diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 354e5d04620..424be0c7684 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -349,8 +349,8 @@ rewriteRuleAction(Query *parsetree, * Make modifiable copies of rule action and qual (what we're passed are * the stored versions in the relcache; don't touch 'em!). */ - rule_action = (Query *) copyObject(rule_action); - rule_qual = (Node *) copyObject(rule_qual); + rule_action = copyObject(rule_action); + rule_qual = copyObject(rule_qual); /* * Acquire necessary locks and fix any deleted JOIN RTE entries. @@ -408,7 +408,7 @@ rewriteRuleAction(Query *parsetree, * that rule action's rtable is separate and shares no substructure with * the main rtable. Hence do a deep copy here. */ - sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable), + sub_action->rtable = list_concat(copyObject(parsetree->rtable), sub_action->rtable); /* @@ -1897,7 +1897,7 @@ CopyAndAddInvertedQual(Query *parsetree, CmdType event) { /* Don't scribble on the passed qual (it's in the relcache!) */ - Node *new_qual = (Node *) copyObject(rule_qual); + Node *new_qual = copyObject(rule_qual); acquireLocksOnSubLinks_context context; context.for_execute = true; diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index b23a3b7046e..da02cfd25ca 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -1412,11 +1412,11 @@ ReplaceVarsFromTargetList_callback(Var *var, else { /* Make a copy of the tlist item to return */ - Node *newnode = copyObject(tle->expr); + Expr *newnode = copyObject(tle->expr); /* Must adjust varlevelsup if tlist item is from higher query */ if (var->varlevelsup > 0) - IncrementVarSublevelsUp(newnode, var->varlevelsup, 0); + IncrementVarSublevelsUp((Node *) newnode, var->varlevelsup, 0); /* * Check to see if the tlist item contains a PARAM_MULTIEXPR Param, @@ -1428,12 +1428,12 @@ ReplaceVarsFromTargetList_callback(Var *var, * create semantic oddities that users of rules would probably prefer * not to cope with. So treat it as an unimplemented feature. */ - if (contains_multiexpr_param(newnode, NULL)) + if (contains_multiexpr_param((Node *) newnode, NULL)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command"))); - return newnode; + return (Node *) newnode; } } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 6258a14c390..3055b483b1a 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -616,7 +616,7 @@ pg_parse_query(const char *query_string) #ifdef COPY_PARSE_PLAN_TREES /* Optional debugging check: pass raw parsetrees through copyObject() */ { - List *new_list = (List *) copyObject(raw_parsetree_list); + List *new_list = copyObject(raw_parsetree_list); /* This checks both copyObject() and the equal() routines... */ if (!equal(new_list, raw_parsetree_list)) @@ -756,7 +756,7 @@ pg_rewrite_query(Query *query) { List *new_list; - new_list = (List *) copyObject(querytree_list); + new_list = copyObject(querytree_list); /* This checks both copyObject() and the equal() routines... */ if (!equal(new_list, querytree_list)) elog(WARNING, "copyObject() failed to produce equal parse tree"); @@ -803,7 +803,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) #ifdef COPY_PARSE_PLAN_TREES /* Optional debugging check: pass plan output through copyObject() */ { - PlannedStmt *new_plan = (PlannedStmt *) copyObject(plan); + PlannedStmt *new_plan = copyObject(plan); /* * equal() currently does not have routines to compare Plan nodes, so diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index d284ab7d3df..043085d3a76 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -361,7 +361,7 @@ CompleteCachedPlan(CachedPlanSource *plansource, "CachedPlanQuery", ALLOCSET_START_SMALL_SIZES); MemoryContextSwitchTo(querytree_context); - querytree_list = (List *) copyObject(querytree_list); + querytree_list = copyObject(querytree_list); } plansource->query_context = querytree_context; @@ -734,7 +734,7 @@ RevalidateCachedQuery(CachedPlanSource *plansource) ALLOCSET_START_SMALL_SIZES); oldcxt = MemoryContextSwitchTo(querytree_context); - qlist = (List *) copyObject(tlist); + qlist = copyObject(tlist); /* * Use the planner machinery to extract dependencies. Data is saved in @@ -909,7 +909,7 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, if (qlist == NIL) { if (!plansource->is_oneshot) - qlist = (List *) copyObject(plansource->query_list); + qlist = copyObject(plansource->query_list); else qlist = plansource->query_list; } @@ -953,7 +953,7 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, */ MemoryContextSwitchTo(plan_context); - plist = (List *) copyObject(plist); + plist = copyObject(plist); } else plan_context = CurrentMemoryContext; @@ -1367,9 +1367,9 @@ CopyCachedPlan(CachedPlanSource *plansource) "CachedPlanQuery", ALLOCSET_START_SMALL_SIZES); MemoryContextSwitchTo(querytree_context); - newsource->query_list = (List *) copyObject(plansource->query_list); - newsource->relationOids = (List *) copyObject(plansource->relationOids); - newsource->invalItems = (List *) copyObject(plansource->invalItems); + newsource->query_list = copyObject(plansource->query_list); + newsource->relationOids = copyObject(plansource->relationOids); + newsource->invalItems = copyObject(plansource->invalItems); if (plansource->search_path) newsource->search_path = CopyOverrideSearchPath(plansource->search_path); newsource->query_context = querytree_context; diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index bc52183bfb0..bc220989a15 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -4697,7 +4697,7 @@ RelationGetIndexExpressions(Relation relation) /* Quick exit if we already computed the result. */ if (relation->rd_indexprs) - return (List *) copyObject(relation->rd_indexprs); + return copyObject(relation->rd_indexprs); /* Quick exit if there is nothing to do. */ if (relation->rd_indextuple == NULL || @@ -4733,7 +4733,7 @@ RelationGetIndexExpressions(Relation relation) /* Now save a copy of the completed tree in the relcache entry. */ oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt); - relation->rd_indexprs = (List *) copyObject(result); + relation->rd_indexprs = copyObject(result); MemoryContextSwitchTo(oldcxt); return result; @@ -4760,7 +4760,7 @@ RelationGetIndexPredicate(Relation relation) /* Quick exit if we already computed the result. */ if (relation->rd_indpred) - return (List *) copyObject(relation->rd_indpred); + return copyObject(relation->rd_indpred); /* Quick exit if there is nothing to do. */ if (relation->rd_indextuple == NULL || @@ -4802,7 +4802,7 @@ RelationGetIndexPredicate(Relation relation) /* Now save a copy of the completed tree in the relcache entry. */ oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt); - relation->rd_indpred = (List *) copyObject(result); + relation->rd_indpred = copyObject(result); MemoryContextSwitchTo(oldcxt); return result; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index b9369ac2754..963ce45ae33 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -610,7 +610,13 @@ extern int16 *readAttrNumberCols(int numCols); /* * nodes/copyfuncs.c */ -extern void *copyObject(const void *obj); +extern void *copyObjectImpl(const void *obj); +/* cast result back to argument type, if supported by compiler */ +#ifdef HAVE_TYPEOF +#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj)) +#else +#define copyObject(obj) copyObjectImpl(obj) +#endif /* * nodes/equalfuncs.c diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h index 976024a1647..ccb93d8c802 100644 --- a/src/include/optimizer/tlist.h +++ b/src/include/optimizer/tlist.h @@ -17,8 +17,8 @@ #include "nodes/relation.h" -extern TargetEntry *tlist_member(Node *node, List *targetlist); -extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist); +extern TargetEntry *tlist_member(Expr *node, List *targetlist); +extern TargetEntry *tlist_member_ignore_relabel(Expr *node, List *targetlist); extern List *add_to_flat_tlist(List *tlist, List *exprs); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index e1c1c9e9b47..03e980328bd 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -603,6 +603,9 @@ /* Define to 1 if you have the `towlower' function. */ #undef HAVE_TOWLOWER +/* Define to 1 if your compiler understands `typeof' or something similar. */ +#undef HAVE_TYPEOF + /* Define to 1 if you have the external array `tzname'. */ #undef HAVE_TZNAME @@ -931,6 +934,9 @@ /* Define to empty if the C compiler does not understand signed types. */ #undef signed +/* Define to how the compiler spells `typeof'. */ +#undef typeof + /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 5af8369202c..9293ddd3a50 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -454,6 +454,9 @@ /* Define to 1 if you have the `towlower' function. */ #define HAVE_TOWLOWER 1 +/* Define to 1 if your compiler understands `typeof' or something similar. */ +#define HAVE_TYPEOF 1 + /* Define to 1 if you have the external array `tzname'. */ /* #undef HAVE_TZNAME */ @@ -682,3 +685,6 @@ /* Define to empty if the C compiler does not understand signed types. */ /* #undef signed */ + +/* Define to how the compiler spells `typeof'. */ +#define typeof decltype |