mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			78 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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);
 | |
| }
 |