2008-05-17 09:28:26 +08:00
|
|
|
/*
|
2010-09-21 04:08:53 +08:00
|
|
|
* contrib/pg_trgm/trgm.h
|
2008-05-17 09:28:26 +08:00
|
|
|
*/
|
2004-06-01 01:18:12 +08:00
|
|
|
#ifndef __TRGM_H__
|
|
|
|
#define __TRGM_H__
|
|
|
|
|
|
|
|
#include "access/gist.h"
|
|
|
|
#include "access/itup.h"
|
2018-03-21 19:57:42 +08:00
|
|
|
#include "access/stratnum.h"
|
2004-06-01 01:18:12 +08:00
|
|
|
#include "storage/bufpage.h"
|
|
|
|
|
2013-04-09 13:05:55 +08:00
|
|
|
/*
|
|
|
|
* Options ... but note that trgm_regexp.c effectively assumes these values
|
|
|
|
* of LPADDING and RPADDING.
|
|
|
|
*/
|
2004-06-01 01:18:12 +08:00
|
|
|
#define LPADDING 2
|
|
|
|
#define RPADDING 1
|
|
|
|
#define KEEPONLYALNUM
|
2011-02-01 10:33:55 +08:00
|
|
|
/*
|
|
|
|
* Caution: IGNORECASE macro means that trigrams are case-insensitive.
|
2013-04-09 13:05:55 +08:00
|
|
|
* If this macro is disabled, the ~* and ~~* operators must be removed from
|
|
|
|
* the operator classes, because we can't handle case-insensitive wildcard
|
|
|
|
* search with case-sensitive trigrams. Failure to do this will result in
|
|
|
|
* "cannot handle ~*(~~*) with case-sensitive trigrams" errors.
|
2011-02-01 10:33:55 +08:00
|
|
|
*/
|
2004-06-01 01:18:12 +08:00
|
|
|
#define IGNORECASE
|
|
|
|
#define DIVUNION
|
|
|
|
|
2010-12-04 13:16:21 +08:00
|
|
|
/* operator strategy numbers */
|
2018-03-21 19:57:42 +08:00
|
|
|
#define SimilarityStrategyNumber 1
|
|
|
|
#define DistanceStrategyNumber 2
|
|
|
|
#define LikeStrategyNumber 3
|
|
|
|
#define ILikeStrategyNumber 4
|
|
|
|
#define RegExpStrategyNumber 5
|
|
|
|
#define RegExpICaseStrategyNumber 6
|
|
|
|
#define WordSimilarityStrategyNumber 7
|
|
|
|
#define WordDistanceStrategyNumber 8
|
|
|
|
#define StrictWordSimilarityStrategyNumber 9
|
|
|
|
#define StrictWordDistanceStrategyNumber 10
|
2020-11-15 13:52:12 +08:00
|
|
|
#define EqualStrategyNumber 11
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
typedef char trgm[3];
|
|
|
|
|
|
|
|
#define CMPCHAR(a,b) ( ((a)==(b)) ? 0 : ( ((a)<(b)) ? -1 : 1 ) )
|
2011-09-12 02:54:32 +08:00
|
|
|
#define CMPPCHAR(a,b,i) CMPCHAR( *(((const char*)(a))+i), *(((const char*)(b))+i) )
|
2004-06-01 01:18:12 +08:00
|
|
|
#define CMPTRGM(a,b) ( CMPPCHAR(a,b,0) ? CMPPCHAR(a,b,0) : ( CMPPCHAR(a,b,1) ? CMPPCHAR(a,b,1) : CMPPCHAR(a,b,2) ) )
|
|
|
|
|
|
|
|
#define CPTRGM(a,b) do { \
|
|
|
|
*(((char*)(a))+0) = *(((char*)(b))+0); \
|
|
|
|
*(((char*)(a))+1) = *(((char*)(b))+1); \
|
|
|
|
*(((char*)(a))+2) = *(((char*)(b))+2); \
|
Get rid of trailing semicolons in C macro definitions.
Writing a trailing semicolon in a macro is almost never the right thing,
because you almost always want to write a semicolon after each macro
call instead. (Even if there was some reason to prefer not to, pgindent
would probably make a hash of code formatted that way; so within PG the
rule should basically be "don't do it".) Thus, if we have a semi inside
the macro, the compiler sees "something;;". Much of the time the extra
empty statement is harmless, but it could lead to mysterious syntax
errors at call sites. In perhaps an overabundance of neatnik-ism, let's
run around and get rid of the excess semicolons whereever possible.
The only thing worse than a mysterious syntax error is a mysterious
syntax error that only happens in the back branches; therefore,
backpatch these changes where relevant, which is most of them because
most of these mistakes are old. (The lack of reported problems shows
that this is largely a hypothetical issue, but still, it could bite
us in some future patch.)
John Naylor and Tom Lane
Discussion: https://postgr.es/m/CACPNZCs0qWTqJ2QUSGJ07B7uvAvzMb-KbG2q+oo+J3tsWN5cqw@mail.gmail.com
2020-05-02 05:28:00 +08:00
|
|
|
} while(0)
|
2004-06-01 01:18:12 +08:00
|
|
|
|
2008-11-12 21:43:54 +08:00
|
|
|
#ifdef KEEPONLYALNUM
|
2022-10-06 23:08:56 +08:00
|
|
|
#define ISWORDCHR(c) (t_isalnum(c))
|
2008-11-12 21:43:54 +08:00
|
|
|
#define ISPRINTABLECHAR(a) ( isascii( *(unsigned char*)(a) ) && (isalnum( *(unsigned char*)(a) ) || *(unsigned char*)(a)==' ') )
|
|
|
|
#else
|
2013-04-09 13:05:55 +08:00
|
|
|
#define ISWORDCHR(c) (!t_isspace(c))
|
2008-11-12 21:43:54 +08:00
|
|
|
#define ISPRINTABLECHAR(a) ( isascii( *(unsigned char*)(a) ) && isprint( *(unsigned char*)(a) ) )
|
|
|
|
#endif
|
2011-02-01 10:33:55 +08:00
|
|
|
#define ISPRINTABLETRGM(t) ( ISPRINTABLECHAR( ((char*)(t)) ) && ISPRINTABLECHAR( ((char*)(t))+1 ) && ISPRINTABLECHAR( ((char*)(t))+2 ) )
|
|
|
|
|
|
|
|
#define ISESCAPECHAR(x) (*(x) == '\\') /* Wildcard escape character */
|
|
|
|
#define ISWILDCARDCHAR(x) (*(x) == '_' || *(x) == '%') /* Wildcard
|
|
|
|
* meta-character */
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-03-01 06:44:38 +08:00
|
|
|
int32 vl_len_; /* varlena header (do not touch directly!) */
|
2004-06-01 01:18:12 +08:00
|
|
|
uint8 flag;
|
2015-02-20 13:11:42 +08:00
|
|
|
char data[FLEXIBLE_ARRAY_MEMBER];
|
2004-06-01 01:18:12 +08:00
|
|
|
} TRGM;
|
|
|
|
|
2007-03-01 06:44:38 +08:00
|
|
|
#define TRGMHDRSIZE (VARHDRSZ + sizeof(uint8))
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
/* gist */
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-31 00:17:11 +08:00
|
|
|
#define SIGLEN_DEFAULT (sizeof(int) * 3)
|
|
|
|
#define SIGLEN_MAX GISTMaxIndexKeySize
|
2004-06-01 01:18:12 +08:00
|
|
|
#define BITBYTE 8
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-31 00:17:11 +08:00
|
|
|
#define SIGLENBIT(siglen) ((siglen) * BITBYTE - 1) /* see makesign */
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
typedef char *BITVECP;
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-31 00:17:11 +08:00
|
|
|
#define LOOPBYTE(siglen) \
|
|
|
|
for (i = 0; i < (siglen); i++)
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
|
2011-02-01 10:33:55 +08:00
|
|
|
#define GETBITBYTE(x,i) ( (((char)(x)) >> (i)) & 0x01 )
|
2004-06-01 01:18:12 +08:00
|
|
|
#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
|
|
|
|
#define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITBYTE ) )
|
|
|
|
#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 )
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-31 00:17:11 +08:00
|
|
|
#define HASHVAL(val, siglen) (((unsigned int)(val)) % SIGLENBIT(siglen))
|
|
|
|
#define HASH(sign, val, siglen) SETBIT((sign), HASHVAL(val, siglen))
|
2004-06-01 01:18:12 +08:00
|
|
|
|
|
|
|
#define ARRKEY 0x01
|
|
|
|
#define SIGNKEY 0x02
|
|
|
|
#define ALLISTRUE 0x04
|
2004-08-29 13:07:03 +08:00
|
|
|
|
2004-06-01 01:18:12 +08:00
|
|
|
#define ISARRKEY(x) ( ((TRGM*)x)->flag & ARRKEY )
|
|
|
|
#define ISSIGNKEY(x) ( ((TRGM*)x)->flag & SIGNKEY )
|
|
|
|
#define ISALLTRUE(x) ( ((TRGM*)x)->flag & ALLISTRUE )
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-31 00:17:11 +08:00
|
|
|
#define CALCGTSIZE(flag, len) ( TRGMHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(trgm)) : (((flag) & ALLISTRUE) ? 0 : (len)) ) )
|
2007-03-01 06:44:38 +08:00
|
|
|
#define GETSIGN(x) ( (BITVECP)( (char*)x+TRGMHDRSIZE ) )
|
|
|
|
#define GETARR(x) ( (trgm*)( (char*)x+TRGMHDRSIZE ) )
|
|
|
|
#define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
|
2004-06-01 01:18:12 +08:00
|
|
|
|
2016-03-16 23:59:21 +08:00
|
|
|
/*
|
|
|
|
* If DIVUNION is defined then similarity formula is:
|
|
|
|
* count / (len1 + len2 - count)
|
|
|
|
* else if DIVUNION is not defined then similarity formula is:
|
|
|
|
* count / max(len1, len2)
|
|
|
|
*/
|
|
|
|
#ifdef DIVUNION
|
|
|
|
#define CALCSML(count, len1, len2) ((float4) (count)) / ((float4) ((len1) + (len2) - (count)))
|
|
|
|
#else
|
|
|
|
#define CALCSML(count, len1, len2) ((float4) (count)) / ((float4) (((len1) > (len2)) ? (len1) : (len2)))
|
|
|
|
#endif
|
|
|
|
|
2013-04-09 13:05:55 +08:00
|
|
|
typedef struct TrgmPackedGraph TrgmPackedGraph;
|
|
|
|
|
2016-03-16 22:44:58 +08:00
|
|
|
extern double similarity_threshold;
|
2016-03-16 23:59:21 +08:00
|
|
|
extern double word_similarity_threshold;
|
2018-03-21 19:57:42 +08:00
|
|
|
extern double strict_word_similarity_threshold;
|
2007-03-01 06:44:38 +08:00
|
|
|
|
2018-03-21 19:57:42 +08:00
|
|
|
extern double index_strategy_get_limit(StrategyNumber strategy);
|
2013-04-09 13:05:55 +08:00
|
|
|
extern uint32 trgm2int(trgm *ptr);
|
|
|
|
extern void compact_trigram(trgm *tptr, char *str, int bytelen);
|
|
|
|
extern TRGM *generate_trgm(char *str, int slen);
|
|
|
|
extern TRGM *generate_wildcard_trgm(const char *str, int slen);
|
2016-03-16 23:59:21 +08:00
|
|
|
extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
|
2013-04-09 13:05:55 +08:00
|
|
|
extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
|
2013-04-11 01:30:14 +08:00
|
|
|
extern bool *trgm_presence_map(TRGM *query, TRGM *key);
|
|
|
|
extern TRGM *createTrgmNFA(text *text_re, Oid collation,
|
|
|
|
TrgmPackedGraph **graph, MemoryContext rcontext);
|
2013-04-09 13:05:55 +08:00
|
|
|
extern bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check);
|
2004-06-01 01:18:12 +08:00
|
|
|
|
2010-12-04 13:16:21 +08:00
|
|
|
#endif /* __TRGM_H__ */
|