Cast result of copyObject() to correct type
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 9 Mar 2017 20:18:59 +0000 (15:18 -0500)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 29 Mar 2017 01:59:23 +0000 (21:59 -0400)
copyObject() is declared to return void *, which allows easily assigning
the result independent of the input, but it loses all type checking.

If the compiler supports typeof or something similar, cast the result to
the input type.  This creates a greater amount of type safety.  In some
cases, where the result is assigned to a generic type such as Node * or
Expr *, new casts are now necessary, but in general casts are now
unnecessary in the normal case and indicate that something unusual is
happening.

Reviewed-by: Mark Dilger <hornschnorter@gmail.com>
36 files changed:
config/c-compiler.m4
configure
configure.in
src/backend/bootstrap/bootstrap.c
src/backend/commands/copy.c
src/backend/commands/createas.c
src/backend/commands/event_trigger.c
src/backend/commands/prepare.c
src/backend/commands/view.c
src/backend/nodes/copyfuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/planagg.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/tlist.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_utilcmd.c
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteManip.c
src/backend/tcop/postgres.c
src/backend/utils/cache/plancache.c
src/backend/utils/cache/relcache.c
src/include/nodes/nodes.h
src/include/optimizer/tlist.h
src/include/pg_config.h.in
src/include/pg_config.h.win32

index 3321f226f3e4abd68d679e9a03b0b4fc18fe88e9..b366e40cff0df236af9d2ff2077b8dadbd4ba7f2 100644 (file)
@@ -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,
index 4b8229e959fa9d03eaeb198c63be6b8ba989db42..3c92cabb924de355566a8605f12e02f3d5605008 100755 (executable)
--- a/configure
+++ b/configure
@@ -11667,6 +11667,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; }
index 6c7421417112bbb971f7076b7a0c43e09507d802..d7c501af6a546175483f85a6f34ab116f201e1ab 100644 (file)
@@ -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
index d8efdb5ed3d1a98dc6b714a4030b517747ab3d40..46c207c86c8fd6d8feaf7ab36c0f2647bb7d6da8 100644 (file)
@@ -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 */
index ab59be8455261d85dcbd5af751b0976965fa1cac..0158eda591772434aacab9d38248077fc225df25 100644 (file)
@@ -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 */
index 3daffc894a1669db37830a2dd39d819cc4b029e2..20cb64661a6944b31e3d7a29fbc7e3e8ed5381de 100644 (file)
@@ -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)
index 7366fc74bec757ab727ffc81e0c8857ca831c333..d7c199f3144288d786d06922b1c0b259e6eb469c 100644 (file)
@@ -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);
index a92461097748f5ce5957eee5e1945b579344a8aa..dc6d43ec6d688c22820424cf814968749f735a25 100644 (file)
@@ -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);
 }
 
 /*
index 7d76f567a8e5dd663b2822338d85ea84559778b4..35e25db7dca6f686e442a9a718376d8c1d052e72 100644 (file)
@@ -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);
index c23d5c52851eea5bf29bb194709b19973d034bdf..1c88d601bd1c30479699badb3e33a6c7fcc7baa8 100644 (file)
@@ -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;
 
index c2b72d410af0a916f5b782064f1dc53b49813f64..a5d19f9b1c58b212994730f69ab9306ae8c1991f 100644 (file)
@@ -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;
    }
index aafec58281b6caf32c2c3327baeb0545f8275fae..d357479829f503c1154fb1f9ba2ee4a72f586c9e 100644 (file)
@@ -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);
            }
        }
index b4ac224a7a8a6c52d1052ee40acf01657661c0ed..53aefbd1a3dea8fc56f89d15d6ce4aee83072ee2 100644 (file)
@@ -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);
 
index c3fbf3cdf82cd927909fce1b5a866f4eb3c4bcfb..55657360fc380a6a8b76e44912f66504c38c706b 100644 (file)
@@ -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);
index fa7a5f8427744a8002d8f10e8ed5001fdf2dcf76..f99257b59939bc1c23eaa0423a869e7562eff028 100644 (file)
@@ -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);
index 5930747eba4839a2b9bbc486a30de77981e38027..4e3f6ee960f469d4487b9df6f295b07480c1e6b4 100644 (file)
@@ -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)
index 6fa654066247cf58d4928ba305d0c4eb6a45dcdb..db0e5b31e2e78d3bf4f19abf04bf0d1c08ceb1c7 100644 (file)
@@ -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
index 048815d7b07d4f8968b362140bc6b171e2fd6413..348c6b791f42c93ad099b40cdb2ac125b8df7474 100644 (file)
@@ -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)
index 824af3f54cb646e320f1075cc46793f158781803..de47153bacef43eec0736043e6beb6fa6159823c 100644 (file)
@@ -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,
index d88738ec7cbd915917562c4d823623ac9aa68a24..e327e66f6b9ee5430ef96bd816ce4999bfbcc201 100644 (file)
@@ -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;
index 5728f70c8b07cd6c3188a521939da98ef4f5e815..09523853d0c3f0a70f333d98fb950c8c57701ca4 100644 (file)
@@ -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));
index 25699fbc4aab04c2fce07cc50356b865a4ad55cd..f6025225be40b2d2fa6918f16f1219f08cf5f63c 100644 (file)
@@ -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 */
index 20865c0ee000064e992ba6219e4e81d2e7e9253a..9d53a29ad276fb79907888ad68a60a9abfa44886 100644 (file)
@@ -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");
index 47ca685b568be2a596e5766a11066678f26442c4..4f391d2d4110fba6f77b07da3cd86965842f4973 100644 (file)
@@ -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 */
index d3ed073cee29e4406c1c24bfc475db4daf9f4aa4..323be23bca63fbd6dc755d3cf0305c1ce885c196 100644 (file)
@@ -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);
        }
index 2eea258d28d4218249264485084508b8af0c51a0..2c19e0cbf583ff0d8c540506cdb11f9601c2d5ed 100644 (file)
@@ -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 */
index 673276a9d3d38ec5b2affeaece6d06f34ac39d9c..1ae43dc25dc2f4e0609f227bebba89fd855f1cab 100644 (file)
@@ -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);
index 354e5d0462005cd5e0d70bcd08f63e51d0ea3c6b..424be0c768409ddf17842791d5de48fcf84f9b42 100644 (file)
@@ -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;
index b23a3b7046e857c6fdbee845466b2a75762c08b5..da02cfd25ca92710542e9ea75d4b9150f781a302 100644 (file)
@@ -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;
    }
 }
 
index 6258a14c3907ba1ae2ebf8641814952a34a17fc0..3055b483b1ab415c95d76fc95390cd8b8f2c6365 100644 (file)
@@ -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
index d284ab7d3dfb1448bae78aac9f0b49acc34e00a7..043085d3a76ccd8f79a355d7531bbd153731ac2a 100644 (file)
@@ -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;
index bc52183bfb0867479bcdfe15e14a6051ece6ea9c..bc220989a150332418a0af429383d36b4a4879c1 100644 (file)
@@ -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;
index b9369ac275426a08698e524284574d2d5f1274bf..963ce45ae338432e79f5237b7adbdf33c58e4eb6 100644 (file)
@@ -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
index 976024a164744ce174928b9e840a08afe08a5fc6..ccb93d8c8023733bba6a7c65893ea10ed7d47259 100644 (file)
@@ -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);
 
index e1c1c9e9b4787c95412bd0be61bcfa41f1b72704..03e980328bda9556a24cf25dc49646a737eb164d 100644 (file)
 /* 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
 
 /* 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
index 5af8369202ca8e923e05ccd7d93abf7df7acd01d..9293ddd3a50bc523bba179d8230d1c4aa1073e7f 100644 (file)
 /* 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 */
 
 
 /* Define to empty if the C compiler does not understand signed types. */
 /* #undef signed */
+
+/* Define to how the compiler spells `typeof'. */
+#define typeof decltype