MCPcopy Create free account
hub / github.com/apache/cloudberry / transformDistinctClause

Function transformDistinctClause

src/backend/parser/parse_clause.c:3123–3192  ·  view source on GitHub ↗

* transformDistinctClause - * transform a DISTINCT clause * * Since we may need to add items to the query's targetlist, that list * is passed by reference. * * As with GROUP BY, we absorb the sorting semantics of ORDER BY as much as * possible into the distinctClause. This avoids a possible need to re-sort, * and allows the user to choose the equality semantics used by DISTINCT, * shou

Source from the content-addressed store, hash-verified

3121 * of error messages.
3122 */
3123List *
3124transformDistinctClause(ParseState *pstate,
3125 List **targetlist, List *sortClause, bool is_agg)
3126{
3127 List *result = NIL;
3128 ListCell *slitem;
3129 ListCell *tlitem;
3130
3131 /*
3132 * The distinctClause should consist of all ORDER BY items followed by all
3133 * other non-resjunk targetlist items. There must not be any resjunk
3134 * ORDER BY items --- that would imply that we are sorting by a value that
3135 * isn't necessarily unique within a DISTINCT group, so the results
3136 * wouldn't be well-defined. This construction ensures we follow the rule
3137 * that sortClause and distinctClause match; in fact the sortClause will
3138 * always be a prefix of distinctClause.
3139 *
3140 * Note a corner case: the same TLE could be in the ORDER BY list multiple
3141 * times with different sortops. We have to include it in the
3142 * distinctClause the same way to preserve the prefix property. The net
3143 * effect will be that the TLE value will be made unique according to both
3144 * sortops.
3145 */
3146 foreach(slitem, sortClause)
3147 {
3148 SortGroupClause *scl = (SortGroupClause *) lfirst(slitem);
3149 TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);
3150
3151 if (tle->resjunk)
3152 ereport(ERROR,
3153 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
3154 is_agg ?
3155 errmsg("in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list") :
3156 errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list"),
3157 parser_errposition(pstate,
3158 exprLocation((Node *) tle->expr))));
3159 result = lappend(result, copyObject(scl));
3160 }
3161
3162 /*
3163 * Now add any remaining non-resjunk tlist items, using default sort/group
3164 * semantics for their data types.
3165 */
3166 foreach(tlitem, *targetlist)
3167 {
3168 TargetEntry *tle = (TargetEntry *) lfirst(tlitem);
3169
3170 if (tle->resjunk)
3171 continue; /* ignore junk */
3172 result = addTargetToGroupList(pstate, tle,
3173 result, *targetlist,
3174 exprLocation((Node *) tle->expr));
3175 }
3176
3177 /*
3178 * Complain if we found nothing to make DISTINCT. Returning an empty list
3179 * would cause the parsed Query to look like it didn't have DISTINCT, with
3180 * results that would probably surprise the user. Note: this case is

Callers 5

rewriteQueryForIMMVFunction · 0.85
transformSelectStmtFunction · 0.85
transformPLAssignStmtFunction · 0.85
transformAggregateCallFunction · 0.85

Calls 8

get_sortgroupclause_tleFunction · 0.85
parser_errpositionFunction · 0.85
exprLocationFunction · 0.85
lappendFunction · 0.85
addTargetToGroupListFunction · 0.85
foreachFunction · 0.50
errcodeFunction · 0.50
errmsgFunction · 0.50

Tested by

no test coverage detected