Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit186cbbd

Browse files
committed
Provide hashing support for arrays.
The core of this patch is hash_array() and associated typcacheinfrastructure, which works just about exactly like the existing supportfor array comparison.In addition I did some work to ensure that the planner won't think that anarray type is hashable unless its element type is hashable, and similarlyfor sorting. This includes adding a datatype parameter to op_hashjoinableand op_mergejoinable, and adding an explicit "hashable" flag toSortGroupClause. The lack of a cross-check on the element type was apre-existing bug in mergejoin support --- but it didn't matter so muchbefore, because if you couldn't sort the element type there wasn't any goodalternative to failing anyhow. Now that we have the alternative of hashingthe array type, there are cases where we can avoid a failure by being pickyat the planner stage, so it's time to be picky.The issue of exactly how to combine the per-element hash values to producean array hash is still open for discussion, but the rest of this is prettysolid, so I'll commit it as-is.
1 parentbd1ff97 commit186cbbd

30 files changed

+375
-88
lines changed

‎src/backend/commands/analyze.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,8 @@ std_typanalyze(VacAttrStats *stats)
17941794
/* Look for default "<" and "=" operators for column's type */
17951795
get_sort_group_operators(stats->attrtypid,
17961796
false, false, false,
1797-
&ltopr,&eqopr,NULL);
1797+
&ltopr,&eqopr,NULL,
1798+
NULL);
17981799

17991800
/* If column has no "=" operator, we can't do much of anything */
18001801
if (!OidIsValid(eqopr))

‎src/backend/nodes/copyfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,7 @@ _copySortGroupClause(SortGroupClause *from)
18821882
COPY_SCALAR_FIELD(eqop);
18831883
COPY_SCALAR_FIELD(sortop);
18841884
COPY_SCALAR_FIELD(nulls_first);
1885+
COPY_SCALAR_FIELD(hashable);
18851886

18861887
returnnewnode;
18871888
}

‎src/backend/nodes/equalfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,7 @@ _equalSortGroupClause(SortGroupClause *a, SortGroupClause *b)
22272227
COMPARE_SCALAR_FIELD(eqop);
22282228
COMPARE_SCALAR_FIELD(sortop);
22292229
COMPARE_SCALAR_FIELD(nulls_first);
2230+
COMPARE_SCALAR_FIELD(hashable);
22302231

22312232
return true;
22322233
}

‎src/backend/nodes/outfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,7 @@ _outSortGroupClause(StringInfo str, SortGroupClause *node)
20732073
WRITE_OID_FIELD(eqop);
20742074
WRITE_OID_FIELD(sortop);
20752075
WRITE_BOOL_FIELD(nulls_first);
2076+
WRITE_BOOL_FIELD(hashable);
20762077
}
20772078

20782079
staticvoid

‎src/backend/nodes/readfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ _readSortGroupClause(void)
264264
READ_OID_FIELD(eqop);
265265
READ_OID_FIELD(sortop);
266266
READ_BOOL_FIELD(nulls_first);
267+
READ_BOOL_FIELD(hashable);
267268

268269
READ_DONE();
269270
}

‎src/backend/optimizer/path/equivclass.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,9 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
925925
(IsA(inner_em->em_expr,RelabelType)&&
926926
IsA(((RelabelType*)inner_em->em_expr)->arg,Var)))
927927
score++;
928-
if (!enable_hashjoin||op_hashjoinable(eq_op))
928+
if (!enable_hashjoin||
929+
op_hashjoinable(eq_op,
930+
exprType((Node*)outer_em->em_expr)))
929931
score++;
930932
if (score>best_score)
931933
{

‎src/backend/optimizer/plan/createplan.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path)
958958
sortcl->eqop=eqop;
959959
sortcl->sortop=sortop;
960960
sortcl->nulls_first= false;
961+
sortcl->hashable= false;/* no need to make this accurate */
961962
sortList=lappend(sortList,sortcl);
962963
groupColPos++;
963964
}

‎src/backend/optimizer/plan/initsplan.c‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include"catalog/pg_operator.h"
1818
#include"catalog/pg_type.h"
19+
#include"nodes/nodeFuncs.h"
1920
#include"optimizer/clauses.h"
2021
#include"optimizer/cost.h"
2122
#include"optimizer/joininfo.h"
@@ -1486,6 +1487,7 @@ check_mergejoinable(RestrictInfo *restrictinfo)
14861487
{
14871488
Expr*clause=restrictinfo->clause;
14881489
Oidopno;
1490+
Node*leftarg;
14891491

14901492
if (restrictinfo->pseudoconstant)
14911493
return;
@@ -1495,8 +1497,9 @@ check_mergejoinable(RestrictInfo *restrictinfo)
14951497
return;
14961498

14971499
opno= ((OpExpr*)clause)->opno;
1500+
leftarg=linitial(((OpExpr*)clause)->args);
14981501

1499-
if (op_mergejoinable(opno)&&
1502+
if (op_mergejoinable(opno,exprType(leftarg))&&
15001503
!contain_volatile_functions((Node*)clause))
15011504
restrictinfo->mergeopfamilies=get_mergejoin_opfamilies(opno);
15021505

@@ -1521,6 +1524,7 @@ check_hashjoinable(RestrictInfo *restrictinfo)
15211524
{
15221525
Expr*clause=restrictinfo->clause;
15231526
Oidopno;
1527+
Node*leftarg;
15241528

15251529
if (restrictinfo->pseudoconstant)
15261530
return;
@@ -1530,8 +1534,9 @@ check_hashjoinable(RestrictInfo *restrictinfo)
15301534
return;
15311535

15321536
opno= ((OpExpr*)clause)->opno;
1537+
leftarg=linitial(((OpExpr*)clause)->args);
15331538

1534-
if (op_hashjoinable(opno)&&
1539+
if (op_hashjoinable(opno,exprType(leftarg))&&
15351540
!contain_volatile_functions((Node*)clause))
15361541
restrictinfo->hashjoinoperator=opno;
15371542
}

‎src/backend/optimizer/plan/planagg.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
518518
info->aggsortop);
519519
sortcl->sortop=info->aggsortop;
520520
sortcl->nulls_first=info->nulls_first;
521+
sortcl->hashable= false;/* no need to make this accurate */
521522
subparse->sortClause=list_make1(sortcl);
522523

523524
/* set up LIMIT 1 */

‎src/backend/optimizer/plan/subselect.c‎

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -861,28 +861,45 @@ testexpr_is_hashable(Node *testexpr)
861861
return false;
862862
}
863863

864+
/*
865+
* Check expression is hashable + strict
866+
*
867+
* We could use op_hashjoinable() and op_strict(), but do it like this to
868+
* avoid a redundant cache lookup.
869+
*/
864870
staticbool
865871
hash_ok_operator(OpExpr*expr)
866872
{
867873
Oidopid=expr->opno;
868-
HeapTupletup;
869-
Form_pg_operatoroptup;
870874

871875
/* quick out if not a binary operator */
872876
if (list_length(expr->args)!=2)
873877
return false;
874-
/* else must look up the operator properties */
875-
tup=SearchSysCache1(OPEROID,ObjectIdGetDatum(opid));
876-
if (!HeapTupleIsValid(tup))
877-
elog(ERROR,"cache lookup failed for operator %u",opid);
878-
optup= (Form_pg_operator)GETSTRUCT(tup);
879-
if (!optup->oprcanhash|| !func_strict(optup->oprcode))
878+
if (opid==ARRAY_EQ_OP)
879+
{
880+
/* array_eq is strict, but must check input type to ensure hashable */
881+
Node*leftarg=linitial(expr->args);
882+
883+
returnop_hashjoinable(opid,exprType(leftarg));
884+
}
885+
else
880886
{
887+
/* else must look up the operator properties */
888+
HeapTupletup;
889+
Form_pg_operatoroptup;
890+
891+
tup=SearchSysCache1(OPEROID,ObjectIdGetDatum(opid));
892+
if (!HeapTupleIsValid(tup))
893+
elog(ERROR,"cache lookup failed for operator %u",opid);
894+
optup= (Form_pg_operator)GETSTRUCT(tup);
895+
if (!optup->oprcanhash|| !func_strict(optup->oprcode))
896+
{
897+
ReleaseSysCache(tup);
898+
return false;
899+
}
881900
ReleaseSysCache(tup);
882-
returnfalse;
901+
returntrue;
883902
}
884-
ReleaseSysCache(tup);
885-
return true;
886903
}
887904

888905

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp