2 * contrib/pg_trgm/trgm_gin.c
8 #include "access/gin.h"
9 #include "access/itup.h"
10 #include "access/skey.h"
11 #include "access/tuptoaster.h"
12 #include "storage/bufpage.h"
13 #include "utils/array.h"
14 #include "utils/builtins.h"
17 PG_FUNCTION_INFO_V1(gin_extract_trgm);
18 Datum gin_extract_trgm(PG_FUNCTION_ARGS);
20 PG_FUNCTION_INFO_V1(gin_extract_value_trgm);
21 Datum gin_extract_value_trgm(PG_FUNCTION_ARGS);
23 PG_FUNCTION_INFO_V1(gin_extract_query_trgm);
24 Datum gin_extract_query_trgm(PG_FUNCTION_ARGS);
26 PG_FUNCTION_INFO_V1(gin_trgm_consistent);
27 Datum gin_trgm_consistent(PG_FUNCTION_ARGS);
30 * This function can only be called if a pre-9.1 version of the GIN operator
31 * class definition is present in the catalogs (probably as a consequence
32 * of upgrade-in-place). Cope.
35 gin_extract_trgm(PG_FUNCTION_ARGS)
38 return gin_extract_value_trgm(fcinfo);
40 return gin_extract_query_trgm(fcinfo);
41 elog(ERROR, "unexpected number of arguments to gin_extract_trgm");
46 gin_extract_value_trgm(PG_FUNCTION_ARGS)
48 text *val = (text *) PG_GETARG_TEXT_P(0);
49 int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
50 Datum *entries = NULL;
56 trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
57 trglen = ARRNELEM(trg);
65 entries = (Datum *) palloc(sizeof(Datum) * trglen);
68 for (i = 0; i < trglen; i++)
70 int32 item = trgm2int(ptr);
72 entries[i] = Int32GetDatum(item);
77 PG_RETURN_POINTER(entries);
81 gin_extract_query_trgm(PG_FUNCTION_ARGS)
83 text *val = (text *) PG_GETARG_TEXT_P(0);
84 int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
85 StrategyNumber strategy = PG_GETARG_UINT16(2);
86 /* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */
87 /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
88 /* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */
89 int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
90 Datum *entries = NULL;
98 case SimilarityStrategyNumber:
99 trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
101 case ILikeStrategyNumber:
103 elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
106 case LikeStrategyNumber:
108 * For wildcard search we extract all the trigrams that every
109 * potentially-matching string must include.
111 trg = generate_wildcard_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
114 elog(ERROR, "unrecognized strategy number: %d", strategy);
115 trg = NULL; /* keep compiler quiet */
119 trglen = ARRNELEM(trg);
124 entries = (Datum *) palloc(sizeof(Datum) * trglen);
126 for (i = 0; i < trglen; i++)
128 int32 item = trgm2int(ptr);
130 entries[i] = Int32GetDatum(item);
136 * If no trigram was extracted then we have to scan all the index.
139 *searchMode = GIN_SEARCH_MODE_ALL;
141 PG_RETURN_POINTER(entries);
145 gin_trgm_consistent(PG_FUNCTION_ARGS)
147 bool *check = (bool *) PG_GETARG_POINTER(0);
148 StrategyNumber strategy = PG_GETARG_UINT16(1);
149 /* text *query = PG_GETARG_TEXT_P(2); */
150 int32 nkeys = PG_GETARG_INT32(3);
151 /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
152 bool *recheck = (bool *) PG_GETARG_POINTER(5);
157 /* All cases served by this function are inexact */
162 case SimilarityStrategyNumber:
163 /* Count the matches */
165 for (i = 0; i < nkeys; i++)
171 res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= trgm_limit) ? true : false);
173 res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
176 case ILikeStrategyNumber:
178 elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
181 case LikeStrategyNumber:
182 /* Check if all extracted trigrams are presented. */
184 for (i = 0; i < nkeys; i++)
194 elog(ERROR, "unrecognized strategy number: %d", strategy);
195 res = false; /* keep compiler quiet */