0001-Fix-record-hash-support-variant-2.patch
text/plain
Filename: 0001-Fix-record-hash-support-variant-2.patch
Type: text/plain
Part: 1
Patch
Format: format-patch
Series: patch 0001
Subject: Fix record hash support, variant 2
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/joinpath.c | 1 | 1 |
| src/backend/optimizer/plan/initsplan.c | 1 | 1 |
| src/backend/parser/analyze.c | 13 | 5 |
| src/backend/parser/parse_clause.c | 6 | 0 |
| src/backend/rewrite/rewriteSearchCycle.c | 3 | 3 |
| src/backend/utils/cache/lsyscache.c | 1 | 1 |
| src/include/parser/analyze.h | 1 | 1 |
From 512ba0bdc53aa140027a18449426bf1327ba3efe Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 27 Aug 2021 10:50:49 +0200
Subject: [PATCH] Fix record hash support, variant 2
---
src/backend/optimizer/path/joinpath.c | 2 +-
src/backend/optimizer/plan/initsplan.c | 2 +-
src/backend/parser/analyze.c | 18 +++++++++++++-----
src/backend/parser/parse_clause.c | 6 ++++++
src/backend/rewrite/rewriteSearchCycle.c | 6 +++---
src/backend/utils/cache/lsyscache.c | 2 +-
src/include/parser/analyze.h | 2 +-
7 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 6407ede12a..385a41606e 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -437,7 +437,7 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info,
TYPECACHE_HASH_PROC | TYPECACHE_EQ_OPR);
/* can't use a memoize node without a valid hash equals operator */
- if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr))
+ if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr) || typentry->type_id == RECORDOID)
{
list_free(*operators);
list_free(*param_exprs);
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index e25dc9a7ca..5fc411dcce 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2733,7 +2733,7 @@ check_memoizable(RestrictInfo *restrictinfo)
typentry = lookup_type_cache(exprType(leftarg), TYPECACHE_HASH_PROC |
TYPECACHE_EQ_OPR);
- if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr))
+ if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr) || typentry->type_id == RECORDOID)
return;
restrictinfo->hasheqoperator = typentry->eq_opr;
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 15669c8238..07623f1daa 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -1852,9 +1852,12 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
/*
* Make a SortGroupClause node for a SetOperationStmt's groupClauses
+ *
+ * If need_hash is true, the caller is indicating that they need hash support
+ * or they will fail. So look extra hard for hash support.
*/
SortGroupClause *
-makeSortGroupClauseForSetOp(Oid rescoltype)
+makeSortGroupClauseForSetOp(Oid rescoltype, bool need_hash)
{
SortGroupClause *grpcl = makeNode(SortGroupClause);
Oid sortop;
@@ -1867,6 +1870,9 @@ makeSortGroupClauseForSetOp(Oid rescoltype)
&sortop, &eqop, NULL,
&hashable);
+ if (rescoltype == RECORDOID)
+ hashable = need_hash;
+
/* we don't have a tlist yet, so can't assign sortgrouprefs */
grpcl->tleSortGroupRef = 0;
grpcl->eqop = eqop;
@@ -2027,6 +2033,9 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
ListCell *ltl;
ListCell *rtl;
const char *context;
+ bool recursive = (pstate->p_parent_cte &&
+ pstate->p_parent_cte->cterecursive);
+
context = (stmt->op == SETOP_UNION ? "UNION" :
(stmt->op == SETOP_INTERSECT ? "INTERSECT" :
@@ -2048,9 +2057,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
* containing CTE as having those result columns. We should do this
* only at the topmost setop of the CTE, of course.
*/
- if (isTopLevel &&
- pstate->p_parent_cte &&
- pstate->p_parent_cte->cterecursive)
+ if (isTopLevel && recursive)
determineRecursiveColTypes(pstate, op->larg, ltargetlist);
/*
@@ -2182,8 +2189,9 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
setup_parser_errposition_callback(&pcbstate, pstate,
bestlocation);
+ /* If it's a recursive union, we need to require hashing support. */
op->groupClauses = lappend(op->groupClauses,
- makeSortGroupClauseForSetOp(rescoltype));
+ makeSortGroupClauseForSetOp(rescoltype, recursive));
cancel_parser_errposition_callback(&pcbstate);
}
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index b3f151d33b..3518d359aa 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -3318,6 +3318,8 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle,
true, true, false,
&sortop, &eqop, NULL,
&hashable);
+ if (restype == RECORDOID)
+ hashable = false;
reverse = false;
break;
case SORTBY_DESC:
@@ -3325,6 +3327,8 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle,
false, true, true,
NULL, &eqop, &sortop,
&hashable);
+ if (restype == RECORDOID)
+ hashable = false;
reverse = true;
break;
case SORTBY_USING:
@@ -3449,6 +3453,8 @@ addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
false, true, false,
&sortop, &eqop, NULL,
&hashable);
+ if (restype == RECORDOID)
+ hashable = false;
cancel_parser_errposition_callback(&pcbstate);
diff --git a/src/backend/rewrite/rewriteSearchCycle.c b/src/backend/rewrite/rewriteSearchCycle.c
index c50ebdba24..ef38f4025a 100644
--- a/src/backend/rewrite/rewriteSearchCycle.c
+++ b/src/backend/rewrite/rewriteSearchCycle.c
@@ -594,7 +594,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
sos->colCollations = lappend_oid(sos->colCollations, InvalidOid);
if (!sos->all)
sos->groupClauses = lappend(sos->groupClauses,
- makeSortGroupClauseForSetOp(search_seq_type));
+ makeSortGroupClauseForSetOp(search_seq_type, true));
}
if (cte->cycle_clause)
{
@@ -603,14 +603,14 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
sos->colCollations = lappend_oid(sos->colCollations, cte->cycle_clause->cycle_mark_collation);
if (!sos->all)
sos->groupClauses = lappend(sos->groupClauses,
- makeSortGroupClauseForSetOp(cte->cycle_clause->cycle_mark_type));
+ makeSortGroupClauseForSetOp(cte->cycle_clause->cycle_mark_type, true));
sos->colTypes = lappend_oid(sos->colTypes, RECORDARRAYOID);
sos->colTypmods = lappend_int(sos->colTypmods, -1);
sos->colCollations = lappend_oid(sos->colCollations, InvalidOid);
if (!sos->all)
sos->groupClauses = lappend(sos->groupClauses,
- makeSortGroupClauseForSetOp(RECORDARRAYOID));
+ makeSortGroupClauseForSetOp(RECORDARRAYOID, true));
}
/*
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 4ebaa552a2..f66b09d940 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -1421,7 +1421,7 @@ op_hashjoinable(Oid opno, Oid inputtype)
else if (opno == RECORD_EQ_OP)
{
typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC);
- if (typentry->hash_proc == F_HASH_RECORD)
+ if (typentry->hash_proc == F_HASH_RECORD && inputtype != RECORDOID)
result = true;
}
else
diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h
index 6716db6c13..89d61238e9 100644
--- a/src/include/parser/analyze.h
+++ b/src/include/parser/analyze.h
@@ -48,6 +48,6 @@ extern void applyLockingClause(Query *qry, Index rtindex,
extern List *BuildOnConflictExcludedTargetlist(Relation targetrel,
Index exclRelIndex);
-extern SortGroupClause *makeSortGroupClauseForSetOp(Oid rescoltype);
+extern SortGroupClause *makeSortGroupClauseForSetOp(Oid rescoltype, bool need_hash);
#endif /* ANALYZE_H */
--
2.33.0