I believe that attached version of patch can be backpatched. It fixes this problem without altering of index building procedure. It just makes checks in internal pages softener enough to compensate effect of gist_box_same implementation.
------ With best regards, Alexander Korotkov.
*** a/src/backend/access/gist/gistproc.c --- b/src/backend/access/gist/gistproc.c *************** *** 70,76 **** gist_box_consistent(PG_FUNCTION_ARGS) if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); ! /* * if entry is not leaf, use rtree_internal_consistent, else use * gist_box_leaf_consistent --- 70,76 ---- if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); ! /* * if entry is not leaf, use rtree_internal_consistent, else use * gist_box_leaf_consistent *************** *** 80,88 **** gist_box_consistent(PG_FUNCTION_ARGS) query, strategy)); else ! PG_RETURN_BOOL(rtree_internal_consistent(DatumGetBoxP(entry->key), query, strategy)); } static void --- 80,102 ---- query, strategy)); else ! { ! /* ! * Box in internal page can be narrower than box in leaf page not ! * more than EPSILON in each boundary. Do corresponding correction. ! */ ! BOX key, *entrykey; ! ! entrykey = DatumGetBoxP(entry->key); ! key.low.x = entrykey->low.x - EPSILON; ! key.low.y = entrykey->low.y - EPSILON; ! key.high.x = entrykey->high.x + EPSILON; ! key.high.y = entrykey->high.y + EPSILON; ! ! PG_RETURN_BOOL(rtree_internal_consistent(&key, query, strategy)); + } } static void *************** *** 847,852 **** gist_box_same(PG_FUNCTION_ARGS) --- 861,871 ---- BOX *b2 = PG_GETARG_BOX_P(1); bool *result = (bool *) PG_GETARG_POINTER(2); + /* + * box_same function allow difference between boxes limited by EPSILON. + * Thus box in internal page can be narrower than box in leaf page not + * more than EPSILON in each boundary. + */ if (b1 && b2) *result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), *************** *** 1072,1077 **** gist_poly_consistent(PG_FUNCTION_ARGS) --- 1091,1097 ---- GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); POLYGON *query = PG_GETARG_POLYGON_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + BOX key, *entrykey; /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); *************** *** 1083,1094 **** gist_poly_consistent(PG_FUNCTION_ARGS) if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); /* * Since the operators require recheck anyway, we can just use * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not polygons.) */ ! result = rtree_internal_consistent(DatumGetBoxP(entry->key), &(query->boundbox), strategy); /* Avoid memory leak if supplied poly is toasted */ --- 1103,1128 ---- if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); + entrykey = DatumGetBoxP(entry->key); + if (!GIST_LEAF(entry)) + { + /* + * Box in internal page can be narrower than box in leaf page not + * more than EPSILON in each boundary. Do corresponding correction. + */ + key.low.x = entrykey->low.x - EPSILON; + key.low.y = entrykey->low.y - EPSILON; + key.high.x = entrykey->high.x + EPSILON; + key.high.y = entrykey->high.y + EPSILON; + entrykey = &key; + } + /* * Since the operators require recheck anyway, we can just use * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not polygons.) */ ! result = rtree_internal_consistent(entrykey, &(query->boundbox), strategy); /* Avoid memory leak if supplied poly is toasted */ *************** *** 1152,1158 **** gist_circle_consistent(PG_FUNCTION_ARGS) /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); ! BOX bbox; bool result; /* All cases served by this function are inexact */ --- 1186,1192 ---- /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); ! BOX bbox, *entrykey, key; bool result; /* All cases served by this function are inexact */ *************** *** 1170,1177 **** gist_circle_consistent(PG_FUNCTION_ARGS) bbox.low.x = query->center.x - query->radius; bbox.high.y = query->center.y + query->radius; bbox.low.y = query->center.y - query->radius; ! result = rtree_internal_consistent(DatumGetBoxP(entry->key), &bbox, strategy); PG_RETURN_BOOL(result); --- 1204,1225 ---- bbox.low.x = query->center.x - query->radius; bbox.high.y = query->center.y + query->radius; bbox.low.y = query->center.y - query->radius; + + entrykey = DatumGetBoxP(entry->key); + if (!GIST_LEAF(entry)) + { + /* + * Box in internal page can be narrower than box in leaf page not + * more than EPSILON in each boundary. Do corresponding correction. + */ + key.low.x = entrykey->low.x - EPSILON; + key.low.y = entrykey->low.y - EPSILON; + key.high.x = entrykey->high.x + EPSILON; + key.high.y = entrykey->high.y + EPSILON; + entrykey = &key; + } ! result = rtree_internal_consistent(entrykey, &bbox, strategy); PG_RETURN_BOOL(result); *************** *** 1337,1348 **** gist_point_consistent(PG_FUNCTION_ARGS) *recheck = false; break; case BoxStrategyNumberGroup: ! result = DatumGetBool(DirectFunctionCall5( ! gist_box_consistent, ! PointerGetDatum(entry), ! PG_GETARG_DATUM(1), ! Int16GetDatum(RTOverlapStrategyNumber), ! 0, PointerGetDatum(recheck))); break; case PolygonStrategyNumberGroup: { --- 1385,1419 ---- *recheck = false; break; case BoxStrategyNumberGroup: ! { ! /* ! * This strategy should behave like on_ob which uses simple ! * comparison rather than FP* functions. Thus we use simple ! * comparison for leaf entries. Also we use box_overlap which ! * allows difference not more than EPSILON compensating ! * possible narrower boxes in internal pages. ! */ ! ! BOX *query = PG_GETARG_BOX_P(1); ! ! if (GIST_LEAF(entry)) ! { ! BOX *key; ! key = DatumGetBoxP(entry->key); ! *recheck = false; ! result = key->high.x >= query->low.x && ! key->low.x <= query->high.x && ! key->high.y >= query->low.y && ! key->low.y <= query->high.y; ! } ! else ! { ! result = DatumGetBool(DirectFunctionCall2( ! box_overlap, ! entry->key, ! PointerGetDatum(query))); ! } ! } break; case PolygonStrategyNumberGroup: {
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers