aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-10-30 21:55:20 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2010-10-30 21:56:11 -0400
commit186cbbda8f8dc5e42f68fc7892f206a76d56a20f (patch)
tree2c909d8365726683a61515b639c02a9ac00682f4 /src/backend/optimizer/util
parentbd1ff9713369c2f54391112b92e0c22ab5c99180 (diff)
downloadpostgresql-186cbbda8f8dc5e42f68fc7892f206a76d56a20f.tar.gz
postgresql-186cbbda8f8dc5e42f68fc7892f206a76d56a20f.zip
Provide hashing support for arrays.
The core of this patch is hash_array() and associated typcache infrastructure, which works just about exactly like the existing support for array comparison. In addition I did some work to ensure that the planner won't think that an array type is hashable unless its element type is hashable, and similarly for sorting. This includes adding a datatype parameter to op_hashjoinable and op_mergejoinable, and adding an explicit "hashable" flag to SortGroupClause. The lack of a cross-check on the element type was a pre-existing bug in mergejoin support --- but it didn't matter so much before, because if you couldn't sort the element type there wasn't any good alternative to failing anyhow. Now that we have the alternative of hashing the array type, there are cases where we can avoid a failure by being picky at the planner stage, so it's time to be picky. The issue of exactly how to combine the per-element hash values to produce an array hash is still open for discussion, but the rest of this is pretty solid, so I'll commit it as-is.
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/pathnode.c7
-rw-r--r--src/backend/optimizer/util/tlist.c8
2 files changed, 7 insertions, 8 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 8214acc5713..20d8074bce4 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -18,6 +18,7 @@
#include "catalog/pg_operator.h"
#include "miscadmin.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
@@ -878,6 +879,7 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
Relids left_varnos;
Relids right_varnos;
Relids all_varnos;
+ Oid opinputtype;
/* Is it a binary opclause? */
if (!IsA(op, OpExpr) ||
@@ -908,6 +910,7 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
left_varnos = pull_varnos(left_expr);
right_varnos = pull_varnos(right_expr);
all_varnos = bms_union(left_varnos, right_varnos);
+ opinputtype = exprType(left_expr);
/* Does it reference both sides? */
if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
@@ -946,14 +949,14 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
if (all_btree)
{
/* oprcanmerge is considered a hint... */
- if (!op_mergejoinable(opno) ||
+ if (!op_mergejoinable(opno, opinputtype) ||
get_mergejoin_opfamilies(opno) == NIL)
all_btree = false;
}
if (all_hash)
{
/* ... but oprcanhash had better be correct */
- if (!op_hashjoinable(opno))
+ if (!op_hashjoinable(opno, opinputtype))
all_hash = false;
}
if (!(all_btree || all_hash))
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 0220aa0e5f8..8096fcbe613 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -18,7 +18,6 @@
#include "nodes/nodeFuncs.h"
#include "optimizer/tlist.h"
#include "optimizer/var.h"
-#include "utils/lsyscache.h"
/*****************************************************************************
@@ -348,10 +347,7 @@ grouping_is_sortable(List *groupClause)
/*
* grouping_is_hashable - is it possible to implement grouping list by hashing?
*
- * We assume hashing is OK if the equality operators are marked oprcanhash.
- * (If there isn't actually a supporting hash function, the executor will
- * complain at runtime; but this is a misdeclaration of the operator, not
- * a system bug.)
+ * We rely on the parser to have set the hashable flag correctly.
*/
bool
grouping_is_hashable(List *groupClause)
@@ -362,7 +358,7 @@ grouping_is_hashable(List *groupClause)
{
SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
- if (!op_hashjoinable(groupcl->eqop))
+ if (!groupcl->hashable)
return false;
}
return true;