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

Function cdbpullup_findEclassInTargetList

src/backend/cdb/cdbpullup.c:242–335  ·  view source on GitHub ↗

* cdbpullup_findEclassInTargetList * * Searches the given equivalence class for a member that uses no rels * outside the 'relids' set, and either is a member of 'targetlist', or * uses no Vars that are not in 'targetlist'. Furthermore, if * 'hashOpFamily' is valid, the member must be hashable using that hash * operator family. * * If found, returns the chosen member's expression, otherwise

Source from the content-addressed store, hash-verified

240 * targetlist expr.)
241 */
242Expr *
243cdbpullup_findEclassInTargetList(EquivalenceClass *eclass, List *targetlist,
244 Oid hashOpFamily, bool *relabel_stripped)
245{
246 ListCell *lc;
247
248 foreach(lc, eclass->ec_members)
249 {
250 EquivalenceMember *em = (EquivalenceMember *) lfirst(lc);
251 Expr *key = (Expr *) em->em_expr;
252 ListCell *lc_tle;
253
254 if (OidIsValid(hashOpFamily) &&
255 !get_opfamily_member(hashOpFamily, em->em_datatype, em->em_datatype,
256 HTEqualStrategyNumber))
257 continue;
258
259 /* A constant is OK regardless of the target list */
260 if (em->em_is_const)
261 return key;
262
263 /*-------
264 * Try to find this EC member in the target list.
265 *
266 * We do the search in a very lenient way:
267 *
268 * 1. Ignore RelabelType nodes on top of both sides, like
269 * tlist_member_ignore_relabel() does.
270 * 2. Ignore varnoold/varoattno fields in Var nodes, like
271 * tlist_member_match_var() does.
272 * 3. Also Accept "naked" targetlists, without TargetEntry nodes
273 *
274 * Unfortunately, neither tlist_member_ignore_relabel() nor
275 * tlist_member_match_var() does exactly what we need.
276 *-------
277 */
278 while (IsA(key, RelabelType))
279 {
280 key = (Expr *) ((RelabelType *) key)->arg;
281 if(relabel_stripped && (!*relabel_stripped))
282 *relabel_stripped = true;
283 }
284
285 foreach(lc_tle, targetlist)
286 {
287 Node *tlexpr = lfirst(lc_tle);
288 Node *naked_tlexpr;
289
290 /*
291 * Check if targetlist is a List of TargetEntry. (Planner's
292 * RelOptInfo targetlists don't have TargetEntry nodes.)
293 */
294 if (IsA(tlexpr, TargetEntry))
295 tlexpr = (Node *) ((TargetEntry *) tlexpr)->expr;
296
297 /* ignore RelabelType nodes on both sides */
298 naked_tlexpr = tlexpr;
299 while (naked_tlexpr && IsA(naked_tlexpr, RelabelType))

Calls 4

get_opfamily_memberFunction · 0.85
equalFunction · 0.85
foreachFunction · 0.50

Tested by

no test coverage detected