Skip to content

Commit dddbbc4

Browse files
committed
Merge branch 'REL9_5_STABLE' into PGPRO9_5
2 parents 907aa59 + 2acb682 commit dddbbc4

File tree

15 files changed

+89
-58
lines changed

15 files changed

+89
-58
lines changed

contrib/fuzzystrmatch/fuzzystrmatch.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ levenshtein_with_costs(PG_FUNCTION_ARGS)
171171
/* Extract a pointer to the actual character data */
172172
s_data = VARDATA_ANY(src);
173173
t_data = VARDATA_ANY(dst);
174-
/* Determine length of each string in bytes and characters */
174+
/* Determine length of each string in bytes */
175175
s_bytes = VARSIZE_ANY_EXHDR(src);
176176
t_bytes = VARSIZE_ANY_EXHDR(dst);
177177

178-
PG_RETURN_INT32(varstr_levenshtein(s_data, s_bytes, t_data, t_bytes, ins_c,
179-
del_c, sub_c));
178+
PG_RETURN_INT32(varstr_levenshtein(s_data, s_bytes, t_data, t_bytes,
179+
ins_c, del_c, sub_c, false));
180180
}
181181

182182

@@ -194,12 +194,12 @@ levenshtein(PG_FUNCTION_ARGS)
194194
/* Extract a pointer to the actual character data */
195195
s_data = VARDATA_ANY(src);
196196
t_data = VARDATA_ANY(dst);
197-
/* Determine length of each string in bytes and characters */
197+
/* Determine length of each string in bytes */
198198
s_bytes = VARSIZE_ANY_EXHDR(src);
199199
t_bytes = VARSIZE_ANY_EXHDR(dst);
200200

201-
PG_RETURN_INT32(varstr_levenshtein(s_data, s_bytes, t_data, t_bytes, 1, 1,
202-
1));
201+
PG_RETURN_INT32(varstr_levenshtein(s_data, s_bytes, t_data, t_bytes,
202+
1, 1, 1, false));
203203
}
204204

205205

@@ -221,13 +221,14 @@ levenshtein_less_equal_with_costs(PG_FUNCTION_ARGS)
221221
/* Extract a pointer to the actual character data */
222222
s_data = VARDATA_ANY(src);
223223
t_data = VARDATA_ANY(dst);
224-
/* Determine length of each string in bytes and characters */
224+
/* Determine length of each string in bytes */
225225
s_bytes = VARSIZE_ANY_EXHDR(src);
226226
t_bytes = VARSIZE_ANY_EXHDR(dst);
227227

228-
PG_RETURN_INT32(varstr_levenshtein_less_equal(s_data, s_bytes, t_data,
229-
t_bytes, ins_c, del_c,
230-
sub_c, max_d));
228+
PG_RETURN_INT32(varstr_levenshtein_less_equal(s_data, s_bytes,
229+
t_data, t_bytes,
230+
ins_c, del_c, sub_c,
231+
max_d, false));
231232
}
232233

233234

@@ -246,12 +247,14 @@ levenshtein_less_equal(PG_FUNCTION_ARGS)
246247
/* Extract a pointer to the actual character data */
247248
s_data = VARDATA_ANY(src);
248249
t_data = VARDATA_ANY(dst);
249-
/* Determine length of each string in bytes and characters */
250+
/* Determine length of each string in bytes */
250251
s_bytes = VARSIZE_ANY_EXHDR(src);
251252
t_bytes = VARSIZE_ANY_EXHDR(dst);
252253

253-
PG_RETURN_INT32(varstr_levenshtein_less_equal(s_data, s_bytes, t_data,
254-
t_bytes, 1, 1, 1, max_d));
254+
PG_RETURN_INT32(varstr_levenshtein_less_equal(s_data, s_bytes,
255+
t_data, t_bytes,
256+
1, 1, 1,
257+
max_d, false));
255258
}
256259

257260

doc/src/sgml/fuzzystrmatch.sgml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,20 @@ levenshtein_less_equal(text source, text target, int max_d) returns int
106106

107107
<para>
108108
Both <literal>source</literal> and <literal>target</literal> can be any
109-
non-null string, with a maximum of 255 bytes. The cost parameters
109+
non-null string, with a maximum of 255 characters. The cost parameters
110110
specify how much to charge for a character insertion, deletion, or
111111
substitution, respectively. You can omit the cost parameters, as in
112112
the second version of the function; in that case they all default to 1.
113-
<literal>levenshtein_less_equal</literal> is accelerated version of
114-
levenshtein function for low values of distance. If actual distance
115-
is less or equal then max_d, then <literal>levenshtein_less_equal</literal>
116-
returns accurate value of it. Otherwise this function returns value
117-
which is greater than max_d.
113+
</para>
114+
115+
<para>
116+
<function>levenshtein_less_equal</function> is an accelerated version of the
117+
Levenshtein function for use when only small distances are of interest.
118+
If the actual distance is less than or equal to <literal>max_d</>,
119+
then <function>levenshtein_less_equal</function> returns the correct
120+
distance; otherwise it returns some value greater than <literal>max_d</>.
121+
If <literal>max_d</> is negative then the behavior is the same as
122+
<function>levenshtein</function>.
118123
</para>
119124

120125
<para>

src/backend/parser/parse_relation.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
550550
varstr_levenshtein_less_equal(actual, strlen(actual), match, matchlen,
551551
1, 1, 1,
552552
fuzzystate->distance + 1
553-
- fuzzy_rte_penalty);
553+
- fuzzy_rte_penalty,
554+
true);
554555

555556
/*
556557
* If more than half the characters are different, don't treat it as a
@@ -843,10 +844,12 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, char *colname,
843844
*/
844845
if (alias != NULL)
845846
fuzzy_rte_penalty =
846-
varstr_levenshtein(alias, strlen(alias),
847-
rte->eref->aliasname,
848-
strlen(rte->eref->aliasname),
849-
1, 1, 1);
847+
varstr_levenshtein_less_equal(alias, strlen(alias),
848+
rte->eref->aliasname,
849+
strlen(rte->eref->aliasname),
850+
1, 1, 1,
851+
MAX_FUZZY_DISTANCE + 1,
852+
true);
850853

851854
/*
852855
* Scan for a matching column; if we find an exact match, we're

src/backend/postmaster/postmaster.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4068,6 +4068,14 @@ BackendInitialize(Port *port)
40684068
else
40694069
snprintf(remote_ps_data, sizeof(remote_ps_data), "%s(%s)", remote_host, remote_port);
40704070

4071+
/*
4072+
* Save remote_host and remote_port in port structure (after this, they
4073+
* will appear in log_line_prefix data for log messages).
4074+
*/
4075+
port->remote_host = strdup(remote_host);
4076+
port->remote_port = strdup(remote_port);
4077+
4078+
/* And now we can issue the Log_connections message, if wanted */
40714079
if (Log_connections)
40724080
{
40734081
if (remote_port[0])
@@ -4081,12 +4089,6 @@ BackendInitialize(Port *port)
40814089
remote_host)));
40824090
}
40834091

4084-
/*
4085-
* save remote_host and remote_port in port structure
4086-
*/
4087-
port->remote_host = strdup(remote_host);
4088-
port->remote_port = strdup(remote_port);
4089-
40904092
/*
40914093
* If we did a reverse lookup to name, we might as well save the results
40924094
* rather than possibly repeating the lookup during authentication.

src/backend/utils/adt/levenshtein.c

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,16 @@
2626
#define MAX_LEVENSHTEIN_STRLEN 255
2727

2828
/*
29-
* Calculates Levenshtein distance metric between supplied csrings, which are
30-
* not necessarily null-terminated. Generally (1, 1, 1) penalty costs suffices
31-
* for common cases, but your mileage may vary.
29+
* Calculates Levenshtein distance metric between supplied strings, which are
30+
* not necessarily null-terminated.
31+
*
32+
* source: source string, of length slen bytes.
33+
* target: target string, of length tlen bytes.
34+
* ins_c, del_c, sub_c: costs to charge for character insertion, deletion,
35+
* and substitution respectively; (1, 1, 1) costs suffice for common
36+
* cases, but your mileage may vary.
37+
* max_d: if provided and >= 0, maximum distance we care about; see below.
38+
* trusted: caller is trusted and need not obey MAX_LEVENSHTEIN_STRLEN.
3239
*
3340
* One way to compute Levenshtein distance is to incrementally construct
3441
* an (m+1)x(n+1) matrix where cell (i, j) represents the minimum number
@@ -43,7 +50,7 @@
4350
* array.
4451
*
4552
* If max_d >= 0, we only need to provide an accurate answer when that answer
46-
* is less than or equal to the bound. From any cell in the matrix, there is
53+
* is less than or equal to max_d. From any cell in the matrix, there is
4754
* theoretical "minimum residual distance" from that cell to the last column
4855
* of the final row. This minimum residual distance is zero when the
4956
* untransformed portions of the strings are of equal length (because we might
@@ -58,12 +65,15 @@
5865
*/
5966
int
6067
#ifdef LEVENSHTEIN_LESS_EQUAL
61-
varstr_levenshtein_less_equal(const char *source, int slen, const char *target,
62-
int tlen, int ins_c, int del_c, int sub_c,
63-
int max_d)
68+
varstr_levenshtein_less_equal(const char *source, int slen,
69+
const char *target, int tlen,
70+
int ins_c, int del_c, int sub_c,
71+
int max_d, bool trusted)
6472
#else
65-
varstr_levenshtein(const char *source, int slen, const char *target, int tlen,
66-
int ins_c, int del_c, int sub_c)
73+
varstr_levenshtein(const char *source, int slen,
74+
const char *target, int tlen,
75+
int ins_c, int del_c, int sub_c,
76+
bool trusted)
6777
#endif
6878
{
6979
int m,
@@ -95,15 +105,7 @@ varstr_levenshtein(const char *source, int slen, const char *target, int tlen,
95105
#define STOP_COLUMN m
96106
#endif
97107

98-
/*
99-
* A common use for Levenshtein distance is to match attributes when
100-
* building diagnostic, user-visible messages. Restrict the size of
101-
* MAX_LEVENSHTEIN_STRLEN at compile time so that this is guaranteed to
102-
* work.
103-
*/
104-
StaticAssertStmt(NAMEDATALEN <= MAX_LEVENSHTEIN_STRLEN,
105-
"Levenshtein hinting mechanism restricts NAMEDATALEN");
106-
108+
/* Convert string lengths (in bytes) to lengths in characters */
107109
m = pg_mbstrlen_with_len(source, slen);
108110
n = pg_mbstrlen_with_len(target, tlen);
109111

@@ -118,14 +120,18 @@ varstr_levenshtein(const char *source, int slen, const char *target, int tlen,
118120

119121
/*
120122
* For security concerns, restrict excessive CPU+RAM usage. (This
121-
* implementation uses O(m) memory and has O(mn) complexity.)
123+
* implementation uses O(m) memory and has O(mn) complexity.) If
124+
* "trusted" is true, caller is responsible for not making excessive
125+
* requests, typically by using a small max_d along with strings that are
126+
* bounded, though not necessarily to MAX_LEVENSHTEIN_STRLEN exactly.
122127
*/
123-
if (m > MAX_LEVENSHTEIN_STRLEN ||
124-
n > MAX_LEVENSHTEIN_STRLEN)
128+
if (!trusted &&
129+
(m > MAX_LEVENSHTEIN_STRLEN ||
130+
n > MAX_LEVENSHTEIN_STRLEN))
125131
ereport(ERROR,
126132
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
127-
errmsg("argument exceeds the maximum length of %d bytes",
128-
MAX_LEVENSHTEIN_STRLEN)));
133+
errmsg("levenshtein argument exceeds maximum length of %d characters",
134+
MAX_LEVENSHTEIN_STRLEN)));
129135

130136
#ifdef LEVENSHTEIN_LESS_EQUAL
131137
/* Initialize start and stop columns. */

src/bin/pg_dump/pg_dump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9592,7 +9592,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
95929592
appendPQExpBuffer(labelq, "CONSTRAINT %s ",
95939593
fmtId(domcheck->dobj.name));
95949594
appendPQExpBuffer(labelq, "ON DOMAIN %s",
9595-
fmtId(qtypname));
9595+
qtypname);
95969596
dumpComment(fout, labelq->data,
95979597
tyinfo->dobj.namespace->dobj.name,
95989598
tyinfo->rolname,

src/include/utils/builtins.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,14 @@ extern Datum textoverlay_no_len(PG_FUNCTION_ARGS);
808808
extern Datum name_text(PG_FUNCTION_ARGS);
809809
extern Datum text_name(PG_FUNCTION_ARGS);
810810
extern int varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid);
811-
extern int varstr_levenshtein(const char *source, int slen, const char *target,
812-
int tlen, int ins_c, int del_c, int sub_c);
811+
extern int varstr_levenshtein(const char *source, int slen,
812+
const char *target, int tlen,
813+
int ins_c, int del_c, int sub_c,
814+
bool trusted);
813815
extern int varstr_levenshtein_less_equal(const char *source, int slen,
814-
const char *target, int tlen, int ins_c,
815-
int del_c, int sub_c, int max_d);
816+
const char *target, int tlen,
817+
int ins_c, int del_c, int sub_c,
818+
int max_d, bool trusted);
816819
extern List *textToQualifiedNameList(text *textval);
817820
extern bool SplitIdentifierString(char *rawstring, char separator,
818821
List **namelist);

src/test/mb/expected/big5.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ drop table
22
create table �t�Ӹ�� (��~�O text, ���q���Y varchar, �a�} varchar(16));
33
create index �t�Ӹ��index1 on �t�Ӹ�� using btree (��~�O);
44
create index �t�Ӹ��index2 on �t�Ӹ�� using hash (���q���Y);
5+
WARNING: hash indexes are not WAL-logged and their use is discouraged
56
insert into �t�Ӹ�� values ('�q���~', '�F�F���', '�_A01��');
67
insert into �t�Ӹ�� values ('�s�y�~', '�]���������q', '��B10��');
78
insert into �t�Ӹ�� values ('�\���~', '�����ѥ��������q', '��Z01�E');

src/test/mb/expected/euc_jp.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ERROR: table "
33
create table �׻����Ѹ� (�Ѹ� text, ʬ�ॳ���� varchar, ����1A���� char(16));
44
create index �׻����Ѹ�index1 on �׻����Ѹ� using btree (�Ѹ�);
55
create index �׻����Ѹ�index2 on �׻����Ѹ� using hash (ʬ�ॳ����);
6+
WARNING: hash indexes are not WAL-logged and their use is discouraged
67
insert into �׻����Ѹ� values('����ԥ塼���ǥ����ץ쥤','��A01��');
78
insert into �׻����Ѹ� values('����ԥ塼������ե��å���','ʬB10��');
89
insert into �׻����Ѹ� values('����ԥ塼���ץ�����ޡ�','��Z01��');

src/test/mb/expected/euc_kr.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ERROR: table "ͪߩѦ
33
create table ͪߩѦ��� (��� text, ��׾�ڵ� varchar, ���1A�� char(16));
44
create index ͪߩѦ���index1 on ͪߩѦ��� using btree (���);
55
create index ͪߩѦ���index2 on ͪߩѦ��� using hash (��׾�ڵ�);
6+
WARNING: hash indexes are not WAL-logged and their use is discouraged
67
insert into ͪߩѦ��� values('��ǻ�͵��÷���', 'ѦA01߾');
78
insert into ͪߩѦ��� values('��ǻ�ͱ׷��Ƚ�', '��B10��');
89
insert into ͪߩѦ��� values('��ǻ�����α׷���', '��Z01��');

src/test/mb/expected/euc_tw.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ERROR: table "
33
create table ��ٸ���� (����ɱ text, ��Ƴ��� varchar, ���� varchar(16));
44
create index ��ٸ����index1 on ��ٸ���� using btree (����ɱ);
55
create index ��ٸ����index2 on ��ٸ���� using hash (��Ƴ���);
6+
WARNING: hash indexes are not WAL-logged and their use is discouraged
67
insert into ��ٸ���� values ('�����', '������', 'ơA01��');
78
insert into ��ٸ���� values ('������', '����ȴ����Ƴ', '��B10��');
89
insert into ��ٸ���� values ('����', 'ӡ��ϴǹȴ����Ƴ', '��Z01Ħ');

src/test/mb/expected/gb18030.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ drop table Ӌ
22
create table Ӌ��C���Z (���Z text, ����`�� varchar, �俼1A���� char(16));
33
create index Ӌ��C���Zindex1 on Ӌ��C���Z using btree (���Z);
44
create index Ӌ��C���Zindex2 on Ӌ��C���Z using hash (����`��);
5+
WARNING: hash indexes are not WAL-logged and their use is discouraged
56
insert into Ӌ��C���Z values('����ԥ�`���ǥ����ץ쥤','�CA01��');
67
insert into Ӌ��C���Z values('����ԥ�`������ե��å���','��B10��');
78
insert into Ӌ��C���Z values('����ԥ�`���ץ�����ީ`','��Z01��');

src/test/mb/expected/mule_internal.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ERROR: table "
33
create table ��ג�������ђ�� (��ђ�� text, �ʬ������������ varchar, ������1A������ char(16));
44
create index ��ג�������ђ��index1 on ��ג�������ђ�� using btree (��ђ��);
55
create index ��ג�������ђ��index2 on ��ג�������ђ�� using hash (�ʬ������������);
6+
WARNING: hash indexes are not WAL-logged and their use is discouraged
67
insert into ��ג�������ђ�� values('������Ԓ�咡������ǒ�������ג�쒥�','���A01���');
78
insert into ��ג�������ђ�� values('������Ԓ�咡���������钥Ւ����Ò�����','�ʬB10���');
89
insert into ��ג�������ђ�� values('������Ԓ�咡������ג�풥���钥ޒ��','���Z01���');
@@ -177,6 +178,7 @@ ERROR: table "
177178
create table �ͪ�ߩ�Ѧ��듾� (��듾� text, ��“׾��ړ�� varchar, ����1A��󓱸 char(16));
178179
create index �ͪ�ߩ�Ѧ��듾�index1 on �ͪ�ߩ�Ѧ��듾� using btree (��듾�);
179180
create index �ͪ�ߩ�Ѧ��듾�index2 on �ͪ�ߩ�Ѧ��듾� using hash (��“׾��ړ��);
181+
WARNING: hash indexes are not WAL-logged and their use is discouraged
180182
insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓�𓽺��Ó�����', '�ѦA01�߾');
181183
insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓�ד����ȓ��', '���B10���');
182184
insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓����Γ�ד�����', '���Z01���');

src/test/mb/expected/sjis.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ drop table
22
create table �v�Z�@�p�� (�p�� text, ���ރR�[�h varchar, ���l1A���� char(16));
33
create index �v�Z�@�p��index1 on �v�Z�@�p�� using btree (�p��);
44
create index �v�Z�@�p��index2 on �v�Z�@�p�� using hash (���ރR�[�h);
5+
WARNING: hash indexes are not WAL-logged and their use is discouraged
56
insert into �v�Z�@�p�� values('�R���s���[�^�f�B�X�v���C','�@A01��');
67
insert into �v�Z�@�p�� values('�R���s���[�^�O���t�B�b�N�X','��B10��');
78
insert into �v�Z�@�p�� values('�R���s���[�^�v���O���}�[','�lZ01��');

src/test/mb/expected/utf8.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ERROR: table "計算機用語" does not exist
33
create table 計算機用語 (用語 text, 分類コード varchar, 備考1Aだよ char(16));
44
create index 計算機用語index1 on 計算機用語 using btree (用語);
55
create index 計算機用語index2 on 計算機用語 using hash (分類コード);
6+
WARNING: hash indexes are not WAL-logged and their use is discouraged
67
insert into 計算機用語 values('コンピュータディスプレイ','機A01上');
78
insert into 計算機用語 values('コンピュータグラフィックス','分B10中');
89
insert into 計算機用語 values('コンピュータプログラマー','人Z01下');

0 commit comments

Comments
 (0)