diff options
author | Andres Freund <andres@anarazel.de> | 2018-02-15 21:55:31 -0800 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2018-02-15 21:55:31 -0800 |
commit | 773aec7aa98abd38d6d9435913bb8e14e392c274 (patch) | |
tree | 149ffe4c29433a85e84e128eb47aa22f3b388853 /src/backend/executor/nodeSubplan.c | |
parent | 51db0d18fbf58b0c2e5ebc2b5b2c48daf45c8d93 (diff) | |
download | postgresql-773aec7aa98abd38d6d9435913bb8e14e392c274.tar.gz postgresql-773aec7aa98abd38d6d9435913bb8e14e392c274.zip |
Do execGrouping.c via expression eval machinery.
This has a performance benefit on own, although not hugely so. The
primary benefit is that it will allow for to JIT tuple deforming and
comparator invocations.
Author: Andres Freund
Discussion: https://postgr.es/m/20171129080934.amqqkke2zjtekd4t@alap3.anarazel.de
Diffstat (limited to 'src/backend/executor/nodeSubplan.c')
-rw-r--r-- | src/backend/executor/nodeSubplan.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index edf7d034bd3..fcf739b5e23 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -494,7 +494,9 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; - node->hashtable = BuildTupleHashTable(ncols, + node->hashtable = BuildTupleHashTable(node->parent, + node->descRight, + ncols, node->keyColIdx, node->tab_eq_funcs, node->tab_hash_funcs, @@ -514,7 +516,9 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; } - node->hashnulls = BuildTupleHashTable(ncols, + node->hashnulls = BuildTupleHashTable(node->parent, + node->descRight, + ncols, node->keyColIdx, node->tab_eq_funcs, node->tab_hash_funcs, @@ -598,6 +602,78 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) MemoryContextSwitchTo(oldcontext); } + +/* + * execTuplesUnequal + * Return true if two tuples are definitely unequal in the indicated + * fields. + * + * Nulls are neither equal nor unequal to anything else. A true result + * is obtained only if there are non-null fields that compare not-equal. + * + * slot1, slot2: the tuples to compare (must have same columns!) + * numCols: the number of attributes to be examined + * matchColIdx: array of attribute column numbers + * eqFunctions: array of fmgr lookup info for the equality functions to use + * evalContext: short-term memory context for executing the functions + */ +static bool +execTuplesUnequal(TupleTableSlot *slot1, + TupleTableSlot *slot2, + int numCols, + AttrNumber *matchColIdx, + FmgrInfo *eqfunctions, + MemoryContext evalContext) +{ + MemoryContext oldContext; + bool result; + int i; + + /* Reset and switch into the temp context. */ + MemoryContextReset(evalContext); + oldContext = MemoryContextSwitchTo(evalContext); + + /* + * We cannot report a match without checking all the fields, but we can + * report a non-match as soon as we find unequal fields. So, start + * comparing at the last field (least significant sort key). That's the + * most likely to be different if we are dealing with sorted input. + */ + result = false; + + for (i = numCols; --i >= 0;) + { + AttrNumber att = matchColIdx[i]; + Datum attr1, + attr2; + bool isNull1, + isNull2; + + attr1 = slot_getattr(slot1, att, &isNull1); + + if (isNull1) + continue; /* can't prove anything here */ + + attr2 = slot_getattr(slot2, att, &isNull2); + + if (isNull2) + continue; /* can't prove anything here */ + + /* Apply the type-specific equality function */ + + if (!DatumGetBool(FunctionCall2(&eqfunctions[i], + attr1, attr2))) + { + result = true; /* they are unequal */ + break; + } + } + + MemoryContextSwitchTo(oldContext); + + return result; +} + /* * findPartialMatch: does the hashtable contain an entry that is not * provably distinct from the tuple? @@ -887,6 +963,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) NULL); tupDesc = ExecTypeFromTL(righttlist, false); + sstate->descRight = tupDesc; slot = ExecInitExtraTupleSlot(estate); ExecSetSlotDescriptor(slot, tupDesc); sstate->projRight = ExecBuildProjectionInfo(righttlist, |