There is a common coding pattern that goes like this: RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); Assert(IsA(rinfo, RestrictInfo));
(Arguably, the Assert should come before the cast, but I guess it's done this way out of convenience.) (Not to mention the other common coding pattern of just doing the cast and hoping for the best.) I propose a macro castNode() that combines the assertion and the cast, so this would become RestrictInfo *rinfo = castNode(RestrictInfo, lfirst(lc)); This is inspired by the dynamic_cast operator in C++, but follows the syntax of the well-known makeNode() macro. Besides saving a bunch of code and making things safer, the function syntax also makes some code easier to read by saving levels of parentheses, for example: - Assert(IsA(sstate->testexpr, BoolExprState)); - oplist = ((BoolExprState *) sstate->testexpr)->args; + oplist = castNode(BoolExprState, sstate->testexpr)->args; Attached is a patch that shows how this would work. There is a lot more that can be done, but I just stopped after a while for now. -- Peter Eisentraut http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From fd1e766ff765ecc58380d09c657ca254a6bf5674 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <pete...@gmx.net> Date: Wed, 28 Dec 2016 12:00:00 -0500 Subject: [PATCH] Add castNode() macro --- contrib/pg_stat_statements/pg_stat_statements.c | 10 ++++------ contrib/postgres_fdw/deparse.c | 5 +---- contrib/postgres_fdw/postgres_fdw.c | 12 ++++-------- src/backend/catalog/pg_proc.c | 3 +-- src/backend/commands/aggregatecmds.c | 4 ++-- src/backend/commands/analyze.c | 6 +++--- src/backend/commands/async.c | 8 ++++---- src/backend/commands/collationcmds.c | 2 +- src/backend/commands/constraint.c | 2 +- src/backend/commands/copy.c | 14 +++++++------- src/backend/commands/createas.c | 5 ++--- src/backend/commands/dropcmds.c | 4 +--- src/backend/commands/explain.c | 16 +++++++--------- src/backend/commands/functioncmds.c | 7 ++----- src/backend/commands/matview.c | 3 +-- src/backend/commands/opclasscmds.c | 9 +++------ src/backend/commands/tablecmds.c | 14 ++++---------- src/backend/commands/trigger.c | 4 +--- src/backend/commands/user.c | 4 +--- src/backend/commands/view.c | 3 +-- src/backend/executor/execAmi.c | 3 +-- src/backend/executor/execQual.c | 6 ++---- src/backend/executor/execTuples.c | 5 +---- src/backend/executor/functions.c | 6 ++---- src/backend/executor/nodeAgg.c | 6 ++---- src/backend/executor/nodeCtescan.c | 3 +-- src/backend/executor/nodeCustom.c | 3 +-- src/backend/executor/nodeHashjoin.c | 7 ++----- src/backend/executor/nodeLockRows.c | 4 +--- src/backend/executor/nodeModifyTable.c | 4 +--- src/backend/executor/nodeSubplan.c | 15 +++++---------- src/backend/executor/nodeWorktablescan.c | 4 ++-- src/include/nodes/nodes.h | 2 ++ 33 files changed, 74 insertions(+), 129 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 8ce24e0401..d21f1d044c 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2336,9 +2336,8 @@ JumbleRangeTable(pgssJumbleState *jstate, List *rtable) foreach(lc, rtable) { - RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); + RangeTblEntry *rte = castNode(RangeTblEntry, lfirst(lc)); - Assert(IsA(rte, RangeTblEntry)); APP_JUMB(rte->rtekind); switch (rte->rtekind) { @@ -2524,7 +2523,7 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) APP_JUMB(sublink->subLinkType); APP_JUMB(sublink->subLinkId); JumbleExpr(jstate, (Node *) sublink->testexpr); - JumbleQuery(jstate, (Query *) sublink->subselect); + JumbleQuery(jstate, castNode(Query, sublink->subselect)); } break; case T_FieldSelect: @@ -2590,9 +2589,8 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) JumbleExpr(jstate, (Node *) caseexpr->arg); foreach(temp, caseexpr->args) { - CaseWhen *when = (CaseWhen *) lfirst(temp); + CaseWhen *when = castNode(CaseWhen, lfirst(temp)); - Assert(IsA(when, CaseWhen)); JumbleExpr(jstate, (Node *) when->expr); JumbleExpr(jstate, (Node *) when->result); } @@ -2804,7 +2802,7 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) /* we store the string name because RTE_CTE RTEs need it */ APP_JUMB_STRING(cte->ctename); - JumbleQuery(jstate, (Query *) cte->ctequery); + JumbleQuery(jstate, castNode(Query, cte->ctequery)); } break; case T_SetOperationStmt: diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index 66b059ac96..1453f49a46 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -1315,10 +1315,7 @@ deparseExplicitTargetList(List *tlist, List **retrieved_attrs, foreach(lc, tlist) { - TargetEntry *tle = (TargetEntry *) lfirst(lc); - - /* Extract expression if TargetEntry node */ - Assert(IsA(tle, TargetEntry)); + TargetEntry *tle = castNode(TargetEntry, lfirst(lc)); if (i > 0) appendStringInfoString(buf, ", "); diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index fbe69295e7..de9d971892 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -1159,9 +1159,7 @@ postgresGetForeignPlan(PlannerInfo *root, */ foreach(lc, scan_clauses) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); - - Assert(IsA(rinfo, RestrictInfo)); + RestrictInfo *rinfo = castNode(RestrictInfo, lfirst(lc)); /* Ignore any pseudoconstants, they're dealt with elsewhere */ if (rinfo->pseudoconstant) @@ -4958,14 +4956,12 @@ conversion_error_callback(void *arg) { /* error occurred in a scan against a foreign join */ ForeignScanState *fsstate = errpos->fsstate; - ForeignScan *fsplan = (ForeignScan *) fsstate->ss.ps.plan; + ForeignScan *fsplan = castNode(ForeignScan, fsstate->ss.ps.plan); EState *estate = fsstate->ss.ps.state; TargetEntry *tle; - Assert(IsA(fsplan, ForeignScan)); - tle = (TargetEntry *) list_nth(fsplan->fdw_scan_tlist, - errpos->cur_attno - 1); - Assert(IsA(tle, TargetEntry)); + tle = castNode(TargetEntry, list_nth(fsplan->fdw_scan_tlist, + errpos->cur_attno - 1)); /* * Target list can have Vars and expressions. For Vars, we can get diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index c1d1505e64..d1e3c6eff1 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -513,8 +513,7 @@ ProcedureCreate(const char *procedureName, Anum_pg_proc_proargdefaults, &isnull); Assert(!isnull); - oldDefaults = (List *) stringToNode(TextDatumGetCString(proargdefaults)); - Assert(IsA(oldDefaults, List)); + oldDefaults = castNode(List, stringToNode(TextDatumGetCString(proargdefaults))); Assert(list_length(oldDefaults) == oldproc->pronargdefaults); /* new list can have more defaults than old, advance over 'em */ diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 19db38d7fc..f338273a93 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -109,13 +109,13 @@ DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List aggKind = AGGKIND_ORDERED_SET; else numDirectArgs = 0; - args = (List *) linitial(args); + args = castNode(List, linitial(args)); } /* Examine aggregate's definition clauses */ foreach(pl, parameters) { - DefElem *defel = (DefElem *) lfirst(pl); + DefElem *defel = castNode(DefElem, lfirst(pl)); /* * sfunc1, stype1, and initcond1 are accepted as obsolete spellings diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f4afcd9aae..9f9c74cd7c 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -722,9 +722,9 @@ compute_index_stats(Relation onerel, double totalrows, econtext->ecxt_scantuple = slot; /* Set up execution state for predicate. */ - predicate = (List *) - ExecPrepareExpr((Expr *) indexInfo->ii_Predicate, - estate); + predicate = castNode(List, + ExecPrepareExpr((Expr *) indexInfo->ii_Predicate, + estate)); /* Compute and save index expression values */ exprvals = (Datum *) palloc(numrows * attr_cnt * sizeof(Datum)); diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 716f1c3318..6d9308ea81 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -1636,7 +1636,7 @@ AtSubCommit_Notify(void) List *parentPendingActions; List *parentPendingNotifies; - parentPendingActions = (List *) linitial(upperPendingActions); + parentPendingActions = castNode(List, linitial(upperPendingActions)); upperPendingActions = list_delete_first(upperPendingActions); Assert(list_length(upperPendingActions) == @@ -1647,7 +1647,7 @@ AtSubCommit_Notify(void) */ pendingActions = list_concat(parentPendingActions, pendingActions); - parentPendingNotifies = (List *) linitial(upperPendingNotifies); + parentPendingNotifies = castNode(List, linitial(upperPendingNotifies)); upperPendingNotifies = list_delete_first(upperPendingNotifies); Assert(list_length(upperPendingNotifies) == @@ -1679,13 +1679,13 @@ AtSubAbort_Notify(void) */ while (list_length(upperPendingActions) > my_level - 2) { - pendingActions = (List *) linitial(upperPendingActions); + pendingActions = castNode(List, linitial(upperPendingActions)); upperPendingActions = list_delete_first(upperPendingActions); } while (list_length(upperPendingNotifies) > my_level - 2) { - pendingNotifies = (List *) linitial(upperPendingNotifies); + pendingNotifies = castNode(List, linitial(upperPendingNotifies)); upperPendingNotifies = list_delete_first(upperPendingNotifies); } } diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 9bba748708..7e20e1ada4 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -61,7 +61,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters) foreach(pl, parameters) { - DefElem *defel = (DefElem *) lfirst(pl); + DefElem *defel = castNode(DefElem, lfirst(pl)); DefElem **defelp; if (pg_strcasecmp(defel->defname, "from") == 0) diff --git a/src/backend/commands/constraint.c b/src/backend/commands/constraint.c index 26f9114f55..775cbbef88 100644 --- a/src/backend/commands/constraint.c +++ b/src/backend/commands/constraint.c @@ -37,7 +37,7 @@ Datum unique_key_recheck(PG_FUNCTION_ARGS) { - TriggerData *trigdata = (TriggerData *) fcinfo->context; + TriggerData *trigdata = castNode(TriggerData, fcinfo->context); const char *funcname = "unique_key_recheck"; HeapTuple new_row; ItemPointerData tmptid; diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index aa25a23336..d5f8973431 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1017,7 +1017,7 @@ ProcessCopyOptions(ParseState *pstate, /* Extract options from the statement node tree */ foreach(option, options) { - DefElem *defel = (DefElem *) lfirst(option); + DefElem *defel = castNode(DefElem, lfirst(option)); if (strcmp(defel->defname, "format") == 0) { @@ -1114,7 +1114,7 @@ ProcessCopyOptions(ParseState *pstate, if (defel->arg && IsA(defel->arg, A_Star)) cstate->force_quote_all = true; else if (defel->arg && IsA(defel->arg, List)) - cstate->force_quote = (List *) defel->arg; + cstate->force_quote = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1130,7 +1130,7 @@ ProcessCopyOptions(ParseState *pstate, errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); if (defel->arg && IsA(defel->arg, List)) - cstate->force_notnull = (List *) defel->arg; + cstate->force_notnull = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1145,7 +1145,7 @@ ProcessCopyOptions(ParseState *pstate, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); if (defel->arg && IsA(defel->arg, List)) - cstate->force_null = (List *) defel->arg; + cstate->force_null = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1167,7 +1167,7 @@ ProcessCopyOptions(ParseState *pstate, parser_errposition(pstate, defel->location))); cstate->convert_selectively = true; if (defel->arg == NULL || IsA(defel->arg, List)) - cstate->convert_select = (List *) defel->arg; + cstate->convert_select = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1467,7 +1467,7 @@ BeginCopy(ParseState *pstate, /* examine queries to determine which error message to issue */ foreach(lc, rewritten) { - Query *q = (Query *) lfirst(lc); + Query *q = castNode(Query, lfirst(lc)); if (q->querySource == QSRC_QUAL_INSTEAD_RULE) ereport(ERROR, @@ -1484,7 +1484,7 @@ BeginCopy(ParseState *pstate, errmsg("multi-statement DO INSTEAD rules are not supported for COPY"))); } - query = (Query *) linitial(rewritten); + query = castNode(Query, linitial(rewritten)); /* The grammar allows SELECT INTO, but we don't support that */ if (query->utilityStmt != NULL && diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index d6d52d9929..ffd6e8cab9 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -224,7 +224,7 @@ ObjectAddress ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag) { - Query *query = (Query *) stmt->query; + Query *query = castNode(Query, stmt->query); IntoClause *into = stmt->into; bool is_matview = (into->viewQuery != NULL); DestReceiver *dest; @@ -261,11 +261,10 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, * The contained Query could be a SELECT, or an EXECUTE utility command. * If the latter, we just pass it off to ExecuteQuery. */ - Assert(IsA(query, Query)); if (query->commandType == CMD_UTILITY && IsA(query->utilityStmt, ExecuteStmt)) { - ExecuteStmt *estmt = (ExecuteStmt *) query->utilityStmt; + ExecuteStmt *estmt = castNode(ExecuteStmt, query->utilityStmt); Assert(!is_matview); /* excluded by syntax */ ExecuteQuery(estmt, into, queryString, params, dest, completionTag); diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 61ff8f2190..fae045787f 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -222,12 +222,10 @@ type_in_list_does_not_exist_skipping(List *typenames, const char **msg, foreach(l, typenames) { - TypeName *typeName = (TypeName *) lfirst(l); + TypeName *typeName = castNode(TypeName, lfirst(l)); if (typeName != NULL) { - Assert(IsA(typeName, TypeName)); - if (!OidIsValid(LookupTypeNameOid(NULL, typeName, true))) { /* type doesn't exist, try to find why */ diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 0a669d9b43..f032ef87e3 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -1466,25 +1466,25 @@ ExplainNode(PlanState *planstate, List *ancestors, planstate, es); break; case T_Agg: - show_agg_keys((AggState *) planstate, ancestors, es); + show_agg_keys(castNode(AggState, planstate), ancestors, es); show_upper_qual(plan->qual, "Filter", planstate, ancestors, es); if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); break; case T_Group: - show_group_keys((GroupState *) planstate, ancestors, es); + show_group_keys(castNode(GroupState, planstate), ancestors, es); show_upper_qual(plan->qual, "Filter", planstate, ancestors, es); if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); break; case T_Sort: - show_sort_keys((SortState *) planstate, ancestors, es); - show_sort_info((SortState *) planstate, es); + show_sort_keys(castNode(SortState, planstate), ancestors, es); + show_sort_info(castNode(SortState, planstate), es); break; case T_MergeAppend: - show_merge_append_keys((MergeAppendState *) planstate, + show_merge_append_keys(castNode(MergeAppendState, planstate), ancestors, es); break; case T_Result: @@ -1496,11 +1496,11 @@ ExplainNode(PlanState *planstate, List *ancestors, planstate, es); break; case T_ModifyTable: - show_modifytable_info((ModifyTableState *) planstate, ancestors, + show_modifytable_info(castNode(ModifyTableState, planstate), ancestors, es); break; case T_Hash: - show_hash_info((HashState *) planstate, es); + show_hash_info(castNode(HashState, planstate), es); break; default: break; @@ -2156,7 +2156,6 @@ show_tablesample(TableSampleClause *tsc, PlanState *planstate, static void show_sort_info(SortState *sortstate, ExplainState *es) { - Assert(IsA(sortstate, SortState)); if (es->analyze && sortstate->sort_Done && sortstate->tuplesortstate != NULL) { @@ -2190,7 +2189,6 @@ show_hash_info(HashState *hashstate, ExplainState *es) { HashJoinTable hashtable; - Assert(IsA(hashstate, HashState)); hashtable = hashstate->hashtable; if (hashtable) diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index becafc3045..c2a33ec279 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -578,9 +578,8 @@ update_proconfig_value(ArrayType *a, List *set_items) foreach(l, set_items) { - VariableSetStmt *sstmt = (VariableSetStmt *) lfirst(l); + VariableSetStmt *sstmt = castNode(VariableSetStmt, lfirst(l)); - Assert(IsA(sstmt, VariableSetStmt)); if (sstmt->kind == VAR_RESET_ALL) a = NULL; else @@ -971,9 +970,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) { ListCell *lc; - Assert(IsA(transformDefElem, List)); - - foreach(lc, (List *) transformDefElem) + foreach(lc, castNode(List, transformDefElem)) { Oid typeid = typenameTypeId(NULL, lfirst(lc)); Oid elt = get_base_element_type(typeid); diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 6cddcbd02c..c81df5173e 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -264,8 +264,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, * The stored query was rewritten at the time of the MV definition, but * has not been scribbled on by the planner. */ - dataQuery = (Query *) linitial(actions); - Assert(IsA(dataQuery, Query)); + dataQuery = castNode(Query, linitial(actions)); /* * Check for active uses of the relation in the current transaction, such diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index f4dfdb9642..b229846770 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -462,13 +462,12 @@ DefineOpClass(CreateOpClassStmt *stmt) */ foreach(l, stmt->items) { - CreateOpClassItem *item = lfirst(l); + CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l)); Oid operOid; Oid funcOid; Oid sortfamilyOid; OpFamilyMember *member; - Assert(IsA(item, CreateOpClassItem)); switch (item->itemtype) { case OPCLASS_ITEM_OPERATOR: @@ -847,13 +846,12 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, */ foreach(l, items) { - CreateOpClassItem *item = lfirst(l); + CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l)); Oid operOid; Oid funcOid; Oid sortfamilyOid; OpFamilyMember *member; - Assert(IsA(item, CreateOpClassItem)); switch (item->itemtype) { case OPCLASS_ITEM_OPERATOR: @@ -981,12 +979,11 @@ AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, */ foreach(l, items) { - CreateOpClassItem *item = lfirst(l); + CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l)); Oid lefttype, righttype; OpFamilyMember *member; - Assert(IsA(item, CreateOpClassItem)); switch (item->itemtype) { case OPCLASS_ITEM_OPERATOR: diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 2f605ce83d..e7933e7172 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5932,11 +5932,10 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, colName))); /* Generate new proposed attoptions (text array) */ - Assert(IsA(options, List)); datum = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions, &isnull); newOptions = transformRelOptions(isnull ? (Datum) 0 : datum, - (List *) options, NULL, NULL, false, + castNode(List, options), NULL, NULL, false, isReset); /* Validate new options */ (void) attribute_reloptions(newOptions, true); @@ -7141,8 +7140,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, bool found = false; ObjectAddress address; - Assert(IsA(cmd->def, Constraint)); - cmdcon = (Constraint *) cmd->def; + cmdcon = castNode(Constraint, cmd->def); conrel = heap_open(ConstraintRelationId, RowExclusiveLock); @@ -9290,9 +9288,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, IndexStmt *indstmt; Oid indoid; - Assert(IsA(cmd->def, IndexStmt)); - - indstmt = (IndexStmt *) cmd->def; + indstmt = castNode(IndexStmt, cmd->def); indoid = get_constraint_index(oldId); if (!rewrite) @@ -9315,9 +9311,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, { Constraint *con; - Assert(IsA(cmd->def, Constraint)); - - con = (Constraint *) cmd->def; + con = castNode(Constraint, cmd->def); con->old_pktable_oid = refRelId; /* rewriting neither side of a FK */ if (con->contype == CONSTR_FOREIGN && diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 02e9693f28..029425a12d 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -340,9 +340,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, foreach(lc, varList) { - TriggerTransition *tt = (TriggerTransition *) lfirst(lc); - - Assert(IsA(tt, TriggerTransition)); + TriggerTransition *tt = castNode(TriggerTransition, lfirst(lc)); if (!(tt->isTable)) ereport(ERROR, diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index a3521e7757..6d2786ffef 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -1396,11 +1396,9 @@ roleSpecsToIds(List *memberNames) foreach(l, memberNames) { - RoleSpec *rolespec = (RoleSpec *) lfirst(l); + RoleSpec *rolespec = castNode(RoleSpec, lfirst(l)); Oid roleid; - Assert(IsA(rolespec, RoleSpec)); - roleid = get_rolespec_oid(rolespec, false); result = lappend_oid(result, roleid); } diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 414507f3b7..70e4bb48b0 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -511,9 +511,8 @@ DefineView(ViewStmt *stmt, const char *queryString) foreach(targetList, viewParse->targetList) { - TargetEntry *te = (TargetEntry *) lfirst(targetList); + TargetEntry *te = castNode(TargetEntry, lfirst(targetList)); - Assert(IsA(te, TargetEntry)); /* junk columns don't get aliases */ if (te->resjunk) continue; diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 2587ef7046..a8b3e6c4ce 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -399,8 +399,7 @@ ExecSupportsMarkRestore(Path *pathnode) return true; case T_CustomScan: - Assert(IsA(pathnode, CustomPath)); - if (((CustomPath *) pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE) + if (castNode(CustomPath, pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE) return true; return false; diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index ec1ca01c5a..e333242b27 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -4940,10 +4940,9 @@ ExecInitExpr(Expr *node, PlanState *parent) cstate->arg = ExecInitExpr(caseexpr->arg, parent); foreach(l, caseexpr->args) { - CaseWhen *when = (CaseWhen *) lfirst(l); + CaseWhen *when = castNode(CaseWhen, lfirst(l)); CaseWhenState *wstate = makeNode(CaseWhenState); - Assert(IsA(when, CaseWhen)); wstate->xprstate.evalfunc = NULL; /* not used */ wstate->xprstate.expr = (Expr *) when; wstate->expr = ExecInitExpr(when->expr, parent); @@ -5437,9 +5436,8 @@ ExecCleanTargetListLength(List *targetlist) foreach(tl, targetlist) { - TargetEntry *curTle = (TargetEntry *) lfirst(tl); + TargetEntry *curTle = castNode(TargetEntry, lfirst(tl)); - Assert(IsA(curTle, TargetEntry)); if (!curTle->resjunk) len++; } diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 533050dc85..cf37747429 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -160,10 +160,7 @@ ExecResetTupleTable(List *tupleTable, /* tuple table */ foreach(lc, tupleTable) { - TupleTableSlot *slot = (TupleTableSlot *) lfirst(lc); - - /* Sanity checks */ - Assert(IsA(slot, TupleTableSlot)); + TupleTableSlot *slot = castNode(TupleTableSlot, lfirst(lc)); /* Always release resources and reset the slot to empty */ ExecClearTuple(slot); diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 470db5bb4a..c80058ddb6 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -479,19 +479,17 @@ init_execution_state(List *queryTree_list, foreach(lc1, queryTree_list) { - List *qtlist = (List *) lfirst(lc1); + List *qtlist = castNode(List, lfirst(lc1)); execution_state *firstes = NULL; execution_state *preves = NULL; ListCell *lc2; foreach(lc2, qtlist) { - Query *queryTree = (Query *) lfirst(lc2); + Query *queryTree = castNode(Query, lfirst(lc2)); Node *stmt; execution_state *newes; - Assert(IsA(queryTree, Query)); - /* Plan the query if needed */ if (queryTree->commandType == CMD_UTILITY) stmt = queryTree->utilityStmt; diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index ad5edbad29..8859b49fc0 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -2607,8 +2607,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) if (phase > 0) { aggnode = list_nth(node->chain, phase - 1); - sortnode = (Sort *) aggnode->plan.lefttree; - Assert(IsA(sortnode, Sort)); + sortnode = castNode(Sort, aggnode->plan.lefttree); } else { @@ -3044,10 +3043,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) */ foreach(arg, pertrans->aggref->args) { - TargetEntry *source_tle = (TargetEntry *) lfirst(arg); + TargetEntry *source_tle = castNode(TargetEntry, lfirst(arg)); TargetEntry *tle; - Assert(IsA(source_tle, TargetEntry)); tle = flatCopyTargetEntry(source_tle); tle->resno += column_offset; diff --git a/src/backend/executor/nodeCtescan.c b/src/backend/executor/nodeCtescan.c index 162650ad8a..1228601cfd 100644 --- a/src/backend/executor/nodeCtescan.c +++ b/src/backend/executor/nodeCtescan.c @@ -210,7 +210,7 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags) prmdata = &(estate->es_param_exec_vals[node->cteParam]); Assert(prmdata->execPlan == NULL); Assert(!prmdata->isnull); - scanstate->leader = (CteScanState *) DatumGetPointer(prmdata->value); + scanstate->leader = castNode(CteScanState, DatumGetPointer(prmdata->value)); if (scanstate->leader == NULL) { /* I am the leader */ @@ -223,7 +223,6 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags) else { /* Not the leader */ - Assert(IsA(scanstate->leader, CteScanState)); /* Create my own read pointer, and ensure it is at start */ scanstate->readptr = tuplestore_alloc_read_pointer(scanstate->leader->cte_table, diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c index 322abca282..e53fc35d5e 100644 --- a/src/backend/executor/nodeCustom.c +++ b/src/backend/executor/nodeCustom.c @@ -35,8 +35,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) * methods field correctly at this time. Other standard fields should be * set to zero. */ - css = (CustomScanState *) cscan->methods->CreateCustomScanState(cscan); - Assert(IsA(css, CustomScanState)); + css = castNode(CustomScanState, cscan->methods->CreateCustomScanState(cscan)); /* ensure flags is filled correctly */ css->flags = cscan->flags; diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 369e666f88..bd869e9fc9 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -570,12 +570,9 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) hoperators = NIL; foreach(l, hjstate->hashclauses) { - FuncExprState *fstate = (FuncExprState *) lfirst(l); - OpExpr *hclause; + FuncExprState *fstate = castNode(FuncExprState, lfirst(l)); + OpExpr *hclause = castNode(OpExpr, fstate->xprstate.expr); - Assert(IsA(fstate, FuncExprState)); - hclause = (OpExpr *) fstate->xprstate.expr; - Assert(IsA(hclause, OpExpr)); lclauses = lappend(lclauses, linitial(fstate->args)); rclauses = lappend(rclauses, lsecond(fstate->args)); hoperators = lappend_oid(hoperators, hclause->opno); diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c index 4ebcaffe69..3f97de635e 100644 --- a/src/backend/executor/nodeLockRows.c +++ b/src/backend/executor/nodeLockRows.c @@ -401,12 +401,10 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) epq_arowmarks = NIL; foreach(lc, node->rowMarks) { - PlanRowMark *rc = (PlanRowMark *) lfirst(lc); + PlanRowMark *rc = castNode(PlanRowMark, lfirst(lc)); ExecRowMark *erm; ExecAuxRowMark *aerm; - Assert(IsA(rc, PlanRowMark)); - /* ignore "parent" rowmarks; they are irrelevant at runtime */ if (rc->isParent) continue; diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 0d85b151c2..b534bd6134 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1901,11 +1901,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) */ foreach(l, node->rowMarks) { - PlanRowMark *rc = (PlanRowMark *) lfirst(l); + PlanRowMark *rc = castNode(PlanRowMark, lfirst(l)); ExecRowMark *erm; - Assert(IsA(rc, PlanRowMark)); - /* ignore "parent" rowmarks; they are irrelevant at runtime */ if (rc->isParent) continue; diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index d3436000d0..adcc1240ba 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -814,8 +814,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) else if (and_clause((Node *) sstate->testexpr->expr)) { /* multiple combining operators */ - Assert(IsA(sstate->testexpr, BoolExprState)); - oplist = ((BoolExprState *) sstate->testexpr)->args; + oplist = castNode(BoolExprState, sstate->testexpr)->args; } else { @@ -835,8 +834,8 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) i = 1; foreach(l, oplist) { - FuncExprState *fstate = (FuncExprState *) lfirst(l); - OpExpr *opexpr = (OpExpr *) fstate->xprstate.expr; + FuncExprState *fstate = castNode(FuncExprState, lfirst(l)); + OpExpr *opexpr = castNode(OpExpr, fstate->xprstate.expr); ExprState *exstate; Expr *expr; TargetEntry *tle; @@ -845,8 +844,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) Oid left_hashfn; Oid right_hashfn; - Assert(IsA(fstate, FuncExprState)); - Assert(IsA(opexpr, OpExpr)); Assert(list_length(fstate->args) == 2); /* Process lefthand argument */ @@ -1226,10 +1223,8 @@ ExecAlternativeSubPlan(AlternativeSubPlanState *node, ExprDoneCond *isDone) { /* Just pass control to the active subplan */ - SubPlanState *activesp = (SubPlanState *) list_nth(node->subplans, - node->active); - - Assert(IsA(activesp, SubPlanState)); + SubPlanState *activesp = castNode(SubPlanState, + list_nth(node->subplans, node->active)); return ExecSubPlan(activesp, econtext, diff --git a/src/backend/executor/nodeWorktablescan.c b/src/backend/executor/nodeWorktablescan.c index cfed6e6329..993d03563c 100644 --- a/src/backend/executor/nodeWorktablescan.c +++ b/src/backend/executor/nodeWorktablescan.c @@ -95,8 +95,8 @@ ExecWorkTableScan(WorkTableScanState *node) param = &(estate->es_param_exec_vals[plan->wtParam]); Assert(param->execPlan == NULL); Assert(!param->isnull); - node->rustate = (RecursiveUnionState *) DatumGetPointer(param->value); - Assert(node->rustate && IsA(node->rustate, RecursiveUnionState)); + node->rustate = castNode(RecursiveUnionState, DatumGetPointer(param->value)); + Assert(node->rustate); /* * The scan tuple type (ie, the rowtype we expect to find in the work diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 201f248774..39a3c3fb9e 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -549,6 +549,8 @@ extern PGDLLIMPORT Node *newNodeMacroHolder; #define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_) +#define castNode(_type_,nodeptr) (AssertMacro(!nodeptr || IsA(nodeptr,_type_)), (_type_ *)(nodeptr)) + /* ---------------------------------------------------------------- * extern declarations follow * ---------------------------------------------------------------- -- 2.11.0
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers