diff --git a/h3/CMakeLists.txt b/h3/CMakeLists.txt index 885ab754..216477a8 100644 --- a/h3/CMakeLists.txt +++ b/h3/CMakeLists.txt @@ -13,6 +13,7 @@ PostgreSQL_add_extension(postgresql_h3 src/binding/regions.c src/binding/traversal.c src/binding/vertex.c + src/algos.c src/deprecated.c src/extension.c src/guc.c diff --git a/h3/sql/install/14-opclass_gist.sql b/h3/sql/install/14-opclass_gist.sql index 63b9d1f6..70f3fbac 100644 --- a/h3/sql/install/14-opclass_gist.sql +++ b/h3/sql/install/14-opclass_gist.sql @@ -35,11 +35,11 @@ CREATE OR REPLACE FUNCTION h3index_gist_same(h3index, h3index, internal) RETURNS CREATE OR REPLACE FUNCTION h3index_gist_distance(internal, h3index, smallint, oid, internal) RETURNS float8 AS 'h3' LANGUAGE C STRICT; -CREATE OPERATOR CLASS h3index_ops DEFAULT FOR TYPE h3index USING gist AS - OPERATOR 3 && , - OPERATOR 6 = , - OPERATOR 7 @> , - OPERATOR 8 <@ , +CREATE OPERATOR CLASS experimental_h3index_ops FOR TYPE h3index USING gist AS + OPERATOR 3 && , -- RTOverlapStrategyNumber + OPERATOR 6 = , -- RTSameStrategyNumber + OPERATOR 7 @> , -- RTContainsStrategyNumber + OPERATOR 8 <@ , -- RTContainedByStrategyNumber OPERATOR 15 <-> (h3index, h3index) FOR ORDER BY integer_ops, FUNCTION 1 h3index_gist_consistent(internal, h3index, smallint, oid, internal), diff --git a/h3/sql/updates/h3--4.1.3--unreleased.sql b/h3/sql/updates/h3--4.1.3--unreleased.sql index fdfa4c25..f990500c 100644 --- a/h3/sql/updates/h3--4.1.3--unreleased.sql +++ b/h3/sql/updates/h3--4.1.3--unreleased.sql @@ -38,7 +38,7 @@ CREATE OR REPLACE FUNCTION h3index_gist_same(h3index, h3index, internal) RETURNS CREATE OR REPLACE FUNCTION h3index_gist_distance(internal, h3index, smallint, oid, internal) RETURNS float8 AS 'h3' LANGUAGE C STRICT; -CREATE OPERATOR CLASS h3index_ops DEFAULT FOR TYPE h3index USING gist AS +CREATE OPERATOR CLASS experimental_h3index_ops FOR TYPE h3index USING gist AS OPERATOR 3 && , OPERATOR 6 = , OPERATOR 7 @> , diff --git a/h3/src/algos.c b/h3/src/algos.c new file mode 100644 index 00000000..0fbd0115 --- /dev/null +++ b/h3/src/algos.c @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Bytes & Brains + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "algos.h" +#include "error.h" + +H3Index +finest_common_ancestor(H3Index a, H3Index b) +{ + int aRes, + bRes, + coarsestRes; + H3Index aParent, + bParent; + + if (a == b) + return a; + + /* do not even share the basecell */ + if (getBaseCellNumber(a) != getBaseCellNumber(b)) + return H3_NULL; + + aRes = getResolution(a); + bRes = getResolution(b); + coarsestRes = (aRes < bRes) ? aRes : bRes; + + /* iterate backwards through resolutions */ + for (int i = coarsestRes; i > 0; i--) + { + h3_assert(cellToParent(a, i, &aParent)); + h3_assert(cellToParent(b, i, &bParent)); + if (aParent == bParent) + return aParent; + } + + return H3_NULL; +} diff --git a/h3/src/algos.h b/h3/src/algos.h new file mode 100644 index 00000000..c698d658 --- /dev/null +++ b/h3/src/algos.h @@ -0,0 +1,24 @@ +/* + * Copyright 2023 Bytes & Brains + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef H3_ALGOS_H +#define H3_ALGOS_H + +#include + +H3Index finest_common_ancestor(H3Index, H3Index); + +#endif /* H3_ALGOS_H */ diff --git a/h3/src/opclass_gist.c b/h3/src/opclass_gist.c index 65fd384b..fcb02103 100644 --- a/h3/src/opclass_gist.c +++ b/h3/src/opclass_gist.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 Bytes & Brains + * Copyright 2019-2023 Bytes & Brains * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,9 @@ #include // GiST #include // Main H3 include -#include "type.h" +#include "algos.h" #include "error.h" - -#define H3_ROOT_INDEX -1 - +#include "type.h" PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_gist_union); PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_gist_consistent); @@ -58,54 +56,16 @@ gist_cmp(H3Index a, H3Index b) /* a contains b */ error = cellToParent(b, aRes, &bParent); - if (!error && a == H3_ROOT_INDEX || (aRes < bRes && bParent == a)) + if (!error && a == H3_NULL || (aRes < bRes && bParent == a)) return 1; /* a contained by b */ error = cellToParent(a, bRes, &aParent); - if (!error && b == H3_ROOT_INDEX || (aRes > bRes && aParent == b)) + if (!error && b == H3_NULL || (aRes > bRes && aParent == b)) return -1; /* no overlap */ - return 0; -} - -/** - * GiST support - */ - -static H3Index -common_ancestor(H3Index a, H3Index b) -{ - int aRes, - bRes, - bigRes; - H3Index aParent, - bParent; - - if (a == b) - return a; - - /* do not even share the basecell */ - if (getBaseCellNumber(a) != getBaseCellNumber(b)) - return H3_ROOT_INDEX; - - aRes = getResolution(a); - bRes = getResolution(b); - bigRes = (aRes > bRes) ? aRes : bRes; - - /* iterate back basecells */ - for (int i = bigRes; i > 0; i--) - { - if (cellToParent(a, i, &aParent)) - continue; - if (cellToParent(b, i, &bParent)) - continue; - if (aParent == bParent) - return aParent; - } - - return H3_ROOT_INDEX; + return 0; } /** @@ -125,7 +85,7 @@ h3index_gist_union(PG_FUNCTION_ARGS) for (int i = 1; i < n; i++) { tmp = DatumGetH3Index(entries[i].key); - out = common_ancestor(out, tmp); + out = finest_common_ancestor(out, tmp); } PG_RETURN_H3INDEX(out); @@ -154,10 +114,13 @@ h3index_gist_consistent(PG_FUNCTION_ARGS) switch (strategy) { case RTOverlapStrategyNumber: + /* x && y */ PG_RETURN_BOOL(gist_cmp(key, query) != 0); case RTContainsStrategyNumber: + /* x @> y */ PG_RETURN_BOOL(gist_cmp(key, query) > 0); case RTContainedByStrategyNumber: + /* x <@ y */ if (GIST_LEAF(entry)) { PG_RETURN_BOOL(gist_cmp(key, query) < 0); @@ -201,7 +164,7 @@ h3index_gist_penalty(PG_FUNCTION_ARGS) H3Index orig = DatumGetH3Index(origentry->key); H3Index new = DatumGetH3Index(newentry->key); - H3Index ancestor = common_ancestor(orig, new); + H3Index ancestor = finest_common_ancestor(orig, new); *penalty = (float) getResolution(orig) - getResolution(ancestor); @@ -219,21 +182,42 @@ h3index_gist_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - OffsetNumber maxoff = entryvec->n - 1; GISTENTRY *ent = entryvec->vector; int i, + j, + real_i, + real_j, nbytes; OffsetNumber *left, *right; + GISTENTRY **raw_entryvec; + H3Index tmp_union, unionL, - unionR; - GISTENTRY **raw_entryvec; + unionR, + a, + b, + seed_union, + seed_left, + seed_right, + check_left, + check_right; bool lset = false, rset = false; + int res_a, + res_b, + res_finest; + int64_t waste, + max_waste, + nchildren, + size_l, + size_r, + check_size_l, + check_size_r; + nbytes = (maxoff + 1) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); @@ -249,48 +233,86 @@ h3index_gist_picksplit(PG_FUNCTION_ARGS) for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(ent[i]); + /* FIRST lets find best initial split (most wasted space if grouped) */ + + max_waste = 0; for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - int real_index = raw_entryvec[i] - ent; + real_i = raw_entryvec[i] - entryvec->vector; + a = DatumGetH3Index(entryvec->vector[real_i].key); + for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) + { + real_j = raw_entryvec[j] - entryvec->vector; + b = DatumGetH3Index(entryvec->vector[real_j].key); - tmp_union = DatumGetH3Index(ent[real_index].key); - /* DEBUG_H3INDEX(tmp_union); */ - /* Assert(tmp_union != NULL); */ + /* no waste if containment */ + if (gist_cmp(a, b) != 0) + { + waste = 0; + /* otherwise lets calc waste */ + } + else + { + seed_union = finest_common_ancestor(a, b); + + res_a = getResolution(a); + res_b = getResolution(b); + res_finest = (res_a > res_b) ? res_a : res_b; + + h3_assert(cellToChildrenSize(seed_union, res_finest, &waste)); + h3_assert(cellToChildrenSize(a, res_finest, &nchildren)); + waste -= nchildren; + h3_assert(cellToChildrenSize(b, res_finest, &nchildren)); + waste -= nchildren; + } + + if (waste > max_waste) + { + max_waste = waste; + seed_left = a; + seed_right = b; + } + } + } + DEBUG("BEST SPLIT %i", max_waste); + DEBUG_H3INDEX(seed_left); + DEBUG_H3INDEX(seed_right); + unionL = seed_left; + size_l = getResolution(unionL); + unionR = seed_right; + size_r = getResolution(unionR); + + /* SECOND assign each node to best seed */ + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + real_i = raw_entryvec[i] - ent; + a = DatumGetH3Index(ent[real_i].key); + + check_left = finest_common_ancestor(unionL, a); + check_size_l = getResolution(check_left); + + check_right = finest_common_ancestor(unionR, a); + check_size_r = getResolution(check_right); /* * Choose where to put the index entries and update unionL and unionR * accordingly. Append the entries to either v_spl_left or * v_spl_right, and care about the counters. */ - - if (v->spl_nleft < v->spl_nright) + if (check_size_l - size_l < check_size_r - size_r) { - if (lset == false) - { - lset = true; - unionL = tmp_union; - } - else - { - unionL = common_ancestor(unionL, tmp_union); - } - *left = real_index; + unionL = check_left; + size_l = check_size_l; + *left = real_i; ++left; ++(v->spl_nleft); } else { - if (rset == false) - { - rset = true; - /* DEBUG_H3INDEX(tmp_union); */ - unionR = tmp_union; - } - else - { - unionR = common_ancestor(unionR, tmp_union); - } - *right = real_index; + unionR = check_right; + size_r = check_size_r; + *right = real_i; ++right; ++(v->spl_nright); } @@ -298,6 +320,7 @@ h3index_gist_picksplit(PG_FUNCTION_ARGS) v->spl_ldatum = H3IndexGetDatum(unionL); v->spl_rdatum = H3IndexGetDatum(unionR); + PG_RETURN_POINTER(v); } diff --git a/h3/test/expected/opclass_gist.out b/h3/test/expected/opclass_gist.out index 9bfb00b6..ffb7fabf 100644 --- a/h3/test/expected/opclass_gist.out +++ b/h3/test/expected/opclass_gist.out @@ -1,33 +1,291 @@ \pset tuples_only on \set hexagon '\'831c02fffffffff\'::h3index' -CREATE TABLE h3_test_gist (hex h3index); -CREATE INDEX GIST_IDX ON h3_test_gist USING gist(hex); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_parent(:hexagon); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_children(:hexagon); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_center_child(:hexagon, 15); +CREATE TABLE h3_test_gist (cell h3index); +CREATE INDEX h3_test_gist_index + ON h3_test_gist + USING gist(cell experimental_h3index_ops); +-- insert data +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_parent(:hexagon); +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_children(:hexagon); +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_center_child(:hexagon, 15); -- -- TEST GiST -- -SELECT COUNT(*) = 1 FROM h3_test_gist WHERE hex @> :hexagon; +SELECT COUNT(*) = 1 FROM h3_test_gist WHERE cell @> :hexagon; t -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <@ :hexagon; +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <@ :hexagon; t -INSERT INTO h3_test_gist (hex) SELECT h3_grid_disk(:hexagon, 2); -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <-> :hexagon = 2; +INSERT INTO h3_test_gist (cell) SELECT h3_grid_disk(:hexagon, 2); +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <-> :hexagon = 2; t -- -- BREAK GIST -- -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <@ :hexagon; +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <@ :hexagon; t -SELECT COUNT(*) FROM h3_test_gist WHERE hex <@ :hexagon; +SELECT COUNT(*) FROM h3_test_gist WHERE cell <@ :hexagon; 8 -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_children(:hexagon, 8); -SELECT COUNT(*) > 8 FROM h3_test_gist WHERE hex <@ :hexagon; +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_children(:hexagon, 8); +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c18fffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c2afffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c1cfffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c1dfffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c1efffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c31fffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c33fffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c14fffffffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c10fffffffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c18fffffffff +NOTICE: index: 881c02045bfffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c11fffffffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c2afffffffff +NOTICE: index: 881c020465fffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c13fffffffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c18fffffffff +NOTICE: index: 881c02045dfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1cfffffffff +NOTICE: index: 881c02046dfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1dfffffffff +NOTICE: index: 881c0204adfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c2afffffffff +NOTICE: index: 881c020465fffff +NOTICE: BEST SPLIT 1588792951 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c15fffffffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1efffffffff +NOTICE: index: 881c02056dfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c31fffffffff +NOTICE: index: 881c020623fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c33fffffffff +NOTICE: index: 881c020c09fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c18fffffffff +NOTICE: index: 881c020483fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c14fffffffff +NOTICE: index: 881c020e19fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1cfffffffff +NOTICE: index: 881c02046dfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c10fffffffff +NOTICE: index: 881c020de5fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02045bfffff +NOTICE: index: 881c022035fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1dfffffffff +NOTICE: index: 881c0204adfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c2afffffffff +NOTICE: index: 881c020469fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c11fffffffff +NOTICE: index: 881c021651fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1efffffffff +NOTICE: index: 881c020589fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c0225e1fffff +NOTICE: index: 881c024007fffff +NOTICE: BEST SPLIT -1819921932 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 831c03fffffffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c31fffffffff +NOTICE: index: 881c020623fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c13fffffffff +NOTICE: index: 881c022313fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02045dfffff +NOTICE: index: 881c0224dbfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c18fffffffff +NOTICE: index: 881c020489fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c33fffffffff +NOTICE: index: 881c020f11fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c05fffffffff +NOTICE: index: 881c023363fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c04fffffffff +NOTICE: index: 881c0235adfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c14fffffffff +NOTICE: index: 881c020ec5fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020465fffff +NOTICE: index: 881c023a81fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1cfffffffff +NOTICE: index: 881c020485fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c10fffffffff +NOTICE: index: 881c0212c9fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c15fffffffff +NOTICE: index: 881c024015fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02056dfffff +NOTICE: index: 881c024a85fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1dfffffffff +NOTICE: index: 881c0204c7fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c06fffffffff +NOTICE: index: 881c024cabfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c2afffffffff +NOTICE: index: 881c02046bfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020c09fffff +NOTICE: index: 881c025929fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02045bfffff +NOTICE: index: 881c022187fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1efffffffff +NOTICE: index: 881c0205b9fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020483fffff +NOTICE: index: 881c0250a3fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c11fffffffff +NOTICE: index: 881c021723fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020e19fffff +NOTICE: index: 881c026507fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02046dfffff +NOTICE: index: 881c026589fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c0225e1fffff +NOTICE: index: 881c024007fffff +NOTICE: BEST SPLIT 955561769 +NOTICE: index: 8f1c02000000000 +NOTICE: index: 881c022311fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020de5fffff +NOTICE: index: 881c0261cdfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02162bfffff +NOTICE: index: 881c022035fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c13fffffffff +NOTICE: index: 881c02299bfffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c31fffffffff +NOTICE: index: 881c0208cbfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c0204adfffff +NOTICE: index: 881c0271c7fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020469fffff +NOTICE: index: 881c027a39fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c021651fffff +NOTICE: index: 881c0281abfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02045dfffff +NOTICE: index: 881c022921fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c18fffffffff +NOTICE: index: 881c02048bfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020589fffff +NOTICE: index: 881c0281c5fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c33fffffffff +NOTICE: index: 881c020f5bfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c028ad7fffff +NOTICE: index: 881c02a067fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c14fffffffff +NOTICE: index: 881c021115fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c05fffffffff +NOTICE: index: 881c0234a9fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c03fffffffff +NOTICE: index: 881c028c01fffff +NOTICE: BEST SPLIT 81233 +NOTICE: index: 831c04fffffffff +NOTICE: index: 881c02389dfffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020623fffff +NOTICE: index: 881c028ed1fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020465fffff +NOTICE: index: 881c0240b3fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c022313fffff +NOTICE: index: 881c029363fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c0224dbfffff +NOTICE: index: 881c029827fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c1cfffffffff +NOTICE: index: 881c020491fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020489fffff +NOTICE: index: 881c02a909fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c10fffffffff +NOTICE: index: 881c0215b1fffff +NOTICE: BEST SPLIT 669478 +NOTICE: index: 831c15fffffffff +NOTICE: index: 881c024509fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c020f11fffff +NOTICE: index: 881c02ac85fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c02056dfffff +NOTICE: index: 881c024ab7fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c023363fffff +NOTICE: index: 881c02adc3fffff +NOTICE: BEST SPLIT 16805 +NOTICE: index: 881c0235adfffff +NOTICE: index: 881c02b62bfffff +SELECT COUNT(*) > 8 FROM h3_test_gist WHERE cell <@ :hexagon; t diff --git a/h3/test/sql/opclass_gist.sql b/h3/test/sql/opclass_gist.sql index 17bdcfcc..ef1086ec 100644 --- a/h3/test/sql/opclass_gist.sql +++ b/h3/test/sql/opclass_gist.sql @@ -1,26 +1,30 @@ \pset tuples_only on \set hexagon '\'831c02fffffffff\'::h3index' -CREATE TABLE h3_test_gist (hex h3index); -CREATE INDEX GIST_IDX ON h3_test_gist USING gist(hex); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_parent(:hexagon); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_children(:hexagon); -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_center_child(:hexagon, 15); +CREATE TABLE h3_test_gist (cell h3index); +CREATE INDEX h3_test_gist_index + ON h3_test_gist + USING gist(cell experimental_h3index_ops); + +-- insert data +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_parent(:hexagon); +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_children(:hexagon); +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_center_child(:hexagon, 15); -- -- TEST GiST -- -SELECT COUNT(*) = 1 FROM h3_test_gist WHERE hex @> :hexagon; -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <@ :hexagon; +SELECT COUNT(*) = 1 FROM h3_test_gist WHERE cell @> :hexagon; +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <@ :hexagon; -INSERT INTO h3_test_gist (hex) SELECT h3_grid_disk(:hexagon, 2); -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <-> :hexagon = 2; +INSERT INTO h3_test_gist (cell) SELECT h3_grid_disk(:hexagon, 2); +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <-> :hexagon = 2; -- -- BREAK GIST -- -SELECT COUNT(*) = 8 FROM h3_test_gist WHERE hex <@ :hexagon; -SELECT COUNT(*) FROM h3_test_gist WHERE hex <@ :hexagon; -INSERT INTO h3_test_gist (hex) SELECT h3_cell_to_children(:hexagon, 8); -SELECT COUNT(*) > 8 FROM h3_test_gist WHERE hex <@ :hexagon; +SELECT COUNT(*) = 8 FROM h3_test_gist WHERE cell <@ :hexagon; +SELECT COUNT(*) FROM h3_test_gist WHERE cell <@ :hexagon; +INSERT INTO h3_test_gist (cell) SELECT h3_cell_to_children(:hexagon, 8); +SELECT COUNT(*) > 8 FROM h3_test_gist WHERE cell <@ :hexagon;