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)
        {
                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:
                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);
                }
 
                /* 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:
 
 
    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, ", ");
 
     */
    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)
    {
        /* 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
 
                                             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 */
 
            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
 
        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));
 
    List       *parentPendingActions;
    List       *parentPendingNotifies;
 
-   parentPendingActions = (List *) linitial(upperPendingActions);
+   parentPendingActions = castNode(List, linitial(upperPendingActions));
    upperPendingActions = list_delete_first(upperPendingActions);
 
    Assert(list_length(upperPendingActions) ==
     */
    pendingActions = list_concat(parentPendingActions, pendingActions);
 
-   parentPendingNotifies = (List *) linitial(upperPendingNotifies);
+   parentPendingNotifies = castNode(List, linitial(upperPendingNotifies));
    upperPendingNotifies = list_delete_first(upperPendingNotifies);
 
    Assert(list_length(upperPendingNotifies) ==
     */
    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);
    }
 }
 
 
    foreach(pl, parameters)
    {
-       DefElem    *defel = (DefElem *) lfirst(pl);
+       DefElem    *defel = castNode(DefElem, lfirst(pl));
        DefElem   **defelp;
 
        if (pg_strcasecmp(defel->defname, "from") == 0)
 
 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;
 
    /* 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)
        {
                         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),
                        (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),
                         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),
            /* 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,
                     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 &&
 
 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;
     * 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);
 
 
    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 */
 
                                           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:
                                           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;
 static void
 show_sort_info(SortState *sortstate, ExplainState *es)
 {
-   Assert(IsA(sortstate, SortState));
    if (es->analyze && sortstate->sort_Done &&
        sortstate->tuplesortstate != NULL)
    {
 {
    HashJoinTable hashtable;
 
-   Assert(IsA(hashstate, HashState));
    hashtable = hashstate->hashtable;
 
    if (hashtable)
 
 
    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
    {
        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);
 
     * 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
 
     */
    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:
     */
    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:
     */
    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:
 
                        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,
-                                    isReset);
+                                    castNode(List, options), NULL, NULL,
+                                    false, isReset);
    /* Validate new options */
    (void) attribute_reloptions(newOptions, true);
 
    bool        found = false;
    ObjectAddress address;
 
-   Assert(IsA(cmd->def, Constraint));
-   cmdcon = (Constraint *) cmd->def;
+   cmdcon = castNode(Constraint, cmd->def);
 
    conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
 
                    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)
                {
                    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 &&
 
 
        foreach(lc, varList)
        {
-           TriggerTransition   *tt = (TriggerTransition *) lfirst(lc);
-
-           Assert(IsA(tt, TriggerTransition));
+           TriggerTransition   *tt = castNode(TriggerTransition, lfirst(lc));
 
            if (!(tt->isTable))
                ereport(ERROR,
 
 
    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);
    }
 
 
        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;
 
            return true;
 
        case T_CustomScan:
-           Assert(IsA(pathnode, CustomPath));
-           if (((CustomPath *) pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
+       {
+           CustomPath *customPath = castNode(CustomPath, pathnode);
+           if (customPath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
                return true;
            return false;
-
+       }
        case T_Result:
 
            /*
 
                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);
 
    foreach(tl, targetlist)
    {
-       TargetEntry *curTle = (TargetEntry *) lfirst(tl);
+       TargetEntry *curTle = castNode(TargetEntry, lfirst(tl));
 
-       Assert(IsA(curTle, TargetEntry));
        if (!curTle->resjunk)
            len++;
    }
 
 
    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);
 
 
    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));
            PlannedStmt *stmt;
            execution_state *newes;
 
-           Assert(IsA(queryTree, Query));
-
            /* Plan the query if needed */
            if (queryTree->commandType == CMD_UTILITY)
            {
 
 
        if (phase > 0)
        {
-           aggnode = list_nth(node->chain, phase - 1);
-           sortnode = (Sort *) aggnode->plan.lefttree;
-           Assert(IsA(sortnode, Sort));
+           aggnode = castNode(Agg, list_nth(node->chain, phase - 1));
+           sortnode = castNode(Sort, aggnode->plan.lefttree);
        }
        else
        {
         */
        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;
 
 
    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 */
    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,
 
     * 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;
 
    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);
 
    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;
 
     */
    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;
 
        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
        {
        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;
            Oid         left_hashfn;
            Oid         right_hashfn;
 
-           Assert(IsA(fstate, FuncExprState));
-           Assert(IsA(opexpr, OpExpr));
            Assert(list_length(fstate->args) == 2);
 
            /* Process lefthand argument */
                       bool *isNull)
 {
    /* 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, isNull);
 }
 
        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