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

Commitea8e42f

Browse files
committed
Fix failure to check whether a rowtype's component types are sortable.
The existence of a btree opclass accepting composite types caused us toassume that every composite type is sortable. This isn't true of course;we need to check if the column types are all sortable. There was logicfor this for the case of array comparison (ie, check that the elementtype is sortable), but we missed the point for rowtypes. Per Teodor'sreport of an ANALYZE failure for an unsortable composite type.Rather than just add some more ad-hoc logic for this, I moved knowledge ofthe issue into typcache.c. The typcache will now only report out array_eq,record_cmp, and friends as usable operators if the array or composite typewill work with those functions.Unfortunately we don't have enough info to do this for anonymous RECORDtypes; in that case, just assume it will work, and take the runtime failureas before if it doesn't.This patch might be a candidate for back-patching at some point, butgiven the lack of complaints from the field, I'd rather just test it inHEAD for now.Note: most of the places touched in this patch will need further workwhen we get around to supporting hashing of record types.
1 parent3ece391 commitea8e42f

File tree

8 files changed

+348
-126
lines changed

8 files changed

+348
-126
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,7 @@ hash_ok_operator(OpExpr *expr)
891891
if (opid==ARRAY_EQ_OP)
892892
{
893893
/* array_eq is strict, but must check input type to ensure hashable */
894+
/* XXX record_eq will need same treatment when it becomes hashable */
894895
Node*leftarg=linitial(expr->args);
895896

896897
returnop_hashjoinable(opid,exprType(leftarg));

‎src/backend/parser/parse_oper.c

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -211,42 +211,6 @@ get_sort_group_operators(Oid argtype,
211211
gt_opr=typentry->gt_opr;
212212
hashable=OidIsValid(typentry->hash_proc);
213213

214-
/*
215-
* If the datatype is an array, then we can use array_lt and friends ...
216-
* but only if there are suitable operators for the element type.
217-
* Likewise, array types are only hashable if the element type is. Testing
218-
* all three operator IDs here should be redundant, but let's do it
219-
* anyway.
220-
*/
221-
if (lt_opr==ARRAY_LT_OP||
222-
eq_opr==ARRAY_EQ_OP||
223-
gt_opr==ARRAY_GT_OP)
224-
{
225-
Oidelem_type=get_base_element_type(argtype);
226-
227-
if (OidIsValid(elem_type))
228-
{
229-
typentry=lookup_type_cache(elem_type,cache_flags);
230-
if (!OidIsValid(typentry->eq_opr))
231-
{
232-
/* element type is neither sortable nor hashable */
233-
lt_opr=eq_opr=gt_opr=InvalidOid;
234-
}
235-
elseif (!OidIsValid(typentry->lt_opr)||
236-
!OidIsValid(typentry->gt_opr))
237-
{
238-
/* element type is hashable but not sortable */
239-
lt_opr=gt_opr=InvalidOid;
240-
}
241-
hashable=OidIsValid(typentry->hash_proc);
242-
}
243-
else
244-
{
245-
lt_opr=eq_opr=gt_opr=InvalidOid;/* bogus array type? */
246-
hashable= false;
247-
}
248-
}
249-
250214
/* Report errors if needed */
251215
if ((needLT&& !OidIsValid(lt_opr))||
252216
(needGT&& !OidIsValid(gt_opr)))

‎src/backend/utils/cache/lsyscache.c

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include"utils/array.h"
3434
#include"utils/builtins.h"
3535
#include"utils/datum.h"
36+
#include"utils/fmgroids.h"
3637
#include"utils/lsyscache.h"
3738
#include"utils/syscache.h"
3839
#include"utils/typcache.h"
@@ -1120,34 +1121,35 @@ op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
11201121
* opfamily entries for this operator and associated sortops. The pg_operator
11211122
* flag is just a hint to tell the planner whether to bother looking.)
11221123
*
1123-
* In some cases (currently only array_eq), mergejoinability depends on the
1124-
* specific input data type the operator is invoked for, so that must be
1125-
* passed as well.We currently assume that only one input's type is needed
1126-
* to check this --- by convention, pass the left input's data type.
1124+
* In some cases (currently only array_eq and record_eq), mergejoinability
1125+
*depends on thespecific input data type the operator is invoked for, so
1126+
*that must bepassed as well.We currently assume that only one input's type
1127+
*is neededto check this --- by convention, pass the left input's data type.
11271128
*/
11281129
bool
11291130
op_mergejoinable(Oidopno,Oidinputtype)
11301131
{
1131-
HeapTupletp;
11321132
boolresult= false;
1133+
HeapTupletp;
1134+
TypeCacheEntry*typentry;
11331135

1136+
/*
1137+
* For array_eq or record_eq, we can sort if the element or field types
1138+
* are all sortable. We could implement all the checks for that here, but
1139+
* the typcache already does that and caches the results too, so let's
1140+
* rely on the typcache.
1141+
*/
11341142
if (opno==ARRAY_EQ_OP)
11351143
{
1136-
/*
1137-
* For array_eq, can sort if element type has a default btree opclass.
1138-
* We could use GetDefaultOpClass, but that's fairly expensive and not
1139-
* cached, so let's use the typcache instead.
1140-
*/
1141-
Oidelem_type=get_base_element_type(inputtype);
1142-
1143-
if (OidIsValid(elem_type))
1144-
{
1145-
TypeCacheEntry*typentry;
1146-
1147-
typentry=lookup_type_cache(elem_type,TYPECACHE_BTREE_OPFAMILY);
1148-
if (OidIsValid(typentry->btree_opf))
1149-
result= true;
1150-
}
1144+
typentry=lookup_type_cache(inputtype,TYPECACHE_CMP_PROC);
1145+
if (typentry->cmp_proc==F_BTARRAYCMP)
1146+
result= true;
1147+
}
1148+
elseif (opno==RECORD_EQ_OP)
1149+
{
1150+
typentry=lookup_type_cache(inputtype,TYPECACHE_CMP_PROC);
1151+
if (typentry->cmp_proc==F_BTRECORDCMP)
1152+
result= true;
11511153
}
11521154
else
11531155
{
@@ -1178,22 +1180,17 @@ op_mergejoinable(Oid opno, Oid inputtype)
11781180
bool
11791181
op_hashjoinable(Oidopno,Oidinputtype)
11801182
{
1181-
HeapTupletp;
11821183
boolresult= false;
1184+
HeapTupletp;
1185+
TypeCacheEntry*typentry;
11831186

1187+
/* As in op_mergejoinable, let the typcache handle the hard cases */
1188+
/* Eventually we'll need a similar case for record_eq ... */
11841189
if (opno==ARRAY_EQ_OP)
11851190
{
1186-
/* For array_eq, can hash if element type has a default hash opclass */
1187-
Oidelem_type=get_base_element_type(inputtype);
1188-
1189-
if (OidIsValid(elem_type))
1190-
{
1191-
TypeCacheEntry*typentry;
1192-
1193-
typentry=lookup_type_cache(elem_type,TYPECACHE_HASH_OPFAMILY);
1194-
if (OidIsValid(typentry->hash_opf))
1195-
result= true;
1196-
}
1191+
typentry=lookup_type_cache(inputtype,TYPECACHE_HASH_PROC);
1192+
if (typentry->hash_proc==F_HASH_ARRAY)
1193+
result= true;
11971194
}
11981195
else
11991196
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp