mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +03:00
Add GIN support for pg_trgm. From Guillaume Smet <guillaume.smet@gmail.com>
with minor editorization by me.
This commit is contained in:
77
contrib/pg_trgm/trgm_gin.c
Normal file
77
contrib/pg_trgm/trgm_gin.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include "trgm.h"
|
||||
|
||||
#include "access/gin.h"
|
||||
#include "access/itup.h"
|
||||
#include "access/tuptoaster.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
PG_FUNCTION_INFO_V1(gin_extract_trgm);
|
||||
Datum gin_extract_trgm(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(gin_trgm_consistent);
|
||||
Datum gin_trgm_consistent(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum
|
||||
gin_extract_trgm(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *val = (text *) PG_GETARG_TEXT_P(0);
|
||||
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
|
||||
Datum *entries = NULL;
|
||||
TRGM *trg;
|
||||
int4 trglen;
|
||||
|
||||
*nentries = 0;
|
||||
|
||||
trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
|
||||
trglen = ARRNELEM(trg);
|
||||
|
||||
if (trglen > 0)
|
||||
{
|
||||
trgm *ptr;
|
||||
int4 i = 0,
|
||||
item;
|
||||
|
||||
*nentries = (int32) trglen;
|
||||
entries = (Datum *) palloc(sizeof(Datum) * trglen);
|
||||
|
||||
ptr = GETARR(trg);
|
||||
while (ptr - GETARR(trg) < ARRNELEM(trg))
|
||||
{
|
||||
item = TRGMINT(ptr);
|
||||
entries[i++] = Int32GetDatum(item);
|
||||
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
PG_RETURN_POINTER(entries);
|
||||
}
|
||||
|
||||
Datum
|
||||
gin_trgm_consistent(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool *check = (bool *) PG_GETARG_POINTER(0);
|
||||
text *query = (text *) PG_GETARG_TEXT_P(2);
|
||||
bool res = FALSE;
|
||||
TRGM *trg;
|
||||
int4 i,
|
||||
trglen,
|
||||
ntrue = 0;
|
||||
|
||||
trg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
|
||||
trglen = ARRNELEM(trg);
|
||||
|
||||
for (i = 0; i < trglen; i++)
|
||||
if (check[i])
|
||||
ntrue ++;
|
||||
|
||||
#ifdef DIVUNION
|
||||
res = (trglen == ntrue) ? true : ((((((float4) ntrue) / ((float4) (trglen - ntrue)))) >= trgm_limit) ? true : false);
|
||||
#else
|
||||
res = (trglen == 0) ? false : ((((((float4) ntrue) / ((float4) trglen))) >= trgm_limit) ? true : false);
|
||||
#endif
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
Reference in New Issue
Block a user