*** a/contrib/pg_trgm/pg_trgm--1.0.sql --- b/contrib/pg_trgm/pg_trgm--1.0.sql *************** *** 148,153 **** RETURNS bool --- 148,158 ---- AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT; + CREATE FUNCTION gin_trgm_compare_partial(int4, int4, int2, internal) + RETURNS int + AS 'MODULE_PATHNAME' + LANGUAGE C IMMUTABLE STRICT; + -- create the operator class for gin CREATE OPERATOR CLASS gin_trgm_ops FOR TYPE text USING gin *************** *** 157,162 **** AS --- 162,168 ---- FUNCTION 2 gin_extract_value_trgm (text, internal), FUNCTION 3 gin_extract_query_trgm (text, internal, int2, internal, internal, internal, internal), FUNCTION 4 gin_trgm_consistent (internal, int2, text, int4, internal, internal, internal, internal), + FUNCTION 5 gin_trgm_compare_partial (int4, int4, int2, internal), STORAGE int4; -- Add operators that are new in 9.1. *** a/contrib/pg_trgm/trgm.h --- b/contrib/pg_trgm/trgm.h *************** *** 42,47 **** typedef char trgm[3]; --- 42,49 ---- *(((char*)(a))+2) = *(((char*)(b))+2); \ } while(0); + #define TRGMCHARLEN(t) ( (*(((char*)(t))+2)=='\0') ? ( (*(((char*)(t))+1)=='\0') ? 1 : 2) : 3 ) + uint32 trgm2int(trgm *ptr); #ifdef KEEPONLYALNUM *************** *** 100,105 **** typedef char *BITVECP; --- 102,108 ---- #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) ) extern float4 trgm_limit; + extern bool trgm_pmatch; TRGM *generate_trgm(char *str, int slen); TRGM *generate_wildcard_trgm(const char *str, int slen); *** a/contrib/pg_trgm/trgm_gin.c --- b/contrib/pg_trgm/trgm_gin.c *************** *** 21,26 **** Datum gin_extract_query_trgm(PG_FUNCTION_ARGS); --- 21,29 ---- PG_FUNCTION_INFO_V1(gin_trgm_consistent); Datum gin_trgm_consistent(PG_FUNCTION_ARGS); + PG_FUNCTION_INFO_V1(gin_trgm_compare_partial); + Datum gin_trgm_compare_partial(PG_FUNCTION_ARGS); + /* * This function can only be called if a pre-9.1 version of the GIN operator * class definition is present in the catalogs (probably as a consequence *************** *** 46,51 **** gin_extract_value_trgm(PG_FUNCTION_ARGS) --- 49,57 ---- TRGM *trg; int32 trglen; + #ifdef KEEPONLYALNUM + trgm_pmatch = true; + #endif *nentries = 0; trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ); *************** *** 79,86 **** gin_extract_query_trgm(PG_FUNCTION_ARGS) int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); ! /* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */ ! /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ /* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */ int32 *searchMode = (int32 *) PG_GETARG_POINTER(6); Datum *entries = NULL; --- 85,92 ---- int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); ! bool **pmatch = (bool **) PG_GETARG_POINTER(3); ! Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4); /* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */ int32 *searchMode = (int32 *) PG_GETARG_POINTER(6); Datum *entries = NULL; *************** *** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS) --- 95,104 ---- trgm *ptr; int32 i; + #ifdef KEEPONLYALNUM + trgm_pmatch = true; + #endif + switch (strategy) { case SimilarityStrategyNumber: *************** *** 115,120 **** gin_extract_query_trgm(PG_FUNCTION_ARGS) --- 125,132 ---- trglen = ARRNELEM(trg); *nentries = trglen; + *pmatch = NULL; + *extra_data = NULL; if (trglen > 0) { *************** *** 124,129 **** gin_extract_query_trgm(PG_FUNCTION_ARGS) --- 136,159 ---- { int32 item = trgm2int(ptr); + #ifdef KEEPONLYALNUM + if (trgm_pmatch) + { + int trgmcharlen = TRGMCHARLEN(ptr); + + if (trgmcharlen < 3) + { + if (*pmatch == NULL) + { + *pmatch = (bool *) palloc0(sizeof(bool) * trglen); + *extra_data = (Pointer *) palloc0(sizeof(int) * trglen); + } + *(*pmatch + i) = true; + *((int *)(*extra_data + i)) = trgmcharlen; + } + } + #endif + entries[i] = Int32GetDatum(item); ptr++; } *************** *** 197,199 **** gin_trgm_consistent(PG_FUNCTION_ARGS) --- 227,245 ---- PG_RETURN_BOOL(res); } + + Datum + gin_trgm_compare_partial(PG_FUNCTION_ARGS) + { + int32 a = PG_GETARG_INT32(0); + int32 b = PG_GETARG_INT32(1); + int32 shiftlen = (3 - PG_GETARG_INT32(3)) * 8; + + a >>= shiftlen; + b >>= shiftlen; + + if (a == b) + PG_RETURN_INT32(0); + else + PG_RETURN_INT32(1); + } *** a/contrib/pg_trgm/trgm_op.c --- b/contrib/pg_trgm/trgm_op.c *************** *** 15,20 **** PG_MODULE_MAGIC; --- 15,22 ---- float4 trgm_limit = 0.3f; + bool trgm_pmatch = false; + PG_FUNCTION_INFO_V1(set_limit); Datum set_limit(PG_FUNCTION_ARGS); *************** *** 142,148 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen) --- 144,163 ---- char *ptr = str; if (charlen < 3) + { + #ifdef KEEPONLYALNUM + if (trgm_pmatch) + { + int i; + + Assert(bytelen == charlen); + for (i = 0; i < 3; i++) + *(((char *)tptr) + i) = (i < bytelen) ? *(ptr + i) : '\0'; + tptr++; + } + #endif return tptr; + } #ifdef USE_WIDE_UPPER_LOWER if (pg_database_encoding_max_length() > 1)