aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeSubplan.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2018-02-15 21:55:31 -0800
committerAndres Freund <andres@anarazel.de>2018-02-15 21:55:31 -0800
commit773aec7aa98abd38d6d9435913bb8e14e392c274 (patch)
tree149ffe4c29433a85e84e128eb47aa22f3b388853 /src/backend/executor/nodeSubplan.c
parent51db0d18fbf58b0c2e5ebc2b5b2c48daf45c8d93 (diff)
downloadpostgresql-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.c81
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,