aboutsummaryrefslogtreecommitdiff
path: root/contrib/pg_trgm/trgm_gin.c
blob: ed2ba0eae759e9f70c770c405b0bba997fc910ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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);
}