1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-25 21:42:33 +03:00

Avoid using list_length() to test for empty list.

The standard way to check for list emptiness is to compare the
List pointer to NIL; our list code goes out of its way to ensure
that that is the only representation of an empty list.  (An
acceptable alternative is a plain boolean test for non-null
pointer, but explicit mention of NIL is usually preferable.)

Various places didn't get that memo and expressed the condition
with list_length(), which might not be so bad except that there
were such a variety of ways to check it exactly: equal to zero,
less than or equal to zero, less than one, yadda yadda.  In the
name of code readability, let's standardize all those spellings
as "list == NIL" or "list != NIL".  (There's probably some
microscopic efficiency gain too, though few of these look to be
at all performance-critical.)

A very small number of cases were left as-is because they seemed
more consistent with other adjacent list_length tests that way.

Peter Smith, with bikeshedding from a number of us

Discussion: https://postgr.es/m/CAHut+PtQYe+ENX5KrONMfugf0q6NHg4hR5dAhqEXEc2eefFeig@mail.gmail.com
This commit is contained in:
Tom Lane 2022-08-17 11:12:35 -04:00
parent 4a319fce76
commit efd0c16bec
28 changed files with 47 additions and 48 deletions

View File

@ -2186,7 +2186,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
else else
{ {
name = textarray_to_strvaluelist(namearr); name = textarray_to_strvaluelist(namearr);
if (list_length(name) < 1) if (name == NIL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("name list length must be at least %d", 1))); errmsg("name list length must be at least %d", 1)));

View File

@ -947,7 +947,7 @@ getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok)
if (list_length(seqlist) > 1) if (list_length(seqlist) > 1)
elog(ERROR, "more than one owned sequence found"); elog(ERROR, "more than one owned sequence found");
else if (list_length(seqlist) < 1) else if (seqlist == NIL)
{ {
if (missing_ok) if (missing_ok)
return InvalidOid; return InvalidOid;

View File

@ -1143,9 +1143,9 @@ trackDroppedObjectsNeeded(void)
* true if any sql_drop, table_rewrite, ddl_command_end event trigger * true if any sql_drop, table_rewrite, ddl_command_end event trigger
* exists * exists
*/ */
return list_length(EventCacheLookup(EVT_SQLDrop)) > 0 || return (EventCacheLookup(EVT_SQLDrop) != NIL) ||
list_length(EventCacheLookup(EVT_TableRewrite)) > 0 || (EventCacheLookup(EVT_TableRewrite) != NIL) ||
list_length(EventCacheLookup(EVT_DDLCommandEnd)) > 0; (EventCacheLookup(EVT_DDLCommandEnd) != NIL);
} }
/* /*
@ -1616,7 +1616,7 @@ EventTriggerAlterTableEnd(void)
parent = currentEventTriggerState->currentCommand->parent; parent = currentEventTriggerState->currentCommand->parent;
/* If no subcommands, don't collect */ /* If no subcommands, don't collect */
if (list_length(currentEventTriggerState->currentCommand->d.alterTable.subcmds) != 0) if (currentEventTriggerState->currentCommand->d.alterTable.subcmds != NIL)
{ {
MemoryContext oldcxt; MemoryContext oldcxt;

View File

@ -419,7 +419,7 @@ interpret_function_parameter_list(ParseState *pstate,
* Make sure no variables are referred to (this is probably dead * Make sure no variables are referred to (this is probably dead
* code now that add_missing_from is history). * code now that add_missing_from is history).
*/ */
if (list_length(pstate->p_rtable) != 0 || if (pstate->p_rtable != NIL ||
contain_var_clause(def)) contain_var_clause(def))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE), (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
@ -1209,7 +1209,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
returnsSet = false; returnsSet = false;
} }
if (list_length(trftypes_list) > 0) if (trftypes_list != NIL)
{ {
ListCell *lc; ListCell *lc;
Datum *arr; Datum *arr;

View File

@ -848,12 +848,12 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
&schemaidlist); &schemaidlist);
/* FOR ALL TABLES IN SCHEMA requires superuser */ /* FOR ALL TABLES IN SCHEMA requires superuser */
if (list_length(schemaidlist) > 0 && !superuser()) if (schemaidlist != NIL && !superuser())
ereport(ERROR, ereport(ERROR,
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create FOR ALL TABLES IN SCHEMA publication")); errmsg("must be superuser to create FOR ALL TABLES IN SCHEMA publication"));
if (list_length(relations) > 0) if (relations != NIL)
{ {
List *rels; List *rels;
@ -871,7 +871,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
CloseTableList(rels); CloseTableList(rels);
} }
if (list_length(schemaidlist) > 0) if (schemaidlist != NIL)
{ {
/* /*
* Schema lock is held until the publication is created to prevent * Schema lock is held until the publication is created to prevent

View File

@ -339,7 +339,7 @@ CreateStatistics(CreateStatsStmt *stmt)
if ((list_length(stmt->exprs) == 1) && (list_length(stxexprs) == 1)) if ((list_length(stmt->exprs) == 1) && (list_length(stxexprs) == 1))
{ {
/* statistics kinds not specified */ /* statistics kinds not specified */
if (list_length(stmt->stat_types) > 0) if (stmt->stat_types != NIL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("when building statistics on a single expression, statistics kinds may not be specified"))); errmsg("when building statistics on a single expression, statistics kinds may not be specified")));
@ -391,7 +391,7 @@ CreateStatistics(CreateStatsStmt *stmt)
* automatically. This allows calculating good estimates for stats that * automatically. This allows calculating good estimates for stats that
* consider per-clause estimates (e.g. functional dependencies). * consider per-clause estimates (e.g. functional dependencies).
*/ */
build_expressions = (list_length(stxexprs) > 0); build_expressions = (stxexprs != NIL);
/* /*
* Check that at least two columns were specified in the statement, or * Check that at least two columns were specified in the statement, or

View File

@ -410,7 +410,7 @@ get_publications_str(List *publications, StringInfo dest, bool quote_literal)
ListCell *lc; ListCell *lc;
bool first = true; bool first = true;
Assert(list_length(publications) > 0); Assert(publications != NIL);
foreach(lc, publications) foreach(lc, publications)
{ {

View File

@ -2097,7 +2097,7 @@ ExecuteTruncateGuts(List *explicit_rels,
* Assemble an array of relids so we can write a single WAL record for the * Assemble an array of relids so we can write a single WAL record for the
* whole action. * whole action.
*/ */
if (list_length(relids_logged) > 0) if (relids_logged != NIL)
{ {
xl_heap_truncate xlrec; xl_heap_truncate xlrec;
int i = 0; int i = 0;
@ -16264,11 +16264,11 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
} }
/* /*
* Check that the table is not part any publication when changing to * Check that the table is not part of any publication when changing to
* UNLOGGED as UNLOGGED tables can't be published. * UNLOGGED, as UNLOGGED tables can't be published.
*/ */
if (!toLogged && if (!toLogged &&
list_length(GetRelationPublications(RelationGetRelid(rel))) > 0) GetRelationPublications(RelationGetRelid(rel)) != NIL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("cannot change table \"%s\" to unlogged because it is part of a publication", errmsg("cannot change table \"%s\" to unlogged because it is part of a publication",

View File

@ -3503,7 +3503,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
* Domains don't allow variables (this is probably dead code now that * Domains don't allow variables (this is probably dead code now that
* add_missing_from is history, but let's be sure). * add_missing_from is history, but let's be sure).
*/ */
if (list_length(pstate->p_rtable) != 0 || if (pstate->p_rtable != NIL ||
contain_var_clause(expr)) contain_var_clause(expr))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE), (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),

View File

@ -685,7 +685,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
* list and searching for ancestry relationships to each index in the * list and searching for ancestry relationships to each index in the
* ancestor table. * ancestor table.
*/ */
if (list_length(rootResultRelInfo->ri_onConflictArbiterIndexes) > 0) if (rootResultRelInfo->ri_onConflictArbiterIndexes != NIL)
{ {
List *childIdxs; List *childIdxs;

View File

@ -2915,14 +2915,14 @@ CheckRADIUSAuth(Port *port)
Assert(offsetof(radius_packet, vector) == 4); Assert(offsetof(radius_packet, vector) == 4);
/* Verify parameters */ /* Verify parameters */
if (list_length(port->hba->radiusservers) < 1) if (port->hba->radiusservers == NIL)
{ {
ereport(LOG, ereport(LOG,
(errmsg("RADIUS server not specified"))); (errmsg("RADIUS server not specified")));
return STATUS_ERROR; return STATUS_ERROR;
} }
if (list_length(port->hba->radiussecrets) < 1) if (port->hba->radiussecrets == NIL)
{ {
ereport(LOG, ereport(LOG,
(errmsg("RADIUS secret not specified"))); (errmsg("RADIUS secret not specified")));

View File

@ -1564,7 +1564,7 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
MANDATORY_AUTH_ARG(parsedline->radiusservers, "radiusservers", "radius"); MANDATORY_AUTH_ARG(parsedline->radiusservers, "radiusservers", "radius");
MANDATORY_AUTH_ARG(parsedline->radiussecrets, "radiussecrets", "radius"); MANDATORY_AUTH_ARG(parsedline->radiussecrets, "radiussecrets", "radius");
if (list_length(parsedline->radiusservers) < 1) if (parsedline->radiusservers == NIL)
{ {
ereport(elevel, ereport(elevel,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
@ -1575,7 +1575,7 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
return NULL; return NULL;
} }
if (list_length(parsedline->radiussecrets) < 1) if (parsedline->radiussecrets == NIL)
{ {
ereport(elevel, ereport(elevel,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),

View File

@ -1957,7 +1957,7 @@ compute_cpu_sort_cost(PlannerInfo *root, List *pathkeys, int nPresortedKeys,
List *cache_varinfos = NIL; List *cache_varinfos = NIL;
/* fallback if pathkeys is unknown */ /* fallback if pathkeys is unknown */
if (list_length(pathkeys) == 0) if (pathkeys == NIL)
{ {
/* /*
* If we'll use a bounded heap-sort keeping just K tuples in memory, * If we'll use a bounded heap-sort keeping just K tuples in memory,

View File

@ -2462,7 +2462,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path)
if (rollup->is_hashed) if (rollup->is_hashed)
strat = AGG_HASHED; strat = AGG_HASHED;
else if (list_length(linitial(rollup->gsets)) == 0) else if (linitial(rollup->gsets) == NIL)
strat = AGG_PLAIN; strat = AGG_PLAIN;
else else
strat = AGG_SORTED; strat = AGG_SORTED;

View File

@ -3097,7 +3097,7 @@ reorder_grouping_sets(List *groupingsets, List *sortclause)
GroupingSetData *gs = makeNode(GroupingSetData); GroupingSetData *gs = makeNode(GroupingSetData);
while (list_length(sortclause) > list_length(previous) && while (list_length(sortclause) > list_length(previous) &&
list_length(new_elems) > 0) new_elems != NIL)
{ {
SortGroupClause *sc = list_nth(sortclause, list_length(previous)); SortGroupClause *sc = list_nth(sortclause, list_length(previous));
int ref = sc->tleSortGroupRef; int ref = sc->tleSortGroupRef;
@ -4120,7 +4120,7 @@ consider_groupingsets_paths(PlannerInfo *root,
/* /*
* If we have sorted input but nothing we can do with it, bail. * If we have sorted input but nothing we can do with it, bail.
*/ */
if (list_length(gd->rollups) == 0) if (gd->rollups == NIL)
return; return;
/* /*
@ -6477,7 +6477,7 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
group_clauses, group_clauses,
orderAggPathkeys); orderAggPathkeys);
Assert(list_length(pathkey_orderings) > 0); Assert(pathkey_orderings != NIL);
/* process all potentially interesting grouping reorderings */ /* process all potentially interesting grouping reorderings */
foreach(lc2, pathkey_orderings) foreach(lc2, pathkey_orderings)
@ -6650,7 +6650,7 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
group_clauses, group_clauses,
orderAggPathkeys); orderAggPathkeys);
Assert(list_length(pathkey_orderings) > 0); Assert(pathkey_orderings != NIL);
/* process all potentially interesting grouping reorderings */ /* process all potentially interesting grouping reorderings */
foreach(lc2, pathkey_orderings) foreach(lc2, pathkey_orderings)
@ -6994,7 +6994,7 @@ create_partial_grouping_paths(PlannerInfo *root,
group_clauses, group_clauses,
orderAggPathkeys); orderAggPathkeys);
Assert(list_length(pathkey_orderings) > 0); Assert(pathkey_orderings != NIL);
/* process all potentially interesting grouping reorderings */ /* process all potentially interesting grouping reorderings */
foreach(lc2, pathkey_orderings) foreach(lc2, pathkey_orderings)
@ -7145,7 +7145,7 @@ create_partial_grouping_paths(PlannerInfo *root,
group_clauses, group_clauses,
orderAggPathkeys); orderAggPathkeys);
Assert(list_length(pathkey_orderings) > 0); Assert(pathkey_orderings != NIL);
/* process all potentially interesting grouping reorderings */ /* process all potentially interesting grouping reorderings */
foreach(lc2, pathkey_orderings) foreach(lc2, pathkey_orderings)

View File

@ -2383,7 +2383,7 @@ get_steps_using_prefix(GeneratePruningStepsContext *context,
context->rel->part_scheme->strategy == PARTITION_STRATEGY_HASH); context->rel->part_scheme->strategy == PARTITION_STRATEGY_HASH);
/* Quick exit if there are no values to prefix with. */ /* Quick exit if there are no values to prefix with. */
if (list_length(prefix) == 0) if (prefix == NIL)
{ {
PartitionPruneStep *step; PartitionPruneStep *step;

View File

@ -383,7 +383,7 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn)
* immediate restarts. We don't need it if there are no tables that need * immediate restarts. We don't need it if there are no tables that need
* syncing. * syncing.
*/ */
if (table_states_not_ready && !last_start_times) if (table_states_not_ready != NIL && !last_start_times)
{ {
HASHCTL ctl; HASHCTL ctl;
@ -397,7 +397,7 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn)
* Clean up the hash table when we're done with all tables (just to * Clean up the hash table when we're done with all tables (just to
* release the bit of memory). * release the bit of memory).
*/ */
else if (!table_states_not_ready && last_start_times) else if (table_states_not_ready == NIL && last_start_times)
{ {
hash_destroy(last_start_times); hash_destroy(last_start_times);
last_start_times = NULL; last_start_times = NULL;
@ -1498,7 +1498,7 @@ FetchTableStates(bool *started_tx)
* if table_state_not_ready was empty we still need to check again to * if table_state_not_ready was empty we still need to check again to
* see if there are 0 tables. * see if there are 0 tables.
*/ */
has_subrels = (list_length(table_states_not_ready) > 0) || has_subrels = (table_states_not_ready != NIL) ||
HasSubscriptionRelations(MySubscription->oid); HasSubscriptionRelations(MySubscription->oid);
table_states_valid = true; table_states_valid = true;
@ -1534,7 +1534,7 @@ AllTablesyncsReady(void)
* Return false when there are no tables in subscription or not all tables * Return false when there are no tables in subscription or not all tables
* are in ready state; true otherwise. * are in ready state; true otherwise.
*/ */
return has_subrels && list_length(table_states_not_ready) == 0; return has_subrels && (table_states_not_ready == NIL);
} }
/* /*

View File

@ -450,7 +450,7 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
errmsg("client sent proto_version=%d but we only support protocol %d or higher", errmsg("client sent proto_version=%d but we only support protocol %d or higher",
data->protocol_version, LOGICALREP_PROTO_MIN_VERSION_NUM))); data->protocol_version, LOGICALREP_PROTO_MIN_VERSION_NUM)));
if (list_length(data->publication_names) < 1) if (data->publication_names == NIL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("publication_names parameter missing"))); errmsg("publication_names parameter missing")));

View File

@ -313,7 +313,7 @@ DefineQueryRewrite(const char *rulename,
* *
* So there cannot be INSTEAD NOTHING, ... * So there cannot be INSTEAD NOTHING, ...
*/ */
if (list_length(action) == 0) if (action == NIL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("INSTEAD NOTHING rules on SELECT are not implemented"), errmsg("INSTEAD NOTHING rules on SELECT are not implemented"),

View File

@ -1610,7 +1610,6 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
/* The bitmap may be partially built. */ /* The bitmap may be partially built. */
Assert(clauses != NIL); Assert(clauses != NIL);
Assert(list_length(clauses) >= 1);
Assert(mcvlist != NULL); Assert(mcvlist != NULL);
Assert(mcvlist->nitems > 0); Assert(mcvlist->nitems > 0);
Assert(mcvlist->nitems <= STATS_MCVLIST_MAX_ITEMS); Assert(mcvlist->nitems <= STATS_MCVLIST_MAX_ITEMS);

View File

@ -913,7 +913,7 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
int done = 0; int done = 0;
/* Done if no locks to wait for */ /* Done if no locks to wait for */
if (list_length(locktags) == 0) if (locktags == NIL)
return; return;
/* Collect the transactions we need to wait on */ /* Collect the transactions we need to wait on */

View File

@ -567,7 +567,7 @@ extract_jsp_path_expr(JsonPathGinContext *cxt, JsonPathGinPath path,
/* extract a list of nodes to be AND-ed */ /* extract a list of nodes to be AND-ed */
List *nodes = extract_jsp_path_expr_nodes(cxt, path, jsp, scalar); List *nodes = extract_jsp_path_expr_nodes(cxt, path, jsp, scalar);
if (list_length(nodes) <= 0) if (nodes == NIL)
/* no nodes were extracted => full scan is needed for this path */ /* no nodes were extracted => full scan is needed for this path */
return NULL; return NULL;

View File

@ -2552,7 +2552,7 @@ JsonValueListLength(const JsonValueList *jvl)
static bool static bool
JsonValueListIsEmpty(JsonValueList *jvl) JsonValueListIsEmpty(JsonValueList *jvl)
{ {
return !jvl->singleton && list_length(jvl->list) <= 0; return !jvl->singleton && (jvl->list == NIL);
} }
static JsonbValue * static JsonbValue *

View File

@ -459,7 +459,7 @@ makeIndexArray(List *list)
ListCell *cell; ListCell *cell;
int i = 0; int i = 0;
Assert(list_length(list) > 0); Assert(list != NIL);
v->value.array.nelems = list_length(list); v->value.array.nelems = list_length(list);
v->value.array.elems = palloc(sizeof(v->value.array.elems[0]) * v->value.array.elems = palloc(sizeof(v->value.array.elems[0]) *

View File

@ -8114,7 +8114,7 @@ get_parameter(Param *param, deparse_context *context)
{ {
deparse_namespace *dpns = lfirst(lc); deparse_namespace *dpns = lfirst(lc);
if (list_length(dpns->rtable_names) > 0) if (dpns->rtable_names != NIL)
{ {
should_qualify = true; should_qualify = true;
break; break;

View File

@ -3408,7 +3408,7 @@ estimate_num_groups_incremental(PlannerInfo *root, List *groupExprs,
* for normal cases with GROUP BY or DISTINCT, but it is possible for * for normal cases with GROUP BY or DISTINCT, but it is possible for
* corner cases with set operations.) * corner cases with set operations.)
*/ */
if (groupExprs == NIL || (pgset && list_length(*pgset) < 1)) if (groupExprs == NIL || (pgset && *pgset == NIL))
return 1.0; return 1.0;
/* /*

View File

@ -829,7 +829,7 @@ parse_tsquery(char *buf,
close_tsvector_parser(state.valstate); close_tsvector_parser(state.valstate);
if (list_length(state.polstr) == 0) if (state.polstr == NIL)
{ {
ereport(NOTICE, ereport(NOTICE,
(errmsg("text-search query doesn't contain lexemes: \"%s\"", (errmsg("text-search query doesn't contain lexemes: \"%s\"",

View File

@ -95,7 +95,7 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
SetSingleFuncCall(fcinfo, 0); SetSingleFuncCall(fcinfo, 0);
if (list_length(cmd->d.alterTable.subcmds) == 0) if (cmd->d.alterTable.subcmds == NIL)
elog(ERROR, "empty alter table subcommand list"); elog(ERROR, "empty alter table subcommand list");
foreach(cell, cmd->d.alterTable.subcmds) foreach(cell, cmd->d.alterTable.subcmds)