trgm_compare_partial_v0.patch
application/octet-stream
Filename: trgm_compare_partial_v0.patch
Type: application/octet-stream
Part: 0
Message:
pg_trgm partial-match
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
Series: patch v0
| File | + | − |
|---|---|---|
| contrib/pg_trgm/pg_trgm--1.0.sql | 6 | 0 |
| contrib/pg_trgm/trgm_gin.c | 48 | 0 |
| contrib/pg_trgm/trgm.h | 3 | 0 |
| contrib/pg_trgm/trgm_op.c | 15 | 0 |
*** 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)