/** * Is a result node memory intensive? It is if it contains function calls. * We special-case certain functions used by ORCA which we know that are not * memory intensive * TODO caragg 03/04/2014: Revert these changes when ORCA has the new partition * operator (MPP-22799) */ bool IsResultMemoryIntesive(Result *res) { List *funcNodes = extract_nodes(NULL /* glob */, (Node *) ((Plan *) res)->targetlist, T_FuncExpr); int nFuncExpr = list_length(funcNodes); if (nFuncExpr == 0) { /* No function expressions, not memory intensive */ return false; } bool isMemoryIntensive = false; ListCell *lc = NULL; foreach(lc, funcNodes) { FuncExpr *funcExpr = lfirst(lc); Assert(IsA(funcExpr, FuncExpr)); if ( isMemoryIntensiveFunction(funcExpr->funcid)) { /* Found a function that we don't know of. Mark as memory intensive */ isMemoryIntensive = true; break; } }
/** * This method looks at the Append part of the plan under a join and extracts out interesting bits of information. * These include: partitionOid of the master table, partitionInfo that is a struct containing partitioning information, * what are the partitioning keys and what does an all null row of the partitioned table look like. */ static void MatchAppendPattern(Plan *append, PartitionJoinMutatorContext *ctx) { ctx->partitionOid = InvalidOid; /** * It is possible we have already applied the transformation to this subtree. * Check for result node as child. */ Append *appendNode = (Append *) append; Assert(list_length(appendNode->appendplans) > 0); Plan *child = (Plan *) list_nth(appendNode->appendplans, 0); if (IsA(child, Result)) { ctx->safeToConvert = false; return; } /** * Find all the vars in the targetlist and check if they're from a partitioned table. */ List *allVars = extract_nodes(NULL /* PlannerGlobal */, (Node *) append->targetlist, T_Var); ListCell *lc = NULL; foreach (lc, allVars) { Var *v = (Var *) lfirst(lc); RangeTblEntry *rte = rt_fetch(v->varno, ctx->rtable); Assert(rte); if (!rel_is_partitioned(rte->relid)) { ctx->safeToConvert = false; return; } if (ctx->partitionOid == InvalidOid) { ctx->partitionOid = rte->relid; ctx->partitionVarno = v->varno; } if (ctx->partitionOid != rte->relid) { ctx->safeToConvert = false; return; } }