1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Improve castNode notation by introducing list-extraction-specific variants.

This extends the castNode() notation introduced by commit 5bcab1114 to
provide, in one step, extraction of a list cell's pointer and coercion to
a concrete node type.  For example, "lfirst_node(Foo, lc)" is the same
as "castNode(Foo, lfirst(lc))".  Almost half of the uses of castNode
that have appeared so far include a list extraction call, so this is
pretty widely useful, and it saves a few more keystrokes compared to the
old way.

As with the previous patch, back-patch the addition of these macros to
pg_list.h, so that the notation will be available when back-patching.

Patch by me, after an idea of Andrew Gierth's.

Discussion: https://postgr.es/m/14197.1491841216@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2017-04-10 13:51:29 -04:00
parent 56dd8e85c4
commit 8f0530f580
65 changed files with 176 additions and 168 deletions

View File

@@ -109,13 +109,13 @@ DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List
aggKind = AGGKIND_ORDERED_SET;
else
numDirectArgs = 0;
args = castNode(List, linitial(args));
args = linitial_node(List, args);
}
/* Examine aggregate's definition clauses */
foreach(pl, parameters)
{
DefElem *defel = castNode(DefElem, lfirst(pl));
DefElem *defel = lfirst_node(DefElem, pl);
/*
* sfunc1, stype1, and initcond1 are accepted as obsolete spellings

View File

@@ -1636,7 +1636,7 @@ AtSubCommit_Notify(void)
List *parentPendingActions;
List *parentPendingNotifies;
parentPendingActions = castNode(List, linitial(upperPendingActions));
parentPendingActions = linitial_node(List, upperPendingActions);
upperPendingActions = list_delete_first(upperPendingActions);
Assert(list_length(upperPendingActions) ==
@@ -1647,7 +1647,7 @@ AtSubCommit_Notify(void)
*/
pendingActions = list_concat(parentPendingActions, pendingActions);
parentPendingNotifies = castNode(List, linitial(upperPendingNotifies));
parentPendingNotifies = linitial_node(List, 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 = castNode(List, linitial(upperPendingActions));
pendingActions = linitial_node(List, upperPendingActions);
upperPendingActions = list_delete_first(upperPendingActions);
}
while (list_length(upperPendingNotifies) > my_level - 2)
{
pendingNotifies = castNode(List, linitial(upperPendingNotifies));
pendingNotifies = linitial_node(List, upperPendingNotifies);
upperPendingNotifies = list_delete_first(upperPendingNotifies);
}
}

View File

@@ -71,7 +71,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
foreach(pl, parameters)
{
DefElem *defel = castNode(DefElem, lfirst(pl));
DefElem *defel = lfirst_node(DefElem, pl);
DefElem **defelp;
if (pg_strcasecmp(defel->defname, "from") == 0)

View File

@@ -1034,7 +1034,7 @@ ProcessCopyOptions(ParseState *pstate,
/* Extract options from the statement node tree */
foreach(option, options)
{
DefElem *defel = castNode(DefElem, lfirst(option));
DefElem *defel = lfirst_node(DefElem, option);
if (strcmp(defel->defname, "format") == 0)
{
@@ -1488,7 +1488,7 @@ BeginCopy(ParseState *pstate,
/* examine queries to determine which error message to issue */
foreach(lc, rewritten)
{
Query *q = castNode(Query, lfirst(lc));
Query *q = lfirst_node(Query, lc);
if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
ereport(ERROR,
@@ -1505,7 +1505,7 @@ BeginCopy(ParseState *pstate,
errmsg("multi-statement DO INSTEAD rules are not supported for COPY")));
}
query = castNode(Query, linitial(rewritten));
query = linitial_node(Query, rewritten);
/* The grammar allows SELECT INTO, but we don't support that */
if (query->utilityStmt != NULL &&

View File

@@ -323,7 +323,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
elog(ERROR, "unexpected rewrite result for %s",
is_matview ? "CREATE MATERIALIZED VIEW" :
"CREATE TABLE AS SELECT");
query = castNode(Query, linitial(rewritten));
query = linitial_node(Query, rewritten);
Assert(query->commandType == CMD_SELECT);
/* plan the query --- note we disallow parallelism */

View File

@@ -214,7 +214,7 @@ type_in_list_does_not_exist_skipping(List *typenames, const char **msg,
foreach(l, typenames)
{
TypeName *typeName = castNode(TypeName, lfirst(l));
TypeName *typeName = lfirst_node(TypeName, l);
if (typeName != NULL)
{
@@ -371,8 +371,8 @@ does_not_exist_skipping(ObjectType objtype, Node *object)
{
/* XXX quote or no quote? */
msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
name = TypeNameToString(castNode(TypeName, linitial(castNode(List, object))));
args = TypeNameToString(castNode(TypeName, lsecond(castNode(List, object))));
name = TypeNameToString(linitial_node(TypeName, castNode(List, object)));
args = TypeNameToString(lsecond_node(TypeName, castNode(List, object)));
}
}
break;
@@ -380,7 +380,7 @@ does_not_exist_skipping(ObjectType objtype, Node *object)
if (!type_in_list_does_not_exist_skipping(list_make1(linitial(castNode(List, object))), &msg, &name))
{
msg = gettext_noop("transform for type %s language \"%s\" does not exist, skipping");
name = TypeNameToString(castNode(TypeName, linitial(castNode(List, object))));
name = TypeNameToString(linitial_node(TypeName, castNode(List, object)));
args = strVal(lsecond(castNode(List, object)));
}
break;

View File

@@ -253,7 +253,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString,
/* Explain every plan */
foreach(l, rewritten)
{
ExplainOneQuery(castNode(Query, lfirst(l)),
ExplainOneQuery(lfirst_node(Query, l),
CURSOR_OPT_PARALLEL_OK, NULL, es,
queryString, params, queryEnv);
@@ -408,7 +408,7 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es,
rewritten = QueryRewrite(castNode(Query, copyObject(ctas->query)));
Assert(list_length(rewritten) == 1);
ExplainOneQuery(castNode(Query, linitial(rewritten)),
ExplainOneQuery(linitial_node(Query, rewritten),
0, ctas->into, es,
queryString, params, queryEnv);
}
@@ -427,7 +427,7 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es,
rewritten = QueryRewrite(castNode(Query, copyObject(dcs->query)));
Assert(list_length(rewritten) == 1);
ExplainOneQuery(castNode(Query, linitial(rewritten)),
ExplainOneQuery(linitial_node(Query, rewritten),
dcs->options, NULL, es,
queryString, params, queryEnv);
}

View File

@@ -714,7 +714,7 @@ execute_sql_string(const char *sql, const char *filename)
*/
foreach(lc1, raw_parsetree_list)
{
RawStmt *parsetree = castNode(RawStmt, lfirst(lc1));
RawStmt *parsetree = lfirst_node(RawStmt, lc1);
List *stmt_list;
ListCell *lc2;
@@ -727,7 +727,7 @@ execute_sql_string(const char *sql, const char *filename)
foreach(lc2, stmt_list)
{
PlannedStmt *stmt = castNode(PlannedStmt, lfirst(lc2));
PlannedStmt *stmt = lfirst_node(PlannedStmt, lc2);
CommandCounterIncrement();

View File

@@ -1589,7 +1589,7 @@ ImportForeignSchema(ImportForeignSchemaStmt *stmt)
*/
foreach(lc2, raw_parsetree_list)
{
RawStmt *rs = castNode(RawStmt, lfirst(lc2));
RawStmt *rs = lfirst_node(RawStmt, lc2);
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) rs->stmt;
PlannedStmt *pstmt;

View File

@@ -578,7 +578,7 @@ update_proconfig_value(ArrayType *a, List *set_items)
foreach(l, set_items)
{
VariableSetStmt *sstmt = castNode(VariableSetStmt, lfirst(l));
VariableSetStmt *sstmt = lfirst_node(VariableSetStmt, l);
if (sstmt->kind == VAR_RESET_ALL)
a = NULL;
@@ -972,7 +972,8 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
foreach(lc, castNode(List, transformDefElem))
{
Oid typeid = typenameTypeId(NULL, lfirst(lc));
Oid typeid = typenameTypeId(NULL,
lfirst_node(TypeName, lc));
Oid elt = get_base_element_type(typeid);
typeid = elt ? elt : typeid;

View File

@@ -264,7 +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 = castNode(Query, linitial(actions));
dataQuery = linitial_node(Query, actions);
/*
* Check for active uses of the relation in the current transaction, such

View File

@@ -460,7 +460,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
*/
foreach(l, stmt->items)
{
CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l));
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
Oid operOid;
Oid funcOid;
Oid sortfamilyOid;
@@ -834,7 +834,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
*/
foreach(l, items)
{
CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l));
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
Oid operOid;
Oid funcOid;
Oid sortfamilyOid;
@@ -959,7 +959,7 @@ AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
*/
foreach(l, items)
{
CreateOpClassItem *item = castNode(CreateOpClassItem, lfirst(l));
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
Oid lefttype,
righttype;
OpFamilyMember *member;

View File

@@ -83,7 +83,7 @@ PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params,
if (list_length(rewritten) != 1)
elog(ERROR, "non-SELECT statement in DECLARE CURSOR");
query = castNode(Query, linitial(rewritten));
query = linitial_node(Query, rewritten);
if (query->commandType != CMD_SELECT)
elog(ERROR, "non-SELECT statement in DECLARE CURSOR");

View File

@@ -267,7 +267,7 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("prepared statement is not a SELECT")));
pstmt = castNode(PlannedStmt, linitial(plan_list));
pstmt = linitial_node(PlannedStmt, plan_list);
if (pstmt->commandType != CMD_SELECT)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -679,7 +679,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
/* Explain each query */
foreach(p, plan_list)
{
PlannedStmt *pstmt = castNode(PlannedStmt, lfirst(p));
PlannedStmt *pstmt = lfirst_node(PlannedStmt, p);
if (pstmt->commandType != CMD_UTILITY)
ExplainOnePlan(pstmt, into, es, query_string, paramLI, queryEnv,

View File

@@ -5942,7 +5942,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod
foreach(option, castNode(List, def))
{
DefElem *defel = castNode(DefElem, lfirst(option));
DefElem *defel = lfirst_node(DefElem, option);
if (strcmp(defel->defname, "generated") == 0)
{
@@ -9547,7 +9547,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd,
querytree_list = NIL;
foreach(list_item, raw_parsetree_list)
{
RawStmt *rs = castNode(RawStmt, lfirst(list_item));
RawStmt *rs = lfirst_node(RawStmt, list_item);
Node *stmt = rs->stmt;
if (IsA(stmt, IndexStmt))

View File

@@ -340,7 +340,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
foreach(lc, varList)
{
TriggerTransition *tt = castNode(TriggerTransition, lfirst(lc));
TriggerTransition *tt = lfirst_node(TriggerTransition, lc);
if (!(tt->isTable))
ereport(ERROR,

View File

@@ -1388,7 +1388,7 @@ roleSpecsToIds(List *memberNames)
foreach(l, memberNames)
{
RoleSpec *rolespec = castNode(RoleSpec, lfirst(l));
RoleSpec *rolespec = lfirst_node(RoleSpec, l);
Oid roleid;
roleid = get_rolespec_oid(rolespec, false);

View File

@@ -516,7 +516,7 @@ DefineView(ViewStmt *stmt, const char *queryString,
foreach(targetList, viewParse->targetList)
{
TargetEntry *te = castNode(TargetEntry, lfirst(targetList));
TargetEntry *te = lfirst_node(TargetEntry, targetList);
/* junk columns don't get aliases */
if (te->resjunk)