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

Commit7a5f8de

Browse files
committed
Fix typcache's failure to treat ranges as container types.
Like the similar logic for arrays and records, it's necessary to examinethe range's subtype to decide whether the range type can support hashing.We can omit checking the subtype for btree-defined operations, though,since range subtypes are required to have those operations. (Possiblythat simplification for btree cases led us to overlook that it doesnot apply for hash cases.)This is only an issue if the subtype lacks hash support, which is nottrue of any built-in range type, but it's easy to demonstrate a problemwith a range type over, eg, money: you can get a "could not identifya hash function" failure when the planner is misled into thinking thathash join or aggregation would work.This was born broken, so back-patch to all supported branches.
1 parent0ab77a3 commit7a5f8de

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ static void cache_array_element_properties(TypeCacheEntry *typentry);
168168
staticboolrecord_fields_have_equality(TypeCacheEntry*typentry);
169169
staticboolrecord_fields_have_compare(TypeCacheEntry*typentry);
170170
staticvoidcache_record_field_properties(TypeCacheEntry*typentry);
171+
staticboolrange_element_has_hashing(TypeCacheEntry*typentry);
172+
staticvoidcache_range_element_properties(TypeCacheEntry*typentry);
171173
staticvoidTypeCacheRelCallback(Datumarg,Oidrelid);
172174
staticvoidTypeCacheOpcCallback(Datumarg,intcacheid,uint32hashvalue);
173175
staticvoidTypeCacheConstrCallback(Datumarg,intcacheid,uint32hashvalue);
@@ -485,6 +487,13 @@ lookup_type_cache(Oid type_id, int flags)
485487
!array_element_has_hashing(typentry))
486488
hash_proc=InvalidOid;
487489

490+
/*
491+
* Likewise for hash_range.
492+
*/
493+
if (hash_proc==F_HASH_RANGE&&
494+
!range_element_has_hashing(typentry))
495+
hash_proc=InvalidOid;
496+
488497
/* Force update of hash_proc_finfo only if we're changing state */
489498
if (typentry->hash_proc!=hash_proc)
490499
typentry->hash_proc_finfo.fn_oid=InvalidOid;
@@ -1129,6 +1138,10 @@ cache_array_element_properties(TypeCacheEntry *typentry)
11291138
typentry->flags |=TCFLAGS_CHECKED_ELEM_PROPERTIES;
11301139
}
11311140

1141+
/*
1142+
* Likewise, some helper functions for composite types.
1143+
*/
1144+
11321145
staticbool
11331146
record_fields_have_equality(TypeCacheEntry*typentry)
11341147
{
@@ -1199,6 +1212,43 @@ cache_record_field_properties(TypeCacheEntry *typentry)
11991212
typentry->flags |=TCFLAGS_CHECKED_FIELD_PROPERTIES;
12001213
}
12011214

1215+
/*
1216+
* Likewise, some helper functions for range types.
1217+
*
1218+
* We can borrow the flag bits for array element properties to use for range
1219+
* element properties, since those flag bits otherwise have no use in a
1220+
* range type's typcache entry.
1221+
*/
1222+
1223+
staticbool
1224+
range_element_has_hashing(TypeCacheEntry*typentry)
1225+
{
1226+
if (!(typentry->flags&TCFLAGS_CHECKED_ELEM_PROPERTIES))
1227+
cache_range_element_properties(typentry);
1228+
return (typentry->flags&TCFLAGS_HAVE_ELEM_HASHING)!=0;
1229+
}
1230+
1231+
staticvoid
1232+
cache_range_element_properties(TypeCacheEntry*typentry)
1233+
{
1234+
/* load up subtype link if we didn't already */
1235+
if (typentry->rngelemtype==NULL&&
1236+
typentry->typtype==TYPTYPE_RANGE)
1237+
load_rangetype_info(typentry);
1238+
1239+
if (typentry->rngelemtype!=NULL)
1240+
{
1241+
TypeCacheEntry*elementry;
1242+
1243+
/* might need to calculate subtype's hash function properties */
1244+
elementry=lookup_type_cache(typentry->rngelemtype->type_id,
1245+
TYPECACHE_HASH_PROC);
1246+
if (OidIsValid(elementry->hash_proc))
1247+
typentry->flags |=TCFLAGS_HAVE_ELEM_HASHING;
1248+
}
1249+
typentry->flags |=TCFLAGS_CHECKED_ELEM_PROPERTIES;
1250+
}
1251+
12021252

12031253
/*
12041254
* lookup_rowtype_tupdesc_internal --- internal routine to lookup a rowtype

‎src/test/regress/expected/rangetypes.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,18 @@ select *, row_to_json(upper(t)) as u from
13541354
drop type two_ints cascade;
13551355
NOTICE: drop cascades to type two_ints_range
13561356
--
1357+
-- Check behavior when subtype lacks a hash function
1358+
--
1359+
create type cashrange as range (subtype = money);
1360+
set enable_sort = off; -- try to make it pick a hash setop implementation
1361+
select '(2,5)'::cashrange except select '(5,6)'::cashrange;
1362+
cashrange
1363+
---------------
1364+
($2.00,$5.00)
1365+
(1 row)
1366+
1367+
reset enable_sort;
1368+
--
13571369
-- OUT/INOUT/TABLE functions
13581370
--
13591371
create function outparam_succeed(i anyrange, out r anyrange, out t text)

‎src/test/regress/sql/rangetypes.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,18 @@ select *, row_to_json(upper(t)) as u from
461461

462462
droptype two_ints cascade;
463463

464+
--
465+
-- Check behavior when subtype lacks a hash function
466+
--
467+
468+
createtypecashrangeas range (subtype=money);
469+
470+
set enable_sort= off;-- try to make it pick a hash setop implementation
471+
472+
select'(2,5)'::cashrange exceptselect'(5,6)'::cashrange;
473+
474+
reset enable_sort;
475+
464476
--
465477
-- OUT/INOUT/TABLE functions
466478
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp