Commit 9b5c8d45 authored by Tom Lane's avatar Tom Lane

Push index operator lossiness determination down to GIST/GIN opclass

"consistent" functions, and remove pg_amop.opreqcheck, as per recent
discussion.  The main immediate benefit of this is that we no longer need
8.3's ugly hack of requiring @@@ rather than @@ to test weight-using tsquery
searches on GIN indexes.  In future it should be possible to optimize some
other queries better than is done now, by detecting at runtime whether the
index match is exact or not.

Tom Lane, after an idea of Heikki's, and with some help from Teodor.
parent 10be77c1
......@@ -126,12 +126,17 @@ Datum
gbt_bit_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
void *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval = FALSE;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R r = gbt_var_key_readable(key);
/* All cases served by this function are exact */
*recheck = false;
if (GIST_LEAF(entry))
retval = gbt_var_consistent(&r, query, &strategy, TRUE, &tinfo);
else
......
......@@ -96,12 +96,17 @@ Datum
gbt_bytea_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
void *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R r = gbt_var_key_readable(key);
/* All cases served by this function are exact */
*recheck = false;
retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
PG_RETURN_BOOL(retval);
}
......
......@@ -97,9 +97,14 @@ gbt_cash_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Cash query = (*((Cash *) PG_GETARG_POINTER(1)));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
cashKEY *kkk = (cashKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -113,9 +113,14 @@ gbt_date_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
DateADT query = PG_GETARG_DATEADT(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -96,9 +96,14 @@ gbt_float4_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
float4 query = PG_GETARG_FLOAT4(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -95,12 +95,16 @@ gbt_float8_compress(PG_FUNCTION_ARGS)
Datum
gbt_float8_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
float8 query = PG_GETARG_FLOAT8(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
This diff is collapsed.
......@@ -115,9 +115,14 @@ gbt_inet_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
double query = convert_network_to_scalar(PG_GETARG_DATUM(1), INETOID);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
inetKEY *kkk = (inetKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
/* All cases served by this function are inexact */
*recheck = true;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -100,9 +100,14 @@ gbt_int2_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int16 query = PG_GETARG_INT16(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
int16KEY *kkk = (int16KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -95,12 +95,16 @@ gbt_int4_compress(PG_FUNCTION_ARGS)
Datum
gbt_int4_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int32 query = PG_GETARG_INT32(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
int32KEY *kkk = (int32KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -97,9 +97,14 @@ gbt_int8_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int64 query = PG_GETARG_INT64(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
int64KEY *kkk = (int64KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -165,9 +165,14 @@ gbt_intv_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Interval *query = PG_GETARG_INTERVAL_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
intvKEY *kkk = (intvKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -116,12 +116,16 @@ gbt_macad_compress(PG_FUNCTION_ARGS)
Datum
gbt_macad_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
macaddr *query = (macaddr *) PG_GETARG_POINTER(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
macKEY *kkk = (macKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -99,14 +99,18 @@ gbt_numeric_compress(PG_FUNCTION_ARGS)
Datum
gbt_numeric_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
void *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R r = gbt_var_key_readable(key);
/* All cases served by this function are exact */
*recheck = false;
retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
PG_RETURN_BOOL(retval);
}
......
......@@ -95,12 +95,16 @@ gbt_oid_compress(PG_FUNCTION_ARGS)
Datum
gbt_oid_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Oid query = PG_GETARG_OID(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
oidKEY *kkk = (oidKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......
......@@ -130,12 +130,17 @@ Datum
gbt_text_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
void *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R r = gbt_var_key_readable(key);
/* All cases served by this function are exact */
*recheck = false;
if (tinfo.eml == 0)
{
tinfo.eml = pg_database_encoding_max_length();
......@@ -151,12 +156,17 @@ Datum
gbt_bpchar_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
void *query = (void *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
void *trim = (void *) DatumGetPointer(DirectFunctionCall1(rtrim1, PointerGetDatum(query)));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R r = gbt_var_key_readable(key);
void *trim = (void *) DatumGetPointer(DirectFunctionCall1(rtrim1, PointerGetDatum(query)));
/* All cases served by this function are exact */
*recheck = false;
if (tinfo.eml == 0)
{
......
......@@ -151,14 +151,18 @@ gbt_time_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TimeADT query = PG_GETARG_TIMEADT(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
PG_RETURN_BOOL(
gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
);
......@@ -170,11 +174,15 @@ gbt_timetz_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
TimeADT qqq;
GBT_NUMKEY_R key;
/* All cases served by this function are inexact */
*recheck = true;
#ifdef HAVE_INT64_TIMESTAMP
qqq = query->time + (query->zone * INT64CONST(1000000));
#else
......
......@@ -173,9 +173,14 @@ gbt_ts_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Timestamp *query = (Timestamp *) PG_GETARG_POINTER(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
tsKEY *kkk = (tsKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk->lower;
key.upper = (GBT_NUMKEY *) & kkk->upper;
......@@ -190,11 +195,16 @@ gbt_tstz_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TimestampTz *query = (Timestamp *) PG_GETARG_POINTER(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
char *kkk = (char *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
Timestamp qqq;
/* All cases served by this function are exact */
*recheck = false;
key.lower = (GBT_NUMKEY *) & kkk[0];
key.upper = (GBT_NUMKEY *) & kkk[MAXALIGN(tinfo.size)];
tstz_to_ts_gmt(&qqq, query);
......
/* $PostgreSQL: pgsql/contrib/btree_gist/uninstall_btree_gist.sql,v 1.4 2007/11/13 04:24:27 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/btree_gist/uninstall_btree_gist.sql,v 1.5 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -17,7 +17,7 @@ DROP FUNCTION gbt_inet_penalty(internal,internal,internal);
DROP FUNCTION gbt_inet_compress(internal);
DROP FUNCTION gbt_inet_consistent(internal,inet,int2);
DROP FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal);
DROP OPERATOR CLASS gist_vbit_ops USING gist;
......@@ -33,7 +33,7 @@ DROP FUNCTION gbt_bit_penalty(internal,internal,internal);
DROP FUNCTION gbt_bit_compress(internal);
DROP FUNCTION gbt_bit_consistent(internal,bit,int2);
DROP FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal);
DROP OPERATOR CLASS gist_numeric_ops USING gist;
......@@ -47,7 +47,7 @@ DROP FUNCTION gbt_numeric_penalty(internal,internal,internal);
DROP FUNCTION gbt_numeric_compress(internal);
DROP FUNCTION gbt_numeric_consistent(internal,numeric,int2);
DROP FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal);
DROP OPERATOR CLASS gist_bytea_ops USING gist;
......@@ -61,7 +61,7 @@ DROP FUNCTION gbt_bytea_penalty(internal,internal,internal);
DROP FUNCTION gbt_bytea_compress(internal);
DROP FUNCTION gbt_bytea_consistent(internal,bytea,int2);
DROP FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal);
DROP OPERATOR CLASS gist_bpchar_ops USING gist;
......@@ -79,9 +79,9 @@ DROP FUNCTION gbt_bpchar_compress(internal);
DROP FUNCTION gbt_text_compress(internal);
DROP FUNCTION gbt_bpchar_consistent(internal,bpchar,int2);
DROP FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal);
DROP FUNCTION gbt_text_consistent(internal,text,int2);
DROP FUNCTION gbt_text_consistent(internal,text,int2,oid,internal);
DROP OPERATOR CLASS gist_macaddr_ops USING gist;
......@@ -95,7 +95,7 @@ DROP FUNCTION gbt_macad_penalty(internal,internal,internal);
DROP FUNCTION gbt_macad_compress(internal);
DROP FUNCTION gbt_macad_consistent(internal,macaddr,int2);
DROP FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal);
DROP OPERATOR CLASS gist_cash_ops USING gist;
......@@ -109,7 +109,7 @@ DROP FUNCTION gbt_cash_penalty(internal,internal,internal);
DROP FUNCTION gbt_cash_compress(internal);
DROP FUNCTION gbt_cash_consistent(internal,money,int2);
DROP FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal);
DROP OPERATOR CLASS gist_interval_ops USING gist;
......@@ -125,7 +125,7 @@ DROP FUNCTION gbt_intv_decompress(internal);
DROP FUNCTION gbt_intv_compress(internal);
DROP FUNCTION gbt_intv_consistent(internal,interval,int2);
DROP FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal);
DROP OPERATOR CLASS gist_date_ops USING gist;
......@@ -139,7 +139,7 @@ DROP FUNCTION gbt_date_penalty(internal,internal,internal);
DROP FUNCTION gbt_date_compress(internal);
DROP FUNCTION gbt_date_consistent(internal,date,int2);
DROP FUNCTION gbt_date_consistent(internal,date,int2,oid,internal);
DROP OPERATOR CLASS gist_timetz_ops USING gist;
......@@ -157,9 +157,9 @@ DROP FUNCTION gbt_timetz_compress(internal);
DROP FUNCTION gbt_time_compress(internal);
DROP FUNCTION gbt_timetz_consistent(internal,timetz,int2);
DROP FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal);
DROP FUNCTION gbt_time_consistent(internal,time,int2);
DROP FUNCTION gbt_time_consistent(internal,time,int2,oid,internal);
DROP OPERATOR CLASS gist_timestamptz_ops USING gist;
......@@ -177,9 +177,9 @@ DROP FUNCTION gbt_tstz_compress(internal);
DROP FUNCTION gbt_ts_compress(internal);
DROP FUNCTION gbt_tstz_consistent(internal,timestamptz,int2);
DROP FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal);
DROP FUNCTION gbt_ts_consistent(internal,timestamp,int2);
DROP FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal);
DROP OPERATOR CLASS gist_float8_ops USING gist;
......@@ -193,7 +193,7 @@ DROP FUNCTION gbt_float8_penalty(internal,internal,internal);
DROP FUNCTION gbt_float8_compress(internal);
DROP FUNCTION gbt_float8_consistent(internal,float8,int2);
DROP FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal);
DROP OPERATOR CLASS gist_float4_ops USING gist;
......@@ -207,7 +207,7 @@ DROP FUNCTION gbt_float4_penalty(internal,internal,internal);
DROP FUNCTION gbt_float4_compress(internal);
DROP FUNCTION gbt_float4_consistent(internal,float4,int2);
DROP FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal);
DROP OPERATOR CLASS gist_int8_ops USING gist;
......@@ -221,7 +221,7 @@ DROP FUNCTION gbt_int8_penalty(internal,internal,internal);
DROP FUNCTION gbt_int8_compress(internal);
DROP FUNCTION gbt_int8_consistent(internal,int8,int2);
DROP FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal);
DROP OPERATOR CLASS gist_int4_ops USING gist;
......@@ -235,7 +235,7 @@ DROP FUNCTION gbt_int4_penalty(internal,internal,internal);
DROP FUNCTION gbt_int4_compress(internal);
DROP FUNCTION gbt_int4_consistent(internal,int4,int2);
DROP FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal);
DROP OPERATOR CLASS gist_int2_ops USING gist;
......@@ -249,7 +249,7 @@ DROP FUNCTION gbt_int2_penalty(internal,internal,internal);
DROP FUNCTION gbt_int2_compress(internal);
DROP FUNCTION gbt_int2_consistent(internal,int2,int2);
DROP FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal);
DROP OPERATOR CLASS gist_oid_ops USING gist;
......@@ -267,7 +267,7 @@ DROP FUNCTION gbt_decompress(internal);
DROP FUNCTION gbt_oid_compress(internal);
DROP FUNCTION gbt_oid_consistent(internal,oid,int2);
DROP FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal);
DROP TYPE gbtreekey_var CASCADE;
......
/******************************************************************************
$PostgreSQL: pgsql/contrib/cube/cube.c,v 1.34 2007/11/15 21:14:29 momjian Exp $
$PostgreSQL: pgsql/contrib/cube/cube.c,v 1.35 2008/04/14 17:05:32 tgl Exp $
This file contains routines that can be bound to a Postgres backend and
called by the backend in the process of processing queries. The calling
......@@ -381,8 +381,13 @@ g_cube_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
NDBOX *query = PG_GETARG_NDBOX(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool res;
/* All cases served by this function are exact */
*recheck = false;
/*
* if entry is not leaf, use g_cube_internal_consistent, else use
* g_cube_leaf_consistent
......
/* $PostgreSQL: pgsql/contrib/cube/cube.sql.in,v 1.23 2007/11/13 04:24:27 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/cube/cube.sql.in,v 1.24 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -262,7 +262,7 @@ CREATE OPERATOR ~ (
-- define the GiST support methods
CREATE OR REPLACE FUNCTION g_cube_consistent(internal,cube,int4)
CREATE OR REPLACE FUNCTION g_cube_consistent(internal,cube,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -317,7 +317,7 @@ CREATE OPERATOR CLASS gist_cube_ops
OPERATOR 8 <@ ,
OPERATOR 13 @ ,
OPERATOR 14 ~ ,
FUNCTION 1 g_cube_consistent (internal, cube, int4),
FUNCTION 1 g_cube_consistent (internal, cube, int, oid, internal),
FUNCTION 2 g_cube_union (internal, internal),
FUNCTION 3 g_cube_compress (internal),
FUNCTION 4 g_cube_decompress (internal),
......
/* $PostgreSQL: pgsql/contrib/cube/uninstall_cube.sql,v 1.7 2007/11/13 04:24:27 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/cube/uninstall_cube.sql,v 1.8 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -19,7 +19,7 @@ DROP FUNCTION g_cube_decompress(internal);
DROP FUNCTION g_cube_compress(internal);
DROP FUNCTION g_cube_consistent(internal,cube,int4);
DROP FUNCTION g_cube_consistent(internal,cube,int,oid,internal);
DROP OPERATOR ~ (cube, cube);
......
/* $PostgreSQL: pgsql/contrib/hstore/hstore.sql.in,v 1.8 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/hstore/hstore.sql.in,v 1.9 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -214,7 +214,7 @@ RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
CREATE OR REPLACE FUNCTION ghstore_consistent(internal,internal,int4)
CREATE OR REPLACE FUNCTION ghstore_consistent(internal,internal,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -223,12 +223,12 @@ LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gist_hstore_ops
DEFAULT FOR TYPE hstore USING gist
AS
OPERATOR 7 @> RECHECK,
OPERATOR 9 ?(hstore,text) RECHECK,
--OPERATOR 8 <@ RECHECK,
OPERATOR 13 @ RECHECK,
--OPERATOR 14 ~ RECHECK,
FUNCTION 1 ghstore_consistent (internal, internal, int4),
OPERATOR 7 @> ,
OPERATOR 9 ?(hstore,text) ,
--OPERATOR 8 <@ ,
OPERATOR 13 @ ,
--OPERATOR 14 ~ ,
FUNCTION 1 ghstore_consistent (internal, internal, int, oid, internal),
FUNCTION 2 ghstore_union (internal, internal),
FUNCTION 3 ghstore_compress (internal),
FUNCTION 4 ghstore_decompress (internal),
......@@ -249,18 +249,18 @@ RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
CREATE OR REPLACE FUNCTION gin_consistent_hstore(internal, int2, internal)
RETURNS internal
CREATE OR REPLACE FUNCTION gin_consistent_hstore(internal, int2, internal, internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gin_hstore_ops
DEFAULT FOR TYPE hstore USING gin
AS
OPERATOR 7 @> RECHECK,
OPERATOR 7 @> ,
OPERATOR 9 ?(hstore,text),
FUNCTION 1 bttextcmp(text,text),
FUNCTION 2 gin_extract_hstore(internal, internal),
FUNCTION 3 gin_extract_hstore_query(internal, internal, int2),
FUNCTION 4 gin_consistent_hstore(internal, int2, internal),
FUNCTION 4 gin_consistent_hstore(internal, int2, internal, internal),
STORAGE text;
......@@ -113,21 +113,31 @@ Datum gin_consistent_hstore(PG_FUNCTION_ARGS);
Datum
gin_consistent_hstore(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
HStore *query = PG_GETARG_HS(2);
bool *recheck = (bool *) PG_GETARG_POINTER(3);
bool res = true;
if (strategy == HStoreContainsStrategyNumber)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
HStore *query = PG_GETARG_HS(2);
int i;
/*
* Index lost information about correspondence of keys
* and values, so we need recheck
*/
*recheck = true;
for (i = 0; res && i < 2 * query->size; i++)
if (check[i] == false)
res = false;
}
else if (strategy == HStoreExistsStrategyNumber)
{
/* Existence of key is guaranteed */
*recheck = false;
res = true;
}
else
elog(ERROR, "Unsupported strategy number: %d", strategy);
......
......@@ -508,9 +508,14 @@ ghstore_consistent(PG_FUNCTION_ARGS)
{
GISTTYPE *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool res = true;
BITVECP sign;
/* All cases served by this function are inexact */
*recheck = true;
if (ISALLTRUE(entry))
PG_RETURN_BOOL(true);
......
/* $PostgreSQL: pgsql/contrib/hstore/uninstall_hstore.sql,v 1.6 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/hstore/uninstall_hstore.sql,v 1.7 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -37,8 +37,8 @@ DROP FUNCTION ghstore_penalty(internal,internal,internal);
DROP FUNCTION ghstore_picksplit(internal, internal);
DROP FUNCTION ghstore_union(internal, internal);
DROP FUNCTION ghstore_same(internal, internal, internal);
DROP FUNCTION ghstore_consistent(internal,internal,int4);
DROP FUNCTION gin_consistent_hstore(internal, smallint, internal);
DROP FUNCTION ghstore_consistent(internal,internal,int,oid,internal);
DROP FUNCTION gin_consistent_hstore(internal, int2, internal, internal);
DROP FUNCTION gin_extract_hstore(internal, internal);
DROP FUNCTION gin_extract_hstore_query(internal, internal, smallint);
......
/* $PostgreSQL: pgsql/contrib/intarray/_int.sql.in,v 1.27 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/intarray/_int.sql.in,v 1.28 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -323,7 +323,7 @@ CREATE OPERATOR & (
--------------
-- define the GiST support methods
CREATE OR REPLACE FUNCTION g_int_consistent(internal,_int4,int4)
CREATE OR REPLACE FUNCTION g_int_consistent(internal,_int4,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -364,13 +364,13 @@ LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gist__int_ops
DEFAULT FOR TYPE _int4 USING gist AS
OPERATOR 3 &&,
OPERATOR 6 = (anyarray, anyarray) RECHECK,
OPERATOR 6 = (anyarray, anyarray),
OPERATOR 7 @>,
OPERATOR 8 <@,
OPERATOR 13 @,
OPERATOR 14 ~,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 g_int_consistent (internal, _int4, int4),
FUNCTION 1 g_int_consistent (internal, _int4, int, oid, internal),
FUNCTION 2 g_int_union (internal, internal),
FUNCTION 3 g_int_compress (internal),
FUNCTION 4 g_int_decompress (internal),
......@@ -400,7 +400,7 @@ CREATE TYPE intbig_gkey (
OUTPUT = _intbig_out
);
CREATE OR REPLACE FUNCTION g_intbig_consistent(internal,internal,int4)
CREATE OR REPLACE FUNCTION g_intbig_consistent(internal,internal,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -440,14 +440,14 @@ LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gist__intbig_ops
FOR TYPE _int4 USING gist
AS
OPERATOR 3 && RECHECK,
OPERATOR 6 = (anyarray, anyarray) RECHECK,
OPERATOR 7 @> RECHECK,
OPERATOR 8 <@ RECHECK,
OPERATOR 13 @ RECHECK,
OPERATOR 14 ~ RECHECK,
OPERATOR 20 @@ (_int4, query_int) RECHECK,
FUNCTION 1 g_intbig_consistent (internal, internal, int4),
OPERATOR 3 &&,
OPERATOR 6 = (anyarray, anyarray),
OPERATOR 7 @>,
OPERATOR 8 <@,
OPERATOR 13 @,
OPERATOR 14 ~,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 g_intbig_consistent (internal, internal, int, oid, internal),
FUNCTION 2 g_intbig_union (internal, internal),
FUNCTION 3 g_intbig_compress (internal),
FUNCTION 4 g_intbig_decompress (internal),
......@@ -463,7 +463,7 @@ RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
CREATE OR REPLACE FUNCTION ginint4_consistent(internal, int2, internal)
CREATE OR REPLACE FUNCTION ginint4_consistent(internal, int2, internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -472,14 +472,14 @@ CREATE OPERATOR CLASS gin__int_ops
FOR TYPE _int4 USING gin
AS
OPERATOR 3 &&,
OPERATOR 6 = (anyarray, anyarray) RECHECK,
OPERATOR 6 = (anyarray, anyarray),
OPERATOR 7 @>,
OPERATOR 8 <@ RECHECK,
OPERATOR 8 <@,
OPERATOR 13 @,
OPERATOR 14 ~ RECHECK,
OPERATOR 14 ~,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 btint4cmp (int4, int4),
FUNCTION 2 ginarrayextract (anyarray, internal),
FUNCTION 3 ginint4_queryextract (internal, internal, int2),
FUNCTION 4 ginint4_consistent (internal, int2, internal),
FUNCTION 4 ginint4_consistent (internal, int2, internal, internal),
STORAGE int4;
......@@ -82,50 +82,76 @@ ginint4_consistent(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
int res = FALSE;
bool *recheck = (bool *) PG_GETARG_POINTER(3);
bool res = FALSE;
/*
* we can do not check array carefully, it's done by previous
* we need not check array carefully, it's done by previous
* ginarrayextract call
*/
switch (strategy)
{
case RTOverlapStrategyNumber:
/* result is not lossy */
*recheck = false;
/* at least one element in check[] is true, so result = true */
res = TRUE;
break;
case RTContainedByStrategyNumber:
case RTOldContainedByStrategyNumber:
/* we will need recheck */
*recheck = true;
/* at least one element in check[] is true, so result = true */
res = TRUE;
break;
case RTSameStrategyNumber:
{
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
int i,
nentries = ARRNELEMS(query);
/* we will need recheck */
*recheck = true;
res = TRUE;
for (i = 0; i < nentries; i++)
if (!check[i])
{
res = FALSE;
break;
}
}
break;
case RTContainsStrategyNumber:
case RTOldContainsStrategyNumber:
res = TRUE;
do
{
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
int i,
nentries = ARRNELEMS(query);
/* result is not lossy */
*recheck = false;
res = TRUE;
for (i = 0; i < nentries; i++)
if (!check[i])
{
res = FALSE;
break;
}
} while (0);
}
break;
case BooleanSearchStrategy:
do
{
QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(2));
/* result is not lossy */
*recheck = false;
res = ginconsistent(query, check);
} while (0);
}
break;
default:
elog(ERROR, "ginint4_consistent: unknown strategy number: %d", strategy);
elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
strategy);
}
PG_RETURN_BOOL(res);
......
......@@ -34,8 +34,13 @@ g_int_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
ArrayType *query = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
/* this is exact except for RTSameStrategyNumber */
*recheck = (strategy == RTSameStrategyNumber);
if (strategy == BooleanSearchStrategy)
{
retval = execconsistent((QUERYTYPE *) query,
......
......@@ -498,8 +498,13 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
ArrayType *query = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool retval;
/* All cases served by this function are inexact */
*recheck = true;
if (ISALLTRUE(DatumGetPointer(entry->key)))
PG_RETURN_BOOL(true);
......
/* $PostgreSQL: pgsql/contrib/intarray/uninstall__int.sql,v 1.8 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/intarray/uninstall__int.sql,v 1.9 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -7,7 +7,7 @@ DROP OPERATOR CLASS gin__int_ops USING gin;
DROP FUNCTION ginint4_queryextract(internal, internal, int2);
DROP FUNCTION ginint4_consistent(internal, int2, internal);
DROP FUNCTION ginint4_consistent(internal, int2, internal, internal);
DROP OPERATOR CLASS gist__intbig_ops USING gist;
......@@ -23,7 +23,7 @@ DROP FUNCTION g_intbig_decompress(internal);
DROP FUNCTION g_intbig_compress(internal);
DROP FUNCTION g_intbig_consistent(internal,internal,int4);
DROP FUNCTION g_intbig_consistent(internal,internal,int,oid,internal);
DROP TYPE intbig_gkey CASCADE;
......@@ -41,7 +41,7 @@ DROP FUNCTION g_int_decompress(internal);
DROP FUNCTION g_int_compress(internal);
DROP FUNCTION g_int_consistent(internal,_int4,int4);
DROP FUNCTION g_int_consistent(internal,_int4,int,oid,internal);
DROP OPERATOR & (_int4, _int4);
......
......@@ -554,10 +554,15 @@ _ltree_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
char *query = (char *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
bool res = false;
/* All cases served by this function are inexact */
*recheck = true;
switch (strategy)
{
case 10:
......
/* $PostgreSQL: pgsql/contrib/ltree/ltree.sql.in,v 1.16 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/ltree/ltree.sql.in,v 1.17 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -496,7 +496,7 @@ CREATE TYPE ltree_gist (
);
CREATE OR REPLACE FUNCTION ltree_consistent(internal,internal,int2)
CREATE OR REPLACE FUNCTION ltree_consistent(internal,internal,int2,oid,internal)
RETURNS bool as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE;
CREATE OR REPLACE FUNCTION ltree_compress(internal)
......@@ -532,7 +532,7 @@ CREATE OPERATOR CLASS gist_ltree_ops
OPERATOR 15 @ (ltxtquery, ltree) ,
OPERATOR 16 ? (ltree, _lquery) ,
OPERATOR 17 ? (_lquery, ltree) ,
FUNCTION 1 ltree_consistent (internal, internal, int2),
FUNCTION 1 ltree_consistent (internal, internal, int2, oid, internal),
FUNCTION 2 ltree_union (internal, internal),
FUNCTION 3 ltree_compress (internal),
FUNCTION 4 ltree_decompress (internal),
......@@ -822,7 +822,7 @@ CREATE OPERATOR ?@ (
);
--GiST support for ltree[]
CREATE OR REPLACE FUNCTION _ltree_consistent(internal,internal,int2)
CREATE OR REPLACE FUNCTION _ltree_consistent(internal,internal,int2,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -854,15 +854,15 @@ LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gist__ltree_ops
DEFAULT FOR TYPE _ltree USING gist AS
OPERATOR 10 <@ (_ltree, ltree) RECHECK ,
OPERATOR 11 @> (ltree, _ltree) RECHECK ,
OPERATOR 12 ~ (_ltree, lquery) RECHECK ,
OPERATOR 13 ~ (lquery, _ltree) RECHECK ,
OPERATOR 14 @ (_ltree, ltxtquery) RECHECK ,
OPERATOR 15 @ (ltxtquery, _ltree) RECHECK ,
OPERATOR 16 ? (_ltree, _lquery) RECHECK ,
OPERATOR 17 ? (_lquery, _ltree) RECHECK ,
FUNCTION 1 _ltree_consistent (internal, internal, int2),
OPERATOR 10 <@ (_ltree, ltree),
OPERATOR 11 @> (ltree, _ltree),
OPERATOR 12 ~ (_ltree, lquery),
OPERATOR 13 ~ (lquery, _ltree),
OPERATOR 14 @ (_ltree, ltxtquery),
OPERATOR 15 @ (ltxtquery, _ltree),
OPERATOR 16 ? (_ltree, _lquery),
OPERATOR 17 ? (_lquery, _ltree),
FUNCTION 1 _ltree_consistent (internal, internal, int2, oid, internal),
FUNCTION 2 _ltree_union (internal, internal),
FUNCTION 3 _ltree_compress (internal),
FUNCTION 4 ltree_decompress (internal),
......
/*
* GiST support for ltree
* Teodor Sigaev <teodor@stack.net>
* $PostgreSQL: pgsql/contrib/ltree/ltree_gist.c,v 1.22 2007/11/16 01:12:24 momjian Exp $
* $PostgreSQL: pgsql/contrib/ltree/ltree_gist.c,v 1.23 2008/04/14 17:05:32 tgl Exp $
*/
#include "ltree.h"
......@@ -624,11 +624,16 @@ Datum
ltree_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
void *query = NULL;
ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
void *query = NULL;
bool res = false;
/* All cases served by this function are exact */
*recheck = false;
switch (strategy)
{
case BTLessStrategyNumber:
......
/* $PostgreSQL: pgsql/contrib/ltree/uninstall_ltree.sql,v 1.5 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/ltree/uninstall_ltree.sql,v 1.6 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -15,7 +15,7 @@ DROP FUNCTION _ltree_penalty(internal,internal,internal);
DROP FUNCTION _ltree_compress(internal);
DROP FUNCTION _ltree_consistent(internal,internal,int2);
DROP FUNCTION _ltree_consistent(internal,internal,int2,oid,internal);
DROP OPERATOR ?@ (_ltree, ltxtquery);
......@@ -107,7 +107,7 @@ DROP FUNCTION ltree_decompress(internal);
DROP FUNCTION ltree_compress(internal);
DROP FUNCTION ltree_consistent(internal,internal,int2);
DROP FUNCTION ltree_consistent(internal,internal,int2,oid,internal);
DROP TYPE ltree_gist CASCADE;
......
/* $PostgreSQL: pgsql/contrib/pg_trgm/pg_trgm.sql.in,v 1.7 2007/12/09 02:22:46 tgl Exp $ */
/* $PostgreSQL: pgsql/contrib/pg_trgm/pg_trgm.sql.in,v 1.8 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -55,7 +55,7 @@ CREATE TYPE gtrgm (
);
-- support functions for gist
CREATE OR REPLACE FUNCTION gtrgm_consistent(gtrgm,internal,int4)
CREATE OR REPLACE FUNCTION gtrgm_consistent(internal,text,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -95,7 +95,7 @@ CREATE OPERATOR CLASS gist_trgm_ops
FOR TYPE text USING gist
AS
OPERATOR 1 % (text, text),
FUNCTION 1 gtrgm_consistent (gtrgm, internal, int4),
FUNCTION 1 gtrgm_consistent (internal, text, int, oid, internal),
FUNCTION 2 gtrgm_union (bytea, internal),
FUNCTION 3 gtrgm_compress (internal),
FUNCTION 4 gtrgm_decompress (internal),
......@@ -115,7 +115,7 @@ RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
CREATE OR REPLACE FUNCTION gin_trgm_consistent(internal, internal, text)
CREATE OR REPLACE FUNCTION gin_trgm_consistent(internal, int2, text, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -124,9 +124,9 @@ LANGUAGE C IMMUTABLE;
CREATE OPERATOR CLASS gin_trgm_ops
FOR TYPE text USING gin
AS
OPERATOR 1 % (text, text) RECHECK,
OPERATOR 1 % (text, text),
FUNCTION 1 btint4cmp (int4, int4),
FUNCTION 2 gin_extract_trgm (text, internal),
FUNCTION 3 gin_extract_trgm (text, internal, internal),
FUNCTION 4 gin_trgm_consistent (internal, internal, text),
FUNCTION 4 gin_trgm_consistent (internal, int2, text, internal),
STORAGE int4;
......@@ -53,13 +53,18 @@ Datum
gin_trgm_consistent(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
text *query = (text *) PG_GETARG_TEXT_P(2);
/* StrategyNumber strategy = PG_GETARG_UINT16(1); */
text *query = PG_GETARG_TEXT_P(2);
bool *recheck = (bool *) PG_GETARG_POINTER(3);
bool res = FALSE;
TRGM *trg;
int4 i,
trglen,
ntrue = 0;
/* All cases served by this function are inexact */
*recheck = true;
trg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
trglen = ARRNELEM(trg);
......
......@@ -159,12 +159,19 @@ gtrgm_decompress(PG_FUNCTION_ARGS)
Datum
gtrgm_consistent(PG_FUNCTION_ARGS)
{
text *query = (text *) PG_GETARG_TEXT_P(1);
TRGM *key = (TRGM *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
text *query = PG_GETARG_TEXT_P(1);
/* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
TRGM *key = (TRGM *) DatumGetPointer(entry->key);
TRGM *qtrg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
int res = false;
bool res = false;
/* All cases served by this function are exact */
*recheck = false;
if (GIST_LEAF((GISTENTRY *) PG_GETARG_POINTER(0)))
if (GIST_LEAF(entry))
{ /* all leafs contains orig trgm */
float4 tmpsml = cnt_sml(key, qtrg);
......
/* $PostgreSQL: pgsql/contrib/pg_trgm/uninstall_pg_trgm.sql,v 1.5 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/pg_trgm/uninstall_pg_trgm.sql,v 1.6 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -17,7 +17,7 @@ DROP FUNCTION gtrgm_decompress(internal);
DROP FUNCTION gtrgm_compress(internal);
DROP FUNCTION gtrgm_consistent(gtrgm,internal,int4);
DROP FUNCTION gtrgm_consistent(internal,text,int,oid,internal);
DROP TYPE gtrgm CASCADE;
......@@ -27,7 +27,7 @@ DROP FUNCTION gin_extract_trgm(text, internal);
DROP FUNCTION gin_extract_trgm(text, internal, internal);
DROP FUNCTION gin_trgm_consistent(internal, internal, text);
DROP FUNCTION gin_trgm_consistent(internal, int2, text, internal);
DROP OPERATOR % (text, text);
......
......@@ -42,7 +42,11 @@ float32 seg_center(SEG * seg);
/*
** GiST support methods
*/
bool gseg_consistent(GISTENTRY *entry, SEG * query, StrategyNumber strategy);
bool gseg_consistent(GISTENTRY *entry,
SEG * query,
StrategyNumber strategy,
Oid subtype,
bool *recheck);
GISTENTRY *gseg_compress(GISTENTRY *entry);
GISTENTRY *gseg_decompress(GISTENTRY *entry);
float *gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
......@@ -202,8 +206,13 @@ seg_upper(SEG * seg)
bool
gseg_consistent(GISTENTRY *entry,
SEG * query,
StrategyNumber strategy)
StrategyNumber strategy,
Oid subtype,
bool *recheck)
{
/* All cases served by this function are exact */
*recheck = false;
/*
* if entry is not leaf, use gseg_internal_consistent, else use
* gseg_leaf_consistent
......
/* $PostgreSQL: pgsql/contrib/seg/seg.sql.in,v 1.16 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/seg/seg.sql.in,v 1.17 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -322,7 +322,7 @@ CREATE OPERATOR ~ (
-- define the GiST support methods
CREATE OR REPLACE FUNCTION gseg_consistent(internal,seg,int4)
CREATE OR REPLACE FUNCTION gseg_consistent(internal,seg,int,oid,internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE;
......@@ -382,7 +382,7 @@ AS
OPERATOR 8 <@ ,
OPERATOR 13 @ ,
OPERATOR 14 ~ ,
FUNCTION 1 gseg_consistent (internal, seg, int4),
FUNCTION 1 gseg_consistent (internal, seg, int, oid, internal),
FUNCTION 2 gseg_union (internal, internal),
FUNCTION 3 gseg_compress (internal),
FUNCTION 4 gseg_decompress (internal),
......
/* $PostgreSQL: pgsql/contrib/seg/uninstall_seg.sql,v 1.5 2007/11/13 04:24:28 momjian Exp $ */
/* $PostgreSQL: pgsql/contrib/seg/uninstall_seg.sql,v 1.6 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET search_path = public;
......@@ -19,7 +19,7 @@ DROP FUNCTION gseg_decompress(internal);
DROP FUNCTION gseg_compress(internal);
DROP FUNCTION gseg_consistent(internal,seg,int4);
DROP FUNCTION gseg_consistent(internal,seg,int,oid,internal);
DROP OPERATOR <@ (seg, seg);
......
/* $PostgreSQL: pgsql/contrib/tsearch2/tsearch2.sql.in,v 1.4 2007/11/28 19:33:04 tgl Exp $ */
/* $PostgreSQL: pgsql/contrib/tsearch2/tsearch2.sql.in,v 1.5 2008/04/14 17:05:32 tgl Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
......@@ -388,8 +388,8 @@ CREATE FUNCTION headline(text, tsquery)
CREATE OPERATOR CLASS gist_tsvector_ops
FOR TYPE tsvector USING gist
AS
OPERATOR 1 @@ (tsvector, tsquery) RECHECK ,
FUNCTION 1 gtsvector_consistent (gtsvector, internal, int4),
OPERATOR 1 @@ (tsvector, tsquery),
FUNCTION 1 gtsvector_consistent (internal, gtsvector, int, oid, internal),
FUNCTION 2 gtsvector_union (internal, internal),
FUNCTION 3 gtsvector_compress (internal),
FUNCTION 4 gtsvector_decompress (internal),
......@@ -534,9 +534,9 @@ CREATE OR REPLACE FUNCTION tsq_mcontained(tsquery, tsquery)
CREATE OPERATOR CLASS gist_tp_tsquery_ops
FOR TYPE tsquery USING gist
AS
OPERATOR 7 @> (tsquery, tsquery) RECHECK,
OPERATOR 8 <@ (tsquery, tsquery) RECHECK,
FUNCTION 1 gtsquery_consistent (bigint, internal, int4),
OPERATOR 7 @> (tsquery, tsquery),
OPERATOR 8 <@ (tsquery, tsquery),
FUNCTION 1 gtsquery_consistent (internal, internal, int, oid, internal),
FUNCTION 2 gtsquery_union (internal, internal),
FUNCTION 3 gtsquery_compress (internal),
FUNCTION 4 gtsquery_decompress (internal),
......@@ -549,11 +549,11 @@ CREATE OPERATOR CLASS gin_tsvector_ops
FOR TYPE tsvector USING gin
AS
OPERATOR 1 @@ (tsvector, tsquery),
OPERATOR 2 @@@ (tsvector, tsquery) RECHECK,
OPERATOR 2 @@@ (tsvector, tsquery),
FUNCTION 1 bttextcmp(text, text),
FUNCTION 2 gin_extract_tsvector(tsvector,internal),
FUNCTION 3 gin_extract_tsquery(tsquery,internal,smallint),
FUNCTION 4 gin_tsquery_consistent(internal,smallint,tsquery),
FUNCTION 4 gin_tsquery_consistent(internal,smallint,tsquery,internal),
STORAGE text;
CREATE OPERATOR CLASS tsvector_ops
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.164 2008/04/10 22:25:25 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.165 2008/04/14 17:05:32 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
......@@ -606,13 +606,6 @@
<entry>Operator strategy number</entry>
</row>
<row>
<entry><structfield>amopreqcheck</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>Index hit must be rechecked</entry>
</row>
<row>
<entry><structfield>amopopr</structfield></entry>
<entry><type>oid</type></entry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.429 2008/04/10 13:34:33 alvherre Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.430 2008/04/14 17:05:32 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
......@@ -7738,7 +7738,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
</row>
<row>
<entry> <literal>@@@</literal> </entry>
<entry>same as <literal>@@</>, but see <xref linkend="textsearch-indexes"></entry>
<entry>deprecated synonym for <literal>@@</></entry>
<entry><literal>to_tsvector('fat cats ate rats') @@@ to_tsquery('cat &amp; rat')</literal></entry>
<entry><literal>t</literal></entry>
</row>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/gin.sgml,v 2.13 2007/11/16 03:23:07 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/gin.sgml,v 2.14 2008/04/14 17:05:32 tgl Exp $ -->
<chapter id="GIN">
<title>GIN Indexes</title>
......@@ -111,12 +111,12 @@
</varlistentry>
<varlistentry>
<term>bool consistent(bool check[], StrategyNumber n, Datum query)</term>
<term>bool consistent(bool check[], StrategyNumber n, Datum query, bool *recheck)</term>
<listitem>
<para>
Returns TRUE if the indexed value satisfies the query operator with
strategy number <literal>n</> (or would satisfy, if the operator is
marked RECHECK in the operator class). The <literal>check</> array has
strategy number <literal>n</> (or might satisfy, if the recheck
indication is returned). The <literal>check</> array has
the same length as the number of keys previously returned by
<function>extractQuery</> for this query. Each element of the
<literal>check</> array is TRUE if the indexed value contains the
......@@ -124,6 +124,9 @@
<function>extractQuery</> result array is present in the indexed value.
The original <literal>query</> datum (not the extracted key array!) is
passed in case the <function>consistent</> method needs to consult it.
On success, <literal>*recheck</> should be set to TRUE if the heap
tuple needs to be rechecked against the query operator, or FALSE if
the index test is exact.
</para>
</listitem>
</varlistentry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.29 2007/11/13 23:36:26 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.30 2008/04/14 17:05:32 tgl Exp $ -->
<chapter id="GiST">
<title>GiST Indexes</title>
......@@ -103,7 +103,10 @@
Given a predicate <literal>p</literal> on a tree page, and a user
query, <literal>q</literal>, this method will return false if it is
certain that both <literal>p</literal> and <literal>q</literal> cannot
be true for a given data item.
be true for a given data item. For a true result, a
<literal>recheck</> flag must also be returned; this indicates whether
the predicate implies the query (<literal>recheck</> = false) or
not (<literal>recheck</> = true).
</para>
</listitem>
</varlistentry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.25 2008/04/13 19:18:13 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.26 2008/04/14 17:05:32 tgl Exp $ -->
<chapter id="indexam">
<title>Index Access Method Interface Definition</title>
......@@ -183,7 +183,7 @@ aminsert (Relation indexRelation,
parameter. See <xref linkend="index-unique-checks"> for details.
The result is TRUE if an index entry was inserted, FALSE if not. (A FALSE
result does not denote an error condition, but is used for cases such
as an index AM refusing to index a NULL.)
as an index method refusing to index a NULL.)
</para>
<para>
......@@ -430,13 +430,13 @@ amrestrpos (IndexScanDesc scan);
</para>
<para>
The operator family can indicate that the index is <firstterm>lossy</> for a
particular operator; this implies that the index scan will return all the
entries that pass the scan key, plus possibly additional entries that do
not. The core system's index-scan machinery will then apply that operator
again to the heap tuple to verify whether or not it really should be
selected. For non-lossy operators, the index scan must return exactly the
set of matching entries, as there is no recheck.
The access method can report that the index is <firstterm>lossy</>, or
requires rechecks, for a particular query. This implies that the index
scan will return all the entries that pass the scan key, plus possibly
additional entries that do not. The core system's index-scan machinery
will then apply the index conditions again to the heap tuple to verify
whether or not it really should be selected. If the recheck option is not
specified, the index scan must return exactly the set of matching entries.
</para>
<para>
......@@ -849,7 +849,7 @@ amcostestimate (PlannerInfo *root,
<para>
The indexSelectivity should be set to the estimated fraction of the parent
table rows that will be retrieved during the index scan. In the case
of a lossy index, this will typically be higher than the fraction of
of a lossy query, this will typically be higher than the fraction of
rows that actually pass the given qual conditions.
</para>
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_opfamily.sgml,v 1.3 2007/02/14 04:30:26 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_opfamily.sgml,v 1.4 2008/04/14 17:05:32 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> ADD
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) [ RECHECK ]
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> )
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">funcname</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
} [, ... ]
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> DROP
......@@ -154,18 +154,6 @@ ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="
</listitem>
</varlistentry>
<varlistentry>
<term><literal>RECHECK</></term>
<listitem>
<para>
If present, the index is <quote>lossy</> for this operator, and
so the rows retrieved using the index must be rechecked to
verify that they actually satisfy the qualification clause
involving this operator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">support_number</replaceable></term>
<listitem>
......@@ -247,6 +235,14 @@ ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="
is likely to be inlined into the calling query, which will prevent
the optimizer from recognizing that the query matches an index.
</para>
<para>
Before <productname>PostgreSQL</productname> 8.4, the <literal>OPERATOR</>
clause could include a <literal>RECHECK</> option. This is no longer
supported because whether an index operator is <quote>lossy</> is now
determined on-the-fly at runtime. This allows efficient handling of
cases where an operator might or might not be lossy.
</para>
</refsect1>
<refsect1>
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.21 2007/12/03 23:49:51 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.22 2008/04/14 17:05:32 tgl Exp $
PostgreSQL documentation
-->
......@@ -22,7 +22,7 @@ PostgreSQL documentation
<synopsis>
CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT ] FOR TYPE <replaceable class="parameter">data_type</replaceable>
USING <replaceable class="parameter">index_method</replaceable> [ FAMILY <replaceable class="parameter">family_name</replaceable> ] AS
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> [ ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) ] [ RECHECK ]
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> [ ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) ]
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">funcname</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
| STORAGE <replaceable class="parameter">storage_type</replaceable>
} [, ... ]
......@@ -179,18 +179,6 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
</listitem>
</varlistentry>
<varlistentry>
<term><literal>RECHECK</></term>
<listitem>
<para>
If present, the index is <quote>lossy</> for this operator, and
so the rows retrieved using the index must be rechecked to
verify that they actually satisfy the qualification clause
involving this operator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">support_number</replaceable></term>
<listitem>
......@@ -256,6 +244,14 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
is likely to be inlined into the calling query, which will prevent
the optimizer from recognizing that the query matches an index.
</para>
<para>
Before <productname>PostgreSQL</productname> 8.4, the <literal>OPERATOR</>
clause could include a <literal>RECHECK</> option. This is no longer
supported because whether an index operator is <quote>lossy</> is now
determined on-the-fly at runtime. This allows efficient handling of
cases where an operator might or might not be lossy.
</para>
</refsect1>
<refsect1>
......@@ -271,12 +267,12 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
CREATE OPERATOR CLASS gist__int_ops
DEFAULT FOR TYPE _int4 USING gist AS
OPERATOR 3 &amp;&amp;,
OPERATOR 6 = RECHECK,
OPERATOR 6 = (anyarray, anyarray),
OPERATOR 7 @&gt;,
OPERATOR 8 &lt;@,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 g_int_consistent (internal, _int4, int4),
FUNCTION 2 g_int_union (bytea, internal),
FUNCTION 1 g_int_consistent (internal, _int4, int, oid, internal),
FUNCTION 2 g_int_union (internal, internal),
FUNCTION 3 g_int_compress (internal),
FUNCTION 4 g_int_decompress (internal),
FUNCTION 5 g_int_penalty (internal, internal, internal),
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/textsearch.sgml,v 1.42 2008/03/10 03:01:28 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/textsearch.sgml,v 1.43 2008/04/14 17:05:32 tgl Exp $ -->
<chapter id="textsearch">
<title id="textsearch-title">Full Text Search</title>
......@@ -3142,19 +3142,7 @@ SELECT plainto_tsquery('supernovae stars');
A GiST index is <firstterm>lossy</firstterm>, meaning that the index
may produce false matches, and it is necessary
to check the actual table row to eliminate such false matches.
<productname>PostgreSQL</productname> does this automatically; for
example, in the query plan below, the <literal>Filter:</literal>
line indicates the index output will be rechecked:
<programlisting>
EXPLAIN SELECT * FROM apod WHERE textsearch @@ to_tsquery('supernovae');
QUERY PLAN
-------------------------------------------------------------------------
Index Scan using textsearch_gidx on apod (cost=0.00..12.29 rows=2 width=1469)
Index Cond: (textsearch @@ '''supernova'''::tsquery)
Filter: (textsearch @@ '''supernova'''::tsquery)
</programlisting>
(<productname>PostgreSQL</productname> does this automatically when needed.)
GiST indexes are lossy because each document is represented in the
index by a fixed-length signature. The signature is generated by hashing
each word into a random bit in an n-bit string, with all these bits OR-ed
......@@ -3174,57 +3162,11 @@ EXPLAIN SELECT * FROM apod WHERE textsearch @@ to_tsquery('supernovae');
</para>
<para>
GIN indexes are not lossy but their performance depends logarithmically on
the number of unique words.
</para>
<para>
Actually, GIN indexes store only the words (lexemes) of <type>tsvector</>
values, and not their weight labels. Thus, while a GIN index can be
considered non-lossy for a query that does not specify weights, it is
lossy for one that does. Thus a table row recheck is needed when using
a query that involves weights. Unfortunately, in the current design of
<productname>PostgreSQL</>, whether a recheck is needed is a static
property of a particular operator, and not something that can be enabled
or disabled on-the-fly depending on the values given to the operator.
To deal with this situation without imposing the overhead of rechecks
on queries that do not need them, the following approach has been
adopted:
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>
The standard text match operator <literal>@@</> is marked as non-lossy
for GIN indexes.
</para>
</listitem>
<listitem>
<para>
An additional match operator <literal>@@@</> is provided, and marked
as lossy for GIN indexes. This operator behaves exactly like
<literal>@@</> otherwise.
</para>
</listitem>
<listitem>
<para>
When a GIN index search is initiated with the <literal>@@</> operator,
the index support code will throw an error if the query specifies any
weights. This protects against giving wrong answers due to failure
to recheck the weights.
</para>
</listitem>
</itemizedlist>
<para>
In short, you must use <literal>@@@</> rather than <literal>@@</> to
perform GIN index searches on queries that involve weight restrictions.
For queries that do not have weight restrictions, either operator will
work, but <literal>@@</> will be faster.
This awkwardness will probably be addressed in a future release of
<productname>PostgreSQL</>.
GIN indexes are not lossy for standard queries, but their performance
depends logarithmically on the number of unique words.
(However, GIN indexes store only the words (lexemes) of <type>tsvector</>
values, and not their weight labels. Thus a table row recheck is needed
when using a query that involves weights.)
</para>
<para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.61 2007/12/02 04:36:40 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.62 2008/04/14 17:05:32 tgl Exp $ -->
<sect1 id="xindex">
<title>Interfacing Extensions To Indexes</title>
......@@ -913,26 +913,31 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD
<para>
Normally, declaring an operator as a member of an operator class
(or family) means
that the index method can retrieve exactly the set of rows
(or family) means that the index method can retrieve exactly the set of rows
that satisfy a <literal>WHERE</> condition using the operator. For example:
<programlisting>
SELECT * FROM table WHERE integer_column &lt; 4;
</programlisting>
can be satisfied exactly by a B-tree index on the integer column.
But there are cases where an index is useful as an inexact guide to
the matching rows. For example, if a GiST index stores only
bounding boxes for objects, then it cannot exactly satisfy a <literal>WHERE</>
the matching rows. For example, if a GiST index stores only bounding boxes
for geometric objects, then it cannot exactly satisfy a <literal>WHERE</>
condition that tests overlap between nonrectangular objects such as
polygons. Yet we could use the index to find objects whose bounding
box overlaps the bounding box of the target object, and then do the
exact overlap test only on the objects found by the index. If this
scenario applies, the index is said to be <quote>lossy</> for the
operator, and we add <literal>RECHECK</> to the <literal>OPERATOR</> clause
in the <command>CREATE OPERATOR CLASS</> command.
<literal>RECHECK</> is valid if the index is guaranteed to return
all the required rows, plus perhaps some additional rows, which
can be eliminated by performing the original operator invocation.
operator. Lossy index searches are implemented by having the index
method return a <firstterm>recheck</> flag when a row might or might
not really satisfy the query condition. The core system will then
test the original query condition on the retrieved row to see whether
it should be returned as a valid match. This approach works if
the index is guaranteed to return all the required rows, plus perhaps
some additional rows, which can be eliminated by performing the original
operator invocation. The index methods that support lossy searches
(currently, GiST and GIN) allow the support functions of individual
operator classes to set the recheck flag, and so this is essentially an
operator-class feature.
</para>
<para>
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.12 2008/01/01 19:45:46 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.13 2008/04/14 17:05:33 tgl Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
......@@ -95,8 +95,9 @@ ginarrayconsistent(PG_FUNCTION_ARGS)
bool *check = (bool *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
int res,
i,
bool *recheck = (bool *) PG_GETARG_POINTER(3);
bool res;
int i,
nentries;
/* ARRAYCHECK was already done by previous ginarrayextract call */
......@@ -104,25 +105,51 @@ ginarrayconsistent(PG_FUNCTION_ARGS)
switch (strategy)
{
case GinOverlapStrategy:
/* result is not lossy */
*recheck = false;
/* at least one element in check[] is true, so result = true */
res = true;
break;
case GinContainedStrategy:
/* we will need recheck */
*recheck = true;
/* at least one element in check[] is true, so result = true */
res = TRUE;
res = true;
break;
case GinContainsStrategy:
/* result is not lossy */
*recheck = false;
/* must have all elements in check[] true */
nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
res = true;
for (i = 0; i < nentries; i++)
{
if (!check[i])
{
res = false;
break;
}
}
break;
case GinEqualStrategy:
/* we will need recheck */
*recheck = true;
/* must have all elements in check[] true */
nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
res = TRUE;
res = true;
for (i = 0; i < nentries; i++)
{
if (!check[i])
{
res = FALSE;
res = false;
break;
}
}
break;
default:
elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
strategy);
res = FALSE;
res = false;
}
PG_RETURN_BOOL(res);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.12 2008/04/13 19:18:13 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.13 2008/04/14 17:05:33 tgl Exp $
*-------------------------------------------------------------------------
*/
......@@ -343,10 +343,12 @@ entryGetItem(Relation index, GinScanEntry entry)
/*
* Sets key->curItem to new found heap item pointer for one scan key
* returns isFinished!
* Returns isFinished, ie TRUE means we did NOT get a new item pointer!
* Also, *keyrecheck is set true if recheck is needed for this scan key.
*/
static bool
keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey key)
keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
GinScanKey key, bool *keyrecheck)
{
uint32 i;
GinScanEntry entry;
......@@ -391,31 +393,36 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey
return TRUE;
}
if (key->nentries == 1)
{
/* we can do not call consistentFn !! */
key->entryRes[0] = TRUE;
return FALSE;
}
/*
* if key->nentries == 1 then the consistentFn should always succeed,
* but we must call it anyway to find out the recheck status.
*/
/* setting up array for consistentFn */
for (i = 0; i < key->nentries; i++)
{
entry = key->scanEntry + i;
if (entry->isFinished == FALSE && compareItemPointers(&entry->curItem, &key->curItem) == 0)
if (entry->isFinished == FALSE &&
compareItemPointers(&entry->curItem, &key->curItem) == 0)
key->entryRes[i] = TRUE;
else
key->entryRes[i] = FALSE;
}
/*
* Initialize *keyrecheck in case the consistentFn doesn't know it
* should set it. The safe assumption in that case is to force
* recheck.
*/
*keyrecheck = true;
oldCtx = MemoryContextSwitchTo(tempCtx);
res = DatumGetBool(FunctionCall3(
&ginstate->consistentFn,
res = DatumGetBool(FunctionCall4(&ginstate->consistentFn,
PointerGetDatum(key->entryRes),
UInt16GetDatum(key->strategy),
key->query
));
key->query,
PointerGetDatum(keyrecheck)));
MemoryContextSwitchTo(oldCtx);
MemoryContextReset(tempCtx);
} while (!res);
......@@ -430,24 +437,32 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey
static bool
scanGetItem(IndexScanDesc scan, ItemPointerData *item, bool *recheck)
{
uint32 i;
GinScanOpaque so = (GinScanOpaque) scan->opaque;
/* XXX for the moment, treat all GIN operators as lossy */
*recheck = true;
uint32 i;
bool keyrecheck;
/*
* We return recheck = true if any of the keyGetItem calls return
* keyrecheck = true. Note that because the second loop might advance
* some keys, this could theoretically be too conservative. In practice
* though, we expect that a consistentFn's recheck result will depend
* only on the operator and the query, so for any one key it should
* stay the same regardless of advancing to new items. So it's not
* worth working harder.
*/
*recheck = false;
ItemPointerSetMin(item);
for (i = 0; i < so->nkeys; i++)
{
GinScanKey key = so->keys + i;
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx, key) == FALSE)
{
if (compareItemPointers(item, &key->curItem) < 0)
*item = key->curItem;
}
else
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx,
key, &keyrecheck))
return FALSE; /* finished one of keys */
if (compareItemPointers(item, &key->curItem) < 0)
*item = key->curItem;
*recheck |= keyrecheck;
}
for (i = 1; i <= so->nkeys; i++)
......@@ -462,8 +477,10 @@ scanGetItem(IndexScanDesc scan, ItemPointerData *item, bool *recheck)
break;
else if (cmp > 0)
{
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx, key) == TRUE)
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx,
key, &keyrecheck))
return FALSE; /* finished one of keys */
*recheck |= keyrecheck;
}
else
{ /* returns to begin */
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.71 2008/04/13 19:18:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.72 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -151,7 +151,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm)
GISTScanOpaque so;
GISTSearchStack *stk;
IndexTuple it;
bool recheck;
GISTPageOpaque opaque;
bool resetoffset = false;
int64 ntids = 0;
......@@ -257,8 +256,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm)
for (;;)
{
n = gistfindnext(scan, n, dir);
/* XXX for the moment, treat all GIST operators as lossy */
recheck = true;
if (!OffsetNumberIsValid(n))
{
......@@ -304,11 +301,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
ntids++;
if (tbm != NULL)
tbm_add_tuples(tbm, &it->t_tid, 1, recheck);
tbm_add_tuples(tbm, &it->t_tid, 1, scan->xs_recheck);
else
{
scan->xs_ctup.t_self = it->t_tid;
scan->xs_recheck = recheck;
/* scan->xs_recheck is already set */
LockBuffer(so->curbuf, GIST_UNLOCK);
return ntids; /* always 1 */
......@@ -345,6 +342,10 @@ gistnext(IndexScanDesc scan, ScanDirection dir, TIDBitmap *tbm)
/*
* gistindex_keytest() -- does this index tuple satisfy the scan key(s)?
*
* On success return for a leaf tuple, scan->xs_recheck is set to indicate
* whether recheck is needed. We recheck if any of the consistent() functions
* request it.
*
* We must decompress the key in the IndexTuple before passing it to the
* sk_func (and we have previously overwritten the sk_func to use the
* user-defined Consistent method, so we actually are invoking that).
......@@ -371,6 +372,8 @@ gistindex_keytest(IndexTuple tuple,
IncrIndexProcessed();
scan->xs_recheck = false;
/*
* Tuple doesn't restore after crash recovery because of incomplete insert
*/
......@@ -382,6 +385,7 @@ gistindex_keytest(IndexTuple tuple,
Datum datum;
bool isNull;
Datum test;
bool recheck;
GISTENTRY de;
datum = index_getattr(tuple,
......@@ -408,7 +412,6 @@ gistindex_keytest(IndexTuple tuple,
}
else
{
gistdentryinit(giststate, key->sk_attno - 1, &de,
datum, r, p, offset,
FALSE, isNull);
......@@ -416,21 +419,28 @@ gistindex_keytest(IndexTuple tuple,
/*
* Call the Consistent function to evaluate the test. The
* arguments are the index datum (as a GISTENTRY*), the comparison
* datum, and the comparison operator's strategy number and
* subtype from pg_amop.
* datum, the comparison operator's strategy number and
* subtype from pg_amop, and the recheck flag.
*
* (Presently there's no need to pass the subtype since it'll
* always be zero, but might as well pass it for possible future
* use.)
*
* We initialize the recheck flag to true (the safest assumption)
* in case the Consistent function forgets to set it.
*/
test = FunctionCall4(&key->sk_func,
recheck = true;
test = FunctionCall5(&key->sk_func,
PointerGetDatum(&de),
key->sk_argument,
Int32GetDatum(key->sk_strategy),
ObjectIdGetDatum(key->sk_subtype));
ObjectIdGetDatum(key->sk_subtype),
PointerGetDatum(&recheck));
if (!DatumGetBool(test))
return false;
scan->xs_recheck |= recheck;
}
keySize--;
......@@ -444,6 +454,7 @@ gistindex_keytest(IndexTuple tuple,
* Return the offset of the first index entry that is consistent with
* the search key after offset 'n' in the current page. If there are
* no more consistent entries, return InvalidOffsetNumber.
* On success, scan->xs_recheck is set correctly, too.
* Page should be locked....
*/
static OffsetNumber
......
......@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.13 2008/01/01 19:45:46 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.14 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -86,6 +86,11 @@ gist_box_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
BOX *query = PG_GETARG_BOX_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
/* All cases served by this function are exact */
*recheck = false;
if (DatumGetBoxP(entry->key) == NULL || query == NULL)
PG_RETURN_BOOL(FALSE);
......@@ -723,13 +728,18 @@ gist_poly_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
POLYGON *query = PG_GETARG_POLYGON_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
bool result;
/* All cases served by this function are inexact */
*recheck = true;
if (DatumGetBoxP(entry->key) == NULL || query == NULL)
PG_RETURN_BOOL(FALSE);
/*
* Since the operators are marked lossy anyway, we can just use
* 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.)
*/
......@@ -794,14 +804,19 @@ gist_circle_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
CIRCLE *query = PG_GETARG_CIRCLE_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* 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 */
*recheck = true;
if (DatumGetBoxP(entry->key) == NULL || query == NULL)
PG_RETURN_BOOL(FALSE);
/*
* Since the operators are marked lossy anyway, we can just use
* 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 circles.)
*/
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.59 2008/03/26 21:10:37 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.60 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -52,7 +52,6 @@ typedef struct
int number; /* strategy or support proc number */
Oid lefttype; /* lefttype */
Oid righttype; /* righttype */
bool recheck; /* oper recheck flag (unused for proc) */
} OpFamilyMember;
......@@ -445,7 +444,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
member->object = operOid;
member->number = item->number;
member->recheck = item->recheck;
assignOperTypes(member, amoid, typeoid);
addFamilyMember(&operators, member, false);
break;
......@@ -898,7 +896,6 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
member->object = operOid;
member->number = item->number;
member->recheck = item->recheck;
assignOperTypes(member, amoid, InvalidOid);
addFamilyMember(&operators, member, false);
break;
......@@ -1266,7 +1263,6 @@ storeOperators(List *opfamilyname, Oid amoid,
values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype);
values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype);
values[Anum_pg_amop_amopstrategy - 1] = Int16GetDatum(op->number);
values[Anum_pg_amop_amopreqcheck - 1] = BoolGetDatum(op->recheck);
values[Anum_pg_amop_amopopr - 1] = ObjectIdGetDatum(op->object);
values[Anum_pg_amop_amopmethod - 1] = ObjectIdGetDatum(amoid);
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.391 2008/04/13 20:51:20 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.392 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2471,7 +2471,6 @@ _copyCreateOpClassItem(CreateOpClassItem *from)
COPY_NODE_FIELD(name);
COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(number);
COPY_SCALAR_FIELD(recheck);
COPY_NODE_FIELD(class_args);
COPY_NODE_FIELD(storedtype);
......
......@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.320 2008/03/21 22:41:48 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.321 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1275,7 +1275,6 @@ _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
COMPARE_NODE_FIELD(name);
COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(number);
COMPARE_SCALAR_FIELD(recheck);
COMPARE_NODE_FIELD(class_args);
COMPARE_NODE_FIELD(storedtype);
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.611 2008/03/28 00:21:55 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.612 2008/04/14 17:05:33 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -3107,7 +3107,6 @@ opclass_item:
n->name = $3;
n->args = NIL;
n->number = $2;
n->recheck = $4;
$$ = (Node *) n;
}
| OPERATOR Iconst any_operator '(' oper_argtypes ')' opt_recheck
......@@ -3117,7 +3116,6 @@ opclass_item:
n->name = $3;
n->args = $5;
n->number = $2;
n->recheck = $7;
$$ = (Node *) n;
}
| FUNCTION Iconst func_name func_args
......@@ -3156,7 +3154,14 @@ opt_opfamily: FAMILY any_name { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
opt_recheck: RECHECK { $$ = TRUE; }
opt_recheck: RECHECK
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RECHECK is no longer supported"),
errhint("Update your data type.")));
$$ = TRUE;
}
| /*EMPTY*/ { $$ = FALSE; }
;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/tsginidx.c,v 1.10 2008/03/25 22:42:44 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/tsginidx.c,v 1.11 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -54,7 +54,7 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
{
TSQuery query = PG_GETARG_TSQUERY(0);
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
StrategyNumber strategy = PG_GETARG_UINT16(2);
/* StrategyNumber strategy = PG_GETARG_UINT16(2); */
Datum *entries = NULL;
*nentries = 0;
......@@ -89,12 +89,6 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
txt = cstring_to_text_with_len(GETOPERAND(query) + val->distance,
val->length);
entries[j++] = PointerGetDatum(txt);
if (strategy != TSearchWithClassStrategyNumber && val->weight != 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("@@ operator does not support lexeme weight restrictions in GIN index searches"),
errhint("Use the @@@ operator instead.")));
}
}
else
......@@ -109,6 +103,7 @@ typedef struct
{
QueryItem *frst;
bool *mapped_check;
bool *need_recheck;
} GinChkVal;
static bool
......@@ -116,6 +111,10 @@ checkcondition_gin(void *checkval, QueryOperand *val)
{
GinChkVal *gcv = (GinChkVal *) checkval;
/* if any val requiring a weight is used, set recheck flag */
if (val->weight != 0)
*(gcv->need_recheck) = true;
return gcv->mapped_check[((QueryItem *) val) - gcv->frst];
}
......@@ -125,8 +124,12 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
bool *check = (bool *) PG_GETARG_POINTER(0);
/* StrategyNumber strategy = PG_GETARG_UINT16(1); */
TSQuery query = PG_GETARG_TSQUERY(2);
bool *recheck = (bool *) PG_GETARG_POINTER(3);
bool res = FALSE;
/* The query requires recheck only if it involves weights */
*recheck = false;
if (query->size > 0)
{
int i,
......@@ -144,6 +147,7 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
gcv.frst = item = GETQUERY(query);
gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size);
gcv.need_recheck = recheck;
for (i = 0; i < query->size; i++)
if (item[i].type == QI_VAL)
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/tsgistidx.c,v 1.7 2008/01/01 19:45:52 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/tsgistidx.c,v 1.8 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -330,10 +330,15 @@ checkcondition_bit(void *checkval, QueryOperand *val)
Datum
gtsvector_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TSQuery query = PG_GETARG_TSQUERY(1);
SignTSVector *key = (SignTSVector *) DatumGetPointer(
((GISTENTRY *) PG_GETARG_POINTER(0))->key
);
/* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
SignTSVector *key = (SignTSVector *) DatumGetPointer(entry->key);
/* All cases served by this function are inexact */
*recheck = true;
if (!query->size)
PG_RETURN_BOOL(false);
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_gist.c,v 1.4 2008/01/01 19:45:53 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_gist.c,v 1.5 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -52,12 +52,17 @@ Datum
gtsquery_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TSQuerySign *key = (TSQuerySign *) DatumGetPointer(entry->key);
TSQuery query = PG_GETARG_TSQUERY(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
TSQuerySign *key = (TSQuerySign *) DatumGetPointer(entry->key);
TSQuerySign sq = makeTSQuerySign(query);
bool retval;
/* All cases served by this function are inexact */
*recheck = true;
switch (strategy)
{
case RTContainsStrategyNumber:
......
......@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.487 2008/04/13 03:49:22 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.488 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -7456,7 +7456,27 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
*/
resetPQExpBuffer(query);
if (g_fout->remoteVersion >= 80300)
if (g_fout->remoteVersion >= 80400)
{
/*
* Print only those opfamily members that are tied to the opclass by
* pg_depend entries.
*
* XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
* an older server's table in which it is used. Would it be better
* to silently ignore it?
*/
appendPQExpBuffer(query, "SELECT amopstrategy, false as amopreqcheck, "
"amopopr::pg_catalog.regoperator "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
"AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
"AND objid = ao.oid "
"ORDER BY amopstrategy",
opcinfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 80300)
{
/*
* Print only those opfamily members that are tied to the opclass by
......@@ -7649,7 +7669,26 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
* Fetch only those opfamily members that are tied directly to the
* opfamily by pg_depend entries.
*/
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
if (g_fout->remoteVersion >= 80400)
{
/*
* XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
* an older server's table in which it is used. Would it be better
* to silently ignore it?
*/
appendPQExpBuffer(query, "SELECT amopstrategy, false as amopreqcheck, "
"amopopr::pg_catalog.regoperator "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
"AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
"AND objid = ao.oid "
"ORDER BY amopstrategy",
opfinfo->dobj.catId.oid);
}
else
{
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
"amopopr::pg_catalog.regoperator "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
......@@ -7658,6 +7697,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
"AND objid = ao.oid "
"ORDER BY amopstrategy",
opfinfo->dobj.catId.oid);
}
res_ops = PQexec(g_conn, query->data);
check_sql_result(res_ops, g_conn, query->data, PGRES_TUPLES_OK);
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.447 2008/04/10 22:25:25 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.448 2008/04/14 17:05:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200804101
#define CATALOG_VERSION_NO 200804141
#endif
This diff is collapsed.
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.488 2008/04/10 22:25:25 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.489 2008/04/14 17:05:33 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -3941,7 +3941,7 @@ DATA(insert OID = 2588 ( circle_overabove PGNSP PGUID 12 1 0 f f t f i 2 16 "7
DESCR("overlaps or is above");
/* support functions for GiST r-tree emulation */
DATA(insert OID = 2578 ( gist_box_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 603 23" _null_ _null_ _null_ gist_box_consistent - _null_ _null_ ));
DATA(insert OID = 2578 ( gist_box_consistent PGNSP PGUID 12 1 0 f f t f i 5 16 "2281 603 23 26 2281" _null_ _null_ _null_ gist_box_consistent - _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2579 ( gist_box_compress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gist_box_compress - _null_ _null_ ));
DESCR("GiST support");
......@@ -3955,11 +3955,11 @@ DATA(insert OID = 2583 ( gist_box_union PGNSP PGUID 12 1 0 f f t f i 2 603 "22
DESCR("GiST support");
DATA(insert OID = 2584 ( gist_box_same PGNSP PGUID 12 1 0 f f t f i 3 2281 "603 603 2281" _null_ _null_ _null_ gist_box_same - _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2585 ( gist_poly_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 604 23" _null_ _null_ _null_ gist_poly_consistent - _null_ _null_ ));
DATA(insert OID = 2585 ( gist_poly_consistent PGNSP PGUID 12 1 0 f f t f i 5 16 "2281 604 23 26 2281" _null_ _null_ _null_ gist_poly_consistent - _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2586 ( gist_poly_compress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gist_poly_compress - _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2591 ( gist_circle_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 718 23" _null_ _null_ _null_ gist_circle_consistent - _null_ _null_ ));
DATA(insert OID = 2591 ( gist_circle_consistent PGNSP PGUID 12 1 0 f f t f i 5 16 "2281 718 23 26 2281" _null_ _null_ _null_ gist_circle_consistent - _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2592 ( gist_circle_compress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gist_circle_compress - _null_ _null_ ));
DESCR("GiST support");
......@@ -3997,7 +3997,7 @@ DATA(insert OID = 2743 ( ginarrayextract PGNSP PGUID 12 1 0 f f t f i 2 2281 "
DESCR("GIN array support");
DATA(insert OID = 2774 ( ginqueryarrayextract PGNSP PGUID 12 1 0 f f t f i 3 2281 "2277 2281 21" _null_ _null_ _null_ ginqueryarrayextract - _null_ _null_ ));
DESCR("GIN array support");
DATA(insert OID = 2744 ( ginarrayconsistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 21 2281" _null_ _null_ _null_ ginarrayconsistent - _null_ _null_ ));
DATA(insert OID = 2744 ( ginarrayconsistent PGNSP PGUID 12 1 0 f f t f i 4 16 "2281 21 2281 2281" _null_ _null_ _null_ ginarrayconsistent - _null_ _null_ ));
DESCR("GIN array support");
/* overlap/contains/contained */
......@@ -4225,14 +4225,14 @@ DATA(insert OID = 3652 ( gtsvector_same PGNSP PGUID 12 1 0 f f t f i 3 2281 "3
DESCR("GiST tsvector support");
DATA(insert OID = 3653 ( gtsvector_penalty PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_ gtsvector_penalty - _null_ _null_ ));
DESCR("GiST tsvector support");
DATA(insert OID = 3654 ( gtsvector_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "3642 2281 23" _null_ _null_ _null_ gtsvector_consistent - _null_ _null_ ));
DATA(insert OID = 3654 ( gtsvector_consistent PGNSP PGUID 12 1 0 f f t f i 5 16 "2281 3642 23 26 2281" _null_ _null_ _null_ gtsvector_consistent - _null_ _null_ ));
DESCR("GiST tsvector support");
DATA(insert OID = 3656 ( gin_extract_tsvector PGNSP PGUID 12 1 0 f f t f i 2 2281 "3614 2281" _null_ _null_ _null_ gin_extract_tsvector - _null_ _null_ ));
DESCR("GIN tsvector support");
DATA(insert OID = 3657 ( gin_extract_tsquery PGNSP PGUID 12 1 0 f f t f i 3 2281 "3615 2281 21" _null_ _null_ _null_ gin_extract_tsquery - _null_ _null_ ));
DESCR("GIN tsvector support");
DATA(insert OID = 3658 ( gin_tsquery_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 21 3615" _null_ _null_ _null_ gin_tsquery_consistent - _null_ _null_ ));
DATA(insert OID = 3658 ( gin_tsquery_consistent PGNSP PGUID 12 1 0 f f t f i 4 16 "2281 21 3615 2281" _null_ _null_ _null_ gin_tsquery_consistent - _null_ _null_ ));
DESCR("GIN tsvector support");
DATA(insert OID = 3662 ( tsquery_lt PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_lt - _null_ _null_ ));
......@@ -4284,7 +4284,7 @@ DATA(insert OID = 3699 ( gtsquery_same PGNSP PGUID 12 1 0 f f t f i 3 2281
DESCR("GiST tsquery support");
DATA(insert OID = 3700 ( gtsquery_penalty PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_ gtsquery_penalty - _null_ _null_ ));
DESCR("GiST tsquery support");
DATA(insert OID = 3701 ( gtsquery_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "20 2281 23" _null_ _null_ _null_ gtsquery_consistent - _null_ _null_ ));
DATA(insert OID = 3701 ( gtsquery_consistent PGNSP PGUID 12 1 0 f f t f i 5 16 "2281 2281 23 26 2281" _null_ _null_ _null_ gtsquery_consistent - _null_ _null_ ));
DESCR("GiST tsquery support");
DATA(insert OID = 3689 ( ts_stat PGNSP PGUID 12 10 10000 f f t t v 1 2249 "25" "{25,25,23,23}" "{i,o,o,o}" "{query,word,ndoc,nentry}" ts_stat1 - _null_ _null_ ));
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.361 2008/03/21 22:41:48 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.362 2008/04/14 17:05:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1390,7 +1390,6 @@ typedef struct CreateOpClassItem
List *name; /* operator or function name */
List *args; /* argument types */
int number; /* strategy num or support proc num */
bool recheck; /* only used for operators */
List *class_args; /* only used for functions */
/* fields used for a storagetype item: */
TypeName *storedtype; /* datatype stored in index */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment