Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdfd8e6c

Browse files
Fix an issue with index scan using pg_trgm due to char signedness on different architectures.
GIN and GiST indexes utilizing pg_trgm's opclasses store sortedtrigrams within index tuples. When comparing and sorting each trigram,pg_trgm treats each character as a 'char[3]' type in C. However, thechar type in C can be interpreted as either signed char or unsignedchar, depending on the platform, if the signedness is not explicitlyspecified. Consequently, during replication between different CPUarchitectures, there was an issue where index scans on standby serverscould not locate matching index tuples due to the differing treatmentof character signedness.This change introduces comparison functions for trgm that explicitlyhandle signed char and unsigned char. The appropriate comparisonfunction will be dynamically selected based on the charactersignedness stored in the control file. Therefore, upgraded clusterscan utilize the indexes without rebuilding, provided the clusterupgrade occurs on platforms with the same character signedness as theoriginal cluster initialization.The default char signedness information was introduced in44fe30f,so no backpatch.Reviewed-by: Noah Misch <noah@leadboat.com>Discussion:https://postgr.es/m/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07%40amazon.com
1 parent1aab680 commitdfd8e6c

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

‎contrib/pg_trgm/trgm.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,12 @@
4040

4141
typedefchartrgm[3];
4242

43-
#defineCMPCHAR(a,b) ( ((a)==(b)) ? 0 : ( ((a)<(b)) ? -1 : 1 ) )
44-
#defineCMPPCHAR(a,b,i) CMPCHAR( *(((const char*)(a))+i), *(((const char*)(b))+i) )
45-
#defineCMPTRGM(a,b) ( CMPPCHAR(a,b,0) ? CMPPCHAR(a,b,0) : ( CMPPCHAR(a,b,1) ? CMPPCHAR(a,b,1) : CMPPCHAR(a,b,2) ) )
46-
4743
#defineCPTRGM(a,b) do {\
4844
*(((char*)(a))+0) = *(((char*)(b))+0);\
4945
*(((char*)(a))+1) = *(((char*)(b))+1);\
5046
*(((char*)(a))+2) = *(((char*)(b))+2);\
5147
} while(0)
48+
externint(*CMPTRGM) (constvoid*a,constvoid*b);
5249

5350
#defineISWORDCHR(c)(t_isalnum(c))
5451
#defineISPRINTABLECHAR(a)( isascii( *(unsigned char*)(a) ) && (isalnum( *(unsigned char*)(a) ) || *(unsigned char*)(a)==' ') )

‎contrib/pg_trgm/trgm_op.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ PG_FUNCTION_INFO_V1(strict_word_similarity_commutator_op);
4242
PG_FUNCTION_INFO_V1(strict_word_similarity_dist_op);
4343
PG_FUNCTION_INFO_V1(strict_word_similarity_dist_commutator_op);
4444

45+
staticintCMPTRGM_CHOOSE(constvoid*a,constvoid*b);
46+
int(*CMPTRGM) (constvoid*a,constvoid*b)=CMPTRGM_CHOOSE;
47+
4548
/* Trigram with position */
4649
typedefstruct
4750
{
@@ -107,6 +110,47 @@ _PG_init(void)
107110
MarkGUCPrefixReserved("pg_trgm");
108111
}
109112

113+
#defineCMPCHAR(a,b) ( ((a)==(b)) ? 0 : ( ((a)<(b)) ? -1 : 1 ) )
114+
115+
/*
116+
* Functions for comparing two trgms while treating each char as "signed char" or
117+
* "unsigned char".
118+
*/
119+
staticinlineint
120+
CMPTRGM_SIGNED(constvoid*a,constvoid*b)
121+
{
122+
#defineCMPPCHAR_S(a,b,i) CMPCHAR( *(((const signed char*)(a))+i), *(((const signed char*)(b))+i) )
123+
124+
returnCMPPCHAR_S(a,b,0) ?CMPPCHAR_S(a,b,0)
125+
: (CMPPCHAR_S(a,b,1) ?CMPPCHAR_S(a,b,1)
126+
:CMPPCHAR_S(a,b,2));
127+
}
128+
129+
staticinlineint
130+
CMPTRGM_UNSIGNED(constvoid*a,constvoid*b)
131+
{
132+
#defineCMPPCHAR_UNS(a,b,i) CMPCHAR( *(((const unsigned char*)(a))+i), *(((const unsigned char*)(b))+i) )
133+
134+
returnCMPPCHAR_UNS(a,b,0) ?CMPPCHAR_UNS(a,b,0)
135+
: (CMPPCHAR_UNS(a,b,1) ?CMPPCHAR_UNS(a,b,1)
136+
:CMPPCHAR_UNS(a,b,2));
137+
}
138+
139+
/*
140+
* This gets called on the first call. It replaces the function pointer so
141+
* that subsequent calls are routed directly to the chosen implementation.
142+
*/
143+
staticint
144+
CMPTRGM_CHOOSE(constvoid*a,constvoid*b)
145+
{
146+
if (GetDefaultCharSignedness())
147+
CMPTRGM=CMPTRGM_SIGNED;
148+
else
149+
CMPTRGM=CMPTRGM_UNSIGNED;
150+
151+
returnCMPTRGM(a,b);
152+
}
153+
110154
/*
111155
* Deprecated function.
112156
* Use "pg_trgm.similarity_threshold" GUC variable instead of this function.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp