Fuzzy substring searching with the pg_trgm extension

Started by Artur Zakirovabout 10 years ago43 messages
#1Artur Zakirov
a.zakirov@postgrespro.ru
5 attachment(s)

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy
text search. It provides some functions and operators for determining
the similarity of the given texts using trigram matching.

At the moment, in pg_trgm both the similarity function and the %
operator match two strings expecting that they are similar entirely. But
they give bad results if we want to find documents by a query which is
substring of a document.

For this purpose we need a new operator which enables to find strings
that have a fragment most similar to the given string. This patch adds
some functions and operator:
- function substring_similarity - Returns a number that indicates how
similar the first string to the most similar substring of the second
string. The range of the result is zero (indicating that the two strings
are completely dissimilar) to one (indicating that the first string is
identical to substring of the second substring).
- function show_substring_limit - Returns the current similarity
threshold used by the <% operator. This sets the minimum substring
similarity between two phrases.
- function set_substring_limit - Sets the current substring similarity
threshold that is used by the <% operator. The threshold must be between
0 and 1 (default is 0.6). Returns the same value passed in.
- operator <% - Returns true if its arguments have a substring
similarity that is greater than the current substring similarity
threshold set by set_substring_limit. Has an index support.

Substring similarity algorithm
------------------------------
1 - generate trigram arrays for a query string and for a text.
2 - create an array that contains trigrams from both arrays from the
step 1 and contains position (index) for trigrams from the second array.
The array stores the following structure:

typedef struct
{
trgm t; // Trigram
int i; // -1 for the first array and position (index) in
the second array
} ptrgm;

3 - sort the array from the step 2.
4 - search trigrams from a query string in a given text and store a
search result in the new boolean array using the array from the step 2.
5 - calculate similarity using the array from the step 4. In this step
lower and upper indexes of the second array from the step 1 are used. An
upper index is moved in each iteration of the calculation. And a lower
index is moved if current similarity is bigger than a maximum similarity
calculated in previous iterations. In a result lower and upper indexes
point to a substring that has a maxumim similarity value.

Changes
-------
Version was increased to 1.3.

Added some functions into trgm_op.c to calculate substring similarity.

Made some fixes into trgm_gin.c in gin_extract_query_trgm,
gin_trgm_consistent and gin_trgm_triconsistent functions to add GIN
index supporing for <% operator.

Made some fixes into trgm_gist.c in gtrgm_consistent and gtrgm_distance
functions to add GIST index support for <% operator.

Added pg_substring_trgm test.

Tests
-----
I have done tests to show performance of the new operator. Tests have
been done using a table that contains 10254520 records. This table
contains texts that have trigram count between 2 and 121. 214 queries
were done to this table using GIN and GIST indexes and same queries were
done without indexes.

Two graphs ("GIN - index time.png" and "GIST - index time.png") show the
dependence of the actual time of bitmap index scan from the trigram
count of a searched text.
Third graph (Sequential scan.png) shows the dependence of the actual
time of sequential scan from the trigram count of a searched text.

Until now I have not done tests to show performance of the search in
large texts. I can do it if it is interesting.

Alexander Korotkov <a(dot)korotkov(at)postgrespro(dot)ru> is co-author
of the patch. Thank you for review and for help.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

GIN - index time.pngimage/png; name="GIN - index time.png"Download
GIST - index time.pngimage/png; name="GIST - index time.png"Download
�PNG


IHDR X�v�psBIT|d�	pHYsaa�?�i IDATx���{\�e����pE���f�&����iZb�Q���[`S[j��.V��6��������o�tS���Dm1[�����
�g��7��� 0������t��������\��j�""""""���i9��������(�Q"""""".�DDDDDD\F��������q """""�2
@DDDDD�e��������(�Q"""""".�DDDDDD\F��������q """""�2
@DDDDD�e��������(�Q"""""".�DDDDDD\F��������q """""�2
@DDDDD�e��������(�Q"""""".�DDDDDD\F��������q """""�2
@DDDDD�e��������(�Q"""""".�DDDDDD\F��������������=�#F��S'�������c��<�?��|��7v��������3���v�Z~�����kW|}}i��]�ve��<��#,\��vmBB�]{����""�ty5vDD�����g����:u�����|��������W_e���t���a;&��n��w���G�;VRR��}���o���g����7����c2�j}���4. ""-�k���SO=e����`���0�6m�PXX����Y�z5EEE�naa!�'O��_~���y�����q��1�l��7�|c@��7��w���}������g�9@����0a��sbcck��ED��(i��o�NRR�m?,,��K�S��3g���G��U�j;##���L&���[:w�lw��b!##��?b�F�aw���smH��]y��'/����H���l��9������~�m�����?>� !!!���b����j%33��5^^^2�v��fM# ""-���+m�L|||����o_L&V��1c�p�e�q�u���!C���k��y""�<hDD���o��������U]���g����v���y��G��������_$%%Cdd$�����i6����|���k�����s�7o������c���l���v��fK��H��K�ggg��		���+�����}����	��m�v�����''N��K.�]c�X�7o^�^���4;
@DDZ�a���������>����SO=�SO=E``�E?�k���}����;���l:u�d;���s����H��DD��4i�����Gy���7�K�6l������3��������m�]�v��Li��
��H��W/^x��}�Y8���^K\\�������={����_��O�8�K/�����g���@��9}�4��/g��=�k�����5��H��DD��{���i��5IIIQZZ����Y�|y�kM&���H:�Z��_�����;�n���<��Cu""�������n�����	 ""�_|����72|�p	

b��1����a{s���g�������{w��y�b[���IHH ,,�V�Z��U��5��\�I�&�k�.��yL��������.]�0t�P�M��w�}��o�Y�~��Tm����XV�\���>�
7��W\A�6m����}���x�����[�\�//���U�]���DD��2Y+*D���>����������{�����[�s�N�����i���};111DGG���Os���O���#G��y3�����^z�%�O��3�<��7�Lff&��M�������]W\\�5�\�����5k���g��y,_����t���BDDDD�)p�$//���Hj\�����5�|�
999�n����\���y��'�5k��K�.$$$�}����/3m�4�l���W^	���4i���c�������OZ�n�w�}�P/[DDDD�Is�)X)))�>}�)S�8��b��l�2��c>�X*r���,^��v,--���b��HLL�j��d�������gO[������q����d�����EDDDD��
@���[BBB����o��x{{��C}�QN�8��q��WW��w�������g��e����:v�Hhh([�n���e��6�kEDDDDZ�
@���8u��������{X�r%��������[cZ@ppp������Z�9r�v���/�����

��F1/gmV~�����HK�������QTT��3HJJ��}||�<y2�V������{)""""���m���;1b����bW�6mb��Q�1bQUaa!&���� [{���U\
���k�����������_9"""""M�%�\�%�\���h��6���/�����7�L���~���j���G��������t��������;p������������6�k+��?111����^�����4�N�:����+�#�
@����o����N�>}l�+*�0OOOF����~Jrr��2�_}�O=������8���HMM�@RSS1�L������q�L�0���L�������_���;:�������o.�-�+0y�d^����F����:�'��=����:�'��=�N���m��1n�8�������6>|8��v�?�<eee0��������Q�F1p�@f�����^�m��fW��}��vHPP��M����#88��n�����3s�Lz�!z��i�v�����?��c�2k�,���X�`;v� ==��}���+�����7��j�����*��T���:�'��~T���:�'��=�����`����f������;�r�-����<���,Z��vMdd$_�5����u�]$&&a[���g�}��_�E�1b�����3�<���������a���:��{���Gs��A������z��v���mG@���x���y���k�.::�/�����|���x����{]���IMM��6EDDDDZ
���E�4y��sOcw���{R���������Q������T��D���j�Z�b��q#���g��
J�i��y��iDDDDDD\�������;8q�DcwC�(00������������)i�v��ADDDcwC.Rvv��iq�4C#���<UTP������D
@�1UL��FI�"""""�2
@DDDDD�e��������(�Q"""""".�DDDDDD\F�4[.�w����O>��#��������G�PDDDD�R"��g�}����O����0a����7����W�v��I��/4BOEDDD�2"�f��7�$""�5k����AII	W^y%,��[o�]�x�b-Z��U����k�����h�E((( qb"Q��I��('&RPP�l��g��������W������hrssm�9r�	&��C1d��z{�������F@�\~~>�#c���7&����X��ui�kv�����6m���,�7o&""�v��O>����g��������H�����2s�\����~)���!iFR�|��~�;���8p III���������>
��+x���Y�`�����L�x
@�\��L���d�����y��~;����8q�P\\�?��n��VN�<��?��w���Q����O���'^^^\~����o��>����H�)qs,�F"��(?�L�w����e�N�<����?���^�y�N�>���s��q#c���O�>|����z����w����?��~������S�����8
���7��U��������

����=m�����������C��b�
����p�-�4h_DDDD�:������1���������y����2r�H���>�m�Fdd���}��e���
�qN��K��L�M=`/PV~��=6� yFr�~^e3f��������[v�������L�������HCR�����X����z��"bE��{���P�K�6��*l���W^y��_~�.]�e�GEE�u�Vv����c�X�z5QQQ
���r@Z���0�����>�������k[��������r��7r�w���_r��q�~�i��ODDDD���4{�f�b������T;��O>��Z�n����)**�o�qqq��S��4{�=��=������~;��~�{$""""�hDDDDDD\F��������q """""�2
@DDDDD�e��������(�Q"""""".�DDDDD����'&50����D
�"qb"��5�#UB�&)??���������)�;�f�Ulfu�j���#,,���)��i����bR {F�
)���!iFRcwQ�@����H��6en��.#��O�7�;���fGS�DDDDZ��M7&�������&�o]3�(�>��}�����hDDDD���Mm��O
������4��M^x��7C�R���������4;
@�Y���������v��
rss/�8������������DJKK2d����~�x����"""
�6�iI���%)MjjSL��W�o��{[������(l�f�d2]�������0b�~��g�L���/�\�����u����������%""�lS��V4��M�3�Y��r�3�W�e@�������F�����J6m����#9t����:�?����<x��{'""R?lS��V4��Maaa�K[G��$2�3�`�/b������$�T�����.i0��C��_�gk�4����U�VOII	~�!w�}wcwIDD�A���!k_�1�i�����ao����{��k�nH=R�����l��G7���������q����c����x����GDD�����4�|nj�^Mm���DZ4������y��Wh��=��9���;�}���|��W�=���t�����*""Ro4�I�i�f��
��E�.(�x���7�L�y��
@DD����&i,Z�WZ���8��o�y�6|������U�)--����n������4k
@�E3�L����<�����������]�v5v�DDDD��i�L&�����'�d��=<���EDDD������={6S�N%//�n��-[�4v�DDDLAA��E��H�F�81��������9%��������

m���g/��L�:��C��b��NLi.����KN��	�*zd�e�:n5���i%,i0
@�������yV������L&,����v��6�z��g��'���o$--��]��{��j�*�m�����o���DDD��


��t7WYNw���t���b�V:�\
9��4#I+dI�Q"���d��>�v�j�b2�x��7����d2a2����8���{���y��G����Y�l�_������}������K�u$#ss�q=T���2�3]�2��Q"�RYY�_�lU���v�������sV|PDD�1�u$���V��@�(8�����x�q^��(iM������_P��/���q������������"
D�DDDD�8gS�XH�F2b����/�V�������<��HC�2�""""M��T�������Y
xR����������!b)�dl������3�]���R""""��en��.��(�4�GS`��E@�q��d����.m	�	�
x������*	�	Z�W��`����4q����#��`%p���R1���|$#,,LK�J�P""""��Y0�ZU���,�A�������Xz&u@|HNs^D�1)q�.E�BYI�1�*�\}��\h���k���?"C�����u-��<�<��V������0��J����"""�


H��H��("F50������=���L�+���3����70c�����e��-?/�L�m���_�����'3��(���>|8���1f��U����K��=����{��<���X,������'!!���0Z�jEll,�V�j��*""�����s]�u���uS�7g�5<���T����NA�m�)0�=��nl�(���q���������<	�����������mR���_�������������};C��b��������������_��C���z����<y2w�u+V�`��	���f���v�3l�0���+����g�}F������o�u��iI������
��SU��]�8-��b���i�]��������pbb��O9}�t���Y�l�[�������3{�lf������y��y���y��<x0%%%L�6���'s��W������[��n�:��!C���III|��w
��EDDZ����F�������d��~���:�k�3�Y�����_nW��q�������ba��e�3�|t����C��x�b����4���ILL�k#11����%Kl�/^L��=m����'���#33������K�rN�d���hESuP�@q'n�L�8ooo��mK\\k����������������}�{�f����={�-[���W��cGBCC�����w[�lq�&`w����\<�h��`����3�����7C�R���V�:�p��CE���k�������f+��O��4;n��k����'��;����_��o�w�^���+cZ@ppp������Z�9r�v���/�����

��PXX�������q��Y�N����_N�v�:t(6lpxmzz:,_��������V�W	��u����H�p���}���o_�������;���7S�L���on��Icz���y������;������?6l��m��K.�]w��)~�a���n���F������-G�m6�b-�rQ9�"R�v���m�r����������bBBBc�����BL&AAA���P\\LQQ��k+����Y���uN�8����#'����&11�E�1{�l���[N�8�����{��g9u�s��i�n��H-��V��"bE��{��hE}�9i,n;r>&��=z����?�P���?�Hxx8>>>���~��nU�p��a���*����{;m����I�&��m[�cc��������R������>��C�.]�o~��}�]


8s����a�=

%77�vl�����?���
0�8q��G�6H�""-���7�����s���������_���n�,�2��9H��$fN�I�6m��nh��E|��'v��;�H�q-*9r�K�.�_�~��b��Q|���$''�V��������������������v^SSS1�L������q�L�0���L�������_���;���y����|```�_|�f�.\��Laa!^^^6�{��0�!`�����w�`��]>|��.3~����2r�H�����k`` ���k��ED�}<1�	R�S�4�Oe��_�T�`6�1��v�6n�H����G��m������/����h�����c���
|����f�����^�m����O?��3g�>}:����@����6m�=�����t�M�_���3g��C��gO�����g����;�Y�f����c���.}*?������w��y��og���|��G�����Dll,��{/c��%44�v��d�����7�����\v�e����&00����0�N����Q��DD�y+(( iF��3�`�/b���<#�N��luN��mRQ$�lTe�C��FcuS�f��������];�����}���1c�X����j�n���:|�pk�V��m����y������a�s���FFFZ}}}���u���9�j�X�]w��A�<`
		����[ccc�+W����6l��
6��u�%&Z�aaV+�����N�y������W_�FGG[M&��d2Y���k��_�b��������b�3�<c�����M�6�!C���^l������m}����eee�?��O��;Z���������Y����^�??i><h�����X��b%x��}k������Z�aeFy{�`5�}S�����D����m���!��#���h��S
��n��YM&�588���s�Y�m�v�m���X���g2d��j�Z_{�5��d���9����n2d�500�z����z� ]� IDAT~q�����		�������X&$���^����	#����+���L��+�W�qD��_��
VK6p T�������y�9r�%K��x�bv��uQm&''�}�vRRR��_������>}:��
��>���S��?���/""�+ss&t�qU����k�)Ue�X
@Z�w���n��c��9 
�����?�������SRR���S��������7����Z��}�v^x�f��I�=8~�8����[��K/%44�����}1""R/��2�,`�q��Q~���ZUv����y�]��'�$���y�_~9��Mc��m|���<����������;3b�RSS9~�x��������r�UW��?���\qq����3g��u�����������H-N%���do����O�Z��uq��4���8��^V~��T�]��q������+����+V0n�8���;��O�HNv�����sY�~=���.&�	�6m���sg���JKK���o8y�$QQQ.yM""�EC�<���)3���/6�@�((�4�R���C���:���l���:�il���KUTe��f+?����k�����|H�����J��������>|8o��&K�.��?���vx��]��:u*S�L�w��v����������_OLL~�!���L�8�/ED�Y���g���}�nc�XPYyY|}��d~�Y��������5�*m��[���2���]�v�2��3�Y��r�3���e@�t�4M���M# �����;v,K�,a���y��������>}z�s�=�/��{�������G������&�J�q#���O
���������n��Z�i�p���������+��R���XA��^�.%RN# �"xx8���Wlp���L�:�!�$"���N��1��e�2F�����f����n�6���MG�vyU��1��bTL�������H��)9c�<8Zr���|-�F3���h4#�oY���Q��|�
Z�V�I�,��R���N�mX�Zk��n�p4���h�m����s+��^�L�H��3��;[��i�������^p29T�p4�j��������Id�gb��^���!9-Yy"M�������������u��>�������!F�����hEH|	e�e���
������$�V�m>�����W�R��H��DDD��82�8������Z-o{>s�2������f�L�A��f��{S������HFg�K�j4C��)q#5��X4b'G�4F$��G$���5k`�@x����F��L#Xh�*����V��S������5.�����DDD������d��:	]�qy���a�2((�#G`��BQ��drG�Y5���"�4��|�FV���m��1�������i�Tj�j��m��(���X��@[�y��]��>�~#!ueK&�Z%?�k���i�����4���L����u�V���e���(��<�S�2�>�����[��j@PX�iWG��GX��_W�d��f��hLs���"���������Q��3EN�L��RT�o�����
S�,���]��<�@�(��xy�\(+)��w�UHM���^���<?�7A��"-��fl��m�������<5�rx�
����Gr�#s������.x��q���M>�J`X��{�UP������d��	�������D/(�\D�S�0n��F��\��?Gq5%���Zk�1/��2�2#���
�<����Frf�1��6w����C������Z
�- �Pxx8����8q���"uHxxxcwCD\$ss�����(�q���l����eF>�����@~�r#��+���w��U�CN��Pr[I��������fJ^ED��W���y{���i��l_�1��0[��v��<�6f��J{��\�y�������ZO�- """
��W��>�MIn�1RG��6t#�K�+Eu����+wCH��vcH���oo/�:��S#O����8��""�A���H���p2����C��c*V�r����N����q��s/�;&B�O��9����[k��%�K��=�1HR�@�/�m"""��l�0��6*�"�CN@D��v���4�"�oYG��gdW
"2�(�1��j�E�4G�����/�[�T0��R"""����a���Y�q-'������3Ns/�R��6��4�D�^�m$�W	�T4PD���FdKPw4*ov�{Q�"��`��Y�1������Z����"R�����4��z��:�8O�Em���o�dN�"��<�"""����R�b����������*F%��7��b�$�7�^��s4�^%�7A�E�e4"""���W���soJn��\��Q��IAA�1�ks�)X34KD���Z��C��C�}�hr�b��b*5��c��"���+��^��
��ib��Vk�DD���T����7�����P_
]�����c�y8�����[�\��`7M��p)���t9`��R�����)�co�^J��:<G<F�G�"�B�O�6�\�yu��9���\~^D�hDDD��/�����~�J��XW���fX�Vi0��z��M�k_��ib�x�t9`�������:_.& �.#�c�u�q�X�?���Hc�4�M��5~�?[�BG����Hm(�@��K��e�,��7Y��s�@� (-\J��W4��M1}c`���Md���� """��C���vx�������{��h"���g$�cS��0Q����������DDD��>��T	$B2h�� �lx�!�g���'�;HBo"������"bE��{�H�������'""�LT|HO������8]���V�����&�g����4#!E��/���:��S�N����mB��j*R("R_�����j������_q�r�N6|��x^�W�P^P�oI��5n9�9�c�A�G�T;i�����[����u
\jA�9�L�������4
@DD�-�����.5��&���ED��((( qb"Q��I��('&RPPP���~��\e�%���������;PS���~F�"""u�i�{����F�*�������~-��i���i��0
@DD����W�):7��$��.�5��5N�r����'����*��6St�������������;\DD��(��i���so�-�G�X�0`���?2������)�W��%gKH-N���Q���'����.j�7GD��P""".SSbx��%��#�aW�.����0,���#NV9����(�s�������gu8��'�������_��I""nN����L��L#������1�����# ��_%��8Nz�4��:rB
�m��fh��f�"�0?
GAi{8y)�o����+�#$VB����q
@DD�e�-�pHM�C����t�< ��`�jp�
����Y^f�9�U�g�+�����E(d`l��<�p0��Wy��
b����-q;
@DD��m������&�@.VO+�R];v����1p�.#�c{�.�������J�^�.���T�8�������a�rU1��k���o�����F>����������4��=������+7�[�����."�)�z�u�V���e���U���3o'|
U�����ys��}�������lk���Y��1�<�7��k��^��b�o���:E����1�R�m���N�U����5
U�PD�9R""����7����7�G	�w��^�`��Y��.����v'&��/�����0r6
�/��� 8
!�C���1�1��� (�97�+�LX{�U��H�%��r�aw�DD���o��.��s�%�W-8�_'S	X��mpL^&��J��������S}zV�7%�J���2r9<��7������V�z���M�*+?�@M�x�H����,1�����y""�H��HV�o�k
\���;*8�'����s@��������XX���O�iQE���#���FG�BL��j����!k_��)]y���*�xU����K��
-X�4*"�~����`u�f����2*��b
p;N��C��>]�BX��iQ��[�pt�Y��mD��������m��#5^x�K������i!<�""�x���|QI��E��H�F�81�������(�4�KR�eo�a�ux�1��<c����/�l$}{�=���<�=u�F�#	�	�J�E��z��"�7��2�{^%��hz�Z�=P)�p��@"�o�����!b)�dl��5�����#}�""������	���RI��b�����g��Q��Q�rF�x�q�bt!��0'��G��:�����=��[�:8YC QS��,�+"�iDD������PZZ
�@[��~m����+0��|����%�w��������z�spWl�o����N5��p��g$�cS�VIY�������D]FiDD��F@DDZ�����F�q
�x;����z�!`7���������.�����}%�{��*��n��T_��)�)>9��e��2�""������`5}�N�H�8���00���!��QT�A����ul���+�c�jW�{x�+��M�	���DD��s��:�_�F�xa8��~2�]H�M��H@���d��/����h��ZW��E���8�Ey�Qu�Y�1���jyMlS�F�a��������we��;fw��"��H��$tq�����g������Jk�dM���*�WF�q)����>K1���3�"��H��q�d5a�g����r@(��g��gS��F��(���4/i��m�Fxt8��|����N��G�����Gy�x��Z���~��(��*�""��hDD�	*((0V���dlg����xns#�������fc�+�3<���=x��&���S����"�Pe\DD��6ib����KN��Z'c;
4zG�������kvWko����l1r-�V8���83�t3��83�3�J3t�h��]��Ve<�qmgU�ED�y1Y�VkcwB7n���l����������4��������U�5��u�Ca�t�h� 
�p`�T��=�7�wJ��k��tnG�;�-�KF��O�s���]�g��<�H]V�*((������w����hSD������kQ9 )))xxxX����>|8���1f�v������s���gO������;�?�<K������$$$F�V����e��U���D��dn�4>��10g���\~��)3��/�\��pX\	�J�C�����`W�e�l^O�����@�����.b�*���{�"�^��H�MP�!"�FZ����<���?��S'�?nwn���2���h>��c��9����������y3����k_z�%�O��3�<��7�Lff&��M#//���~�v]qq1��
������3����3o�<���HOOg���.{�"������o�����������-��T��t��b�x�x/������u�f#�i}
�
;�>`�B�N�S���u��@��>H�<]�3u^�JU�ED�_�	@y��J�v�X�h�����������e�h��5���'<<���g3k�,>��/���?��/�����)))a��iL�<�+�������l���u��1`��B�>}HJJ����s�K�f����h5��w�^R�N������������@3��.#�c�u��+�~x�o=0F@����\c���DD��1k����^�����S5��b��l�2��c>�v����CY�x��XZZ���$&&�������je��%�c�/�g��������q�����������e�����?�`�7�����P2��a�>�m����K���S�*�qn����gUZy
_'���<H��U""R�@<�����5k�:U_22''���"����j�z�����;9{���e����:v�Hhh([�n���e��6�kED*�������K��'h���?�1�iI�t��Hc�$�8�K�`" �z-�3�q�3�~{���x3D,����m��8���}��9
\��b���8��_QM�8�^�z��#�8<��a������j�r��:t��������������AAA��
��Y��""U�?�~�����������������F�a5�g
x2jv�1�2�>_#Wr��0�|n���pi�����Jo�r_���x���{��J9 ��������d�c""���u�h�"�-[���������������Ca8�alo����������k0����qw��g^F��*AF��=X�KI��Lfz�z��9t���M��	X������
>[����F���W��L6��M 9�nu@DD�ep�����L�4���:p��Q�t�c�����EHH`�XTUXX��d"((������)**�������^{�m?$$�i��ED����t��+�K/��8�
cT��V���a�Rme*��x>�|����`���Saaa����i_�b������ �"??���g3{��j����������?����~���5?��#�������r:~��bb��o>p������������6�k��4im���;6f������^������GA�-G�Z����]G���'�s������'����k����-.i�7���0�:�u��3�Z�y_�����E���'��;v�X#��}�mr�%���W_a2�[��j�2k�,������

����Q�F�������l[	+77�������z�v\\~~~���� ����L&���m����&L�@ff��Z��������~E����}��y��)����NId	����Fb�@��!�����/�M�j^�xaI���_���:���3�m��a����# 34]JD�����l�;VQ	]��m___n���j��{�=<==�
��9�k����n����~�V��}��vHPP��M����#88��n�����3s�Lz�!z��i�v�����?��c�2k�,���X�`;v� ==�a_��4F�D���5}����[Y�o����\9t$:tpX�0; ���(�X7 :e��p|�q��d��Y�ZU�ED���6q�d2���DFF���_3e����.���6l�g�������������={6�\r	�<�S�N�������+W����c�=�������_|��_}��Ni|������%�_N���5}���w�p��Z��'��+S���}��%NL${_��T�	0������C��$�r������U+�I�����a��`��������:���^H�Mp���������II�7�x:s.p�x�paE���|���h3��{�u�j��\}^�x-nDD��9�]�-��>*>�����M[��Mg+S�8�2n5KV_Rw��>���;�Z�,
�����8�DD�"���3`�v{�6
Vk�����q������~���S����t��y�����QdY����t��2��?""�B��DDD�y|���>��(��*m��)���WW��o���tQ����9��R1�Ril��@���U���9W	=b)�dl���W~^DD�E�����EX�r9�6T�fE
�l��Wz�o����(h:~<�Y�����<c�����g$�:n59�T�����i�������F@DD.��3'�	GA��!��'0�!�:������ldg���k~�^`�|u�Jm�0�*,,�ui�H�M�Wz/"VD�+�	�	Z�WDD\N# ""�cD�H7���dl�t3�yaf8����+�����bY�FS�HHMb����/��R��+k9�N�,�]DD�����\�R�����|`l�>����	�4�it����/��r�1���0cVM4�JDD�; ""��R�&�	�>+���m����7���
�jl+d��|���Q����TI3������Cr����"""M�i�j������i��v�^�1�a:k��FA�;�6]j����
��{~U�N%""����E�-�81����� IDAT��QD�$j`���m�W~��8Lv6|����_�-������e���#pX��2�k��I���qwM:���%--���7vWD����'��R�S��)������E��T���jv���RK��v������s��jo�<��nlz��#w����A��T�\DD���L��:u*�O����^ ==��n���g���];V�^MTTT#�RD����~����6F(*x��2�2���P��g�{9�rx���������QTRd�|,�R�cI��\^x%���
������*=O�ED�k2# �~�)W^y�m��i������s�e����/6b�D�9I�:�}X��/m7�9���|�I�Q��T���5�S9�X�D-������#�U ���|����Gxx8�b���,_����8���y��'��"�\�.:
��8��%=�����`l��D����6�[l�Y%7���#EAF�QQ�o?p3�JW�%P�elnS�	kI���<�Z2WDDZ�&3b�Z)+3��\�f
�p�
t���C�5f�D�����0`�8�}��e���Q�Aq�cL�:�����c�[�������2���x��2��\AM \��2��tO/#����0Wt:�
�""�b5��{��,]������111��������� g�&DD�0a$�[��Z���m��f����t
��J"�����	|<}H�M�W��D�M��WI�M�{����<5���6���w��Q�����3�$$ 	�=9h�"�(�`���`�O�%t��`YZ�AE1PEO�Q�������
< r���R� �����"��&���d�I&Q.�L����k�/��wg�����y~�P4�z������w(��kV� ?���Y�p!QQQ���;��g?s�������."�^&�:��0�����z%�.�3��6XL���9���dm�u���un��N����y}����P����%�����d	>��=GDDDZ���y��G���d����z��L�2�}������'?���D�9q9]�qG}U@����������fv������m�q�i^�v-��3f?�?�����l�M0c�~F�}���y4��==M��ED$�Lp���s���78�x�b?�FD�-fV��u�v��������=>�t���K��A�szM����o����~�	6��7\N �TW�mI��["""/���f��|���D�c��7NL�r���.�r��h8a�03�QPv�������K��]�We�d��LHv�M6�i��<_
����J~���3x�`:v�HDD�m���������)�����z�oX?Rf�`��`(���0��L
���
�e��Y�6���5is
�C�%WX
��Gp�c�����F���@��qV �o1��7���5M�z����V}^DD$������IOOg���u�]���x��X[!"���fl.l����[��8�AL���������z�>�3��X-,-[
�����`�	.{�S��,3no�A�F���gm���M���EDDX� o���f����^��PD�hj)����b��2�D�`�[&\�����!w���/ �a��'�~!v��6�yV�����\��$�i"��a�-�[�)bU�y�0K�.\���Q��:PD�S�K�ZI��hu��f��������t��A�1��7�>\l�E��2[��eO�@��&��	������H�
�d��Q�����0D��hr)�Yj���H�
1�U��mY� o`�������������25t*����Y����\��$�i"�HOK'��8���^/����HO��eEDD��������~��1cg���DEE5���1�65��"M�I[�)U������T���3��v��\���V�H7j���h�����	��o��>}���������78o�X������D$%H���f�Q���d���S:|�\�����2�=]I q9eEDDE� �<�����������
���7�K}4�mS�w o�l�����'�����MT�r�Vru�7���������	��L�z�j�����O>����H�h�Y��m�Y���W�� �nHe���
��\`3p���5���1[�����Y�S���P�r��&��l8�����Qj�F�%S���7:��my��'(���T���r9.g�������""r-
�d���|���9��C���;�t4�����D��0�v4^��[��2#��g�B/�J�^n�A��,`�x��Ayy9����Z�J3$"�����Lxp��rq��TZ�����W��C�&s!�)-/�@p8�CEG���x�A�����w�����s9���f�"""-Y� 53.d���
��
�H`��?F�9�izpT�;=q�����k�����k���9���(,(�������&B2��x��)�:(���S����.�-Q�r�F����,Y��!��H~(�1�N�g����`f<��*��1Vg@�x����p"��Q��s!��v �S?������s,-[zIA�/s9��{c�R�r�fL2u�TAD�@��\,,<E7Af��������D|���%�����c���`�@���z/�skW��|��Wj�j'x_n.��,�i������� ���8{�����I��<���U���p*���{��Bk
����u
�0����P��lWe��`��K���\��%_SC��wc_zm�E��}�:U%xED��03 "��Y*-&Xh�v�J�_	Dg;S�{��o_�l�E���k
����x���$�C�EDD<iDD�����p�QG�Zn�3��iVP;1R#xBBC��3=-���� �Ppf���A���0�������|���&x'H0���r9DDD.��*���a%ff"6��|�f��2��~+�=3�4��k���5������jL@���	x��1���z�t���#������\�4�r���|[Z�%r����M��{�����(>"&A}'T�6�����,_���~���n`g�FBU�������KS.�|����4�D�t�}-����b�Eh
�L���3����PY}�2���������a��=f��{��&���q�%��)���:�E�u�V:w�L�^��=�������3g��UX�A��3�d�C�.��1yUu|
��<�4�
u�Y5H�f��T���.�"""�Y��>��}��������{8"�^��,�$�[	��������l).��#�Vs��/YZ��[��������o��������<�{�1��ZU�k�:c��CUE��q6�]�*���@�a�Mv�����Hk���3g���g����|����z/�)"��{� �����P1���Ro��F������z�Ve@h�y������vT8��/�w!]����|�2���H�jHZZ���_���"�B�g�-_:�C���/p6J��;�h:}7��A{ �������Kui�������m��!�4{����/y4�����|�����<&�i�ky_�\|&�]�r)ui�nd���|��G��s�KVV=z��c����H�����G#?"��r��:`��W��@��X���>������7�:`1�AM�s5]�K���w4�)��zv�2���H�0����0a�7o�b1�~}��G�������5111,X����i\.����&?���'�r���sW����� �n.��q�& �{��0AJ�B��XTc��S�%X�g�f����X����b����Q�����8:��e��Y�|/�k5+��.��W�j�������X/������X/�c8f%	��e��6	�����|��	�d�����7����j���\ll,���~�H��d�����g�g2�F��s�L�G�R�1�p�{�����Z{0�������N����EDD��&)((��o�z�j�����U�d^+	�$BU����f?�(L��?V�����/b��=+d����U��7��k���������{�r�u��xD"-����9�'�]C	�	!�k(��8���"2!��\P��wa��������tF_	�03�l�0����`�5vRDDDZ��	@&M�������k�;	 ''�����L�<���i�����Mw����G)��
G�?+��SE���1%u'8�]uH�3f����h����A�Bm^��[��g��������_����#"""~0U������M�HHH���L�6��G���wo�z�)?�P��I~(��I6_x��T�??����1�EM�<�����n���(�59 ��f?��������U`���,n��L�?Z���^��.�>������L��m[�o����Y�v-qqq�����3���c���!�4;�'s�������'`5��AJ<��-����'6l$H������Y+��kLp�������|�q���=�X��jn��&����O.���X�����@DDDN� ���<��S���J*�0�E7���QtD!��~���y������"��`wj��M���t�����L�� L����:t���f#���\N����8�T{���������Q�*7�{0�u�5"ZE���N������Ri!�s,����>}�x������g������GjZ�:����\#*������e��������}��ra�X��%"�[��8^7/��?��+�4�����B�a�<�`��m������H4y�r��c��_^��%�#kw�����H��n��Q�EDD��������'��n�GTT������D��������{�%�q�zp������t?P�����8c���<�V7",���3��?\x��p��i|x����*���t75��.`�W^y������?�����R�R����1��pK_\�lJ
|���3y���r�� �$�S�~����&�����?��n�������`�VU��kB��),,��T�!r�����4��eK90�GF��]XZ��Ov}B��h��$�������A7x��T�n���Q���S�SPPp�cL�`��xk|x������\���C�����|�����PDRc����d��m���W��C���!	pX0U��U�96��|\�XX�"�Z�@k��%�����������A��9��,����W��f!`����w�{��t���1c���!����|n��Vr�9�nu q`�l'm�c`Q����P	'2��._��>e���ua�����������>����$7&\^���ng��&�
�
��t@�N%}}�e-���)`�^�z1b�&N���j%<<�]��f���_�{�"~1s�Lr�������:3����(K4��mY"�K�B���#v�Y�3�3�|Ut�h�}v�r��v�J����H� O>�$�/f�����7�Q,������6���4N�;3aolm���3a �>
�O]��PT/��D����['�-�pN	�"""re����o�Ijj*/�����"pJ�KL�J/I�Q�s;�|��[y�d��!X�	A�f�$(B3�+���t=����F��]������p�TTT0z�hC$0a�>��>Piv�����lX�V@'/���`�[]��p9����v���EDD�e
�2��G���O>�j���{7c�������'::��C����o7�v��]�u�]DDD��I�8v������ >>�V�Zq���3o�<���k�����:u*v����[3t�P6o�|��O�-a�a&i0�G�m����U\��k
D6�Alkl������f��������{���K���H�0��9sx������~���G)**j���(..&66��^z�u�����o��Gz�!^|�E�u�b���8�N�/_��%K8r���~;�O�����/��c�=������a��Og�����1�����2F���-[X�p!�W��S�N$%%�u����!�5k��1�����K�d$;����Xn�u!��NpxB�5�v��G+?bj������^z�wc_��N%66��Do�g]A�������r��������t,d�X������2�����/���������';;�6m����K��=y����9)���t����S���?��}��^z�g�}�}����O^}�U}�Qv������
@ee%7�|3m��it�g��]4��;w2p��+~Wi9


H�@���Ug��@1��!�D��r���
U�	��=�,�$/$��|/��GU�6e5(��oX?�:`���W�*���/�����@DD$@������9s�4y�jU����&?��V��t�v�Z�N��>bcc1b+W�t ��������������0{�lV�Z�@V�\I||�;�

b��)<��3�<y�.]�\������f��i�d}����F���o1M�R�R�����3}�����y-���A3g��/K��1��	8~��I������"""r�&IKK�N��r�������3,_��>������Mii)7����O������)//'$$�}�������sg:t��������ow�y��{���_�4�����1CMW�Q�6<q�mI�X�l
'>���Bx�g0�k��F��k�������Xsr��u��5���k9�
fT��\DDD�T� ��Gy�?��O���X�`�<�`�UDEE5�\TT.��3g���S'
	

%,,�������{5z����kS�,����������PZRj��,}�.����o�\����D(�H��5K?<��O��c������{���Y!��d��0������Y��	N �sq��TZ�����W�k����\� o��&c��%::�7�x��Y���?��g��=��~���|V�^�/�KJKK�5k��[�5����O2��	d�{�A ��#0	X�E�Mo��H8�=�}�a��D���&5-�{�q����X�-�UG~~>���'{`�	^�gb��8��)�
vDDDD�
� S�N��O>!::�An�7�����@RR�=�?��O����Za�����Bdd$`rG���(--�U�V
�<x�{?::��{�������T+�^����{
$*���w��D|���%BpfF�~?�n��1��X���(w�C��K��J�~Uuy�zf��U;S�
�@6M;""""��_�/����]�������������/8p aaa��������{���'!!!�<�={���P��{��)
����������=�k�y��Gi�����I�&1y��o���O���:���E��^�Cao�>C�� � �
����5t>!c�	����	U!`-���P2����]{�������.�={��X����������1������3p�����}6��iiV�X�����q����O�i9���������K[�l!((���8l6�������#==����-[x��'��KJJ�U�V,]��#Y�t)����d���'2}�t�����:�N�-[�m��F�����+����n���+�4el��{���u���E\t^���������O&��������p~�ih��l�_��������}��
������d�S��{�����������
>�����<��������g����4����"dM^�|��~����r�Jn�����������{I�$?�0���c���t�����O�|�r������T�2��s�2x�`���SO=EII	s���c��Hdd$�>�,�=�QQQ�5�O?���s��������x����Mc��E�w�}������v^}�U>��s6n�x?%i�8M��=���N����p��t-���������D����D��14�Di\��^[��^������r���������""""�)`�I���PVV��\ii)999�t��C�������op��Y��i��X�l<������{��G1k�,&O���fc���,X��A��3�<CDD�W�� IDAT-b��t�����~���g{\��M�HMM���/^��[na��u�~�����K4/���c���| ����r�oyC xY0�*.�4nc%z���>��+P��?����M5���������5w���|x$����	����Jr����L���o@�,�&�m>hc����%����Va��6)��U�


�4����`GU�DD�Z��kW��3 o��K�.u�O�>��m�z\s��E���zm�'�/����d��0�*mf�l�l<�`�%Q�RM�[�a��������p�B�|�����X������W7��k�_�.PPP��?{�,�������r���3w�\_O�QY��L��Upd�Y.Ui�'8`P�%��
�����@�����DDDD�-� ��Og�������b�
��!�|+N��	�u�y��@P&E�^A�f�X*o��/�"""��T�Hs���-a�P����Ygy� ��Ew���EDDD�'`���])*��0a|%�����Wjw4�\�������������4GO�x�j�br>f��m.��n��We��Cf�9~$��&""""-�f@D.�.�O���p�pn�,��m���%�';L������5J�Hk6�����@��(I��L�W/�r�=A]��EDD��oB"��h68
w��'`��A>���P��#� .:�s�'�������\��"��f����X�1�����0�>��r&�X�����W��@�a�� ��8�����Z""""~���#F`�4������b��y�f�J�h���EGm��i�Q��CD�~����3>�,�
��N�"""r��k�r�<�"���f���s�	>�l���};��UDDD���k��G���"Mj�����=W�aTb������,-[� wd[�6v���Y�f)D�	LO��z��pb�ys\�����[�IMK��K��������UPP@III�����~�\��������l�M�A+P��-��s�������p��{��Y���R""""~P��~�+.\HQQ�;/�b����+++�<B����vv��a��l��$�c��q����H��A��	���x��B�����%"""�W�k��%���3g���r1{�l�y��w�N��=�������*(( eF
�����������)4���7�3���^����?t����s[�Nw/#"""�fd��E<�����5�����'2p�@f���������A����l�b������@���F}U���� ����=�a�A9�7����T�]��A����""""����9z�(C��j5C*// ,,���g������P�f�;��5�z���r��S���f����wpr��0��"V�������D���v�
���j�mt&l����~|c�
��f�QUU��j�m��?^[b(::�c_�j���e
z����)�{0.����p~������>��7AU���:r�y�*���`[������I�*��_�UDDD$��n��/����}�{��Ob��	X�V/^L�=�;@i�������bVN�'�$s0�Fe"�C���3������T����D`����y��}EDDD�Q3r�=����	�3�<��-[���$**�+V0k�,?�PZ$'����^U@P���"���3����x�\w�W0�Q��Q]�7��8���}��""""�#`f@��y�������}�v�y�,���c��~��TUU&1<����@ 73M��:� ����z�V��������M_��.�"""rM������TE�[UUU�
���u�������0��*��13!��6��)��By}��>|��!`�`�������n �^z^�	�����u��f;3���h�.�	�y����4&`f@���:w�����rM'�/���_������Lxp��f�*�%�c\�����@���,G8����Y3�=o��|���w��n�P�
8Q���^y""""�Lr��w68VXX����i�����"�����0b����{��#.K{��+�9�����{]&��&�81{c�`�����<�K0���K�/,,d��Q�;���%��d�����R��DH�dBx�2�a`�Z��Y	�pwB�5Y������<DDDD.Q���DGG���O2w�\E����Rf��oX?z�M�a�H��B��\3�@���;�����<�VgLe��PRi�y������ML���R�R}�~""""�]���4%::���lC\~~>C�%��l�{����f��]���R++p2�"�*��
V����]�G�T�Z�dm��������?R^^NFF�]w���"n��Y&������������4K��v�UP��
�}@0�[�\n"X��������%	��#F��^�(--���#��o�id�\d��23�f,��%U$;�~n�	>��De��:9 �L�;h)��R����GDDD���oP.���/@��m����x���:t��F&���Yf�m����k���	���V��`�>����=h�S���0�G}��!H3QPP@jZ*Y�=������0����
9Wz����MH��m�WE_y&y�cg��������CDDD��L2o�<]�vmp����,^��9s��adH�J4o�U���Y������q���s�9�����]��g��~�#5-U�>DDDD���	@���HJJ���8q���4 ��h^/�8�y"6Dpn��3"8w�9|��!���C���~��T���'`��\�p���`C@���t���B'5��������y�{���J�������_��������t'�����:t������-[F\\�?�(��Y�x��*-�^g,z�m>�-?D%uEDDD|�����+�7o�{�W��������X�d���%�t�i�h�N����U���i�`�v6�,�.���{~�J�������_�u=����7���^�u����qMhh(qqq����c�h�0��@������i�`�Z((�3g�~��?`rG���<���""""����k�������73h� """�9$	0�g2��oO��b����*:�]"x��S|]�0A�������l���l���	�'TRWDDD����@��}���W_y=w��a


|<"����z����or���V!=�l�L���;������w��i_[���|s#k>_[������ek�:����kC/�n������X�C%uEDDD|$`���1�����x���~������_�����#_s����}pFP����W������@��Wk������ 9�����_��������?���������������m��G$�2k�,�{d�E0������U�
2�9*z�mA|����w�`4����w/!""""^Lr��i:t���\������u�V�;`�L�_Q��?�
���-L4�y���R��lWe@w()/�������H]�t���={�x=�o�>���}<"����� ���.�	2w���mM�q��	�d��1��?���{?r������{������*\&�����g-�J�~u�zex-�^���2�6����0������4&`����y��]��7���#���;yyyl���:0w�\Q����R�R����'6l$H�b����j�u�m�6�AF�����^ ��
���c���""""P��[7>��S�����u���iv���z�y�����H���tuK6\�
�9�d�,�:{]�;Pd,<������|������Gm��\���?\��7��&����k^��WC2k�,���au����P	'2��0A��CPtd������!���T�����E���
kH%�����*��������H��>��������%Kx���)++����*�8�c8
�%����,��t�G��G�<�3����:,_�I4o�?��'`��y}��>�v&	���G���3���{w&L���u��4i���%W���S���������g�D�: �������`
�2��������������H������7�|�;���^�z���/s��I�x�	�?����gQ�����:�t��������`-7�g�!,��,�q��W/�]��������%XYYY���k���;�;w�����>���c3f���W�(4,�rK�I2��.�[V���f�cf���Cl�X@A����Hs�����������p���y��5j6���g��sh��TYL�+�DA���*�,���
��fulkl���j_WDDDD�� ���',,�y��1m�4��o����Y\S�
h�P�8�	oC��:��.W�K��������j�������������������������s��L�8�+VP^^��b��H�	�'x$�;���|��D�����	s���!�t���oc�+������w���O?e��il������t���Gy��C��l�4���l��=��r��)&���N���D�/$RQz�Y�a"C��PPP��w�+U�
�������'y��70`�����PXX��Q��(((�g����V!G���o���V\�.8�gBx��8<�����nUP�uz}P�H�-������}DDDD��DR#,,�)S��e�>��s�~�i.\�@jj*��7V�UU~~>C��p��NT:M%�Jg4G������
��^k ���t�J`[/8���n��;�_�$""""W(������x�����e��5�3��C�K4k�,�o�6���gR���;1y �����&`8�H��$;�
N�8"""""�����|��� �����c�=�DY��`������=�:c�W�]@HT<P�$B��PS� ��y�*��_[iD���H���	�����3�Pb���a�z������������Fnz$�d�""""r��W�r�


HMK%kwN����0 ���e����drWG�_	D6r�n��y��iDx�>�#uY*)3R</=-����������\> rE���:f����Y:UN�r�?vf��HS��:����@���z	VP���BD�&�N"k�g���[O2~�x�������w(	`
@����c�U��h�U%;p�sAwLH�sT���s<������/z���Rf��>����lL�^o����D��;�|Uof9J#�~H��Vj��?w�~oh����dmT�^�@�b��7m��O~�z��E������;����������v�����"""���H&M���c���������j������y���t6,������S����n���C��y��������i���zMs���L@������9������X���HOKo�y��D����H�k����������?��u����O~~>��v[�lq_w��!����d���,Y��#G�p���s��i�{����<��cL�<�
60}�t�����3<�+++c���l�����z�j:u�DRR[�n�����
��2!���GP��o�vv��������`���:����kC/�n�����M�q���5��D����H�k���^y�:v��q,))�n�����3b����CXXk���M�64��={�`�^~�e
y��x���y�����;�����g�����O�>���k����;vp���0|�pn��fRSS���O|�3�����s��0�;��yr��_��fG�H���=��%�k$H����9 5T�WDDD$������@����������t�v�Z&M��>bcc1b+W�t[�~=eee���x�3%%����U���V�\I||�;��Pq��)deeq�������f�Z�n1��#pj>*���������Y�%/����bo�����k��� ;;���Rn���������G�R^^��}�������3:t`����c���k��������C{L?�E��z����f?8	�U"�����z7�}�����;.y����������3fPRR������
 **���QQQ�\.��9C�N�(,,$44�����FFF��PTT��=�>�%(-/�@Y"TV�:Uv4�+�d�r��v�J�����4S���s�=����g~���r�-��{8-FaA!��A%�`P��o�����^k ���&;�;����"������l�D2w�\^|�E������������3cQ_QQ����H��eee���z���^5�6v���m�� ���,�{���w3&	X-~	���s��<��S����c��=
>�w�^z��IHH�;�c��=$$�VZ:u�����x���c���o������<����k�����I��<yr�����c'���A����(3'��6cLp�C����-���S+a���%�8{��?�/"""��+V����z+..��hZW6o�<��bq��3��k~���:u��:w�����_~�
		q=����cEEE���0�#�<����^z�e�Z]t�����X,����c�~������Xv���\;w�������C��x2\���.���b.~���C�x�?Q�\�W�k�������\���}-����_���<���$%%q�=�4��q�m�f�d����7���z������C��y��'��GFF������s���Q����O�;w.?������w_;m�4-Z�}����/���n��W_���?g��������/G��4������� :�c�2���Dg�&������/"""">�b��k�b�XX�~=����8g�X��4})z���G}��Y��<y26���#G�`����<�,Z����K�~�iwU�!!!l�����T~��_p��En����[�������������-i�d�f�V�}9"2#8�x�����,0
����a������X\.����c��]4��;w2p�������R�R����'6l$H ��T�OO�������h{����o����4;���Z i�3 �;M����~C�8����tFd+�����c""""�$ �����|~���i�};��%w�{X""""�'
@�'�,��DDDD$\����6
z�6[�K�D��i�`�Z8r�l�������R"
46��};�?�}�K�D<46�QPP@�u+A�B�l�TY�RP������|
@���Y���|�$
���;��qD���Uv'C��(�oMU����ap��	>�v�?k�,�o�� ��q}6����6�DDDDD�.����%K`�8���l�,���Y���t�>/""""�-hD�����,�\l�>/""""�-(���R�R����'6l$H'��{R6�5�oI�0��C�5��0�F8q�6_������N`��oA9 �K4����1p���Dl��<���\�q�������!����H3�����}P�a�p��@��]�:���������c���=|i&�������x����P��:p��*�+""""WLK����B	&�������f��P�_�������H��D+��Gl&���c��f�;��"""""W��V
�L�y�z����f��k�y�+� �Z��#��y�������������<�7rR�>DDDD�*Q"����Y�z}�����wJK������;HMKU���(7���^""""���,� """""�3
@DDDDD�g��������(�Q"""""">�DDDDDD|F��������� """""�3
@DDDDD�g��������(�Q"""""">�DDDDDD|F��������� """""�3
@DDDDD�g��������(�Q"""""">�DDDDDD|F��������� """""�3
@DDDDD�g��������(�Q""�9�� IDAT"""">�DDDDDD|F��������� """""�3
@DDDDD�g��������(�Q"""""">�DDDDDD|F��������� """""�3
@DDDDD�gZtr��yRSS=z4v������s�^�k�.���."""���d��I;v���������U�V\����7�������|�N���n�u��:���7_�wiNZtr��i/^LEE'N�b�4����C>������Y�d	G����o���������<��cL�<�
60}�t�����3<�+++c���l�����z�j:u�DRR[�n��^ZDDDD$���=��R�=8s����dddx�n��9����v�Z��i��A����',���_v���^�����^��;�����g�}��{�>}���k���~v������
��������IMM��O>�N�]DDDD$����\.���N���k�2i�$w���#X�r������)++#%%��)))�\.V�Z�>�r�J�����@PPS�L!++��'O^�Wi6���1������r�M758���=Jyy9���s��s��t�������������{������\+�������������p�\��BCC	kpmdd��^EEE����sEDDDD�%�|""""""�s� ������������Bdd�����2JKK�^[s��k�g�������\KZt�o#..���0��������{���'!!!���={���������Sr��7�������{��������];�c�&Mb�����f""""r%V�X�����q����O�i9���f�1~�x�{�=������rss��eO<������$Z�j���K=��K�b�XHNNv�8q"��O'++�}���d��e�v�mt����1���+8�j������\������8�k�.
���->Y�n.\���s��>�b�
��KXXs��e����7���z������C��=���H�����{TT�������o��J�,-1Im,M=��(�E��Z*&QZ������Y��U�:�E&������Q�`X!j
��2:�����f�=08���Z�%�����yt��3� --
=z4<��K���GE��}Mm~�a�^��'O�����7�x'O����;"""""!	�2��=z���@�)��/W�$"""@]6����}�����
#G����+��G�{�Z�
�W���S����D����]�vf���?��b����z�*�^x��s�l_�3������ ~^k�6���&|C�6~^k9���EDDDDD���������	9"""""r�6�
/5�~�P��T�AP2���q""""�6�	�)-EfA�b���]!"""���S�������a����0!"""""�aBDDDDD��������	9���:AA�[�9�'DDDD��1!�!�DDDD���EDDDDD��������S��*���@i�r�� N�""""�&aB���"��@�Zu�:QL@�n8rBDDDD�1!���	5�E�DDDDD�0L@�nJ��[TODDDDm������Q��5 �"z%�����cQg4���p�u���]#""""���
R\0^RX��PXl�����oDDDD����R�*W���b�ADDDD��=�"1
���[xFQ�����J]�xN�!"""j�����TC9����DDDDmr7(���-z�����$& �"����;d9�'DDDD�0����(�qQcL@�E�#"l��7\�\��h�YDDDDmrIG�7$""""����*���=zX�����,),��Q+���&��Gd���E��O�3@�	7y~Q+���"��Y�����U��Cyq;�^L@�)���TG@8�ADDD�61��	
RO��l�m	TNI���DDDD�
��@?t(PZ������%���T\,�`���P��p�����^�+aBuJKm������9�����H���P��t���f�Q!""""�cBv���Z��r[v�*qw�^�l�kNlJ&l"""""EL@��rT�l��p��*&DDDD.�	9M�GG5�������	9���`�M���n-���p]��cBNS
���2'�W�8j4
��8�������1�:�(�r]�������[���j}T�v�Hsq$�����6L@l���v��O��
{�Q�62"�LXKZ�����irI����!�h��%K ���2[��2#4DDDD��	����Y�T.���Y��<�`-9����Zj;ne�+l����"""���	�����OOd��g'��������e�a���-�'"""�*& ���{���e��d�I�DDDD.�	�*������$w"""j#���s��),(����:��O3U[Y�n�����H����S�M�U�lZ���?w��F#�l���
��:���""""L@�����F��|���e�|�r��Y�{�-����)S��<�r%Q���\�������|�����;���kF�����$.���S��2w92�zF!8:BDDD���\N��;2F1��n�B�'�G%b���s��Y���^�
�*I�B�k�;A��g��aB�� ('J�IKtWx^/�'����p�,"""r1L@�l`Zo����W�5�������5`B�
�:M�'���aB.�R����\�|
���2uF��n�k��:�j�z�������u#DDDdOL@�������B����n�l��J���`����#������]���U����WP�]�����fL@���VaQVk�~��p�L�����-��J��^.�<�>�$/rIK���l����/LN���H
j]Tc�#��F���:t��`�m~
u�`���J]���-�����[\,����9�8`��Z�6%V��KZ��%V�r�F��hFNl��idDDD��	�*7�Cc��A�TK
���}�[�L	@��?Z��xz"�`����)]J# ���i�ZR�(&'�U�Bfmz�������D)_f�=�"""�`bG���x��g�y�f����o��X�h�N������>P���Q��k�52�������*u��q��"�F���Q����������.��!�Vy2_�N�_������I\A���T�(�$��K��L�����1���'���Cx�����wol����MCmm-�M�����������6��%���+����799RP�~��*� ���J�E�?��*��W[��2��S��2e���@������=y�B�C&�1�� X����Nm�9�&^�>��~����9od��*�o��"j������m��s�Nl���4�1|�pa���:u*t:��{�:l���M%ln
��c���jnL�v�m G����O{�k���C~��(��]��xx�kk������*��2�N�niF��GW�F���`4�@{���y�~����\d�;�Q7�#7�������g����Njtpw7�����v�k�z�T�������_��j�m��I��@)�����J@y�M4�gX���5��X��
�[ W����^���UXKWj4�W����#v�$Cj����6�?����)�}�����2�����x9��a&�m;��e|||0y�d����DL�>?�����'��uq�?|6.x/�u��fh�a;�������[����)%<�z������2kjT����Y��-��B& ��X���h��H�������=�h4��Z_l}������*�)$������or���#v
�du�S���z<TF���6L�T����]��sl��i�u*�����j���������C,�����Inn.���,F9���yyyL@\���Q������e/�P�`s�ByKX������H
;)++C��=-�L��6]j�z����"6�8�?�S��'Mi/�[�"�M��sI�@[#1DDD��	�
���/D��G�'.�IF�h�^���U��-s���MQ;��J����%C���J"""j& v(;�Q^^n�W����	��TTT������F�-Y��j����7***d�_=sK��QU`��(77w�lq�Gq1���o^����p�Ly�B9�U��U+���BLBB�Da��~
�����%�K���W&��
��zj�W�N�Z����S��
�x�����^[�B�-?����}S�hk�l}�]B������\}���}�z?�~a�{�`��g�������a�o��%
����-�N�-?oj�jN�����=b�R���r�BXoF�����c��M���0[�������������!C��9{�,n��6�9s���%"""�&���3:���0gw�Ubb'_~�%�����L�2�T���<C�9����8{��#�JDDDD����8�N���1z�h$%%���K�����M��}�vl��A6���&"""���# vt�������O>Ayy9������O���i	"""""r��&DDDDDD7PYY�y��!<<���8p >��cgw�!*++�p�B���!88:�K�.�m{��a�5
>>>�����I�PXX�����]�0c�������������~�-�����q���[�n���B`` ���Nl�����Vb"g��u��t������B\������d�8`�V�h��o����c///������fm���3g*�O�W�8t�&L����;���QQQx��PUUe�N+19p���___�����{����/�V+1�������'��>��%K���_b����6m6m�����]ii)�~�m�F<�� �@������Euu56o��w�y����P�r�_k��[o���O>�$�����k�����2d���cj��x����e��!++|��w���������vZ�Ic%%%�?>:w�l�����,[����7����[L�Z����|������BJJ�Y-���g��x���AAA���+@[19~�8�
���O�_�������/���?�i����i%&��w��k�����>��~����#Gb���fm���T_|���$Iddd��������pQSS���9^ii��$I,]���n���"$$D\�|�TVTT$<<<DJJ�#�iW����EYee�������Q�LeZ���!C������Z���������/f��):v�hV������GH�$>��3�vZ��B�������[$''���RL�dggI����>k*�RL/^,$I?���Y���?.$IB��d��1",,LTUU��._�,������C��j%&��'��e|||0y�d����D�9s?����z�xBa?���jl���&MB��M�1b�l���.�]HH�EY�p����
@[�P7�������>��|�
V�^m�3���(�;h/������W-F<�ZL��_�:��f����t�����gV����v�����CS1����k�t��w�u���{�;w���'7'���ETT��i�
���sF�\��?�������[�EGG���~������3��x�">l�F��x!P]]�.��7��W_}�����nL~��7��7��/G���-�����d�������������LuZ����{����0`������$\�|��b��������b���������$&&"88III(,,�����u�V�]��������TL�F#��ooQ^_���@{���	�����!  ���������]r9�1P���������0������Bjj*��#))	

���s�r�J$%%�nL���q��7c�����Z�K�N�0o�<�]����x���p��i���b�����nm��+W0e�L�6
�v�����`������6m���`���.]� ;;G�Add$������1s�L��������|����o��hjuu�i�G},�{�I�D.,--
7n������:�;N�����{���Gff&�z�)��%m���~��[��������K0``�~���x��������9�w�Q[[���%K�`��������7ov��m6�D���_��� �&(Z���?b��Q�����+����#==�/_��u���E�z��'0k�,��3���������Kq��i���B�a�d���������z���A}L*//�$I���wt��n���x����K/�o���\�����+�v�
���P����5Ks1�����9s���

EEE���/^�777���1???�7o���]���x���~��1c���~�9�����vb���c�����y������T�������Q[[����
����a��!((?�0����"44�6b����. ==k��P��������_Fxx8��On4�qN���������������~��9�[.%22���8v��E������W/xxx8�g��t�R���E����9�Fuu5~�������������+`������+W���������SSqQ#I���'
G��h1&
�_���#���k-&yyy����M�G��n��T��K.\���2�������|�
�����cG��������s��[����,!I���������#�t�"jkk��3��p���6�S�N����[�=�������=���[B6��x(IHHnnn���T������-���k�Wvv�����������yyyBm�����r.
d*�R<v��!$I/���Y�+��"$I�~��B[1�g0D@@�2d�l��b2j�("*++����]+$I���Bm�����"���'�z�)�r-���������8 �~�m�{�n����
I������5���m���y�x��w�$Ib��)b���b�������B!N�8!|||����EVV�����-���'�t�b���\�RH�$���^��~�o�>��zZ��B<���b������?�����O?S�N�$������(�1c��9 Z�����Ejj�������={���kE�>}������k���V�Q����:t���b��b��e���S��zS��D!222�$Ib��u��Z��_|!t:����;�'�|"v��%^|�E���#���'�F�B;1����=����u���c�X�r�

��~��r��Y[���������J1w�\&��o/`1"��u��]H�$$I:����EEE�v999b��Q���[�����'�_~���=��bcc�b��K�����B<���w�w�}�������_�1Bl�����Vb�d��������\qY�|�8p�����pss!!!b��I���Cm��zUUUb��E"""B����������Tq��u�vZ��u��������CZ����{E||��������}��,���f�����+E���E������>k��hcZ��=HB���DDDDDDtq:9"""""r& DDDDD�0L@������a����0!"""""�aBDDDDD��������	���t�&}���W����X�1�����7���^sv7��Z-��ND�$0�Y�^x�����{�Y���(���X\��	@��}��Q23~�x��������]!"j����""�������

�$I��UUU�����'W�^����
�g[%I���@D�jq
����Ett4����;������5k�����_�>� |}}�����z�N�����oj7s�L��� 77qqq�����Q�;v���	��kWxzz�W�^�={6������d��t:?~�'O��������SO������3f|}}��G���h�k�����U�0`�xyy���w�q>��s�6+V�@��}��C���b��())1�W������(�������N�CFFRSS???�=f�m��
�N�2�&GDDM�""��jvIDAT&I��=������`���fx�&���+1b***�b�
�����m���S-��������1{�l,^�������C���Y�����S�N��W^��a�p��q�����1e�$$$ ))	��o��+p�����s��EJJ
6l���g���0a��k�9s&6l��Gy������@NN���Lm������o��'�����QXX���4dgg����4�f��
����c��aX�~=.^�����w�}����N���5k��c���_~��-[T_)DD�f��!:v�hV6|�p!I�����h?|�p1b����W��$�����������$I����7{�$I����S�Smm�0����HH�$233Mu�=���$I����f�8PH�$���������EHH�x��U��w�^!I�HKKSl���/$Is��1+?p���$I������w�.-��8v{���$��������y��$I����T6n�8��G��ADD�8nLD��0|�p�����k���"..��|��i��L�4�������={6�v�
wwwxxx�{���\�����������/t:���^SY�v����b�����HNNVl�g�u#%

<QQQ��k��3���z������j�����8�������5�]YYBCC-�CBBd�{{{�c��fe��������s�������hx{{���C�AUU��}��������<<<,����U_�����&�:���E��KXXN�>��5�S���o�d_7��	��k��K���8x��E��s������\;v���>L�?��S���m+l���`TWW���s����d��'	g��A�������9��� ��:t��k�,�QVV���`��HDD-�)XDD.�%������������/��322�������o��V��b��;v,`��5�mF�	������<�'N����]��=j����@v*YS�o�W�^��z""����9PMhX7c�����x���������Hdeea���`�]��}����E�A|�����sg�_�����
CBB�����o�a��qh��=�9ooo��3�{��c�=�U�VA��!>>�N�BZZ"""���O�������z����8q"�������!!!6�����[�l��o��A�A�����n��^DDZ����E�m
��]�\���v���y��a����$	c���o���c��S�NV������?�s�����?777�=;w�DDDD�������{�=4����{��OOO�r�-X�x����5k����c�����������e�������n���8s��|�M���������o��%K����)������<,^�/^���4�Z""$a������Ux���������O[�� ""r4���!���:���p�F#v���U�V!!!���& DDm���7^}�U�:u
��]C�n��h�"<��3��N�""""""�6�DDDDD�0L@������a����0!"""""�aBDDDDD��������	9"""""r& DDDDD�0L@������a����0!"""""�aBDDDDD��������	9"""""r& DDDDD�0�A/����V&IEND�B`�
Sequential scan.pngimage/png; name="Sequential scan.png"Download
�PNG


IHDR X�v�psBIT|d�	pHYsaa�?�i IDATx���y\T��?������0�����,�|�jajij�*+�-n�����+����^���{MK��r�43�p
#�$sY>�?�9q�6a������13��>���3=l���B""""""P6w�������`BDDDDD��������	"""""2& DDDDDd0L@������`����0!"""""�aBDDDDD��������	"""""2& DDDDDd0L@������`����0!"""""�aBDDDDD��������	"""""2& DDDDDd0L@������`����0!"""""�aBDDDDD��������	"""""2& DDDDDd0L@������`����0!"""""�aBDDDDD��������	"""""2& DD�,.\��R)�8p���KLL��GDD���BU#����~���899����������
���g������L�V��B�P@�P4���.""j\f��""c���/��O?��]�~��_����~\�v
�
j���	�������W��^���� m#"��������{�����AAA���EAAN�8�#G���Z!d���������o�i�f��,"�*���k����;:���c��9x��w���������<y���SRR0v�Xt����������e��_�`����������t��7�|7n�����4�)66V��i�CmC��������SO�C�������BCC������o��VV�/���5k�������pvv�o����R�WWW����C�Ju:���������_����@t��������D�.]��3�`���:�eC�>}&L���+,--accWWW���`��������������q���[�n������=}�Q�����y���q�F�?ptt���9��m�~��a��y(..�������������m��x������O7��'"28ADD���H�P(�B����";;�����1C:W����#EYY�������:c}}}E��������9[�l���J�����\��H����'F�]c�N�*�o��������:�{����s\]]k����Ckm����k�C�P�����Z�}����3������$''K�"<<�����<)������.]����]����o������L�<QPPP��HDdl8�����}�J��������G}������EPP�w��u��~����P�yx��������/���?��;w�{�n,Z�K�.����9�:u�+���7n�����W�!D������/����=������O?��O?EEE>��#���_o��C�
___��_��/���������8t������p��-[&�7m�4����v�Zk[-,,�����*�
vvv�y�&�����~��o���'�s��
�C�>M�&L�[[[\�x�O��?� n�j�*$&&J�U*�{�9�T*dee��/�����cG����G�h��= ??�}��������%K� >>^��HOO���+^x�dffJ���� !!s��m�{'"j6�����2��O��~��'��s�d����C:��o��}����1;;;�d��)R����8��t���~*�fCz@
���p���/�|�����s�J�������= �=��t������/�c.\�������s������?b��u��w��W�����9���?�t_�y����sV�\�u��?�W�^B�{?�xQ\\,�/,,�o�����}[����M�6���{O�^�Z����&�wqq���m�V����_?���q������
{@���033���d�$&&���+Z1���GHH233��C���K���������x���u���Mddd�_�~8~��T>`�<��#�������*����}�<yR��f���Y�f��=�<JJJ�_���:u�����]v��?���=�]����x���p��������:�
��5k���HJJ���z�����
����;wN6g#22R��T*��w�}�-��[���y�899I�{����'O�^�Z�wIDd\8	�����m�"..����G}�^x���R�����/���z8L])
�a��%�J%��v}������...�kKKK�����:_�6�G��%��K�*��>���������g���8r�1o�<:nnn����}]]]k�;))	�g���}����{z��z��=o��MDdH�!"�C�P�������4iN�:�~��I�srr@�W�_|QW]�^����RYAA�,���B�
I�V��{�.����{/t�����1C�\����k���K���n,���CFF����7����s���@�����j���8,X�iii8w���;�]�v���G^^f������k}�U{�t��m�������9���sssl��3f���mU�7�
��e`BDT�����R����x���d�lmme�5	D�N�����.P�l���Z_�\���J���������c���������'��W}����k'=B���#2d�����{��<�������4���B�/^Dff���W�Q��sMC����x���KR��o��FM>.\�{{{���#44������`�;���W�^ptt���n�:DDD��UQQz�!X[[��G������@�s��g�5�{ "25L@����������1k�,4}�����=
e�h+�J���H�����K�h���}����n(,,����q��a0c��L�87n�<x0^}�U\�~���?�����P(�<�g�}O>�$222p��Y��X[[c���X�j��]�O���!C`mm������8v���y��xC�T*�������z~��S�`aa�!C����z�}��G�T*�!F&L��������l�������-���C��#��S�N�u����K1�DS�T�o����@=�w��x���������III���D�n�������T�W_}�)S��s����{�l�Q���s����KLLL��O(�J1o�<�sk�D�P�9����W�> B���/�lWhh���������1cj}o/���tN�U���q!������e��}�Y��X�z���U��M������`��K�ZWS(u��W�XQ��X�v�_YYY�> J�R�G?���h���V�����0a���V]�������J�4������~��MDEE!$$*�Jk�������������666h��u���v�Zxxx���
=z�����uk(,,DXXT*lmm�}����~jj*���akk�J���p�6���WWWXYY�w��X�n]=���Y��c�L�>���lll`ii�n��a�����g�l��u��!55�=�\\\`ee%�7b�������c���e��a�������v�5k����5������5k:v�KKKx{{c��
��a���lff�/��;v���Q���sgXXX���nnnx��g�a���S�:t�W5F��M�6��W_E���M���u��]��/���,,,������(���fffz������=.��w������9:w���#Gb��]�9s��			��w������%��mOOOL�>]��������!!!��������o��AAAz���>U�DD&��3 ���\aoo/�"&O����!�(//#F����b������b���b��%"55U�d��T*Ett�8p��X�j����S�L����{Wx{{�n���O?�T������Gsss�u����[aff&��#RSS����/��K���#JKKe��&MVVVb������b��yB�T�e��5�]#����_����L��$ U]�rE��p�{�=��M��?�Z����x���d���-J�RdeeIe���B�P�#G�He������K8Pv�������R��C��B�6l��233�R�+V���?e�acc#JJJjl?""j��fVU��
�>��<XZMD���d���"<<\V!������;w�������i�	& ==�.]��,���cx���e�`������;w������ ��y�;w� 99����DF�����o�!//���x�����C�������|��,633���#+���#q��Y���>�u=���XM��b5�5�NNNZ��U���H����*�Z�7??�z���]�b���x�����G!,,�����I���������\���];���%%%:����ib5��b��Y\\�3���z7#"��m�;"""SdR	�fM���R���]�va��X�x�����1�������!%!!!X�b������������������������WVoII���4e��j��jv�������Zq�n���{�����t��4�������O�N���S��n��2����
���5�h�Jk�iddd�&�_�|��������|||����U����@��<fddh�|��i�:�m����t��Ao�U]�t	~~~�x�b��������O���q��1&!
dR	����y�l��yyypqq�^5k���pss��]������
����$11
��G���������#==]�-//���[�����c��ggg���a����={����#G����7�|S�s���X�`>��cDEE��occ����������u+z���X�����5���~s7����h�=��{"�����D��6���g�b��	�t��2�d����u�n��@�R�f��#F����/��={������a���8}�4�m�&���];��?,@�����G�"66�'O�������x�?+V��J�����q��y������r�Jc����6m
1w�\�������������h�"�i�@JJ
6m���K����^�}���7����(��%��������D��6�9�m�'�xO���Pc3�d�������J�}�vl��
�������z����b����2e
�����o_���O=������zvvv���������S'��7����8|��7���Bdd$n����}�b���4h�,v�����g.\���~6665jV�ZsssY���������k��������;��Y�3f4��#""""2~F���u�I///|���u����Dddd�qNNNHLL�S�AAA

�5����-��E��T/QKgR�icBF��^h�&�m�'�xO�x?���h�=��{B�M!���R;q��������s������"""""2���Nuw��yi�b2=vvv���gs7�������������������A(;;�I�:L@L����;��&����"""���	�	���DDDDdj8	�������	""""2z@�^�G2mL@������ED_}dg����6& DDDDd�����"���"�k2]L@������*���J�~M��	���[����vvvx���������+,,���#������DDD���#ww�cBBs��2I�v��+����z��O���9&L����wk���9�����o��-%""�����;���%�F�d�6l�www���A�T����{�����1b�)n�����c���++�fl1�i���>#^�^��^�^��"�l.�^^^����R�����9����_�U��z�*�O����'c��!�vm""""j8���p������9@0�J +?C�p�a�4��L�z���8y�$*++�T*Q^^�S�N���]�y��7aff���W?�������q����;G�t�:��zW �o�b�L�zS�NEvv6������`��i���|���X�~=�����DDDD�����p����.z:�?n��{��g����7n`���(--�?��O�17o���)S����c��Q�������333t���6mj�6Q�1i��Q�gODu���M�z���
233q��M����x����������v�Z�8q����c�=����#F����S�g��Fk5C�e���9 -���IA���&|�����{�_��|�	���������+++:)))X�r%�z��&m=C�e%�`H������`���&|�������'b���x���g��E�^�dK����g��i�vQ�0�\V2& -\\L�N����_X	�7����b�L�zU������~�������Z�
}������Xz.+�N�R�p�a�Y��3��)��L�D�eX�t[�z���;�������K�?�������3g����v�<//�&i5C�e%���V@�RaK��{���2DDD   @Z�Wc��������'�xc����_����c���k5Ls�-���2y+V���?����7k{����������B||<����M�6!44�ZJDDD���sK��0m$��`�,X�@��g�y�<��[DDDD�!.&C"9�3�?�W��?�4����R�aBDDDDFI3�4*&
���(G9�`�>~�K���&�	-C�-���9 DDDDDd0L@������`����0!"""""�aBDDDDD��������	"""""2& DDDDDd0L@������`����0!"""""�aB&I�TB�������P*����_�T����J%���QQQ2d�tm}|����A"""����@�P
���cu������'��/���9s�`���Z1aaapuu�Y�����EDDD��0!�����>|8�\������_u�����/���[GDDDd����pOW��pt���4��^c��oF����2��_����?��M""""jq�f���7����T*(�J����x���_�T*�3f���������z��������\+���aaaP�T���E@@��������T������*�
���(**��+++Cll,\]]aee���{c��uu���������Wc�`
�kBl�����B�����kM>�jQ�b4= W�\��M���O�3�7o�u�||<~�����/]�.��y����t��?�����q�WZZ�a������X�f
����n�:���"55U6����>|8F��%K����s����a�p��1XXXH���O���[�d����"99���:n���y��=�-�F �@||<�y�899a��=���o��%&&b���:�M�6
:th����]�rE(
�7&77W������$�P(Ddd�VVVV���^��/[�L(�J���%�����B!�9"����///1p�@��������[TTTHe�
�Bl��A*���J�R�X�Bv��)S����())�zO�����������	!�(ww!����k��>u=�B!�Je�b]\\�R�yyyZ�
�B�����k�k����s��)�J���?�XG}>?"""2.����3�!XU�:o�<y2BBB��3��<������R��������!�@RR�T�s�Nxxx`���RY�6m0a�������K���|;v/���l	X���c���RYRR�:���$''���0BCC�?��/���o�����Zx��G���DDDD&�(��l����C||�����L������c��ptt��3gd���4j���j���9��urr���S�uR�R(��a�M�����
Bnnns7������2�$??�g���U�jg_\\KKKX[[kk�������%%%h���V��L�y�[����b�q��������R�R(�����o����<��/Avvvs7�����E2����^C��}1i���n
�0�W�Ftt4���1x�`Y�5�Y�.v��������������������k������PZZ��w����J[RR___����JJJ���)spp�=��u��F IDATtt�����?j���u�����jr��x���&}�F���o������:t(RRR��*��I% g��Ayy9�q�c�6m��M�������~Z�k���???)����(..����T�������:O�>
R��1##C��\5�z���mCAA�l�X�:u�9s&~�aY���c1n�8��7��[��7�3����yL�P`����<}�*�7olll��o��'�@rr�l���e��}b����wq��n����H����c>��sY��k���5-Hs.��OQQ��ex/\� 8 ����o�B��>��8p���r��B���amm-�M�&�c���B�T��g�Je6l
�B���RYYY���������(|||d��>|X(
�q�F����3B�T��+W���:u����W�^�z�M�oK�Y�V�2���k��	!�puu����r��7
�R)��m+���;!�C��y�����������L�?����d����u�����3g�c���#�����:;;�6l�������}�����G���'���C����@||<���+V@�Ra���8�<RSSe�Y�r%���1~�xL�6
����;w.|||dK�zzzb���X�h��i� %%�6m���Kaoo�h��5����s��U�j[�j��)�2e��L���DDDDT7F��L�>yyy�Ch�o�����C�P 77��u�W}o��������W�S�N�7o���eq���o���H��}}�����{1h� Y�����g�,\�O?�4lll0j�(�Z�
�����������k��������{w�Y�3f�h��!"""""��4 0HHh����Q% 
���_�###YkNNNHLL������Tk���-Z�E���^"""��DD_}W��_3	!Scr���Vii��P?x��F������D*���J�~Mdj�����`�H��]���Wd��j��I�:����0!"""""�aBDDDDD��������	"""""2& DDDDDd0L@����Z���W/�#�!0�V���{���F���aoo��C�����:cSSS�T*�{�n������ED_}dg����!0�Vg���X�|9����I�&!;;��
��K�dq�n���)S��/`����Z""�������_55& ����q�N�!�q�F���c��X�z5���;��q[�n����[o���[X�fMs4�����*���J�~M����P�TVV�]�v����G��$���w���������GGG����R��C����o?�!$$#G�������n�f���������[�b���())����
�_|�R�`cc��G�b������\���PZZ��'b���x������24& �HD�zlg`�a��1��~��'l���~�).\��B�������?~<�X�B���'��>��|��g����K/������K�����t�&"""j�8��0�*M}�K�.����C�������e�������+p��<x��M�%+W����sq��ql���<�RSS��S'�<y�W����+��sg����S�N077��p����}#DDDD�{@Z	C�r���@^^��k������_���G�������e��l�2Yyyy9&N����@L�:���>/^���b��%

��?�''��}CDDDD�{@Z	C�r���{��GW�^ERRv�������3..?��6o�X�j����p�B6�|�	n������n?Qk���0�*M}������������QVV���h���!  ���Caaa���������o#66nnn�~�:.]��~��I1]�v���#������w.'S��IH��3�jM}����c���8{�,�;�7�xyyy��_�
ggg<���HLL����k����'N���7f��-;VZZ*{}���FDDDu����%`B-B�~���;����~CJJ
&L��#G� "":t@\\��s��]��G�"!!
���m[8;;c������8p7o�����A�QUEEE�����9���E��0�zbB-�R�DPP�l����l��
O>�$~������������9s���#;���l4�f���q�`gg�3f��I
����N�����m
q�i7�C����I�*X�bYYYa���?~<*++u�L�<...X�p�����H\�~~�!N�8�>}������J3�����@���AN���$ i3�����FOB�o@TL��oi�f�	j�J��}�m6�����hQ���J���=I~�HOM7x���C������\9������������3����^��������EM�= DDDDF�f���$����z(,,D��������VY�Y8z��s�15��9�>~�E=����?�����F	�+��7Q1Q�Z��1!"""2rq1qp;��@��J%����n������.����.z:�?N�D8�������T*N>���(�����0����!.9�����bN	Q]1!"""2*�������)���oC����`�2�����@�(����1is����"""�VF�S����������_��AsJ���	Q+��S�H��1+�1+�#��/59�#"""j�T*��U!"HK�����n�L@L���g��	������!�����`���
VL�W��*!�ITL@L���`��	��z������6���Z& &�g�������7��)�@vvv���gs7���L�l�r
���P�\�XK�55& &�_^���Z��S���]���T�\N���`9�\N-	""""#'�\�w.'�������I;�������0!"""2r������_X	�7p�r29��#"""2r����b���Zm����������J��v�E0�!X7o�DTTBBB�R��T*+�����;����� t����������y�p��5���]����B�=�x�b��k�QXX���0�T*���"  ����Ygjj*���akk�J���pi����!66������B����n���"""���z�R?����F��h�+W�`��M(++��1c
�|����o#&&��w��5k�w�^L�<}�q��]Y���K1k�,�7)))�>}:�-[�3f��JKK1l�0���k����]���C���������8p��G�N��k�.|��HMM��a�p��=Y�����b�
DFF"%%c����������7�m#""jT�W_���G~�5
����#t���P(Dll�����B���h����C(
�u�VYVVV���^��.[�L(�J���%�����B!�9"����///1p�@��������[TTTHe�
�Bl��A*���J�R�X�Bv��)S������q��q@?~\�}!""jj��B���7w��.�����a�3�S���O6=L6}�M��=8���J�]+�J�k�N����p�����%''����������p!���$����8p�T��ML�0����t� ??����/����[���www���S*KJJ�B���������Z������*��5��~n�����Gbi"��������,$�&�?�_��r��b�	H}i�jxyyIe���Yl������3g��b}�Q�z5�jb5u�����:99�����:����IB0r$���~LHh�Q]��s�;9}s���s�u%��@N�D�D5q��53�U����1w�\���b���Ryqq1,--amm�uN�v�P\\,�.))A�����4e�X�����u���������,�����0�0M����O��z:�����&"]L����O=�
�m����!"""2	�(����:���DM�d��W�"88�.]��_
WWW�q���j���YlII��8�����beu����u����'�>�!���=��������]W�^EPP�����7����[+F3O###~~~R����Q\\,;���Zu�>}�X�cFFBCC�b���m�6�C�z��e���x���eec����q���CDDDTW��{�����`������?�.c�c�|����2}{�Q=4�*\:�\�W!JJJD�~�D���k\����DX[[�i�����/_.�J�8{��T�a��P(�?� ����	///���/;������G������B�7n����9#�J�X�r����S�
[[[q��U�6sY7"""2���B���M`"B ���D�~n\��������d����u�n��@�R��;#F�<���8u���}��wG���wrrB�=�'���?,@�����G�"66�'O����t^DD���1~�x�X�*�
����������*k���+����c��i(,,���s���#[r���'N��E���M0)))��i�.]
{{����DDDD�P�T8�|Q1QHOMG9�a3���C\rT�5}��Bsg@U���
�B!
�P*���yyy"77W�X����p�:��Y#z��%,--����������Zq��W_���Z�o��Fg;���k���/�������EEEZqeee"&&F���KKK���!��[���3�&"""2n����B����������?�?�~��5ws���LRD������K
Sc���g��`Q�***B��pxz�W`/xz!|F�I��|����~��h�QuF5�����Gaa!��w��z��J +?C�p�a����h���"������H=��T��1��A��	aN�u���J�@W 9������-���:�^U'*��uK�RGj]8���H���W��1�'�T:�E�A���M@B0r$���~l�s@d��fgsM��W�8�����KPT��E="�e�-G��_`�S�?n"Z��T]��tu��.�@z�i$�������H��6��f��u1+��zk�^��u����Z& DDD:���c.�_?�������S�4��\��,8���#�& DDD:���q1qp;����~a%����n���k������E�^�����L�b"""=Zz�Q�J�������\S�-����\�)V��^gP��H?����P��\	 �~������"""�NBLa�]S������k�i��"&�dZ������xc���)z������L
"""2J�Y
���NB'""j�La���L���|D��	Q+���6��,��Rvr'j
���2���b}�Bn�
�L����TpQ+���6��N��vr���<��|���BD�cQ+�7Yl���M����T�����j	IGUq1q8z�I6�3�#"S�"""2y����,����	�wx�z"�2����m�=FD��= DDD�"4��|L:�{@����L@QQ�g��+��{�+��3�Q���Bd"�BDDDd���;�$�!"""2r���Z& DDDdt8�H�;�SK�!XDDDdTZ�p���"D�D!�T:�Q3�����b�����������U��_�~d��44���n�T�]5��H��r�w"C�,""�*
�����Ddg!;$YAYH,M���dH�>��)�k4�N�D������
N�""�^�������5E��n�oP���������=��;�""�*L�����6�;"��+ ;[��I�4�H�:7j�	TS��Ndh0HDDT����^���MHKSA3���HK3|;���!�b�|�F-��4	TQp�����w1o��M��;�!�����������exY` ��1]�
��n���H�8_�H?& DDDU��/�u^���	������>��d���'PD�����CDD��b�p0� r�8C�S]%���_�M��c]��5�����j�p��u�ii�������?���(��V[�9�K91!""��%yl��$=,�9���8_�H?& DDD���/�2��.��<�{>���oX�!""j%�rnBM��6��C�m�b"�?���M9���aV��th�e�bS�G�\�����L�n��e-q��l�b
���P/[���55�"""2a��s9`��������DT�!""2a����FKH:�����DT?�!"�V�>�5g����{-��l�.M�l1QK����Z���d�!Q-q������\�s��-&j���Q�����cH�����������m+��_�8����f�!"�V�)�/qHT��Y�8�2���pOq�g�'�,��/�`�Z		�[����l
��Fc�T��fL@���Uk�/�5�i_�5�T���{wDD0	!"��,"""1�=;�i���TTT����
�B��^�
�B��pi�,�I@n�����(���@�RA�T"66Vg��';;;�k�c��Enn����k����VVV���/^��r�u��J[[[`��}:�LMM���?lmm�R������2������VVV���7��[W��BDD-��|�o��T
�����Ddg!;$YAYH,M��?�"#b4	��+W�i�&���a��1�B{���~�	C�Ayy9�o����dggc��A�r��,v����5k�����L�>��-��3dq���6l����5k�`��]���BCC��w��b8�����S�N��k>�����b��a�w��,v���X�b"##����1c����_��������1�/�-q��9�s��7��?7T�
���ATLT3���d��r��P("66V����������q��T���',,,��9sduXYY��^{Mv��e��R�YYYRY||�P(���#RYyy���������+���EEE�Tv��!�P(��
����L�T*��+d�O�2E��������v��q@?~\��!""�.������g���"���[����M����\�������HNNFqq��#��mG�����W_a���x�����n��a�����s�T������R������IIIR���;�����Jem����	����K�.���q��1����P*��u���pww�]?))	B���s�����sK����HH��k�����|T�����B����h�������T�������B��=q���Fi`U999�{�.}�Q�c>>>�����aP���RyU;v�����}���z� �j���9��urr���S�u��3����K���q"2

N@������[z=�|<��c��s'\\\�d��Fi`U������kk��=��z��kii	kkk��v���ziJJJ��Y���]�j����:�lmmaaa���DDDD��P+S���.�9��8�������={PO ?z�(v�����P�����7�l�F�����Iaa!��'�C=D�����������x\L�Drg�b����tC\r\�\��\�{@�������A�Tb��������H��{,�+))�B�@�v�����R��{Wg��.M��:�^���;::�����q��-��wOv}""��h����O�'�\�J�R�p�a�Y��3��)��L�D�eX�&:D�����G|���6l�m�???i���K��D�1������Z�N�>��={������4222���g�����Q\\ooo����Go��X�cFFBCC�b���m�6�C�z��e���x���eec����q���CDD������h�"������PW��9�h���A��~�:�]0���w]�~
��J������Y�����:��6���xo�{:�5�u����c>��sY��k���5-G���^{
3f��'�|�?��	U��8t������U���a��Q���/'������b�������&�������
����$11
��G���������#==]�-//���[�����c��ggg���a����={����#G���-v6z�h,X���a� IDAT�1���d�����J`�Z�n���� ����Z�7��@bi"p���J���o�{~��R
����O�y97�����N�M!��
�#�D�c��6�u���}��/Qs�4i&M�$+;q�����L-j��L�6
���CZZ�	&H�n���W_}��u����n���7�W���c`�����Fll,|}}1r�H��;w��������$K@��k����c��h��=���q��Q���b�������b#""����c��P�TX�~=��?���TYW�\���`�?��MCaa!����������8q"-Z�6m�`��HII��M��t�R��KDD$�T�z^�.�@zj��s5������W����5��?�YM�6����{`�$�%B�2���q�2Q���6�h��wG^^�.���)
����[�n����9sp��a���a��aX�z5�w��U���k�.�S�NGtt4��i#�+,,DTT���+��}}����o��'�xB����T,\��N����
F��U�V����^��K�b��-�|�2�w���3gj�������?�""�Q��^���{�=�����>��z�����a�yz!+8Kw��?�P���7 �2��^"c��k��~z����S\�~����_�)622�����999!11�Nu!((��8333,Z��-�S�DDDu%�{�����@u�GQ�R�_�p�a���������ldW�""I�W�����|___899���vvvh����HDDDM�.�^DD�{;""����#�=#G�_7t�7��w�����H��= ������C�>}$�>��P��9����e***BTL�O���0����!.&���l���Ei�������?�		U�x.p,���>�Q3�ppB���������Y��Y��fED2
�����W^y��/o�6�ZSHD-M����Ic'�M��@�tO��)~���=<��
�����������������@��N�F�E�
�
e1����Km���
�~���V���Z����R����[�~ ��)���(.HX"QD1!�er��$��;�L&!	��9���m>3G�}��y���{�G����_&�������
R�R�{Z.����F�km���3g�1��\���\��*-u� �=:t{5�ss7�����c"�"�:;���BKc�y*���
w���K),h����?�#"]_���3x���,�D���l�f`n�m���i�����KY��*�fp|����V�3�����$=��� 2�|�VJ���o $"��������������Or��A�?�����\�RS�
K�Pi�Bi��]�~����P��{����6M�n�g5����p�q<_7�`���[o5�o��|�s����""�,���}�2f�~���������q�������48��rs;G��R��<��;���,n9�2�����y[J���K�:�������?���G�
���4�r>����-?�_c�+�����l�:t����Uv�vED�)�d��
,_�����/��	*��{FT���O�7���,n��0j��>��R�^5���O���P��N�j)XEE������U
���*^8���yP�*�@,X����o�M������]�@�����AUTT�v���6���L�*V���pr�m��h�"jjj�3g���kv�fHDD�������y���JGvk�p't��w_U���:k��tY�k�(�T�[b"8`}n{ukWP#=��]�3 �������H'����������2	\�������?�����to A���H��n�|��]��u���K�������[{��H�#���M�DDD:6��������A��to�9DDD�RV������?=""��GD��[#5�\B�k|O't+�#i��FD�7 """~r/�*.6�����\��63���Z?;��s������>�����������GP#"��~*�������R��^�������<����""�iDDD�O�\��|��4��G��ARA�I*H"#"#�jU9�9$���1���������5Y��G3 ""�&�������T{�7y=�
�����tO��l���A�������N"����Ag��V}@:�1`Gv����]�`M�2���$���os�����tym)��UTT��$���c�:���c�\�I�����]�����i����c�����W���{)�Y���{���#%-%(�AD�-�e�������l����/��*wG&�V����U�ggo_3Fm�Mj|^�5���]���l�������x�:S.D��ggo_3F��MRc@���=	�w����""ru��#�\��|��5c��$5����H~~>o��������7���2b��1����g9]J����f��M�
��(�N�,.Pc@��)t��Y����k����a�������������-����'��@ED������]J���m����w���j`Q<N��7�8`����p��z�]�v�v�ZN�<�a�c3f�`��MA���\X]��U���0�������'&������w U��,w�T`qP�V��V`�n
e��K�>~��Y��Gy��n����H�c�������yp""r����=���V�K�:��wyy`es}X���4L\�\�<���"ra<�\QQ��q�,�9�N���&��Mh�2��t)UGw�t�XK��1U��N �d��!�����S�6;���r�%��i`""�y�����el��<1��G�z�����T��;��[-X�UKD:���`����|�r�}�]O:��C�����.\���H�h�E�u�R��j��<��b>sU�`&�7�*X"�	�<���2���d���*���7nqqq<��A���t���{)UFDII$nL$� ����v[�R����Xq����j4�a�G�``��\�vJ��G�����7��mc�����+$$$��G|�A���z���q��H��el����T��q����m���U�4=��bv�*FO`g�N?Q��j�/���^9�JB��M�
����x@�""�������'�/����%���W����f�Kj��f����ak�VJ(���0�X���D/"�/-���i�uGf������0���_��q�9Ph5���[�D/"��6 ���?X�z5����;w���0�w�n�ED�k��2�m��J��@�8
�����48Zp��aQ� "��������w�}������@�~���7��%""���@m���o�_�j�|V���Q,hC��SO�������gBBB�9&��i)������_����NxD85�����#2�!"���TVVr���+��H�=��dw�eV����U�*�l�zY\X�b��""�H�HJJ
�������f0�#""]@kJ�v� $�y�������M���`�U�c�n$�F�����y��'��?�AM������tK^���������%g;��\�3�m[�<|vya_�u���""�M�3 ���L�:��t:�������{��W_s�""�I�_h�|X
��-�#X��������=>>�oD|���u�ep""���w�}��/a����=���p����%"�}�� �����`6�H^]�_Z	��!�M��� "4���u�ep""�����e���<��c����t^�M���!������}�J(�g@U��\�(�.���d��G)�\��J!�������2s��`�EDD����p��e�� ���������d3�s��d������-��yw��{&#��DD.����g�����;�9�V{��w�����B��=3f���/�������L�>���hbbbHOO��O>�����F�Mdd$�^z)�<�.W�%���dddG��=�4i�����=

HII�g��������I��W~""]XNv	�%�p�������~��/	� $����|�s�Syy9)i)�U��w�^�g�w�^����6�ZJF�����ep""J���?����7~���s��A�?��O{����<y2�f��������[n��G��[o����~�L����b��5���R\\�7��
�;�u�_��W�s�=,\���7�x�b�/_��%K�����f��i�����X��
60p�@�����e����7of��Y<�
6���ORPP��i�T5LD�<��xFDII$nL$� ����n�{�G����w�����#���]��3{-���JX�6���pj�)����9����L�g��V,��`�9��Ng�����4�QRR���G?���p8�'N�a7�|�1`����S�s>��S#<<�����=��;fDFFw�y����/_n8�Nc����}O?���p8��;wz��\.c����5�\�u��W_m�7�8��g����
��a�����l�v�2c��]��:DD�Uyy���8�H��d$NJ4�&%�3����6�73�0���mff��I%MJ2�W�����N\i�0#1����8)����3�os��12gt���8�y������?��x{U�����O�>^����CHH����\.^y�222����%m||<S�Ne��������|��������_ff&=�/��c��`����=�k���s^HH���wx������<x0eee���;<��c8�
�L)))$&&�~�z�����~1""A��U��jz�<��J����N6�"����c&���B	��OPV��G>����p����a�^ff&O=�w�u�?�8���g������f��%DEEq������0aB������M����!<<�={�x�76h� ���OQQ�g��={����-�	PTT����=��{�������t�����^I��[���R�o�U������:�ne���~�2���K;����H0t����
��7�`��y$$$x����'��?�@e����_�f�����0���/8p ���DDD��������?n{������7���Hg��U�rs�,t��"��a�5�rz�zq��i�g2���TjWD���������=���X�}���Y}���m���8p�������@N����;w����r��)V�\��65i����U�:��Cg^�u���X=e5��.���!�(���C�_����Vj&CD.
~ �������f9V�#y����������g�b���������,����2p�@�J\����p@ll,���TUUy�K�{��W{^������}����\�q���5��uh����T(-��*���\�E~��op�p�~`+�wjq���b�s+5�!"
���?��!C�x�~!����l��UW]�9���JTT�w�nv��~���#	�4v��Mrr�:��G�RYY��q�<���o{O�s�{�{�n��������V����fI����,\���u""�����e�k34_M
�����S���?~p8������p�u��3gBm-�����z�`	
e�7gY4 tO(':�`E�c����[��k���'/�h���#FX��#
>���ws��z�����c���			a����������x*a�������s���z�KKK#22���<�$//������=�,X����),,���r�X�z5�^{-�
`���$''�z�j~���z*a������b������g|������+��5���Y�w��K�_�Dt���g��������;
��s�@��-��0�:_rs�������p�����u&�����-oo�8���x����m� "A�h�"-Z����w���+��@#�nDx�����X������K�/?��O8v�3f�`��5���k,_��{����c�2k���e��q��Y���C~~>���g���0�+�����?�9����������y��'X�l?��=z�����,����7����?OAA��������x�����������~n��f


x�����������[�|MD�BkM��@;��t]V�9�����Z�c��f0c���,_��S�R�p'�����4h��a���[��

����[�e�#--�2d���Gc����}��g?~���]�v��O7z��i����������?����+V�0F�eDDD#F�0�-[f�\�f�}������=#66����2&M�d��������i����bDEE���FFF�QQQa����FD�w���ffFbb��
;�����tz^k;�av�����t�s�N�eKn�����C����{Jo��]Z�%"�Q���R%&��-���������6�>� ��mESQQAJZ��r��4u�������k���g�%//��z����������g���X6���K %z}5)V���5
i�Wr���u�'N���������n���-[����H h�]_M
����5%��MMEDL~��]�x1�/�*Xk��e����20�
$��������t���������-.*3;���H��W<�
�0DD�#2{h�q��R���L�5�����9Q{���5mkPs!|����G0�9�C������	�DD�������H����(.6�V%n�����������:�R��/�������	�����4{�������:�|�k���g�ai*<."�������t&��4��u���������Bs6���P:�����`(����X-�*++��m.
�v��������vhE��/�
R���o�����K+�x.�U1�����>e���2`-f���Em�t���ED�# ""�,���`�_���2�T(�p�?��;�0_�
����R+��1_��lrQ���:2�ED��R��H;KM5g�m�+��~��f�>f`RS!"��{DD��?>q<�z��;{����&������Q��S)|���TX���UG����tW
@DD��U2vg|?_�������t�
��� �e�w�������p��,�RSA�c.��~{���U����|;C������ sI&cS�2*ucS���$������������S��h��>�a�p8x�����Hw����y?�%XYY���PU����������-K����.��1���a�n��p��%k-5�c�ah���t����n��4�k�0�������y""�y��YX��;�X���X0���<���h�Q��/yb2�9Xf-�h[��h[��^���'���#�DK�DD�5��o��0DD��%n��@��M^�Ru���lE��*��Lj�KX����=���������o�}����\��<��T�������{�O��Pu���M�����HW���m�w1�5�����h���>c��l��xi%��on���UK^u'�S�����+���<R�Rls%~��op�p�~�y����~p�p��T����d���^����@�n��tGA)�[QQ��s��������EDlut�����LF�|�������j��S���5h� �z�+[	e����}%�.��2,���`.SZ���f���.$Z�a]pg��������RP������T)	,"�U��'�/�KV�X����=9����~����RD�N������
+v���3�0����L�z�'���&}@O��!�},S������8�@��@�n��tG/���������?�1�a��C���2l�0F����+�9NK]��+����r�sH��`�$��0�ls��j�,���"������-��(������g?�?���X�`�>�(���'::Zu�E���\�;���|���{	S��7���M�"?�O�7���&��_=l.<�K�W���{)�Y���{������>�Y�3�.x>wDII$nL$� �������N��:x� )))8�fSSS@TT?��O����o�.UYA���eiN�����
3��&���{l��0�z����&2�dR|��z�R�����9}�i�7Fsj�)JC�������1���-��(�$44���:�N'�{�����_?���z������`��Gc�����m�X�S IDAT���f�D�a�����2��`�#��J�#����.���r(W]u����7oN�����/�1"Xc?s9�U@���Qc=�VT���W����[)q�X_������Hpr��7���o����|�n����BBB8}�4�Z�-"����������n��zv�����U[�n"������/<��7���m�x��p8��3��S�e�""�A{��b.���K�u[�����R�6�����>��+���d�����HS� ������o�>��>����!����Sg�����2�d62�[r����w�������h.""-����H;k�n���tUW�������"&N��k���	����,nv>?�9y�y����7���
���	����t> �\r������a�*��	���?n�ED������o�+����k�r�����n~�����4�0�N'��m�|X�|�����q5������n8e]27���Xi!wDelED������������J�m�F�>},���tu��r��,�?��`�_1>q<o������L���t�$o��l��������5��}��>Xu�:2"2��Hl���a����p����t yyy��+++�1c�g���""�R[r9�����l{s�c/\��g������)��~�S��f���Au>��:g������Q����qY�����PDD��������r�}��l�2.\����\0������k0����7�Y����7�*�>z���������C��B�����d.I���i`;P�4@��y�B(��AF����>��3���@���H��.I�������4�������lk��jv���MoG�������P:�>�/���O(_����Z����Q��}�
�%s/�������3p��������'�����.""]K����V�\�%�\�[��\P��rx-�:�����zQ�~����,gG����h���>����Zg-���=��|X��!o
�����_��k�����Ug�*kQ5/���-���PDD:����S�z�^�UUUQ\\����y��g�<8����\���]+�x����*XI���Z�}����y�����8��=}Tch>�q���0� ������UWW������vN���k��M��."�m���U��w���|���q�L�4�����-��:B���K��&�N�ym�����H���O���������p���������|�_�����d���������V�cu�K�DD�k	���o��a������S'JXvQ�$�*�;��o:;b���8����\����^��s��Q3���
Z��:���=��'������%""��9���G���>�<������#�<(��xU|r?����n&,_h�jP�A��������((�����Q��-4,}��� � ����$$��:^-��g��h[��h[��^Ed����������N��A��08l�������^9�9~����t>�����MZZC�4�,++#;;��~�M���Y�d��$,{U�j������ge���CU����rs��>(v__���8�4I&�Uu��O��
Ye�~c:���rGr�;��:i�vYP{������ED����<"a�iN��jP	�%���cy��{��[g`n��3����,�{)9O�4���+(>Rl`]!+zl���w��w�"�
�n����>��>�L�����d���^��;w���W����Q��4����HX��Zn_
��}_���������>���P'��{Y}�j\�\��eF�=���P�����^�>��{��0k�,��'_�4�!"rq��_����{�v�����</**�\jU������<��l����%Q����[g`n����
�ID�����!������!qK�-L���, X�q)7������P��/��������}W�.������?�!s�� 99�U�V1v�X�s"""HHH�G���EDZ����:J ]�[���9�s��+**0���{.u��Nd�{Q/����p���T�3_fw�n��5;T^^NHx���i`�;!���"""M��2��t��k�q��W�.���-���Kzk�����Z��^����N�A^����Y�g�7q�3_�����%���C���8t�!����4Ri*�E�III|��g�5�����_?���v������������JW��-,���k�M��&72���9�?=L���f�!a��;m�I*���H�p�%K���OX���~�����%",M{e\���w�2�L"�_$,�"�_���4�Y
��h����8��VV
�vn�e?����������t} ��og�����n���n�k�+"�1�����m{!����q������B^u'�S�����+���<>)��\fe�	a���F@��P(m��e�������]iLDD�����8v�����<��o_*�e]DD._�:���G@�������0)b�W^����l�����V��{��4�g9`��t�Jc""�=�0���w3u��f����Clll�&"�V�V�
D]��k�����0�5�ce0��I��b2�dr�����D��!)�*`������t/��5k��/���^����Y�|97�hURD������9��hn��=Qy��k��R�w�eV������AA������c��%D��&#"���$7&�T�DFD;�w�����$����!!!\~����5������1~�xBBBX�lY0����o���7�H�~�������<���^�����L�>���hbbbHOO��O>�����F�Mdd$�^z)�<�.W����r222����g��L�4��^��udAA)))������8233�4M�������#GBx�����ty�R������g@3x	����0{�lV=���mE�v��mE�zz��	X����Cy����������x��g������;x���:th0������c��)����������_���^�����)S��r�X�f
�����o|�c��y���_��{�����q�F/^����Y�d��y���L�6��_�+V�a�HZZ[�l�:w�����5����a��|�I


�6m555����H��	%%f����� �����%��M���Q�MK���_*����r��dn��'&��J4Zf����g@�!���\�?����w;��0����6���h������1j�(222x���l���������)))�W�^���2r�H~�����c�PYY��a����������_������?g��=�3���������f��\s�5�?��/��^�z�s�N������;w�>�����v��Ajj*������w6/�����r��W�k�.����6~S"��p��aap�H��M:�'����y9>���5�����PQQAJZ��~��.�\�I^u�u�a�������f�s�;����Hg����x��a���+�t�Mf���mV�\���g��x4�r�x��WHOO����L�:����{����S]]Mff��=2331��^z��o����=�|������|���B>��,�_VV�;���w��	>RRRHLL�z�\��5p�/Wr8��^U����(�z	K����'O�����
�v[�9����n��
���9�9$��`�7���Zf%""&(E�<Hnn.�>�,��9��e��[�l!66��{�2w�\������7�t999DGGSRRBUU&Lhv������i555����g����
D���)**����g�_��=���<x���v��}�����KV�Y�65�u�}D�����>�R�wwk^j�����I�.�[���������=�����^�y�'&���Y�X ���c��5<��3^M���^x��v+�[VV��3g������>HJJ
������`��=l�����J������~��a_~�%�����������������m�	x�m���SD���`E�Y7+��AHc-U��vU�pnG2�����Y������<J0gN��_|��uO��FDD������3���/p��)��������={6�f�b�����������*���Y�t)�]w����s�=���kD�3A;)���IFD�)X�=I�V�����e����j88
���O��:���M�gN�����0�����5�*""��_9 �����k����;s������'eee�X��+/�=���n�n����{�����~���f�?~��ALL��~���TUUY��8������g����v��I�H�HM5�A�zU�zi%��on�@��Z����gR�GA�dj{���9q���wK�V�y���G�����HG�k������(y�������o{�����y���l�;���b���������9���p�!Oc���$''{�;z�(����7��o�����<����w��F��m|O+w�}7}����������}^'"�~�;5
���&�?��8��}����/>�:	��s.|���s�p�����}p8���Y��A�,���b0'������f����=ED����kY�n����'O^��t#�V�Xa\~�����0"""����k��1����'N����y�?����M���a,_��k��~�;��po���a���o�8p�q��)�9�~��n��g?��;~��e�u�]^����m8�Nc��}�}��
��a���[�}������c��������c�������=�v��a8�O���g��k��v�j��!�)efFb���.������3�?aag�K��� ��+
B���B���'a�}��M�da\����G�������1z�w;|zq��Z�������;�]w�e����p8F��}�[o��C�0��s�������>jl������mDEE�������~#::��������_��/�h�7�6l�q��1����W�2�N���Co�����������4~��y�W]]m�7����7�{�9c��M�����pc��-^����FXX�q�M7�6m2������7&L�`���X~.�-�Af�a����qq]3��2�3����mx �{F��$�_`�o��1��7����A���A����G`\:�R#cq��4)�H��h$MJ22g����cK�:�`��=�Nl�oGD������(q;{��������2e��p8��a�9���o~��!?���;g<��F||�f�1�x����=������>}���gO�O�>�M7�d|�����\�b�1j�(#""�1b��l�2��r5;��/�0�������FTT�1i�$��W_����M����#**����5222���
������;HL�~HOl�<��gG.��0s��w��i�����H�u�����J�_������,���	�Ab�v�1������;�H�"���w�eprK�-����6�������y����	������\���<�@��;�[_4�YS����o��`���������=������N�55��yu-��J'C��p�"�^	���Zh�����@���{���u��Z p�0�����9�|((]�ED�?z^k�� n���'??�g�y�_|1������tv���p��D8p����oP���������s�����|�o��}��}�GK1B���g��q���%� #���}y
X���^�l�2`=��~���&M��TPD���y����	����f�������}k�"���T�!���?��������5�{ ���Wyy9s�3��+J����eq���!5���
��Qk}S'��f����
����[��"""�P�;���-���.����`i�R�Y���8�@�� �Wg�C���[�1���ql��b��~$��
�A�QK^u����-�����Z�%""���P�:���iPS^^��Y���`�~8q	����cF{��n���	���{L�I���������`7E����\�I��b��YG������"�)����KY��*������H��4H��J���/B�����,����q�d��p��p4
BZ�����
�	3�H��v��������P�ly�����ap���P(,(l��EDD. "��xf%N\B�Z���P���pj������U����$�2s�����%��K�v��0��5Y����W9��a��YG�(��8���B��t;.\f zj��LK��'DE��o�%��<��Ym����c�^u�����*a��P���g���r�}��1��	�����v������[m>x������tr�=�`%�\��(
Y��u���1��K�1��	�� 5?��vQ-5?����p����g�^��0�+����e#�a��5�n�kX3f�7����.#�/���#�/�\��e�O��6�W��[����\0�U��t;���{d/��������yH�}����w��5�e9����b���������W��
�JV���m����1f��������-sG�K '?���"""�����L�I����k�6��!��h������Z�:[���4OBO�����5���lsGr���PDD:? "��5�\�����V5�~HO��8���{� :��m�#��9�a�XG�!���P7�<	���A6�lC�F\\�J���H����Z�v���F�[���8�:9��.s�]�����lg���u��-8N3����`&p��������	���
2�d26u,�RG16u,�K2�pGJM���������#����q��GPScn}�oV��r���G����-�N8�9+B��p}�F��5DD���%X"���-J����er����������{����Hkm������/���>���G�>�9�8i}S'6�i���!""RO����*'����>nQE��\	��p
�f������a|�6��oXU�d���ch���_����n�G������zq����,�+�GC����������iD����j�!�}�q+�`���VB�d��/�����t_AFn�u����
�RT���w/����+}��$�6�2������.�#p��]�����I����* �v�e_E�����VB�\8;�b�������AF����Z�����f��Z&����0�fp3�g���Y_^��;�H)�YcSC��"9���N6�0���[��������~9�k�����K���<3��7�n��	�$����>`�}@n���@DDDS""���u�t�Z�T��P��9�qv�(7_������},l���f�a���|�y�Yr��XTX�?C��T�WD,�T������K0K���V�7�������'1���v��v�����r0'��c_Nw0>K�������vk�DDD.N�K���uw�t�>>98���XB���%U#��1����K�_w�8���N�0�Jr���#����S���^.��9`2����y�B�����oV�w�����"xLDD�P""�)o��.���)�]�8��c�����z�������-���������������yP���q�eq�{�U��BH�����I�{}lR��������*O�KM��R�_GddC�Gt4�:�pnt�#�t_��olV�Z@�Y	6����y��T�m���|�<��0��I��!""�J
@D��]�)�F���5������j���@��t����a*�*p3I�<�2�[��7���b��
��%���%d"""�������m�����{uu�cM���eV���7�\T��c��Z�?�f�!N��WV��R`�c>}#�6_f��eV"""�P""~�[f�>f�;�o^��eVa�ap��3������6�/�����a���5�m�L��MV�!""
@D$ v��|�������p����rsA_��jg���@8P������l��_������T2���H;R""��	_���w����P[kn���4���`�	f5�F�#������s��r��_�@CDD�����X���05�\�}y IDATB�K���`�������\���=�
w`�i^�
��+u@5$$��1���$2"2�TXDDDZO3 "��W����,�]���eVYY���f~Hii�����P�������V}@���pP��(�A���H�hD����A�,����� sI&o�G����d.���>ZY��>���g9***0d�y���b��-���$OL6	+u���Da��=\������^=��
���HG��H;�5��Y�4��4a�WU��i[�����,���RK r%�N����W."%-�v�SNv[��RBI��ag��5j���A�%����5;�/MDDD�D�H;�������
�~j�cDDx�1+N�4�O�4_Q�U�J(ai�RX�W_50�I5����������x\\;�w�}@�T�������`�������g��,��b����3i "��W�Dg�pxo��fGB�7�J��9�A��0���B�Mv:�-T����N\\�epRQQ��io[��$�O���/��T�J����t2
@D�QG�<��y�k4^���
B]�D�����U�^Z	�s����1_�_D���s!�c9��%$��:g��j�eq]�l�h�	=';�vv����*p�K�H7�N(��0�~5��a��-���`�����
���]��Gc�R�N6�0����JKK��}�'��|}�G�?���Y��W�����"""]��n�WB�]pb�L�����4DN}���gfU��7�����G������������/�{�6�k���W't_�#"""�y)�&|%��T��1�C������u��������F9 W."��0j����q���
4��`#l9����������H��> "�Dn.������q`��sy������0��$/����`���dDd���w$��GR������������-�eq������
gj�X^��z�#"""�9iD��K<����K�<�aUP�p��*��>���b'3mn����=}�����H����@V9b��8r�a�������?i-��3��3_��������c����,f����U������#��0�i�������������H��D�i���m�:�r��������RW����"��;`n�/���S�h����O
?5��9�3��~[�`�G�Qg��*';����p�{������i��#"""���/�t����;�}����	F���a��s�s����l�7oQC��a�"��a6��C��6`?�3@1�8 xX��_��39�!~h��-}uBw����E�H7������'�k��Y����o��Qb='�u�G
�,�.��:�')W��~.5�^��t���Z�����ZJ
s	��:5���2���B��n����`����8EDD�{Q"�MX5tKH��^��"%-����8p�����i��p:8t��f��{}��gCA���K �T��<+v����O/"""]��vPQQa.az�I�Bv��-�����#��������g���j�����)������`�t�i��
�\f��XL�+��XUqUm��"""�et�*X+W���t�������������&&&���t>������`���DFFr�����#��j�p(//'##���8z����I�x���,�YPP@JJ
={�$..���L*�����*//'%-��TmJZJ��7PQQA��L�����G>`,����aF�����^����V�������Y�h������7�����?����	����z�������
DDD���HYY?��O2d�������3e�\.k��!77���b���op��1�s��_q�=��p�B6n�����Y�|9K�,�:����i�������b�
6l����IKKc��-^�n���Y�f1x�`6l���O>IAA��M����}���_v�����a���%,�^�ac��N��4g$���S���L4������_���wU�c����x��gRDDD�����`�y��L�:��}��v�Z�c?�0QQQ���+����+����#G��O��c�PYY���>��C}�Q���:jkk����=����1cx��g(**b��\s�5L�2��/���K��s�N���w�}�=��k��t�OW�\r	������r��w���#L����2#+C�����{��r�t�)�`��	T�<)�d81�+���6����6���9�bU!�	����GDDD�����w\�z5[�n�����0�K��\.^y����=�@||<S�Ne����}���TWW����u���L����^��[�~=�G��!!!|�;������?�0gf�y����O����Bbb���K���e]%
�Y�w?��bs���`V<��y����7l���B�`�W���b�<���-��=�a&�[������"""��t���/���{����c��!�����PUU��	�?~<�,���g�gc�
���y���������\�=��u��)�P�r�u��}��������`���D-���Yk��[��qO'�3'e���EDD���%�`-Y����$�eL��fBk�~������a���_2p�@*++��� **���111�{?~��������o|O�~�'&���^�R��x�����W�����1�E5-�{����9 /b&����
VO;F�Qk�#$�l��kah��� ��r��{����H�����k���+���\���i��t/9�9lM�J	%�~?���~F{=l��r������=��a�.//g��If�G���G��# �� �`.��h��T8h9a����7*��N��Z��+��t"#"�uW��o���"""��t������}�����?f����8q�����������3M?~��AL���Kuu5UUUDFF6;�������������x�������=����#	����W'I����q0���8O�GE�9����rB94��88�\b�h>N�<E���L�����p,	*���l�8�H,����g������,g9V��P�!"""]+9v����<��<�������0�|��YCTT�w7�����2r�H�����<���w����4����TVV2n�8������������������f�6�������>}�x�KOOg���>���#,,�������<�BB"	�'N�p�UW5��p@}<���g�������������Q����k�N'�Rl:��3!���<�W@p%
���1gK��:����deul(�7��K9��A�������^���JXX���"""]���kY�$�����h4�G�
@��������0{�16o�L~~>���'$$��s����/������UZZ����������>--���H�������<�����[�`�/����s���b���\{��4��C����������O����s�N�������/��������+�h��%��o����������d'$ [�"A�*�M����(.��|I[�C�P�����qa�U�EJ����@DY�E�HX���-$�������a�$0�����p�������	�����m� 3����d��
��X���8���O�M�b�rUb�:��w����D��[���~N���Yx��84�����b`����������O��>���M���K��0`�W��������*�E��K*����}��>�S�N%,,�[o��S6f�Z�hA���6l'N�`��Q��U�+�������=#G��F�t���5k�0f�y�7>�-���L�0������_~���D�x�
���;-Z���?��Ot�������������a�h������ry��;h�v������K�h��Y����4/Nb�~U�`�h�*����T����{3|����\�,���}���������C���{	�c���?�g�������c��	�?�:u���s�1b���"##Y�x1C���'�����4o�����s�-�x���}{>��cF�E��=�R�
=z����3��tJ'e��q����%��)p���A�o8iq[��x��u
v�IU��4��������]�O*LI���u�t����u+=�_O2����������/PXX������s��X�:���+{,�S��l�y�1��X�^�q����4�\DD.k��v�.�������b��e�nk���z���v�k�e'N=X����������8=�n1��?����j�1pM�5�u������D���3f���ge�e�������N>��5��s�q���Nx��l�yQ��uA�M�4�J$���3��L��Y���V�N�z�/RDDDB��0{��|��8{v�$ Y�������piQi>���i��k����[��srrX�m����V-��L	�H9�7��2a&��U&�8�J��?�c�1����b����,�8d��f%"""��P�����v�F�`���;v��gJBJ�g�����"��+��M�Y��"���^b=���~���X�����D�f%"""�B	��8����vf�w]�������2w������~����X���mnn��=����k������	9s���b�����
���/����oo�������2�4��	���vB�[�9�o��q���B�9DDD��P"!��7�^���A{�B���l����l~����+~�a���+��M���7��5-�7{������<Q�k�s|��}����x��s���He�DB���v�����gw����<9�I~8��3�Y� �3�i��{�
�^��hNU�����n�!"""��	)m��=99��ho�I��0}:�<i�h�����O�EE���Y���U��`�����Z\���GYDDD.�3�"r��2�w����ln��=�N0�~�=��|>h�����'�'������=��I�u{�e��g�
��A69�'��srr�����7_~N�����a�����
��N`J�����a�-��nvk0����\���HH	4�Z58r���������B����l�������>��].8�}�UY	��N������6�5�{��+�������"""r�S"!�� �����j�N'!�{���������1C���a0y�]��)�3Z]
U?����G{2�^�v�dB��EDD�R�DBJ���@��A�%��K����KzHJ��u�/?���<I}��@��R-
c��L�>I="""����e�i����V��JAAK ���|V�ZMNN*���1������8e�~8�r�^��-lVx�u*��)�3c���z�""""�
% R�����N�<^~����}����hv��M�n����71cF��ii��+;
��#'`��1 ��./����0�?��!""""�M�+�VI"�}�������4��3f��A�S��W��_|Ff�L��#=��N7=�;�q���;�h���J�P����sj{6�?~�A���D*��]��i��/�Zm�T4��tzu�^�V/Z���<?@�U������,�������j������N	�TZ��j9��eo�����tOE�2�����sR���C��[9r�%�DcY�����#������>X�30��)�J�)�(-P]��p��/X?������kV�g=K��=�l�	�v��I��7
�9<E~.��q�gq�""""�'% R��x�����9��|�-���l��o�|���8\�0�;�ZP���p����86�^D����
��NN�C��:gq�""""�'
B�K���v���������?;�Y����ks���{{!����G���9���]�b`w�����~�����B/_DDD�����5�����*����;�i����3�[�v�p��M�
���<N��{<������NP������"(�]������.,(""""�0% ��|��(�Af&c?6jt:	�����QQ�6����][������]�Y�r9�N(�sz�����q^�c+�B�]����+k7���7�Q�Z�\DDD�% ��i��HBrrr��>c���1�������$&&z�T:Q��>��`�s�jE`\�E�a��	]�����P��X���3�@��q��xu��J4DDDDh�x9��7.���lZwk��������0U3i��59��b��i?B��s�A��U��b ��.;��"�z��l��E��dQR��dQ���X�`��?�"^�w�����H�l�n�C��;���d��!��������a��c�}{Vd�S�
&}��p����y�gv2����"��G�����N�z�W+"""Z�"^�L���!%�~�X�_���^k?����V���x�1������k>g��b�cv�(�����0�)B�o��^�'%�����W��#""""^�">.���sW�����ez@8���=��������+����eW;/
��>�������{ �@���G��rw��J<����
�Aq����6�w���=�.�c��(,*��'{������� ��������w�����s	������	�3�+��jy^CN��.{;�	4����c<z
����`�LU��3S����Y0g��O��w��!�{}�O�{������^#��Z�3�=t""""�% R��L���H��0��8���O���g�]��r�	;�������!eo���l�p^*apwv3i�$��������n�����G1XE�F������?J@�#''�!�����2�����������:�w{�W��D��� ����
	��= ����NR��a�������+���g���!IW&���DDDDD	���Y��y���������Vum���Y�mV)�Y�����eY~�\����������7���v��k����t>� t9���FN�?��wf�L��r^����!}P:��#X��v��A�����0s�
���_��n�������R���RSS��l#
74$��H"&E�N$
74d��������	EDDDD	�����(����sT����w��)�
X���L{��������IO?5��_"�|���TG�������b?���������8��$�8��$���N������y�-X�Y{����}	J�������[PX����<9�I�c������G�S%n&�C�&���M?�:����" ��#
��������@=N�2�X�D��""""M	����pJB�O��A�F�k\u|���^��~v����M���p�4����0m%$J�%@o�^�S�Q�|T�yf���]��6�������H�S"@��7�f|�k�����a�{�{�U�T�J�����'#��\PH���r��	C�����!`�h���I�DDDD�|��`��q$oHv[��!�q��<>3�w����d�SIG���dc��E�����~n���*��U��8�@ug�D����H�S"$&&�j�*���h��	)Sh��	iQi^S����^k?�����Y��	���aT��vy=g��n`���v�^�<�D)��������D����H��=)�����w�p���y� '��K|�!x�](.������n�������s���<Q}`��������5?f��,��Lb���$$$��).*����_LQDDDD.����?�\	m�z�`�r��|��������[�������P��9+�z��w��c�����cO=�u��4�{ "2��������(�XJ@�K�^��m���HL���l�B���������`�)�{���3Y9
l�>�:����R��Nw!�����}�""""$J@���^����#��Ow;�p���
�/nX{�]'{����R��T����+o�������H�R"^�z9J+}K@��Y���H�fu���j�+���X�U���5�CDDD�Rv����x�b���GJJ
�����_�^�z�~�z�}��_O�N����#>>���{�s�N�����k4n����h~��_�����v������MZZ��������M�,q�S��E�h��5���$&&���NNI�B%5e
t�))�cI����C��t�k{������^G��t�]�����5;���f�{s� IDAT���5P�j]fN���	S��r����-+�0u�T%""""��K.y����������f������+dgg��U+�.]��o��mt������Y��2e
��o��[n���^�|��<x0��{/.�����_d��A^��<y��;�t�R^}�U���K��������/��w��e�~����S��s���+��h�":v�HAAA���$_~{$\����I�7�|C�n��vr�t���]��M�o�vr���d$�]�=pe����K�I�&�$���V��������h����\�,c�����Rvv6�j��*;v�
6������O?����g��edffR�jU���h��O?�4/��2�����_���4&N��9�K/����{6o�Ljj*o���?�8�V�����%EEE����U�V��/����eKN�8��_��e�y�V��m�����<���>��~�zn��&��[��7�x�BvV���is{2�g��T��X��~R��]�:&{�]��o���z���7ln��o��VDDD�RP���.�\H�� 66���T������v��7o�{��$III�v�m��3�S�`�N�<Izz��9���1������S6g�7n�I>���x���X�z5?��#{��e��������|�n�������,��j'
?��G���	����h��!��D1)��w"i�����uYB?|��g�@ff&����p�
>�6m��O?����"##��y����+������l��)��y3���w<'�S���S�sN�����������_���~*
&�aS�(��
��Qn���0s�L�N%""""�E2h� N�8��#��*�5j��[�F
�1<x���k���KTT111>����{����������L�_�������;��@�/�i���f��3����#G2}�t^�u�7o^��9+����~�	'��Q2��i��^h���V��r��)m��1�������<��c���5kv�EYyyyX�E||�g��'O�����o��J��w���{��/}���e���g�����kv����7$3n���4RDDDD.y�l��1c<?��
��KNN&&&��7��i�&5jDdd$pz����i���g����������_�)k����s�}K7n�H�n�|�-}N'�?�8��W�*���7��{o��.���c�O�S�� �'����yf�3�[8��vPL1.\4��!}F�!""�C��[�DDDD*�|������>\A����K���?o,�2�F����<`j��m�9�)��k����4�=���,//������z��K/��e�n��)�8q��,�|�������Bs�u����[{��_��4m��y�V�Ze,�2o���c���[g�n��3D�|dgg����L�6MLJ���M��X�����������T6�}�rp�������g�}�n����?����o���~�--Z���od��a�8q�Q�Fq��!���+���^|�EF��s�=G���Y�f
#G��_�~������


��������y���ILL��7����>b��E�r�-�}�-[F������$;;�a�����k�����6�+-"""R�������n��7o�e�`�,X�UgYEEE\{��ddd0t�P���^������#�����1|�p����0a����N�:<��s�Y�JDFF�x�b��O<����i��9����J>��o����Q����'U�T�G����vL>DDDDDB�%�r9SF-"""R�������g��K�	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H��Wt�r���-8�����\yN�lT�����

�����F�|��n�N`9��"#"��st4����O������E��"�^R��	����7���\�sV�k	u�\����2���n����_�M7���u��������bbH��,l��kRR|��&Yp�f+r�?���"������@
?m9��e���O�'�L]>p���|9@��v������@s�X��������C�k�vH�����}�����MI������Nm,
�T�:�
�n�_E����k��������e��]XHu�����^�����!N�'��o�{�����u����XX�iC��'��V��0?�u�����),��P(���p���j��5�X��w�4��2��r���������x��/,,$�2�����q���	��%���J}����w�u8����p1���s�u.�-�#P��Lt�F��b����y�;�>��\���P����v�0Rn�9b�z�)S�n]m�5kff���w�u����[�.����a8���Sn�����ug��W��<���][��@�8���O[��|�����9�9��)���2�9����������@����������YQ����u>�����|��B�=�k����;��9/�w��v���L���s�HI9������_�9�v\�q��{��7����P��P�}�r�[���=�����k����DJJ
���>}������>}�Tt�DDDDD�N�������E��8q"�<���������s��<���;t�����JH1����RL�)�_3f(*e)&r�))'s��!..������<==�}�����_VP�.=���K1����RL�)�_���K1��M	H9��y3����\�!n��)[�l��f�����T(% �$77�5j��������I"""""N�������3�n�Sg���rrP�����2F#�DDDB��rR�fM�^���<O�?[�n-�v������9�����T ��+}��ee�gvw
q�o�`�e�tl��}��]p���z��r����?�v��p���"���sz.�����8
����a���b��c�8����k8�v;^CI������kS���^�@�;�����)��� �8��e��tL��������W��M2������g�{\�x��n���fe�=g�{(P,K�m��Mjx8N������6�[��q�s�D:��s��{=��MC��C�v��|���|a>J���?��~������}�����8�����R����6�;g��B��MC ���s�u :������O:.P;������w>�������h�p}G��>w�}����%^�cl��U��.7Z�������e��:t�k���3y������i����1?��#7�|3���vsEDDD�,��[��k�R�N��n�%I	H9Y�`w�q3g�������w���-[�����e�������fSEDDD���SG���-X��[�nt�������?�����3X�p!����c�zC������M= ����c�1�����������s�=��#"""""J�������H�h	% ����G<x0���#&&����������G�e��!t�����D\.c��q�w���t�����8������7;w�r���������)))���R�~}z���8�`(�������;������J�*��Y�6m�������*1q2i�$\.qqq>u����\.��������
�x���g�q�wP�F
�T�BJJ
c����'Tb�����}R��*1X�v-w�uu��%66���T���?r��	��B%&�W��k��T�V���8~��_����;�*1����T��s���?=z4,�E�����3fTt����x��w(,,����p��m�6:t����f��YL�2����s�-�p���`7�����[dee���O3�|^y����i��K�.��*�8|�0III���K��?���\}������^x��_(����{���3�P�n]��O�����^��/�������<��������C�����?�����:t��>��Q�F��?V�ZEBB
4�E�@h�d��M�k����w������G��_�����>}�x����Y��[o���'O��{�������|:v��_|��o���\�P}���,���9���K�.�^�z�����Z|0�e�1c����w�}�V�Z���#��]�v���H3t��`6�\���O>eG�5W^y������,T�H�V�LRR�g;�c��{w��W/���f�V��U*qY�t��,���=;�~�c���g����5�
�_(��IFF��,��5�SJ1>|��,�dffz�����5�e�C�cB'&]�v5u��1'N���9r�$&&��m�z�*1)��`s��!..������<==�}�����_VP�������v3o�<z��M��U=�III�v�m��3'XM,w�j��)+���gZ��f�����C9&���+V�`��	>��P����#z��4i�����(-�b�d����\.~�a �b
@������W�NXX���!��+W��CO\�V��-�����������{�\lJ@*����IMM�Z-�i��l���"�U�dff����
7��S��iSv��AAAA�,8>����=���j<�1��nrrrx��7���Ox��g����O?�����y����[��O}(�e��ADDDP�zu�u����+=u�����S�fM����5kFDD�k�f���9r���u��a>��:v�HRRz1IOO'11���s�N�9��y�x���4h111!���B���|�K�6o�����bSR�rss�Q��OyIYnnn��T����_��1<x0��
�A�q��	F��n<Hdd$�k�����b���8��4�&M�����:��R\���
��o�MFF���
�w��C�,\��x�=6���c�����������������;�����5c����=�z1�_�>l�����d�W�N��=IKK���;Z1i��	�V���Mu����%������.R��9����������y��nN�1b���o���f�����w�#???��%��>��y�����_WtS*�f����Y3�v��m����i��)C��K�.���Q\\L~~>�G�f��!�z��DFF2x�`�,Y�u�I(�<y2			�IPB���~K�N�HNNf��q$&&��_0v�X�9��I�*��A��O�������3b����3f�w���cE���
V�fM�^���<O}�+�AILJ�����,������r7f�^x�^|�E{�1Oy���A�4h��n��v�����\L�=���?��O>I���9t������������\\��^�:w�y'o��'O��x��Y�;v��kW������
���:1)m����[�����)������)..��O>!&&�v�����@�������_j��
�FL������a���L�8�����3���?��z����>����U�n���[�R\\�U�i�&�����hV����LLL7n����i�5"22�ZV~����6l�W](��I�-p��|���!���������Q���g���;v���x���K��
C*.�X�r���=BNB1&�M�<�x��ZL�l�B�&M<�G��o��Sj�K�Bnn.�7of��]�X����<�V��M7���������������������/���]���������
jY���������0�k�v������f3����?�3%dY����k������1����|���a�-[�����0��u3111f��ef��-����KYyyy�^�z��o���R<>��ScY�y�����������g�}f�	������75j�0�Z�r���t�����U�=z������6�e��s�cB+&e����T�^���w��*��\(% �@�.]L�5�;��c�,Yby�cY��>}zE7-(>��c3k�,3e�cY�������Y���Y������1�l������������������?����7����|��?�X�en��v��_�U�Vy���xc�#�<b�y�����ddd�>��<����,�y�C)&�����g�P���>hF�af��m�.]j�~�ms������H�x�b�~��=z�0���f�����O?5/������1={���j11���3g����I��C)&}��q�\�u�������Y�x�y��L\\�����Maa�1&tb�y�f��?����7�|���f���&!!��l��;v�k�P�IyPR	=z�<��S�N�:&**�4k���G�rv��W���eY��ry�{��]����[g:u�dbccM����=��c����
l����C���q�\^��B<�1f�����[o5���&""������n������>��JL�IKK3qqq>����_~�4o��\q�&<<���U������]��g�P�G�'N�a�����$a���j3b�SPP��_(���qqq>�/-�b�|�r��[7S�n]S�J��qc�������<��B!&��o7:t05k�4QQQ&%%��5����B!&��2&��M""""""�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h����T��uV?��/w<�C��v�mAn�L�>�W^y���!"r��J�""d����c���HFFK�,��/55���8���m�@��������{��l����;wVtSDD.I���P��eK����,��)/������\������T�R����reYVE7AD���[�DD*�:��iS�/_N�6m����������k��=�{��T�V���xz�!��Y�����w������F\\�7o�K�.T�V�N�:����r�]w��Abbbh���>�(���^�5z�h\.�6m�����z��$$$�������"�n�J��]�V��\s
��_������y���h��U�T!>>���[���z�3n�87nLtt4�k��_�~�����\W_}5����q-���\.3g�d����W������sg�o��u���?��u�����=����Tb�e���?��o_���/������_��;�m����C�7n
6���?���������={����2|�p�n7����j���~���x~��������];6m�Dx����?}��e���,\��q��q��1�.]�SO=���Cy���y��gi��!w�uW�kNKK����g���;���H��[��]�<�8�w�y�'�x�����s�NF�IFF����f���kv���W>|�p��k����9|�0C��G�l���������o~�����9s^����aDD�R�����Z��WY����eY&##�g������n���=a�cY����O��{��G�eY��w��z.����i�������]�v�����s=u���eY�o���1��77�e������2��mj��e�������|�rcY�9r��}�n�j,�2�?��W�����eYf��������������l��.]j,�2��w��o��Y��,��_x����Ns�5���O��""�\�5h����[�l��U�K�.^�}���{L���}����y��Gi��DFFr��W�����{w�����r�����=eaaa$''���������A����t�R��))�E�����x����H��=���6m
p�v�����-X""�\�:u�j���\j���S^�V-��ccc�Z��WYqq1]�ta����9��M�KQQ�Z����>��Q���vdd$U�T!22��<///�5����x%J��8��N�:���;�sRr�V���(�����DD��;��j����5k|�������y�f6n�����K��}=�;v�8�s�=���HLL��v�?�AIDAT��~���J�}J��}��Q�n]��}��������������>����%11���(""F�`��T"2�k�8r�,�*�9s�Y?WIY�����z���r��q�w0q�D��t�����{��|��5l���S�,X_���~��ow���lEEEq����>^D$��DD�q�9��P��_�~��o���b���$''3�|.\�3]��ySSSINNf��ac�����?d��E|g��v����o_���O?���w�ITT6l 66�����~�����k��r����?��#G�$))���~�s��}���C1h� ���v������gj��u��47�ps����7���o��rq��7���DDB��J�ijX��:�U�R�%K�0x�`��eYt���7�x�;���+�����
��?��������-���t���E����tVm;����M���7������6m111\w�u>�����INNf���L�0����s�����K/����d��}����L�:��M����o2z�h�X����z�-[�0|�p>@QQ�Y+""`������\^|�EF�����}�L����z@DD.#���:`O�[XX��%Kx�������������\Fbcc�����?����'����6l����+�i"""�n�� �4�"""""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4J@DDDDD$h�������H�(��Q""""""A�DDDDDD�F	�������	% """""4��J� ����IEND�B`�
substring_similarity.patchtext/x-patch; name=substring_similarity.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 4,10 **** MODULE_big = pg_trgm
  OBJS = trgm_op.o trgm_gist.o trgm_gin.o trgm_regexp.o $(WIN32RES)
  
  EXTENSION = pg_trgm
! DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
  REGRESS = pg_trgm
--- 4,10 ----
  OBJS = trgm_op.o trgm_gist.o trgm_gin.o trgm_regexp.o $(WIN32RES)
  
  EXTENSION = pg_trgm
! DATA = pg_trgm--1.3.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--1.2--1.3.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
  REGRESS = pg_trgm
*** /dev/null
--- b/contrib/pg_trgm/pg_trgm--1.2--1.3.sql
***************
*** 0 ****
--- 1,53 ----
+ /* contrib/pg_trgm/pg_trgm--1.2--1.3.sql */
+ 
+ -- complain if script is sourced in psql, rather than via ALTER EXTENSION
+ \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.3'" to load this file. \quit
+ 
+ CREATE FUNCTION set_substring_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_substring_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- /dev/null
***************
*** 1,188 ****
- /* contrib/pg_trgm/pg_trgm--1.2.sql */
- 
- -- complain if script is sourced in psql, rather than via CREATE EXTENSION
- \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
- 
- CREATE FUNCTION set_limit(float4)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT VOLATILE;
- 
- CREATE FUNCTION show_limit()
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT STABLE;
- 
- CREATE FUNCTION show_trgm(text)
- RETURNS _text
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION similarity(text,text)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION similarity_op(text,text)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
- 
- CREATE OPERATOR % (
-         LEFTARG = text,
-         RIGHTARG = text,
-         PROCEDURE = similarity_op,
-         COMMUTATOR = '%',
-         RESTRICT = contsel,
-         JOIN = contjoinsel
- );
- 
- CREATE FUNCTION similarity_dist(text,text)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE OPERATOR <-> (
-         LEFTARG = text,
-         RIGHTARG = text,
-         PROCEDURE = similarity_dist,
-         COMMUTATOR = '<->'
- );
- 
- -- gist key
- CREATE FUNCTION gtrgm_in(cstring)
- RETURNS gtrgm
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION gtrgm_out(gtrgm)
- RETURNS cstring
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE TYPE gtrgm (
-         INTERNALLENGTH = -1,
-         INPUT = gtrgm_in,
-         OUTPUT = gtrgm_out
- );
- 
- -- support functions for gist
- CREATE FUNCTION gtrgm_consistent(internal,text,int,oid,internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_distance(internal,text,int,oid)
- RETURNS float8
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_compress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_decompress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_penalty(internal,internal,internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_picksplit(internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_union(bytea, internal)
- RETURNS _int4
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_same(gtrgm, gtrgm, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- -- create the operator class for gist
- CREATE OPERATOR CLASS gist_trgm_ops
- FOR TYPE text USING gist
- AS
-         OPERATOR        1       % (text, text),
-         FUNCTION        1       gtrgm_consistent (internal, text, int, oid, internal),
-         FUNCTION        2       gtrgm_union (bytea, internal),
-         FUNCTION        3       gtrgm_compress (internal),
-         FUNCTION        4       gtrgm_decompress (internal),
-         FUNCTION        5       gtrgm_penalty (internal, internal, internal),
-         FUNCTION        6       gtrgm_picksplit (internal, internal),
-         FUNCTION        7       gtrgm_same (gtrgm, gtrgm, internal),
-         STORAGE         gtrgm;
- 
- -- Add operators and support functions that are new in 9.1.  We do it like
- -- this, leaving them "loose" in the operator family rather than bound into
- -- the gist_trgm_ops opclass, because that's the only state that can be
- -- reproduced during an upgrade from 9.0 (see pg_trgm--unpackaged--1.0.sql).
- 
- ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
-         OPERATOR        2       <-> (text, text) FOR ORDER BY pg_catalog.float_ops,
-         OPERATOR        3       pg_catalog.~~ (text, text),
-         OPERATOR        4       pg_catalog.~~* (text, text),
-         FUNCTION        8 (text, text)  gtrgm_distance (internal, text, int, oid);
- 
- -- Add operators that are new in 9.3.
- 
- ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
-         OPERATOR        5       pg_catalog.~ (text, text),
-         OPERATOR        6       pg_catalog.~* (text, text);
- 
- -- support functions for gin
- CREATE FUNCTION gin_extract_value_trgm(text, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gin_extract_query_trgm(text, internal, int2, internal, internal, internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gin_trgm_consistent(internal, int2, text, int4, internal, internal, internal, internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- -- create the operator class for gin
- CREATE OPERATOR CLASS gin_trgm_ops
- FOR TYPE text USING gin
- AS
-         OPERATOR        1       % (text, text),
-         FUNCTION        1       btint4cmp (int4, int4),
-         FUNCTION        2       gin_extract_value_trgm (text, internal),
-         FUNCTION        3       gin_extract_query_trgm (text, internal, int2, internal, internal, internal, internal),
-         FUNCTION        4       gin_trgm_consistent (internal, int2, text, int4, internal, internal, internal, internal),
-         STORAGE         int4;
- 
- -- Add operators that are new in 9.1.
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         OPERATOR        3       pg_catalog.~~ (text, text),
-         OPERATOR        4       pg_catalog.~~* (text, text);
- 
- -- Add operators that are new in 9.3.
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         OPERATOR        5       pg_catalog.~ (text, text),
-         OPERATOR        6       pg_catalog.~* (text, text);
- 
- -- Add functions that are new in 9.6 (pg_trgm 1.2).
- 
- CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
- RETURNS "char"
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 0 ----
*** /dev/null
--- b/contrib/pg_trgm/pg_trgm--1.3.sql
***************
*** 0 ****
--- 1,241 ----
+ /* contrib/pg_trgm/pg_trgm--1.3.sql */
+ 
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
+ 
+ CREATE FUNCTION set_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION show_trgm(text)
+ RETURNS _text
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
+ 
+ CREATE OPERATOR % (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = similarity_op,
+         COMMUTATOR = '%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE FUNCTION set_substring_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_substring_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE FUNCTION similarity_dist(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = similarity_dist,
+         COMMUTATOR = '<->'
+ );
+ 
+ -- gist key
+ CREATE FUNCTION gtrgm_in(cstring)
+ RETURNS gtrgm
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION gtrgm_out(gtrgm)
+ RETURNS cstring
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE TYPE gtrgm (
+         INTERNALLENGTH = -1,
+         INPUT = gtrgm_in,
+         OUTPUT = gtrgm_out
+ );
+ 
+ -- support functions for gist
+ CREATE FUNCTION gtrgm_consistent(internal,text,int,oid,internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_distance(internal,text,int,oid)
+ RETURNS float8
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_compress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_decompress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_penalty(internal,internal,internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_picksplit(internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_union(bytea, internal)
+ RETURNS _int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_same(gtrgm, gtrgm, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ -- create the operator class for gist
+ CREATE OPERATOR CLASS gist_trgm_ops
+ FOR TYPE text USING gist
+ AS
+         OPERATOR        1       % (text, text),
+         FUNCTION        1       gtrgm_consistent (internal, text, int, oid, internal),
+         FUNCTION        2       gtrgm_union (bytea, internal),
+         FUNCTION        3       gtrgm_compress (internal),
+         FUNCTION        4       gtrgm_decompress (internal),
+         FUNCTION        5       gtrgm_penalty (internal, internal, internal),
+         FUNCTION        6       gtrgm_picksplit (internal, internal),
+         FUNCTION        7       gtrgm_same (gtrgm, gtrgm, internal),
+         STORAGE         gtrgm;
+ 
+ -- Add operators and support functions that are new in 9.1.  We do it like
+ -- this, leaving them "loose" in the operator family rather than bound into
+ -- the gist_trgm_ops opclass, because that's the only state that can be
+ -- reproduced during an upgrade from 9.0 (see pg_trgm--unpackaged--1.0.sql).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        2       <-> (text, text) FOR ORDER BY pg_catalog.float_ops,
+         OPERATOR        3       pg_catalog.~~ (text, text),
+         OPERATOR        4       pg_catalog.~~* (text, text),
+         FUNCTION        8 (text, text)  gtrgm_distance (internal, text, int, oid);
+ 
+ -- Add operators that are new in 9.3.
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        5       pg_catalog.~ (text, text),
+         OPERATOR        6       pg_catalog.~* (text, text);
+ 
+ -- Add operators that are new in 9.6 (pg_trgm 1.3).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
+ -- support functions for gin
+ CREATE FUNCTION gin_extract_value_trgm(text, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gin_extract_query_trgm(text, internal, int2, internal, internal, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gin_trgm_consistent(internal, int2, text, int4, internal, internal, internal, internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ -- create the operator class for gin
+ CREATE OPERATOR CLASS gin_trgm_ops
+ FOR TYPE text USING gin
+ AS
+         OPERATOR        1       % (text, text),
+         FUNCTION        1       btint4cmp (int4, int4),
+         FUNCTION        2       gin_extract_value_trgm (text, internal),
+         FUNCTION        3       gin_extract_query_trgm (text, internal, int2, internal, internal, internal, internal),
+         FUNCTION        4       gin_trgm_consistent (internal, int2, text, int4, internal, internal, internal, internal),
+         STORAGE         int4;
+ 
+ -- Add operators that are new in 9.1.
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        3       pg_catalog.~~ (text, text),
+         OPERATOR        4       pg_catalog.~~* (text, text);
+ 
+ -- Add operators that are new in 9.3.
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        5       pg_catalog.~ (text, text),
+         OPERATOR        6       pg_catalog.~* (text, text);
+ 
+ -- Add functions that are new in 9.6 (pg_trgm 1.2).
+ 
+ CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
+ RETURNS "char"
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
+ 
+ -- Add operators that are new in 9.6 (pg_trgm 1.3).
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text);
*** a/contrib/pg_trgm/pg_trgm.control
--- b/contrib/pg_trgm/pg_trgm.control
***************
*** 1,5 ****
  # pg_trgm extension
  comment = 'text similarity measurement and index searching based on trigrams'
! default_version = '1.2'
  module_pathname = '$libdir/pg_trgm'
  relocatable = true
--- 1,5 ----
  # pg_trgm extension
  comment = 'text similarity measurement and index searching based on trigrams'
! default_version = '1.3'
  module_pathname = '$libdir/pg_trgm'
  relocatable = true
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,37 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
  
  
  typedef char trgm[3];
--- 26,38 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber			1
! #define DistanceStrategyNumber				2
! #define LikeStrategyNumber					3
! #define ILikeStrategyNumber					4
! #define RegExpStrategyNumber				5
! #define RegExpICaseStrategyNumber			6
! #define SubstringSimilarityStrategyNumber	7
  
  
  typedef char trgm[3];
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern float4 trgm_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,125 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ #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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern float4 trgm_limit;
+ extern float4 trgm_substring_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 176,181 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 177,183 ----
  	bool		res;
  	int32		i,
  				ntrue;
+ 	float4		nlimit;
  
  	/* All cases served by this function are inexact */
  	*recheck = true;
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 185,191 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 190,199 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  				if (check[i])
  					ntrue++;
  			}
  #ifdef DIVUNION
! 			res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= trgm_limit) ? true : false);
  #else
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  #endif
  			break;
  		case ILikeStrategyNumber:
--- 193,203 ----
  				if (check[i])
  					ntrue++;
  			}
+ 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  #ifdef DIVUNION
! 			res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= nlimit) ? true : false);
  #else
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= nlimit) ? true : false);
  #endif
  			break;
  		case ILikeStrategyNumber:
***************
*** 256,265 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 260,271 ----
  	int32		i,
  				ntrue;
  	bool	   *boolcheck;
+ 	float4		nlimit;
  
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 267,276 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  				if (check[i] != GIN_FALSE)
  					ntrue++;
  			}
  #ifdef DIVUNION
! 			res = (nkeys == ntrue) ? GIN_MAYBE : (((((float4) ntrue) / ((float4) (nkeys - ntrue))) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  #else
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  #endif
  			break;
  		case ILikeStrategyNumber:
--- 273,283 ----
  				if (check[i] != GIN_FALSE)
  					ntrue++;
  			}
+ 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  #ifdef DIVUNION
! 			res = (nkeys == ntrue) ? GIN_MAYBE : (((((float4) ntrue) / ((float4) (nkeys - ntrue))) >= nlimit) ? GIN_MAYBE : GIN_FALSE);
  #else
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= nlimit) ? GIN_MAYBE : GIN_FALSE);
  #endif
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	float4		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubstringSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,304 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubstringSimilarityStrategyNumber:
! 			/* Similarity search is exact. Substring similarity search is inexact */
! 			*recheck = (strategy == SubstringSimilarityStrategyNumber) ? true : false;
! 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 312,318 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 463,469 **** gtrgm_distance(PG_FUNCTION_ARGS)
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,473 ----
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg, false);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,27 ****
--- 15,33 ----
  PG_MODULE_MAGIC;
  
  float4		trgm_limit = 0.3f;
+ float4		trgm_substring_limit = 0.6f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(substring_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(set_substring_limit);
+ PG_FUNCTION_INFO_V1(show_substring_limit);
+ PG_FUNCTION_INFO_V1(substring_similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_commutator_op);
  
  
  Datum
***************
*** 41,46 **** show_limit(PG_FUNCTION_ARGS)
--- 47,69 ----
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
+ Datum
+ set_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	float4		nlimit = PG_GETARG_FLOAT4(0);
+ 
+ 	if (nlimit < 0 || nlimit > 1.0)
+ 		elog(ERROR, "wrong limit, should be between 0 and 1");
+ 	trgm_substring_limit = nlimit;
+ 	PG_RETURN_FLOAT4(trgm_substring_limit);
+ }
+ 
+ Datum
+ show_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	PG_RETURN_FLOAT4(trgm_substring_limit);
+ }
+ 
  static int
  comp_trgm(const void *a, const void *b)
  {
***************
*** 166,203 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 189,208 ----
  	return tptr;
  }
  
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 237,243 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 242,281 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! static void
! protect_out_of_mem(int slen)
! {
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 254,259 **** generate_trgm(char *str, int slen)
--- 292,534 ----
  	return trg;
  }
  
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	t;
+ 	int		i;
+ } ptrgm;
+ 
+ /*
+  * Make array of positional trigrams from two trigram arrays. The first array
+  * is required substing which positions don't matter and replaced with -1.
+  * The second array is haystack where we search and have to store its
+  * positions.
+  */
+ static ptrgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	ptrgm *result;
+ 	int i, len = len1 + len2;
+ 
+ 	result = (ptrgm *) palloc(sizeof(ptrgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].t, &trg1[i], sizeof(trgm));
+ 		result[i].i = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].t, &trg2[i], sizeof(trgm));
+ 		result[i + len1].i = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const ptrgm	   *p1 = (const ptrgm *)v1;
+ 	const ptrgm	   *p2 = (const ptrgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->t, p2->t);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->i < p2->i)
+ 		return -1;
+ 	else if (p1->i == p2->i)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative procedure if finding maximum similarity with substring.
+  */
+ static float4
+ iterate_substring_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate substring similarity.
+  */
+ static float4
+ calc_substring_similarity(char *str1, int slen1, char *str2, int slen2)
+ {
+ 	bool   *found;
+ 	ptrgm  *ptrg;
+ 	trgm   *trg1;
+ 	trgm   *trg2;
+ 	int		len1,
+ 			len2,
+ 			len,
+ 			i,
+ 			j,
+ 			ulen1;
+ 	int	   *trg2indexes;
+ 	float4	result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(ptrgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required substring.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].t, ptrg[i].t);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].i >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].i] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with substring */
+ 	result = iterate_substring_similarity(trg2indexes, found, ulen1, len2, len);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
  /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
***************
*** 426,442 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 701,707 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 557,563 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 822,828 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 591,604 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 856,869 ----
  		}
  	}
  
! 	/* if inexact then len2 is equal to count */
! 	if (inexact)
! 		return CALCSML(count, len1, count);
! 	else
! 		return CALCSML(count, len1, len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 693,699 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 958,964 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 704,709 **** similarity(PG_FUNCTION_ARGS)
--- 969,990 ----
  }
  
  Datum
+ substring_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2));
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 722,724 **** similarity_op(PG_FUNCTION_ARGS)
--- 1003,1025 ----
  
  	PG_RETURN_BOOL(res >= trgm_limit);
  }
+ 
+ Datum
+ substring_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	float4		res = DatumGetFloat4(DirectFunctionCall2(substring_similarity,
+ 														 PG_GETARG_DATUM(0),
+ 														 PG_GETARG_DATUM(1)));
+ 
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
+ 
+ Datum
+ substring_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	float4		res = DatumGetFloat4(DirectFunctionCall2(substring_similarity,
+ 														 PG_GETARG_DATUM(1),
+ 														 PG_GETARG_DATUM(0)));
+ 
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>substring_similarity(text, text)</function><indexterm><primary>substring_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar substring of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to substring of the second substring).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 111,116 ****
--- 122,145 ----
         Returns the same value passed in.
        </entry>
       </row>
+      <row>
+       <entry><function>show_substring_limit()</function><indexterm><primary>show_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the current similarity threshold used by the <literal>&lt;%</>
+        operator.  This sets the minimum substring similarity between
+        two phrases.
+       </entry>
+      </row>
+      <row>
+       <entry><function>set_substring_limit(real)</function><indexterm><primary>set_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Sets the current substring similarity threshold that is used by
+        the <literal>&lt;%</> operator.  The threshold must be between
+        0 and 1 (default is 0.6).  Returns the same value passed in.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 137,142 ****
--- 166,180 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a substring similarity
+        that is greater than the current substring similarity threshold set by
+        <function>set_substring_limit</>.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 204,209 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 242,262 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for substring
+    similarity.  For example:
+ <programlisting>
+ SELECT t, substring_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a substring
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
substring_similarity_tests.patchtext/x-patch; name=substring_similarity_tests.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.3.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--1.2--1.3.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.3.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--1.2--1.3.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_substring_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,1083 ----
+ Baikal
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala
+ Barkala
+ Bailallie
+ Barkala Park
+ Barkala
+ Barkala
+ Barkala
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Barkal
+ Purba Kalmegha
+ Purba Kalmegha
+ Baikari
+ Barkal
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bakala
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Buyamba-Kalala
+ Bikalabwa
+ Kamba-Kala
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Kabankala
+ Kabankala
+ Bumba-Kalumba
+ Kabankala
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bikala
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bakala
+ Bakala
+ Bakala
+ Bambakala
+ Bakalou
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Tsibakala
+ Kimbakala
+ Bakala
+ Bikala
+ Bakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Bikala
+ Ngao Bakala
+ Bakala
+ Barkala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baikan
+ Baimalang Donggang
+ Baimaling
+ Baimaling
+ Baimaling
+ Baikangshuoma
+ Baitaliao
+ Baimaling
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baika
+ Baiwale
+ Baikan
+ Baikang
+ Baikangnei
+ Baikai
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baikai
+ Baika
+ Bakala
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baikang
+ Baimalin
+ Baikang
+ Subaika
+ Baykal
+ Gabakkale
+ Barkallou
+ Rokba Kala Sardoun
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Bankali
+ Baika
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bankalan
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Bakala
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kebakkalang
+ Ngambakalang
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Mota Sabakal
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Babakalo
+ Buyu Rapanbakalai
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalimundubakalan
+ Bakalan
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kidul
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalibakal
+ Bakaljaya
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Trobakal
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakal
+ Kebakalan
+ Bakalan
+ Desa Bakal
+ Bakalan
+ Bakal
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Sampangbakalan
+ Bakalam
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrapyak
+ Bakalan
+ Bakalan
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakal
+ Desa Bakalan
+ Bakalan
+ Bakalan Tengah
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Kali Bakalan
+ Desa Cemengbakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Desa Bakalanpule
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakal
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kali Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Kali Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalanrayung
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Tanjung Mbakalang
+ Laikalanda
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrajan
+ Bakalan
+ Desa Bakalan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Bakalan
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Bankalan
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Bakalan
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Praikalumbang
+ Bakalan
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakal
+ Bakalan Barat
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Bakaldalam
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Barkala
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Barkal
+ Barkal
+ Bankalah
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkala
+ Barkala
+ Baijalpur
+ Barkali
+ Barkali
+ Baidal
+ Barkal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakal
+ Bakkalmal
+ Bakaly
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Baikai
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Bakal
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Ambadikala
+ Bakalica
+ Bakalica
+ Bakalnica
+ Bakal
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Bankala Hill
+ Bakali
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Bakal
+ Bankali
+ Bakala
+ Maikali
+ Bikal
+ Barkala
+ Bakalum
+ Bakali
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Abakaliki
+ Bakale
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Baikajavri
+ Barkald
+ Barkalden
+ Bakkalia
+ Barkald
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bakkalia
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakal
+ Bakal
+ Bakalsen
+ Baika
+ Baiyaldi
+ Bakale
+ Naikala
+ Baikanda
+ Barkalne
+ Baijalpur
+ Bakalipur
+ Bakaldum
+ Bakal
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Kabankalan
+ Kabankalan
+ Kabankalan
+ City of Kabankalan
+ Bikal
+ Bankal
+ Bankal
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Kabankalan
+ Bakal Tres
+ Daang Bakal
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baykal
+ Baykal
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakaly
+ Bakaly
+ Bakalovskaya Ferma
+ Bakalovo
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Bakal
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Baykalovo
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Baykalovo
+ Baykalovo
+ Baykalovo
+ Baykal
+ Bakala
+ Bakalda
+ Bakalinskiy
+ Ozero Baykal
+ Ozero Baykal
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Ozero Baykal
+ Baykal
+ Baykal
+ Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Baykal
+ Baykal
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Ozero Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Baykalovo
+ Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Prud Novyy Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Baykal
+ Bakaleyka
+ Bakalka
+ Baykal
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Baykal
+ Boloto Baykal
+ Ozero Baykal
+ Bakaly
+ Bakalinskiy Leskhoz
+ Ozero Baykal
+ Bakaly
+ Bakaly
+ Bikalikha
+ Bakalka
+ Kordon Barkalo
+ Bakalda
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Baykal
+ Ozero Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Gbonkobankala
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Babakalia
+ Baikama
+ Bankala
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Keur Samba Kala
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakale
+ Bakalaale
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Barkala
+ Ambakali
+ Ba Kaliin
+ Barkal
+ Bakala
+ Barkale
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Beikala
+ Sungai Utabailale
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Baykal
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Bakalovo
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Sibankala
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Tombankala
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Holiday Inn Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Sahara Palace Marrakech
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_substring_trgm.out
***************
*** 0 ****
--- 1,2211 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select set_substring_limit(0.5);
+  set_substring_limit 
+ ---------------------
+                  0.5
+ (1 row)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select set_substring_limit(0.3);
+  set_substring_limit 
+ ---------------------
+                  0.3
+ (1 row)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_substring_trgm.sql
***************
*** 0 ****
--- 1,37 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ select set_substring_limit(0.5);
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ select set_substring_limit(0.3);
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
#2Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Artur Zakirov (#1)
Re: Fuzzy substring searching with the pg_trgm extension

On 18.12.2015 22:43, Artur Zakirov wrote:

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy
text search. It provides some functions and operators for determining
the similarity of the given texts using trigram matching.

Sorry, I have forgotten to mark previous message with [PROPOSAL].
I registered the patch in commitfest:
https://commitfest.postgresql.org/8/448/

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Alexander Korotkov
a.korotkov@postgrespro.ru
In reply to: Artur Zakirov (#2)
Re: Fuzzy substring searching with the pg_trgm extension

On Fri, Dec 18, 2015 at 10:53 PM, Artur Zakirov <a.zakirov@postgrespro.ru>
wrote:

On 18.12.2015 22:43, Artur Zakirov wrote:

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy
text search. It provides some functions and operators for determining the
similarity of the given texts using trigram matching.

Sorry, I have forgotten to mark previous message with [PROPOSAL].

​I think, you shouldn't mark thread as ​[PROPOSAL] since you're providing a
full patch.

I registered the patch in commitfest:
https://commitfest.postgresql.org/8/448/

​Great.

------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

#4Jeff Janes
jeff.janes@gmail.com
In reply to: Artur Zakirov (#1)
Re: Fuzzy substring searching with the pg_trgm extension

On Fri, Dec 18, 2015 at 11:43 AM, Artur Zakirov
<a.zakirov@postgrespro.ru> wrote:

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy text
search. It provides some functions and operators for determining the
similarity of the given texts using trigram matching.

At the moment, in pg_trgm both the similarity function and the % operator
match two strings expecting that they are similar entirely. But they give
bad results if we want to find documents by a query which is substring of a
document.

This is very interesting. I suspect the index will not be very useful
in cases where the full string is much larger than the substring,
because the limit will not be met often enough to rule out many rows
just based on the index data. I have a pretty good test case to see.

Can you update the patch to incorporate the recent changes committed
under the thread "Patch: pg_trgm: gin index scan performance for
similarity search"? They conflict with your changes.

Thanks,

Jeff

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Jeff Janes (#4)
1 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 27.12.2015 08:12, Jeff Janes wrote:

This is very interesting. I suspect the index will not be very useful
in cases where the full string is much larger than the substring,
because the limit will not be met often enough to rule out many rows
just based on the index data. I have a pretty good test case to see.

Can you update the patch to incorporate the recent changes committed
under the thread "Patch: pg_trgm: gin index scan performance for
similarity search"? They conflict with your changes.

Thanks,

Jeff

I updated the patch and attached it. The patch includes source code and
regression tests now.
It will be very good if you will test it with your case.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

substring_similarity.patchtext/x-patch; name=substring_similarity.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 4,13 **** MODULE_big = pg_trgm
  OBJS = trgm_op.o trgm_gist.o trgm_gin.o trgm_regexp.o $(WIN32RES)
  
  EXTENSION = pg_trgm
! DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 4,13 ----
  OBJS = trgm_op.o trgm_gist.o trgm_gin.o trgm_regexp.o $(WIN32RES)
  
  EXTENSION = pg_trgm
! DATA = pg_trgm--1.3.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--1.2--1.3.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_substring_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,1083 ----
+ Baikal
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala
+ Barkala
+ Bailallie
+ Barkala Park
+ Barkala
+ Barkala
+ Barkala
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Barkal
+ Purba Kalmegha
+ Purba Kalmegha
+ Baikari
+ Barkal
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bakala
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Buyamba-Kalala
+ Bikalabwa
+ Kamba-Kala
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Kabankala
+ Kabankala
+ Bumba-Kalumba
+ Kabankala
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bikala
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bakala
+ Bakala
+ Bakala
+ Bambakala
+ Bakalou
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Tsibakala
+ Kimbakala
+ Bakala
+ Bikala
+ Bakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Bikala
+ Ngao Bakala
+ Bakala
+ Barkala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baikan
+ Baimalang Donggang
+ Baimaling
+ Baimaling
+ Baimaling
+ Baikangshuoma
+ Baitaliao
+ Baimaling
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baika
+ Baiwale
+ Baikan
+ Baikang
+ Baikangnei
+ Baikai
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baikai
+ Baika
+ Bakala
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baikang
+ Baimalin
+ Baikang
+ Subaika
+ Baykal
+ Gabakkale
+ Barkallou
+ Rokba Kala Sardoun
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Bankali
+ Baika
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bankalan
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Bakala
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kebakkalang
+ Ngambakalang
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Mota Sabakal
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Babakalo
+ Buyu Rapanbakalai
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalimundubakalan
+ Bakalan
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kidul
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalibakal
+ Bakaljaya
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Trobakal
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakal
+ Kebakalan
+ Bakalan
+ Desa Bakal
+ Bakalan
+ Bakal
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Sampangbakalan
+ Bakalam
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrapyak
+ Bakalan
+ Bakalan
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakal
+ Desa Bakalan
+ Bakalan
+ Bakalan Tengah
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Kali Bakalan
+ Desa Cemengbakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Desa Bakalanpule
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakal
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kali Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Kali Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalanrayung
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Tanjung Mbakalang
+ Laikalanda
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrajan
+ Bakalan
+ Desa Bakalan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Bakalan
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Bankalan
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Bakalan
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Praikalumbang
+ Bakalan
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakal
+ Bakalan Barat
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Bakaldalam
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Barkala
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Barkal
+ Barkal
+ Bankalah
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkala
+ Barkala
+ Baijalpur
+ Barkali
+ Barkali
+ Baidal
+ Barkal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakal
+ Bakkalmal
+ Bakaly
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Baikai
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Bakal
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Ambadikala
+ Bakalica
+ Bakalica
+ Bakalnica
+ Bakal
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Bankala Hill
+ Bakali
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Bakal
+ Bankali
+ Bakala
+ Maikali
+ Bikal
+ Barkala
+ Bakalum
+ Bakali
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Abakaliki
+ Bakale
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Baikajavri
+ Barkald
+ Barkalden
+ Bakkalia
+ Barkald
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bakkalia
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakal
+ Bakal
+ Bakalsen
+ Baika
+ Baiyaldi
+ Bakale
+ Naikala
+ Baikanda
+ Barkalne
+ Baijalpur
+ Bakalipur
+ Bakaldum
+ Bakal
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Kabankalan
+ Kabankalan
+ Kabankalan
+ City of Kabankalan
+ Bikal
+ Bankal
+ Bankal
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Kabankalan
+ Bakal Tres
+ Daang Bakal
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baykal
+ Baykal
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakaly
+ Bakaly
+ Bakalovskaya Ferma
+ Bakalovo
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Bakal
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Baykalovo
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Baykalovo
+ Baykalovo
+ Baykalovo
+ Baykal
+ Bakala
+ Bakalda
+ Bakalinskiy
+ Ozero Baykal
+ Ozero Baykal
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Ozero Baykal
+ Baykal
+ Baykal
+ Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Baykal
+ Baykal
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Ozero Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Baykalovo
+ Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Prud Novyy Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Baykal
+ Bakaleyka
+ Bakalka
+ Baykal
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Baykal
+ Boloto Baykal
+ Ozero Baykal
+ Bakaly
+ Bakalinskiy Leskhoz
+ Ozero Baykal
+ Bakaly
+ Bakaly
+ Bikalikha
+ Bakalka
+ Kordon Barkalo
+ Bakalda
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Baykal
+ Ozero Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Gbonkobankala
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Babakalia
+ Baikama
+ Bankala
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Keur Samba Kala
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakale
+ Bakalaale
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Barkala
+ Ambakali
+ Ba Kaliin
+ Barkal
+ Bakala
+ Barkale
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Beikala
+ Sungai Utabailale
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Baykal
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Bakalovo
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Sibankala
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Tombankala
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Holiday Inn Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Sahara Palace Marrakech
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_substring_trgm.out
***************
*** 0 ****
--- 1,2211 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select set_substring_limit(0.5);
+  set_substring_limit 
+ ---------------------
+                  0.5
+ (1 row)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select set_substring_limit(0.3);
+  set_substring_limit 
+ ---------------------
+                  0.3
+ (1 row)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/pg_trgm--1.2--1.3.sql
***************
*** 0 ****
--- 1,53 ----
+ /* contrib/pg_trgm/pg_trgm--1.2--1.3.sql */
+ 
+ -- complain if script is sourced in psql, rather than via ALTER EXTENSION
+ \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.3'" to load this file. \quit
+ 
+ CREATE FUNCTION set_substring_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_substring_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- /dev/null
***************
*** 1,188 ****
- /* contrib/pg_trgm/pg_trgm--1.2.sql */
- 
- -- complain if script is sourced in psql, rather than via CREATE EXTENSION
- \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
- 
- CREATE FUNCTION set_limit(float4)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT VOLATILE;
- 
- CREATE FUNCTION show_limit()
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT STABLE;
- 
- CREATE FUNCTION show_trgm(text)
- RETURNS _text
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION similarity(text,text)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION similarity_op(text,text)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
- 
- CREATE OPERATOR % (
-         LEFTARG = text,
-         RIGHTARG = text,
-         PROCEDURE = similarity_op,
-         COMMUTATOR = '%',
-         RESTRICT = contsel,
-         JOIN = contjoinsel
- );
- 
- CREATE FUNCTION similarity_dist(text,text)
- RETURNS float4
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE OPERATOR <-> (
-         LEFTARG = text,
-         RIGHTARG = text,
-         PROCEDURE = similarity_dist,
-         COMMUTATOR = '<->'
- );
- 
- -- gist key
- CREATE FUNCTION gtrgm_in(cstring)
- RETURNS gtrgm
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE FUNCTION gtrgm_out(gtrgm)
- RETURNS cstring
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
- 
- CREATE TYPE gtrgm (
-         INTERNALLENGTH = -1,
-         INPUT = gtrgm_in,
-         OUTPUT = gtrgm_out
- );
- 
- -- support functions for gist
- CREATE FUNCTION gtrgm_consistent(internal,text,int,oid,internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_distance(internal,text,int,oid)
- RETURNS float8
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_compress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_decompress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_penalty(internal,internal,internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_picksplit(internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_union(bytea, internal)
- RETURNS _int4
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gtrgm_same(gtrgm, gtrgm, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- -- create the operator class for gist
- CREATE OPERATOR CLASS gist_trgm_ops
- FOR TYPE text USING gist
- AS
-         OPERATOR        1       % (text, text),
-         FUNCTION        1       gtrgm_consistent (internal, text, int, oid, internal),
-         FUNCTION        2       gtrgm_union (bytea, internal),
-         FUNCTION        3       gtrgm_compress (internal),
-         FUNCTION        4       gtrgm_decompress (internal),
-         FUNCTION        5       gtrgm_penalty (internal, internal, internal),
-         FUNCTION        6       gtrgm_picksplit (internal, internal),
-         FUNCTION        7       gtrgm_same (gtrgm, gtrgm, internal),
-         STORAGE         gtrgm;
- 
- -- Add operators and support functions that are new in 9.1.  We do it like
- -- this, leaving them "loose" in the operator family rather than bound into
- -- the gist_trgm_ops opclass, because that's the only state that can be
- -- reproduced during an upgrade from 9.0 (see pg_trgm--unpackaged--1.0.sql).
- 
- ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
-         OPERATOR        2       <-> (text, text) FOR ORDER BY pg_catalog.float_ops,
-         OPERATOR        3       pg_catalog.~~ (text, text),
-         OPERATOR        4       pg_catalog.~~* (text, text),
-         FUNCTION        8 (text, text)  gtrgm_distance (internal, text, int, oid);
- 
- -- Add operators that are new in 9.3.
- 
- ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
-         OPERATOR        5       pg_catalog.~ (text, text),
-         OPERATOR        6       pg_catalog.~* (text, text);
- 
- -- support functions for gin
- CREATE FUNCTION gin_extract_value_trgm(text, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gin_extract_query_trgm(text, internal, int2, internal, internal, internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- CREATE FUNCTION gin_trgm_consistent(internal, int2, text, int4, internal, internal, internal, internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- -- create the operator class for gin
- CREATE OPERATOR CLASS gin_trgm_ops
- FOR TYPE text USING gin
- AS
-         OPERATOR        1       % (text, text),
-         FUNCTION        1       btint4cmp (int4, int4),
-         FUNCTION        2       gin_extract_value_trgm (text, internal),
-         FUNCTION        3       gin_extract_query_trgm (text, internal, int2, internal, internal, internal, internal),
-         FUNCTION        4       gin_trgm_consistent (internal, int2, text, int4, internal, internal, internal, internal),
-         STORAGE         int4;
- 
- -- Add operators that are new in 9.1.
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         OPERATOR        3       pg_catalog.~~ (text, text),
-         OPERATOR        4       pg_catalog.~~* (text, text);
- 
- -- Add operators that are new in 9.3.
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         OPERATOR        5       pg_catalog.~ (text, text),
-         OPERATOR        6       pg_catalog.~* (text, text);
- 
- -- Add functions that are new in 9.6 (pg_trgm 1.2).
- 
- CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
- RETURNS "char"
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
- 
- ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
-         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 0 ----
*** /dev/null
--- b/contrib/pg_trgm/pg_trgm--1.3.sql
***************
*** 0 ****
--- 1,241 ----
+ /* contrib/pg_trgm/pg_trgm--1.3.sql */
+ 
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
+ 
+ CREATE FUNCTION set_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION show_trgm(text)
+ RETURNS _text
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
+ 
+ CREATE OPERATOR % (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = similarity_op,
+         COMMUTATOR = '%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE FUNCTION set_substring_limit(float4)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT VOLATILE;
+ 
+ CREATE FUNCTION show_substring_limit()
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;
+ 
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE FUNCTION similarity_dist(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = similarity_dist,
+         COMMUTATOR = '<->'
+ );
+ 
+ -- gist key
+ CREATE FUNCTION gtrgm_in(cstring)
+ RETURNS gtrgm
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION gtrgm_out(gtrgm)
+ RETURNS cstring
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE TYPE gtrgm (
+         INTERNALLENGTH = -1,
+         INPUT = gtrgm_in,
+         OUTPUT = gtrgm_out
+ );
+ 
+ -- support functions for gist
+ CREATE FUNCTION gtrgm_consistent(internal,text,int,oid,internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_distance(internal,text,int,oid)
+ RETURNS float8
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_compress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_decompress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_penalty(internal,internal,internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_picksplit(internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_union(bytea, internal)
+ RETURNS _int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gtrgm_same(gtrgm, gtrgm, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ -- create the operator class for gist
+ CREATE OPERATOR CLASS gist_trgm_ops
+ FOR TYPE text USING gist
+ AS
+         OPERATOR        1       % (text, text),
+         FUNCTION        1       gtrgm_consistent (internal, text, int, oid, internal),
+         FUNCTION        2       gtrgm_union (bytea, internal),
+         FUNCTION        3       gtrgm_compress (internal),
+         FUNCTION        4       gtrgm_decompress (internal),
+         FUNCTION        5       gtrgm_penalty (internal, internal, internal),
+         FUNCTION        6       gtrgm_picksplit (internal, internal),
+         FUNCTION        7       gtrgm_same (gtrgm, gtrgm, internal),
+         STORAGE         gtrgm;
+ 
+ -- Add operators and support functions that are new in 9.1.  We do it like
+ -- this, leaving them "loose" in the operator family rather than bound into
+ -- the gist_trgm_ops opclass, because that's the only state that can be
+ -- reproduced during an upgrade from 9.0 (see pg_trgm--unpackaged--1.0.sql).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        2       <-> (text, text) FOR ORDER BY pg_catalog.float_ops,
+         OPERATOR        3       pg_catalog.~~ (text, text),
+         OPERATOR        4       pg_catalog.~~* (text, text),
+         FUNCTION        8 (text, text)  gtrgm_distance (internal, text, int, oid);
+ 
+ -- Add operators that are new in 9.3.
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        5       pg_catalog.~ (text, text),
+         OPERATOR        6       pg_catalog.~* (text, text);
+ 
+ -- Add operators that are new in 9.6 (pg_trgm 1.3).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
+ -- support functions for gin
+ CREATE FUNCTION gin_extract_value_trgm(text, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gin_extract_query_trgm(text, internal, int2, internal, internal, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ CREATE FUNCTION gin_trgm_consistent(internal, int2, text, int4, internal, internal, internal, internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ -- create the operator class for gin
+ CREATE OPERATOR CLASS gin_trgm_ops
+ FOR TYPE text USING gin
+ AS
+         OPERATOR        1       % (text, text),
+         FUNCTION        1       btint4cmp (int4, int4),
+         FUNCTION        2       gin_extract_value_trgm (text, internal),
+         FUNCTION        3       gin_extract_query_trgm (text, internal, int2, internal, internal, internal, internal),
+         FUNCTION        4       gin_trgm_consistent (internal, int2, text, int4, internal, internal, internal, internal),
+         STORAGE         int4;
+ 
+ -- Add operators that are new in 9.1.
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        3       pg_catalog.~~ (text, text),
+         OPERATOR        4       pg_catalog.~~* (text, text);
+ 
+ -- Add operators that are new in 9.3.
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        5       pg_catalog.~ (text, text),
+         OPERATOR        6       pg_catalog.~* (text, text);
+ 
+ -- Add functions that are new in 9.6 (pg_trgm 1.2).
+ 
+ CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
+ RETURNS "char"
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
+ 
+ -- Add operators that are new in 9.6 (pg_trgm 1.3).
+ 
+ ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text);
*** a/contrib/pg_trgm/pg_trgm.control
--- b/contrib/pg_trgm/pg_trgm.control
***************
*** 1,5 ****
  # pg_trgm extension
  comment = 'text similarity measurement and index searching based on trigrams'
! default_version = '1.2'
  module_pathname = '$libdir/pg_trgm'
  relocatable = true
--- 1,5 ----
  # pg_trgm extension
  comment = 'text similarity measurement and index searching based on trigrams'
! default_version = '1.3'
  module_pathname = '$libdir/pg_trgm'
  relocatable = true
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_substring_trgm.sql
***************
*** 0 ****
--- 1,37 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ select set_substring_limit(0.5);
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ select set_substring_limit(0.3);
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,37 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
  
  
  typedef char trgm[3];
--- 26,38 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber			1
! #define DistanceStrategyNumber				2
! #define LikeStrategyNumber					3
! #define ILikeStrategyNumber					4
! #define RegExpStrategyNumber				5
! #define RegExpICaseStrategyNumber			6
! #define SubstringSimilarityStrategyNumber	7
  
  
  typedef char trgm[3];
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern float4 trgm_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,125 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ #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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern float4 trgm_limit;
+ extern float4 trgm_substring_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 184,190 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 272,277 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 274,280 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	float4		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubstringSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,304 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubstringSimilarityStrategyNumber:
! 			/* Similarity search is exact. Substring similarity search is inexact */
! 			*recheck = (strategy == SubstringSimilarityStrategyNumber) ? true : false;
! 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 312,318 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 463,469 **** gtrgm_distance(PG_FUNCTION_ARGS)
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,473 ----
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg, false);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,27 ****
--- 15,33 ----
  PG_MODULE_MAGIC;
  
  float4		trgm_limit = 0.3f;
+ float4		trgm_substring_limit = 0.6f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(substring_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(set_substring_limit);
+ PG_FUNCTION_INFO_V1(show_substring_limit);
+ PG_FUNCTION_INFO_V1(substring_similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_commutator_op);
  
  
  Datum
***************
*** 41,46 **** show_limit(PG_FUNCTION_ARGS)
--- 47,69 ----
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
+ Datum
+ set_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	float4		nlimit = PG_GETARG_FLOAT4(0);
+ 
+ 	if (nlimit < 0 || nlimit > 1.0)
+ 		elog(ERROR, "wrong limit, should be between 0 and 1");
+ 	trgm_substring_limit = nlimit;
+ 	PG_RETURN_FLOAT4(trgm_substring_limit);
+ }
+ 
+ Datum
+ show_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	PG_RETURN_FLOAT4(trgm_substring_limit);
+ }
+ 
  static int
  comp_trgm(const void *a, const void *b)
  {
***************
*** 166,203 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 189,208 ----
  	return tptr;
  }
  
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 237,243 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 242,281 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! static void
! protect_out_of_mem(int slen)
! {
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 254,259 **** generate_trgm(char *str, int slen)
--- 292,534 ----
  	return trg;
  }
  
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	t;
+ 	int		i;
+ } ptrgm;
+ 
+ /*
+  * Make array of positional trigrams from two trigram arrays. The first array
+  * is required substing which positions don't matter and replaced with -1.
+  * The second array is haystack where we search and have to store its
+  * positions.
+  */
+ static ptrgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	ptrgm *result;
+ 	int i, len = len1 + len2;
+ 
+ 	result = (ptrgm *) palloc(sizeof(ptrgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].t, &trg1[i], sizeof(trgm));
+ 		result[i].i = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].t, &trg2[i], sizeof(trgm));
+ 		result[i + len1].i = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const ptrgm	   *p1 = (const ptrgm *)v1;
+ 	const ptrgm	   *p2 = (const ptrgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->t, p2->t);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->i < p2->i)
+ 		return -1;
+ 	else if (p1->i == p2->i)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative procedure if finding maximum similarity with substring.
+  */
+ static float4
+ iterate_substring_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate substring similarity.
+  */
+ static float4
+ calc_substring_similarity(char *str1, int slen1, char *str2, int slen2)
+ {
+ 	bool   *found;
+ 	ptrgm  *ptrg;
+ 	trgm   *trg1;
+ 	trgm   *trg2;
+ 	int		len1,
+ 			len2,
+ 			len,
+ 			i,
+ 			j,
+ 			ulen1;
+ 	int	   *trg2indexes;
+ 	float4	result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(ptrgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required substring.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].t, ptrg[i].t);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].i >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].i] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with substring */
+ 	result = iterate_substring_similarity(trg2indexes, found, ulen1, len2, len);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
  /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
***************
*** 426,442 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 701,707 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 557,563 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 822,828 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 591,604 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 856,869 ----
  		}
  	}
  
! 	/* if inexact then len2 is equal to count */
! 	if (inexact)
! 		return CALCSML(count, len1, count);
! 	else
! 		return CALCSML(count, len1, len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 693,699 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 958,964 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 704,709 **** similarity(PG_FUNCTION_ARGS)
--- 969,990 ----
  }
  
  Datum
+ substring_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2));
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 722,724 **** similarity_op(PG_FUNCTION_ARGS)
--- 1003,1025 ----
  
  	PG_RETURN_BOOL(res >= trgm_limit);
  }
+ 
+ Datum
+ substring_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	float4		res = DatumGetFloat4(DirectFunctionCall2(substring_similarity,
+ 														 PG_GETARG_DATUM(0),
+ 														 PG_GETARG_DATUM(1)));
+ 
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
+ 
+ Datum
+ substring_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	float4		res = DatumGetFloat4(DirectFunctionCall2(substring_similarity,
+ 														 PG_GETARG_DATUM(1),
+ 														 PG_GETARG_DATUM(0)));
+ 
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>substring_similarity(text, text)</function><indexterm><primary>substring_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar substring of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to substring of the second substring).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 111,116 ****
--- 122,145 ----
         Returns the same value passed in.
        </entry>
       </row>
+      <row>
+       <entry><function>show_substring_limit()</function><indexterm><primary>show_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the current similarity threshold used by the <literal>&lt;%</>
+        operator.  This sets the minimum substring similarity between
+        two phrases.
+       </entry>
+      </row>
+      <row>
+       <entry><function>set_substring_limit(real)</function><indexterm><primary>set_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Sets the current substring similarity threshold that is used by
+        the <literal>&lt;%</> operator.  The threshold must be between
+        0 and 1 (default is 0.6).  Returns the same value passed in.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 137,142 ****
--- 166,180 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a substring similarity
+        that is greater than the current substring similarity threshold set by
+        <function>set_substring_limit</>.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 204,209 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 242,262 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for substring
+    similarity.  For example:
+ <programlisting>
+ SELECT t, substring_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a substring
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#6Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Artur Zakirov (#5)
Re: Fuzzy substring searching with the pg_trgm extension

I gave a quick look through the patch and noticed a few minor things
while trying to understand it.

I think the test corpus isn't particularly interesting for how big it
is. I'd rather have (a) a small corpus (say 100 words) with which to do
detailed regression testing, and (b) some larger document for more
extensive testing. I'm not sure (b) is actually necessary.

Overall I think the new functions could stand a lot more commentary.

--- 104,125 ----
#define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
#define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
+ #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

This macro has a multiple evaluation gotcha. Maybe we don't really care
because of the limited applicability but I'd put a comment on top.

/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
}
else if (ISALLTRUE(key))
{					/* non-leaf contains signature */
--- 288,304 ----
switch (strategy)
{
case SimilarityStrategyNumber:
! 		case SubstringSimilarityStrategyNumber:
! 			/* Similarity search is exact. Substring similarity search is inexact */
! 			*recheck = (strategy == SubstringSimilarityStrategyNumber) ? true : false;
! 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;

if (GIST_LEAF(entry))
{ /* all leafs contains orig trgm */
! float4 tmpsml = cnt_sml(qtrg, key, *recheck);

/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit) ? true : false;

What's the compiler bug about? This code and comment were introduced in
cbfa4092bb (May 2004) without any explanation. Do we still need to keep
it, if &nlimit is now a local variable instead of a global? FWIW the
oldest GCC in the buildfarm is 3.4.2/3.4.3 (except for Gaur which uses
GCC 2.95 under HPPA)

BTW you don't need a ternary op just to say "? true : false" -- just
make it
res = foo == bar;
which immediately assigns the correct boolean value. (This pattern
occurs in many places both in the original and in your submitted code.
I see no reason to perpetuate it.)

+ Datum
+ set_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	float4		nlimit = PG_GETARG_FLOAT4(0);
+ 
+ 	if (nlimit < 0 || nlimit > 1.0)
+ 		elog(ERROR, "wrong limit, should be between 0 and 1");

Should be an ereport().

! static void
! protect_out_of_mem(int slen)
! {
! /*
! * Guard against possible overflow in the palloc requests below. (We
! * don't worry about the additive constants, since palloc can detect
! * requests that are a little above MaxAllocSize --- we just need to
! * prevent integer overflow in the multiplications.)
! */
! if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! (Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! ereport(ERROR,
! (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! errmsg("out of memory")));
! }

I think the comment should now be above the function, not inside it.

***************
*** 254,259 **** generate_trgm(char *str, int slen)
--- 292,534 ----
return trg;
}
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	t;
+ 	int		i;
+ } ptrgm;

This struct definition could stand a better name, and better member
names. Also, our policy (not always enforced) is to have these near the
top of the file rather than in the middle. If the struct is used in
many places then IMO it's better that it go at the top; if it's used
only in one function I'd say it's okay to have it just after that
function.

+ /*
+  * Make array of positional trigrams from two trigram arrays. The first array
+  * is required substing which positions don't matter and replaced with -1.
+  * The second array is haystack where we search and have to store its
+  * positions.
+  */
+ static ptrgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	ptrgm *result;
+ 	int i, len = len1 + len2;
+ 
+ 	result = (ptrgm *) palloc(sizeof(ptrgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].t, &trg1[i], sizeof(trgm));
+ 		result[i].i = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].t, &trg2[i], sizeof(trgm));
+ 		result[i + len1].i = i;
+ 	}
+ 
+ 	return result;
+ }

So the output trigram array is the concatenation of both input trigrams?
That's not quite evident from the comment above the function ... I think
some rephrasing there is in order.

--- 856,869 ----
}
}

! /* if inexact then len2 is equal to count */
! if (inexact)
! return CALCSML(count, len1, count);
! else
! return CALCSML(count, len1, len2);

This is where a ternary op would make better code.
CALCSML(count, len1, inexact ? count : len2);
but a better comment would actually explain why we do this, rather than
just stating we do.

+      <row>
+       <entry><function>show_substring_limit()</function><indexterm><primary>show_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the current similarity threshold used by the <literal>&lt;%</>
+        operator.  This sets the minimum substring similarity between
+        two phrases.
+       </entry>
+      </row>
+      <row>
+       <entry><function>set_substring_limit(real)</function><indexterm><primary>set_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Sets the current substring similarity threshold that is used by
+        the <literal>&lt;%</> operator.  The threshold must be between
+        0 and 1 (default is 0.6).  Returns the same value passed in.
+       </entry>

I don't quite understand why aren't we using a custom GUC variable here.
These already have SHOW and SET support ...

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#6)
Re: Fuzzy substring searching with the pg_trgm extension

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

+       <entry><function>show_substring_limit()</function><indexterm><primary>show_substring_limit</primary></indexterm></entry>
+       <entry><function>set_substring_limit(real)</function><indexterm><primary>set_substring_limit</primary></indexterm></entry>

I don't quite understand why aren't we using a custom GUC variable here.

Presumably this is following the existing set_limit() precedent
in pg_trgm. But I tend to agree that that's a crummy precedent
and we should not extend it.

Let's invent a custom GUC for the regular limit, mark show_limit()
and set_limit as deprecated, and then make just a custom GUC for
this other limit.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Teodor Sigaev
teodor@sigaev.ru
In reply to: Alvaro Herrera (#6)
Re: Fuzzy substring searching with the pg_trgm extension

! float4 tmpsml = cnt_sml(qtrg, key, *recheck);

/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit) ? true : false;

What's the compiler bug about? This code and comment were introduced in
cbfa4092bb (May 2004) without any explanation. Do we still need to keep
it, if &nlimit is now a local variable instead of a global? FWIW the
oldest GCC in the buildfarm is 3.4.2/3.4.3 (except for Gaur which uses

As I remeber, the problem was with x87 math coprocessor. Compiler (suppose,
modern compiler could do it too) keeps tmpsml in internal 80-bit wide register
and compares with 32-bit wide float. Of course, it depends on level of
optimization and so, result of comparison was differ in optimization enabled and
disabled instances. Such strange way I choose to force compiler to use main
memory for tmpsml variable. Actually, I don't know better way even now.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Jeff Janes
jeff.janes@gmail.com
In reply to: Jeff Janes (#4)
Re: Fuzzy substring searching with the pg_trgm extension

On Sat, Dec 26, 2015 at 9:12 PM, Jeff Janes <jeff.janes@gmail.com> wrote:

On Fri, Dec 18, 2015 at 11:43 AM, Artur Zakirov
<a.zakirov@postgrespro.ru> wrote:

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy text
search. It provides some functions and operators for determining the
similarity of the given texts using trigram matching.

At the moment, in pg_trgm both the similarity function and the % operator
match two strings expecting that they are similar entirely. But they give
bad results if we want to find documents by a query which is substring of a
document.

This is very interesting. I suspect the index will not be very useful
in cases where the full string is much larger than the substring,
because the limit will not be met often enough to rule out many rows
just based on the index data. I have a pretty good test case to see.

My test case is turning out to be harder to evaluate than I thought,
because it was more complicated than I remembered it being. Hopefully
I can provide some more feedback on it next week.

In the meantime, I had a question about bumping the version to 1.3.

Version 1.2 of pg_trgm has never been included in a community release
(because it didn't make the 9.5 cutoff). So should we really bump the
version to 1.3, or just merge the changes here directly into the
existing 1.2 HEAD code?

I think it would be pretty odd for 9.5. to come with pg_trgm 1.1 and
for 9.6 to come with pg_trgm 1.3.

Thanks,

Jeff

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Janes (#9)
Re: Fuzzy substring searching with the pg_trgm extension

Jeff Janes <jeff.janes@gmail.com> writes:

In the meantime, I had a question about bumping the version to 1.3.

Version 1.2 of pg_trgm has never been included in a community release
(because it didn't make the 9.5 cutoff). So should we really bump the
version to 1.3, or just merge the changes here directly into the
existing 1.2 HEAD code?

I think it would be pretty odd for 9.5. to come with pg_trgm 1.1 and
for 9.6 to come with pg_trgm 1.3.

+1 for not bumping the version, if we've not shipped 1.2 yet. There's
enough maintenance overhead in an extension version bump that we should
not do one unnecessarily.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Alvaro Herrera (#6)
Re: Fuzzy substring searching with the pg_trgm extension

On 12.01.2016 02:31, Alvaro Herrera wrote:

I gave a quick look through the patch and noticed a few minor things
while trying to understand it.

I think the test corpus isn't particularly interesting for how big it
is. I'd rather have (a) a small corpus (say 100 words) with which to do
detailed regression testing, and (b) some larger document for more
extensive testing. I'm not sure (b) is actually necessary.

Overall I think the new functions could stand a lot more commentary.

Thank you for a review. I will send fixed patch in a few days.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Jeff Janes
jeff.janes@gmail.com
In reply to: Artur Zakirov (#1)
Re: Fuzzy substring searching with the pg_trgm extension

On Fri, Dec 18, 2015 at 11:43 AM, Artur Zakirov
<a.zakirov@postgrespro.ru> wrote:

Hello.

PostgreSQL has a contrib module named pg_trgm. It is used to the fuzzy text
search. It provides some functions and operators for determining the
similarity of the given texts using trigram matching.

At the moment, in pg_trgm both the similarity function and the % operator
match two strings expecting that they are similar entirely. But they give
bad results if we want to find documents by a query which is substring of a
document.

For this purpose we need a new operator which enables to find strings that
have a fragment most similar to the given string. This patch adds some
functions and operator:
- function substring_similarity - Returns a number that indicates how
similar the first string to the most similar substring of the second string.
The range of the result is zero (indicating that the two strings are
completely dissimilar) to one (indicating that the first string is identical
to substring of the second substring).

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

The most similar substring of the second string would be 'dog', which
has a similarity of 1.0 if it were an isolated string.

I think that this function should refrain from calculating the
space-padded trigrams at the beginning and end of its first argument.
Since the first argument is expected to be evaluated as a substring, I
wouldn't take it for granted that the beginning and end of the string
as given are at the beginning and end of a 'word', which is what is
currently being enforced.

Or perhaps the 2nd argument needs to have ghost trigrams computed at
each start and stop when comparing that substring to the full
argument.

If we prefer the current behavior, then I think the explanation needs
to be changed.

Also, should we have a function which indicates the position in the
2nd string at which the most similar match to the 1st argument occurs?

select substring_similarity_pos('dog' , 'hotdogpound') ;

answering: 4

When the long string is much longer, it can be hard to figure out
where the best match was (or the first such match, if there is a
series of ties).

Finally, should there be operators for returning the distance,
analogous to the <-> operator? It is awkward to use an operator for
the boolean and a function to get the distance. Especially when you
use %> and so need swap the order of arguments between the operator
and the function.

We could call them <<-> and <->> , where the first corresponds to <%
and the second to %>

Cheers,

Jeff

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Alvaro Herrera (#6)
1 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

I have did some changes to the patch:
- changed version from 1.3 to 1.2
- added check_only parameter to the function
calc_substring_similarity(). If check_only == true then a
calc_substring_similarity() calculates similarity which greater than
pg_trgm.substring_limit variable. This behavior is used in the
substring_similarity_op() and it should increase performance of the
operator. In the substring_similarity() function check_only == false.

On 12.01.2016 02:31, Alvaro Herrera wrote:

I gave a quick look through the patch and noticed a few minor things
while trying to understand it.

I think the test corpus isn't particularly interesting for how big it
is. I'd rather have (a) a small corpus (say 100 words) with which to do
detailed regression testing, and (b) some larger document for more
extensive testing. I'm not sure (b) is actually necessary.

Overall I think the new functions could stand a lot more commentary.

I added some comments to new functions iterate_substring_similarity()
and calc_substring_similarity().

+ #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

This macro has a multiple evaluation gotcha. Maybe we don't really care
because of the limited applicability but I'd put a comment on top.

I added a comment to explain various similarity formula.

BTW you don't need a ternary op just to say "? true : false" -- just
make it
res = foo == bar;
which immediately assigns the correct boolean value. (This pattern
occurs in many places both in the original and in your submitted code.
I see no reason to perpetuate it.)

Fixed all ternary operators.

+ Datum
+ set_substring_limit(PG_FUNCTION_ARGS)
+ {
+ 	float4		nlimit = PG_GETARG_FLOAT4(0);
+
+ 	if (nlimit < 0 || nlimit > 1.0)
+ 		elog(ERROR, "wrong limit, should be between 0 and 1");

Should be an ereport().

Fixed. But an elog() function occurs in trgm_gin.c and trgm_gist.c also.
I'm not sure that it should be replaced with an ereport().

! static void
! protect_out_of_mem(int slen)
! {
! /*
! * Guard against possible overflow in the palloc requests below. (We
! * don't worry about the additive constants, since palloc can detect
! * requests that are a little above MaxAllocSize --- we just need to
! * prevent integer overflow in the multiplications.)
! */
! if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! (Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! ereport(ERROR,
! (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! errmsg("out of memory")));
! }

I think the comment should now be above the function, not inside it.

Fixed.

+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	t;
+ 	int		i;
+ } ptrgm;

This struct definition could stand a better name, and better member
names. Also, our policy (not always enforced) is to have these near the
top of the file rather than in the middle. If the struct is used in
many places then IMO it's better that it go at the top; if it's used
only in one function I'd say it's okay to have it just after that
function.

Renamed this structure to pos_trgm and move it near the top since this
structure is used in a couple of functions. I renamed member names to
trg and index accordingly.

+ /*
+  * Make array of positional trigrams from two trigram arrays. The first array
+  * is required substing which positions don't matter and replaced with -1.
+  * The second array is haystack where we search and have to store its
+  * positions.
+  */
+ static ptrgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	ptrgm *result;
+ 	int i, len = len1 + len2;
+
+ 	result = (ptrgm *) palloc(sizeof(ptrgm) * len);
+
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].t, &trg1[i], sizeof(trgm));
+ 		result[i].i = -1;
+ 	}
+
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].t, &trg2[i], sizeof(trgm));
+ 		result[i + len1].i = i;
+ 	}
+
+ 	return result;
+ }

So the output trigram array is the concatenation of both input trigrams?
That's not quite evident from the comment above the function ... I think
some rephrasing there is in order.

Rephrased the comment.

! /* if inexact then len2 is equal to count */
! if (inexact)
! return CALCSML(count, len1, count);
! else
! return CALCSML(count, len1, len2);

This is where a ternary op would make better code.
CALCSML(count, len1, inexact ? count : len2);
but a better comment would actually explain why we do this, rather than
just stating we do.

Fixed a code and a comment.

+      <row>
+       <entry><function>show_substring_limit()</function><indexterm><primary>show_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the current similarity threshold used by the <literal>&lt;%</>
+        operator.  This sets the minimum substring similarity between
+        two phrases.
+       </entry>
+      </row>
+      <row>
+       <entry><function>set_substring_limit(real)</function><indexterm><primary>set_substring_limit</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Sets the current substring similarity threshold that is used by
+        the <literal>&lt;%</> operator.  The threshold must be between
+        0 and 1 (default is 0.6).  Returns the same value passed in.
+       </entry>

I don't quite understand why aren't we using a custom GUC variable here.
These already have SHOW and SET support ...

Added GUC variables:
- pg_trgm.limit
- pg_trgm.substring_limit
I added this variables to the documentation.
show_limit() and set_limit() functions work correctly and they are
marked as deprecated.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

substring_similarity.patchtext/x-patch; name=substring_similarity.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_substring_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,1083 ----
+ Baikal
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala
+ Barkala
+ Bailallie
+ Barkala Park
+ Barkala
+ Barkala
+ Barkala
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Barkal
+ Purba Kalmegha
+ Purba Kalmegha
+ Baikari
+ Barkal
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bakala
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Buyamba-Kalala
+ Bikalabwa
+ Kamba-Kala
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Kabankala
+ Kabankala
+ Bumba-Kalumba
+ Kabankala
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bikala
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bakala
+ Bakala
+ Bakala
+ Bambakala
+ Bakalou
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Tsibakala
+ Kimbakala
+ Bakala
+ Bikala
+ Bakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Bikala
+ Ngao Bakala
+ Bakala
+ Barkala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baikan
+ Baimalang Donggang
+ Baimaling
+ Baimaling
+ Baimaling
+ Baikangshuoma
+ Baitaliao
+ Baimaling
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baika
+ Baiwale
+ Baikan
+ Baikang
+ Baikangnei
+ Baikai
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baikai
+ Baika
+ Bakala
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baikang
+ Baimalin
+ Baikang
+ Subaika
+ Baykal
+ Gabakkale
+ Barkallou
+ Rokba Kala Sardoun
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Bankali
+ Baika
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bankalan
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Bakala
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kebakkalang
+ Ngambakalang
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Mota Sabakal
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Babakalo
+ Buyu Rapanbakalai
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalimundubakalan
+ Bakalan
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kidul
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalibakal
+ Bakaljaya
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Trobakal
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakal
+ Kebakalan
+ Bakalan
+ Desa Bakal
+ Bakalan
+ Bakal
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Sampangbakalan
+ Bakalam
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrapyak
+ Bakalan
+ Bakalan
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakal
+ Desa Bakalan
+ Bakalan
+ Bakalan Tengah
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Kali Bakalan
+ Desa Cemengbakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Desa Bakalanpule
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakal
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kali Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Kali Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalanrayung
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Tanjung Mbakalang
+ Laikalanda
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrajan
+ Bakalan
+ Desa Bakalan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Bakalan
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Bankalan
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Bakalan
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Praikalumbang
+ Bakalan
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakal
+ Bakalan Barat
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Bakaldalam
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Barkala
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Barkal
+ Barkal
+ Bankalah
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkala
+ Barkala
+ Baijalpur
+ Barkali
+ Barkali
+ Baidal
+ Barkal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakal
+ Bakkalmal
+ Bakaly
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Baikai
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Bakal
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Ambadikala
+ Bakalica
+ Bakalica
+ Bakalnica
+ Bakal
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Bankala Hill
+ Bakali
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Bakal
+ Bankali
+ Bakala
+ Maikali
+ Bikal
+ Barkala
+ Bakalum
+ Bakali
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Abakaliki
+ Bakale
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Baikajavri
+ Barkald
+ Barkalden
+ Bakkalia
+ Barkald
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bakkalia
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakal
+ Bakal
+ Bakalsen
+ Baika
+ Baiyaldi
+ Bakale
+ Naikala
+ Baikanda
+ Barkalne
+ Baijalpur
+ Bakalipur
+ Bakaldum
+ Bakal
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Kabankalan
+ Kabankalan
+ Kabankalan
+ City of Kabankalan
+ Bikal
+ Bankal
+ Bankal
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Kabankalan
+ Bakal Tres
+ Daang Bakal
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baykal
+ Baykal
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakaly
+ Bakaly
+ Bakalovskaya Ferma
+ Bakalovo
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Bakal
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Baykalovo
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Baykalovo
+ Baykalovo
+ Baykalovo
+ Baykal
+ Bakala
+ Bakalda
+ Bakalinskiy
+ Ozero Baykal
+ Ozero Baykal
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Ozero Baykal
+ Baykal
+ Baykal
+ Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Baykal
+ Baykal
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Ozero Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Baykalovo
+ Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Prud Novyy Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Baykal
+ Bakaleyka
+ Bakalka
+ Baykal
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Baykal
+ Boloto Baykal
+ Ozero Baykal
+ Bakaly
+ Bakalinskiy Leskhoz
+ Ozero Baykal
+ Bakaly
+ Bakaly
+ Bikalikha
+ Bakalka
+ Kordon Barkalo
+ Bakalda
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Baykal
+ Ozero Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Gbonkobankala
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Babakalia
+ Baikama
+ Bankala
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Keur Samba Kala
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakale
+ Bakalaale
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Barkala
+ Ambakali
+ Ba Kaliin
+ Barkal
+ Bakala
+ Barkale
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Beikala
+ Sungai Utabailale
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Baykal
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Bakalovo
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Sibankala
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Tombankala
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Holiday Inn Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Sahara Palace Marrakech
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_substring_trgm.out
***************
*** 0 ****
--- 1,2201 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ set "pg_trgm.substring_limit" to 0.5;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ set "pg_trgm.substring_limit" to 0.3;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,49 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
***************
*** 37,42 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 136,142 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
  
  ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
          OPERATOR        5       pg_catalog.~ (text, text),
!         OPERATOR        6       pg_catalog.~* (text, text);
  
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
--- 171,178 ----
  
  ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
          OPERATOR        5       pg_catalog.~ (text, text),
!         OPERATOR        6       pg_catalog.~* (text, text),
!         OPERATOR        7       %> (text, text);
  
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
***************
*** 185,188 **** AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 221,225 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_substring_trgm.sql
***************
*** 0 ****
--- 1,37 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.substring_limit" to 0.5;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.substring_limit" to 0.3;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,37 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
  
  
  typedef char trgm[3];
--- 26,38 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber			1
! #define DistanceStrategyNumber				2
! #define LikeStrategyNumber					3
! #define ILikeStrategyNumber					4
! #define RegExpStrategyNumber				5
! #define RegExpICaseStrategyNumber			6
! #define SubstringSimilarityStrategyNumber	7
  
  
  typedef char trgm[3];
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double trgm_limit;
! extern double trgm_substring_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 184,190 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 208,214 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : (((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 272,277 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 274,280 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubstringSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,304 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubstringSimilarityStrategyNumber:
! 			/* Similarity search is exact. Substring similarity search is inexact */
! 			*recheck = (strategy == SubstringSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 312,318 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 463,469 **** gtrgm_distance(PG_FUNCTION_ARGS)
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,473 ----
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg, false);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,40 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
  	trgm_limit = nlimit;
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
--- 14,96 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double trgm_limit = 0.3f;
! double trgm_substring_limit = 0.6f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(substring_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_commutator_op);
  
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.limit",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_limit,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ 	DefineCustomRealVariable("pg_trgm.substring_limit",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_substring_limit,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
+ 
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.limit" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
  	trgm_limit = nlimit;
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.limit" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
***************
*** 166,203 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 222,249 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 237,243 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 283,329 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 255,260 **** generate_trgm(char *str, int slen)
--- 341,623 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       substring which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with substring.
+  * But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns substring similarity.
+  */
+ static float4
+ iterate_substring_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len,
+ 							 bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that substring similarity is greater than
+ 				 * pg_trgm.substring_limit we do not need to calculate a
+ 				 * maximum similarity
+ 				 */
+ 				if (check_only && smlr_cur >= trgm_substring_limit)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that substring similarity is greater than
+ 			 * pg_trgm.substring_limit we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= trgm_substring_limit)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate substring similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate substring similarity using iterate_substring_similarity.
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a substring, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns substring similarity.
+  */
+ static float4
+ calc_substring_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required substring.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with substring */
+ 	result = iterate_substring_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 426,442 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 789,795 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 557,563 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 910,916 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 591,604 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 944,958 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 693,699 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1047,1053 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 704,709 **** similarity(PG_FUNCTION_ARGS)
--- 1058,1079 ----
  }
  
  Datum
+ substring_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 722,724 **** similarity_op(PG_FUNCTION_ARGS)
--- 1092,1126 ----
  
  	PG_RETURN_BOOL(res >= trgm_limit);
  }
+ 
+ Datum
+ substring_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
+ 
+ Datum
+ substring_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>substring_similarity(text, text)</function><indexterm><primary>substring_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar substring of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to substring of the second substring).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 110,117 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 120,126 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 145,160 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.limit</>.
!       </entry>
!      </row>
!      <row>
!       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
!       <entry><type>boolean</type></entry>
!       <entry>
!        Returns <literal>true</> if its arguments have a substring similarity
!        that is greater than the current substring similarity threshold set by
!        <varname>pg_trgm.substring_limit</> parameter.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 171,213 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-limit" xreflabel="pg_trgm.limit">
+     <term>
+      <varname>pg_trgm.limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-substring-limit" xreflabel="pg_trgm.substring_limit">
+     <term>
+      <varname>pg_trgm.substring_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.substring_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current substring similarity threshold that is used by
+       the <literal>&lt;%</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
***************
*** 204,209 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 262,282 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for substring
+    similarity.  For example:
+ <programlisting>
+ SELECT t, substring_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a substring
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#14Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Artur Zakirov (#13)
Re: Fuzzy substring searching with the pg_trgm extension

Artur Zakirov wrote:

I don't quite understand why aren't we using a custom GUC variable here.
These already have SHOW and SET support ...

Added GUC variables:
- pg_trgm.limit
- pg_trgm.substring_limit
I added this variables to the documentation.
show_limit() and set_limit() functions work correctly and they are marked as
deprecated.

Thanks. I'm willing to commit quickly a small patch that only changes
the existing function to GUCs, then have a look at a separate patch that
adds the new substring operator. Would you split the patch that way?

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Alvaro Herrera (#14)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 21.01.2016 00:25, Alvaro Herrera wrote:

Artur Zakirov wrote:

Added GUC variables:
- pg_trgm.limit
- pg_trgm.substring_limit
I added this variables to the documentation.
show_limit() and set_limit() functions work correctly and they are marked as
deprecated.

Thanks. I'm willing to commit quickly a small patch that only changes
the existing function to GUCs, then have a look at a separate patch that
adds the new substring operator. Would you split the patch that way?

Sure. I attached two patches. But notice that pg_trgm.limit should be
used with this command:

SHOW "pg_trgm.limit";

If you will use this command:

SHOW pg_trgm.limit;

you will get the error:

ERROR: syntax error at or near "limit"
LINE 1: SHOW pg_trgm.limit;
^

This is because "limit" is keyword I think.
If it is important then GUC variables can have names:

- pg_trgm.sml_limit
- pg_trgm.substring_sml_limit

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

pg_trgm_guc.patchtext/x-patch; name=pg_trgm_guc.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		trgm_limit = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,40 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
  	trgm_limit = nlimit;
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
--- 26,73 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.limit",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_limit,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.limit" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
  	trgm_limit = nlimit;
  	PG_RETURN_FLOAT4(trgm_limit);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.limit" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.limit</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-limit" xreflabel="pg_trgm.limit">
+     <term>
+      <varname>pg_trgm.limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
pg_trgm_substring_v4.patchtext/x-patch; name=pg_trgm_substring_v4.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_substring_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,1083 ----
+ Baikal
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala
+ Barkala
+ Bailallie
+ Barkala Park
+ Barkala
+ Barkala
+ Barkala
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Barkal
+ Purba Kalmegha
+ Purba Kalmegha
+ Baikari
+ Barkal
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bakala
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Buyamba-Kalala
+ Bikalabwa
+ Kamba-Kala
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Kabankala
+ Kabankala
+ Bumba-Kalumba
+ Kabankala
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bikala
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bakala
+ Bakala
+ Bakala
+ Bambakala
+ Bakalou
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Bakala
+ Tsibakala
+ Kimbakala
+ Bakala
+ Bikala
+ Bakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Bikala
+ Ngao Bakala
+ Bakala
+ Barkala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baikan
+ Baimalang Donggang
+ Baimaling
+ Baimaling
+ Baimaling
+ Baikangshuoma
+ Baitaliao
+ Baimaling
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baika
+ Baiwale
+ Baikan
+ Baikang
+ Baikangnei
+ Baikai
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baikai
+ Baika
+ Bakala
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baikang
+ Baimalin
+ Baikang
+ Subaika
+ Baykal
+ Gabakkale
+ Barkallou
+ Rokba Kala Sardoun
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Bankali
+ Baika
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bankalan
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Bakala
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kebakkalang
+ Ngambakalang
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Mota Sabakal
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Babakalo
+ Buyu Rapanbakalai
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalimundubakalan
+ Bakalan
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kidul
+ Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Lor
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Kalibakal
+ Bakaljaya
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakalan
+ Trobakal
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakal
+ Kebakalan
+ Bakalan
+ Desa Bakal
+ Bakalan
+ Bakal
+ Bakal
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Sampangbakalan
+ Bakalam
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrapyak
+ Bakalan
+ Bakalan
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakal
+ Desa Bakalan
+ Bakalan
+ Bakalan Tengah
+ Bakalan Kidul
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Kali Bakalan
+ Desa Cemengbakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalrejo
+ Bakalan
+ Desa Bakalanpule
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Gunung Bakal
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalan
+ Bakalan
+ Kali Bakalan
+ Bakalan
+ Desa Kebakalan
+ Kebakalan
+ Bakalan
+ Kali Bakalan
+ Desa Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalanrayung
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Tanjung Mbakalang
+ Laikalanda
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Desa Bakalankrajan
+ Bakalan
+ Desa Bakalan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Bakalan
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Bankalan
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Bakalan
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Praikalumbang
+ Bakalan
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Lor
+ Bakalan
+ Bakalan
+ Bakal
+ Bakalan Barat
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan
+ Bakalan Kulon
+ Bakalan Wetan
+ Bakalan
+ Bakalan
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Bakaldalam
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Barkala
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Barkal
+ Barkal
+ Bankalah
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkala
+ Barkala
+ Baijalpur
+ Barkali
+ Barkali
+ Baidal
+ Barkal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakal
+ Bakkalmal
+ Bakaly
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Baikai
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Bakal
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Ambadikala
+ Bakalica
+ Bakalica
+ Bakalnica
+ Bakal
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Bankala Hill
+ Bakali
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Bakal
+ Bankali
+ Bakala
+ Maikali
+ Bikal
+ Barkala
+ Bakalum
+ Bakali
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Abakaliki
+ Bakale
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Baikajavri
+ Barkald
+ Barkalden
+ Bakkalia
+ Barkald
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bakkalia
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakal
+ Bakal
+ Bakalsen
+ Baika
+ Baiyaldi
+ Bakale
+ Naikala
+ Baikanda
+ Barkalne
+ Baijalpur
+ Bakalipur
+ Bakaldum
+ Bakal
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Kabankalan
+ Kabankalan
+ Kabankalan
+ City of Kabankalan
+ Bikal
+ Bankal
+ Bankal
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Kabankalan
+ Bakal Tres
+ Daang Bakal
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baykal
+ Baykal
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakaly
+ Bakaly
+ Bakalovskaya Ferma
+ Bakalovo
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Bakal
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Baykalovo
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Baykalovo
+ Baykalovo
+ Baykalovo
+ Baykal
+ Bakala
+ Bakalda
+ Bakalinskiy
+ Ozero Baykal
+ Ozero Baykal
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Ozero Baykal
+ Baykal
+ Baykal
+ Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Baykal
+ Baykal
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Ozero Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Baykalovo
+ Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Prud Novyy Baykal
+ Ozero Baykal
+ Ozero Baykal
+ Baykal
+ Bakaleyka
+ Bakalka
+ Baykal
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Baykal
+ Boloto Baykal
+ Ozero Baykal
+ Bakaly
+ Bakalinskiy Leskhoz
+ Ozero Baykal
+ Bakaly
+ Bakaly
+ Bikalikha
+ Bakalka
+ Kordon Barkalo
+ Bakalda
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Baykal
+ Ozero Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Gbonkobankala
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Babakalia
+ Baikama
+ Bankala
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Keur Samba Kala
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakale
+ Bakalaale
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Bakal
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Barkala
+ Ambakali
+ Ba Kaliin
+ Barkal
+ Bakala
+ Barkale
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Beikala
+ Sungai Utabailale
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Baykal
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Bakalovo
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Sibankala
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Tombankala
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Holiday Inn Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Sahara Palace Marrakech
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_substring_trgm.out
***************
*** 0 ****
--- 1,2201 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (56 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  Kabankala                    |   1
+  City of Kabankalan           | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan                   | 0.9
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Bankala                      | 0.6
+  Bankala Hill                 | 0.6
+  Gbonkobankala                | 0.6
+  Ntombankala School           | 0.6
+  Sibankala                    | 0.6
+  Tombankala                   | 0.6
+ (17 rows)
+ 
+ set "pg_trgm.substring_limit" to 0.5;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (59 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+ (25 rows)
+ 
+ set "pg_trgm.substring_limit" to 0.3;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankala                                                   |      0.3
+  Bankala Hill                                              |      0.3
+  Bankalah                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankalan                                                  |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (582 rows)
+ 
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  Kabankala                        |        1
+  City of Kabankalan               |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan                       |      0.9
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Bankala                          |      0.6
+  Bankala Hill                     |      0.6
+  Gbonkobankala                    |      0.6
+  Ntombankala School               |      0.6
+  Sibankala                        |      0.6
+  Tombankala                       |      0.6
+  Kabakala                         | 0.583333
+  Bankalah                         |      0.5
+  Bankalan                         |      0.5
+  Bankalan                         |      0.5
+  Kamba-Kala                       |      0.5
+  Keur Samba Kala                  |      0.5
+  Nehalla Bankalah Reserved Forest |      0.5
+  Rokba Kala Sardoun               |      0.5
+  Kabikala                         | 0.461538
+  Buyamba-Kalala                   | 0.454545
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (161 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,49 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text);
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION substring_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION substring_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE FUNCTION substring_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.substring_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = substring_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 138,144 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
  
  ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
          OPERATOR        5       pg_catalog.~ (text, text),
!         OPERATOR        6       pg_catalog.~* (text, text);
  
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
--- 171,178 ----
  
  ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
          OPERATOR        5       pg_catalog.~ (text, text),
!         OPERATOR        6       pg_catalog.~* (text, text),
!         OPERATOR        7       %> (text, text);
  
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 221,225 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_substring_trgm.sql
***************
*** 0 ****
--- 1,37 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.substring_limit" to 0.5;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.substring_limit" to 0.3;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,substring_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,substring_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,37 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
  
  
  typedef char trgm[3];
--- 26,38 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber			1
! #define DistanceStrategyNumber				2
! #define LikeStrategyNumber					3
! #define ILikeStrategyNumber					4
! #define RegExpStrategyNumber				5
! #define RegExpICaseStrategyNumber			6
! #define SubstringSimilarityStrategyNumber	7
  
  
  typedef char trgm[3];
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_limit;
+ extern double trgm_substring_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 184,190 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 208,214 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : (((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 272,277 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 274,280 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubstringSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubstringSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,304 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubstringSimilarityStrategyNumber:
! 			/* Similarity search is exact. Substring similarity search is inexact */
! 			*recheck = (strategy == SubstringSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ? trgm_limit : trgm_substring_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 312,318 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 463,469 **** gtrgm_distance(PG_FUNCTION_ARGS)
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,473 ----
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg, false);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		trgm_limit = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double trgm_limit = 0.3f;
! double trgm_substring_limit = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,41 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(substring_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_op);
+ PG_FUNCTION_INFO_V1(substring_similarity_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,50 **** _PG_init(void)
--- 56,73 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.substring_limit",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_substring_limit,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 222,249 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 283,329 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 341,623 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       substring which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with substring.
+  * But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns substring similarity.
+  */
+ static float4
+ iterate_substring_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len,
+ 							 bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that substring similarity is greater than
+ 				 * pg_trgm.substring_limit we do not need to calculate a
+ 				 * maximum similarity
+ 				 */
+ 				if (check_only && smlr_cur >= trgm_substring_limit)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that substring similarity is greater than
+ 			 * pg_trgm.substring_limit we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= trgm_substring_limit)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate substring similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate substring similarity using iterate_substring_similarity.
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a substring, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns substring similarity.
+  */
+ static float4
+ calc_substring_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required substring.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with substring */
+ 	result = iterate_substring_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 789,795 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 910,916 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 944,958 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1047,1053 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1058,1079 ----
  }
  
  Datum
+ substring_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1092,1126 ----
  
  	PG_RETURN_BOOL(res >= trgm_limit);
  }
+ 
+ Datum
+ substring_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
+ 
+ Datum
+ substring_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_substring_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_substring_limit);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>substring_similarity(text, text)</function><indexterm><primary>substring_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar substring of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to substring of the second substring).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 149,163 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a substring similarity
+        that is greater than the current substring similarity threshold set by
+        <varname>pg_trgm.substring_limit</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 168,173 ****
--- 188,209 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-substring-limit" xreflabel="pg_trgm.substring_limit">
+     <term>
+      <varname>pg_trgm.substring_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.substring_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current substring similarity threshold that is used by
+       the <literal>&lt;%</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 262,282 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for substring
+    similarity.  For example:
+ <programlisting>
+ SELECT t, substring_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a substring
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#16Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Alvaro Herrera (#14)
Re: Fuzzy substring searching with the pg_trgm extension

On 21.01.2016 00:25, Alvaro Herrera wrote:

Artur Zakirov wrote:

I don't quite understand why aren't we using a custom GUC variable here.
These already have SHOW and SET support ...

Added GUC variables:
- pg_trgm.limit
- pg_trgm.substring_limit
I added this variables to the documentation.
show_limit() and set_limit() functions work correctly and they are marked as
deprecated.

Thanks. I'm willing to commit quickly a small patch that only changes
the existing function to GUCs, then have a look at a separate patch that
adds the new substring operator. Would you split the patch that way?

What status of this patch? In commitfest it is "Needs review".

Can this patch get the status "Ready for Commiter"?

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Artur Zakirov (#16)
Re: Fuzzy substring searching with the pg_trgm extension

Artur Zakirov wrote:

What status of this patch? In commitfest it is "Needs review".

"Needs review" means it needs a reviewer to go over it and, uh, review
it. Did I send an email to you prodding you to review patches? I sent
such an email to several people from PostgresPro, but I don't remember
getting a response from anyone, and honestly I don't see you guys/gal
doing much review on-list. If you can please talk to your colleagues so
that they look over your patch, while at the same time your review their
patches, that would help not only this one patch but everyone else's
patches as well.

Can this patch get the status "Ready for Commiter"?

Sure, as soon as it has gotten enough review to say it's past the "needs
review" phase. Just like all patches.

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Oleg Bartunov
obartunov@gmail.com
In reply to: Alvaro Herrera (#17)
Re: Fuzzy substring searching with the pg_trgm extension

On Fri, Jan 29, 2016 at 1:11 PM, Alvaro Herrera <alvherre@2ndquadrant.com>
wrote:

Artur Zakirov wrote:

What status of this patch? In commitfest it is "Needs review".

"Needs review" means it needs a reviewer to go over it and, uh, review
it. Did I send an email to you prodding you to review patches? I sent
such an email to several people from PostgresPro, but I don't remember
getting a response from anyone, and honestly I don't see you guys/gal
doing much review on-list. If you can please talk to your colleagues so
that they look over your patch, while at the same time your review their
patches, that would help not only this one patch but everyone else's
patches as well.

I think Teodor is planning to review these patches.

Show quoted text

Can this patch get the status "Ready for Commiter"?

Sure, as soon as it has gotten enough review to say it's past the "needs
review" phase. Just like all patches.

--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Teodor Sigaev
teodor@sigaev.ru
In reply to: Artur Zakirov (#15)
Re: Fuzzy substring searching with the pg_trgm extension

Sure. I attached two patches. But notice that pg_trgm.limit should be used with
this command:
SHOW "pg_trgm.limit";
If you will use this command:
SHOW pg_trgm.limit;
you will get the error:
ERROR: syntax error at or near "limit"
LINE 1: SHOW pg_trgm.limit;
^

This is because "limit" is keyword I think.

It's easy to fix in gram.y:
@@ -1499,7 +1499,7 @@ set_rest_more: /* Generic SET syntaxes: */
;

var_name: ColId { $$ = $1; }
- | var_name '.' ColId
+ | var_name '.' ColLabel
{ $$ = psprintf("%s.%s", $1, $3); }
;

ColId doesn't contain reserved_keyword, it's impossible to change initial part
of var_name to ColId because of a lot of conflicts in grammar but could be easy
changed for second part of var_name. It seems like improvement in any case but
sml_limit or similarity_limit or even similarity_treshold is more preferable
name than just simple limit. In future we could introduce more tresholds/limits.

Also, should get/set_limit emit a warning about deprecation?

Some notices about substring patch itself:
1 trgm2.data contains too much duplicates (like Barkala or Bakalan). Is it
really needed for testing?

2 I'm agree with Jeff Janes about <<-> and <->> operation. They are needed.
(/messages/by-id/CAMkU=1zynKQfkR-J2_Uq8Lzp0uho8i+LEdFwGt77CzK_tNtN7g@mail.gmail.com)

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Teodor Sigaev
teodor@sigaev.ru
In reply to: Jeff Janes (#12)
Re: Fuzzy substring searching with the pg_trgm extension

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog pound') ;
substring_similarity
----------------------
1
It seems to me that users search words in long string. But I'm agree that more
detailed explanation needed and, may be, we need to change feature name to
fuzzywordsearch or something else, I can't imagine how.

Also, should we have a function which indicates the position in the
2nd string at which the most similar match to the 1st argument occurs?

select substring_similarity_pos('dog' , 'hotdogpound') ;

answering: 4

Interesting, I think, it will be useful in some cases.

We could call them <<-> and <->> , where the first corresponds to <%
and the second to %>

Agree
--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Teodor Sigaev (#20)
Re: Fuzzy substring searching with the pg_trgm extension

On 29.01.2016 17:15, Teodor Sigaev wrote:

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog
pound') ;
substring_similarity
----------------------
1
It seems to me that users search words in long string. But I'm agree
that more detailed explanation needed and, may be, we need to change
feature name to fuzzywordsearch or something else, I can't imagine how.

Thank you for the review. I will rename the function name. Maybe to
subword_similarity()?

Also, should we have a function which indicates the position in the
2nd string at which the most similar match to the 1st argument occurs?

select substring_similarity_pos('dog' , 'hotdogpound') ;

answering: 4

Interesting, I think, it will be useful in some cases.

We could call them <<-> and <->> , where the first corresponds to <%
and the second to %>

Agree

I will add them.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#22Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Teodor Sigaev (#20)
Re: Fuzzy substring searching with the pg_trgm extension

Teodor Sigaev wrote:

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog pound') ;
substring_similarity
----------------------
1

Hmm, this behavior looks too much like magic to me. I mean, a substring
is a substring -- why are we treating the space as a special character
here?

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#23Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Alvaro Herrera (#22)
Re: Fuzzy substring searching with the pg_trgm extension

On 29.01.2016 18:39, Alvaro Herrera wrote:

Teodor Sigaev wrote:

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog pound') ;
substring_similarity
----------------------
1

Hmm, this behavior looks too much like magic to me. I mean, a substring
is a substring -- why are we treating the space as a special character
here?

I think, I can rename this function to subword_similarity() and correct
the documentation.

The current behavior is developed to find most similar word in a text.
For example, if we will search just substring (not word) then we will
get the following result:

select substring_similarity('dog', 'dogmatist');
substring_similarity
---------------------
1
(1 row)

But this is wrong I think. They are completely different words.

For searching a similar substring (not word) in a text maybe another
function should be added?

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#24Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Artur Zakirov (#23)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 29.01.2016 18:58, Artur Zakirov wrote:

On 29.01.2016 18:39, Alvaro Herrera wrote:

Teodor Sigaev wrote:

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot
dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog
pound') ;
substring_similarity
----------------------
1

Hmm, this behavior looks too much like magic to me. I mean, a substring
is a substring -- why are we treating the space as a special character
here?

I think, I can rename this function to subword_similarity() and correct
the documentation.

The current behavior is developed to find most similar word in a text.
For example, if we will search just substring (not word) then we will
get the following result:

select substring_similarity('dog', 'dogmatist');
substring_similarity
---------------------
1
(1 row)

But this is wrong I think. They are completely different words.

For searching a similar substring (not word) in a text maybe another
function should be added?

I have changed the patch:
1 - trgm2.data was corrected, duplicates were deleted.
2 - I have added operators <<-> and <->> with GiST index supporting. A
regression test will pass only with the patch
/messages/by-id/CAPpHfdt19FwQXarYjkzxb3oxmv-KAn3FLuZrooARE_U3H3CV9g@mail.gmail.com
3 - the function substring_similarity() was renamed to subword_similarity().

But there is not a function substring_similarity_pos() yet. It is not
trivial.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

pg_trgm_guc_v2.patchtext/x-patch; name=pg_trgm_guc_v2.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.sml_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double trgm_sml_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 206,213 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 283,289 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 284,291 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= trgm_sml_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 294,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 294,301 ----
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 309,315 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		trgm_sml_limit = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,44 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
! 	trgm_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  static int
--- 26,77 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.sml_limit",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_sml_limit,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
! 	trgm_sml_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
  static int
***************
*** 720,724 **** similarity_op(PG_FUNCTION_ARGS)
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_limit);
  }
--- 753,757 ----
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.sml_limit</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-sml-limit" xreflabel="pg_trgm.sml_limit">
+     <term>
+      <varname>pg_trgm.sml_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.sml_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
pg_trgm_subword_v5.patchtext/x-patch; name=pg_trgm_subword_v5.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_subword_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,696 ----
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala Park
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Purba Kalmegha
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Bikalabwa
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Bumba-Kalumba
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bambakala
+ Bakalou
+ Tsibakala
+ Kimbakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baimalang Donggang
+ Baikangshuoma
+ Baitaliao
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baiwale
+ Baikangnei
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baimalin
+ Subaika
+ Gabakkale
+ Barkallou
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Desa Bakalan
+ Kebakkalang
+ Ngambakalang
+ Mota Sabakal
+ Bakalan Lor
+ Babakalo
+ Buyu Rapanbakalai
+ Kalimundubakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Desa Bakalrejo
+ Bakalan Kidul
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Gunung Bakalan
+ Kalibakal
+ Bakaljaya
+ Trobakal
+ Bakalan Wetan
+ Desa Bakal
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Sampangbakalan
+ Bakalam
+ Desa Bakalankrapyak
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakalan Tengah
+ Kali Bakalan
+ Desa Cemengbakalan
+ Desa Bakalanpule
+ Gunung Bakal
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Desa Bakalanrayung
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Desa Bakalankrajan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Barat
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkali
+ Baidal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakkalmal
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Bakalica
+ Bakalnica
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Maikali
+ Bakalum
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Barkalden
+ Bakkalia
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakalsen
+ Baiyaldi
+ Naikala
+ Baikanda
+ Barkalne
+ Bakalipur
+ Bakaldum
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Bakal Tres
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakalovskaya Ferma
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Bakalda
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Prud Novyy Baykal
+ Bakaleyka
+ Bakalka
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Bakalinskiy Leskhoz
+ Bikalikha
+ Kordon Barkalo
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakalaale
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Ambakali
+ Ba Kaliin
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_subword_trgm.out
***************
*** 0 ****
--- 1,1044 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+                    QUERY PLAN                   
+ ------------------------------------------------
+  Limit
+    ->  Index Scan using trgm_idx2 on test_trgm2
+          Order By: (t <->> 'Kabankala'::text)
+ (3 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,74 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 51,56 **** CREATE OPERATOR <-> (
--- 84,113 ----
          COMMUTATOR = '<->'
  );
  
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  -- gist key
  CREATE FUNCTION gtrgm_in(cstring)
  RETURNS gtrgm
***************
*** 140,145 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
--- 197,208 ----
          OPERATOR        5       pg_catalog.~ (text, text),
          OPERATOR        6       pg_catalog.~* (text, text);
  
+ -- Add operators that are new in 9.6 (pg_trgm 1.2).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
  RETURNS internal
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
--- 250,254 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text),
          FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_subword_trgm.sql
***************
*** 0 ****
--- 1,42 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,38 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
! 
  
  typedef char trgm[3];
  
--- 26,39 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber		1
! #define DistanceStrategyNumber			2
! #define LikeStrategyNumber				3
! #define ILikeStrategyNumber				4
! #define RegExpStrategyNumber			5
! #define RegExpICaseStrategyNumber		6
! #define SubwordSimilarityStrategyNumber	7
! #define SubwordDistanceStrategyNumber	8
  
  typedef char trgm[3];
  
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
+ extern double trgm_subword_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 184,190 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 207,213 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 209,215 ----
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				(((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 273,278 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 275,281 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubwordSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,301 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,305 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubwordSimilarityStrategyNumber:
! 			/* Similarity search is exact. Subword similarity search is inexact */
! 			*recheck = (strategy == SubwordSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ?
! 				trgm_sml_limit : trgm_subword_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 309,315 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 313,319 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 427,432 **** gtrgm_distance(PG_FUNCTION_ARGS)
--- 431,437 ----
  	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
  
  	/* Oid		subtype = PG_GETARG_OID(3); */
+ 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
  	TRGM	   *key = (TRGM *) DatumGetPointer(entry->key);
  	TRGM	   *qtrg;
  	float8		res;
***************
*** 462,470 **** gtrgm_distance(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,477 ----
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
+ 		case SubwordDistanceStrategyNumber:
+ 			*recheck = strategy == SubwordDistanceStrategyNumber;
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(qtrg, key, *recheck);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		trgm_sml_limit = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double trgm_sml_limit = 0.3f;
! double trgm_subword_limit = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,43 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(subword_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_commutator_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,50 **** _PG_init(void)
--- 58,75 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.subword_limit",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_subword_limit,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 224,251 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 285,331 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 343,625 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       word which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with word in
+  * the string. But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ iterate_subword_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len,
+ 							 bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that subword similarity is greater than
+ 				 * pg_trgm.subword_limit we do not need to calculate a
+ 				 * maximum similarity
+ 				 */
+ 				if (check_only && smlr_cur >= trgm_subword_limit)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that subword similarity is greater than
+ 			 * pg_trgm.subword_limit we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= trgm_subword_limit)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate subword similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate subword similarity using iterate_subword_similarity().
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a word, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ calc_subword_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required word.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with subword */
+ 	result = iterate_subword_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 791,797 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 912,918 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 946,960 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1049,1055 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1060,1081 ----
  }
  
  Datum
+ subword_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1094,1160 ----
  
  	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
+ 
+ Datum
+ subword_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_dist_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
+ 
+ Datum
+ subword_similarity_dist_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>subword_similarity(text, text)</function><indexterm><primary>subword_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar word of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to one of the word of the second string).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 149,163 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a subword similarity
+        that is greater than the current subword similarity threshold set by
+        <varname>pg_trgm.subword_limit</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 145,150 ****
--- 165,178 ----
         one minus the <function>similarity()</> value.
        </entry>
       </row>
+      <row>
+       <entry><type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the <quote>distance</> between the arguments, that is
+        one minus the <function>subword_similarity()</> value.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 168,173 ****
--- 196,217 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-subword-limit" xreflabel="pg_trgm.subword_limit">
+     <term>
+      <varname>pg_trgm.subword_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.subword_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current subword similarity threshold that is used by
+       the <literal>&lt;%</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 270,301 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for subword
+    similarity.  For example:
+ <programlisting>
+ SELECT t, subword_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a word
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
+    A variant of the above query is
+ <programlisting>
+ SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
+   FROM test_trgm
+   ORDER BY dist LIMIT 10;
+ </programlisting>
+    This can be implemented quite efficiently by GiST indexes, but not
+    by GIN indexes.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#25Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Artur Zakirov (#24)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 01.02.2016 20:12, Artur Zakirov wrote:

I have changed the patch:
1 - trgm2.data was corrected, duplicates were deleted.
2 - I have added operators <<-> and <->> with GiST index supporting. A
regression test will pass only with the patch
/messages/by-id/CAPpHfdt19FwQXarYjkzxb3oxmv-KAn3FLuZrooARE_U3H3CV9g@mail.gmail.com

3 - the function substring_similarity() was renamed to
subword_similarity().

But there is not a function substring_similarity_pos() yet. It is not
trivial.

Sorry, in the previous patch was a typo. Here is the fixed patch.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

pg_trgm_guc_v2.patchtext/x-patch; name=pg_trgm_guc_v2.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.sml_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double trgm_sml_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 206,213 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 283,289 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 284,291 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= trgm_sml_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 294,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 294,301 ----
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 309,315 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		trgm_sml_limit = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,44 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
! 	trgm_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  static int
--- 26,77 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.sml_limit",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_sml_limit,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
! 	trgm_sml_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
  static int
***************
*** 720,724 **** similarity_op(PG_FUNCTION_ARGS)
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_limit);
  }
--- 753,757 ----
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.sml_limit</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-sml-limit" xreflabel="pg_trgm.sml_limit">
+     <term>
+      <varname>pg_trgm.sml_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.sml_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
pg_trgm_subword_v6.patchtext/x-patch; name=pg_trgm_subword_v6.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_subword_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,696 ----
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala Park
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Purba Kalmegha
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Bikalabwa
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Bumba-Kalumba
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bambakala
+ Bakalou
+ Tsibakala
+ Kimbakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baimalang Donggang
+ Baikangshuoma
+ Baitaliao
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baiwale
+ Baikangnei
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baimalin
+ Subaika
+ Gabakkale
+ Barkallou
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Desa Bakalan
+ Kebakkalang
+ Ngambakalang
+ Mota Sabakal
+ Bakalan Lor
+ Babakalo
+ Buyu Rapanbakalai
+ Kalimundubakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Desa Bakalrejo
+ Bakalan Kidul
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Gunung Bakalan
+ Kalibakal
+ Bakaljaya
+ Trobakal
+ Bakalan Wetan
+ Desa Bakal
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Sampangbakalan
+ Bakalam
+ Desa Bakalankrapyak
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakalan Tengah
+ Kali Bakalan
+ Desa Cemengbakalan
+ Desa Bakalanpule
+ Gunung Bakal
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Desa Bakalanrayung
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Desa Bakalankrajan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Barat
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkali
+ Baidal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakkalmal
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Bakalica
+ Bakalnica
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Maikali
+ Bakalum
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Barkalden
+ Bakkalia
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakalsen
+ Baiyaldi
+ Naikala
+ Baikanda
+ Barkalne
+ Bakalipur
+ Bakaldum
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Bakal Tres
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakalovskaya Ferma
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Bakalda
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Prud Novyy Baykal
+ Bakaleyka
+ Bakalka
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Bakalinskiy Leskhoz
+ Bikalikha
+ Kordon Barkalo
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakalaale
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Ambakali
+ Ba Kaliin
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_subword_trgm.out
***************
*** 0 ****
--- 1,1044 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+                    QUERY PLAN                   
+ ------------------------------------------------
+  Limit
+    ->  Index Scan using trgm_idx2 on test_trgm2
+          Order By: (t <->> 'Kabankala'::text)
+ (3 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,74 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 51,56 **** CREATE OPERATOR <-> (
--- 84,113 ----
          COMMUTATOR = '<->'
  );
  
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  -- gist key
  CREATE FUNCTION gtrgm_in(cstring)
  RETURNS gtrgm
***************
*** 140,145 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
--- 197,208 ----
          OPERATOR        5       pg_catalog.~ (text, text),
          OPERATOR        6       pg_catalog.~* (text, text);
  
+ -- Add operators that are new in 9.6 (pg_trgm 1.2).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
  RETURNS internal
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
--- 250,254 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text),
          FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_subword_trgm.sql
***************
*** 0 ****
--- 1,42 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,38 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
! 
  
  typedef char trgm[3];
  
--- 26,39 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber		1
! #define DistanceStrategyNumber			2
! #define LikeStrategyNumber				3
! #define ILikeStrategyNumber				4
! #define RegExpStrategyNumber			5
! #define RegExpICaseStrategyNumber		6
! #define SubwordSimilarityStrategyNumber	7
! #define SubwordDistanceStrategyNumber	8
  
  typedef char trgm[3];
  
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
+ extern double trgm_subword_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 176,181 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 177,183 ----
  	bool		res;
  	int32		i,
  				ntrue;
+ 	double		nlimit;
  
  	/* All cases served by this function are inexact */
  	*recheck = true;
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 185,194 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				trgm_sml_limit : trgm_subword_limit;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 207,213 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 213,219 ----
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				(((((float4) ntrue) / ((float4) nkeys))) >= nlimit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 269,278 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 275,289 ----
  	int32		i,
  				ntrue;
  	bool	   *boolcheck;
+ 	double		nlimit;
  
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				trgm_sml_limit : trgm_subword_limit;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 285,291 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
  			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= trgm_sml_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 296,302 ----
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
  			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= nlimit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubwordSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,301 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,305 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubwordSimilarityStrategyNumber:
! 			/* Similarity search is exact. Subword similarity search is inexact */
! 			*recheck = (strategy == SubwordSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ?
! 				trgm_sml_limit : trgm_subword_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 309,315 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 313,319 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 427,432 **** gtrgm_distance(PG_FUNCTION_ARGS)
--- 431,437 ----
  	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
  
  	/* Oid		subtype = PG_GETARG_OID(3); */
+ 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
  	TRGM	   *key = (TRGM *) DatumGetPointer(entry->key);
  	TRGM	   *qtrg;
  	float8		res;
***************
*** 462,470 **** gtrgm_distance(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 467,477 ----
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
+ 		case SubwordDistanceStrategyNumber:
+ 			*recheck = strategy == SubwordDistanceStrategyNumber;
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(qtrg, key, *recheck);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		trgm_sml_limit = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double trgm_sml_limit = 0.3f;
! double trgm_subword_limit = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,43 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(subword_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_commutator_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,50 **** _PG_init(void)
--- 58,75 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.subword_limit",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_subword_limit,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 224,251 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 285,331 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 343,625 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       word which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with word in
+  * the string. But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ iterate_subword_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len,
+ 							 bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that subword similarity is greater than
+ 				 * pg_trgm.subword_limit we do not need to calculate a
+ 				 * maximum similarity
+ 				 */
+ 				if (check_only && smlr_cur >= trgm_subword_limit)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that subword similarity is greater than
+ 			 * pg_trgm.subword_limit we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= trgm_subword_limit)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate subword similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate subword similarity using iterate_subword_similarity().
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a word, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ calc_subword_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required word.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with subword */
+ 	result = iterate_subword_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 791,797 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 912,918 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 946,960 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1049,1055 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1060,1081 ----
  }
  
  Datum
+ subword_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1094,1160 ----
  
  	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
+ 
+ Datum
+ subword_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_dist_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
+ 
+ Datum
+ subword_similarity_dist_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>subword_similarity(text, text)</function><indexterm><primary>subword_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar word of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to one of the word of the second string).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 149,163 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a subword similarity
+        that is greater than the current subword similarity threshold set by
+        <varname>pg_trgm.subword_limit</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 145,150 ****
--- 165,178 ----
         one minus the <function>similarity()</> value.
        </entry>
       </row>
+      <row>
+       <entry><type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the <quote>distance</> between the arguments, that is
+        one minus the <function>subword_similarity()</> value.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 168,173 ****
--- 196,217 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-subword-limit" xreflabel="pg_trgm.subword_limit">
+     <term>
+      <varname>pg_trgm.subword_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.subword_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current subword similarity threshold that is used by
+       the <literal>&lt;%</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 270,301 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for subword
+    similarity.  For example:
+ <programlisting>
+ SELECT t, subword_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a word
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
+    A variant of the above query is
+ <programlisting>
+ SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
+   FROM test_trgm
+   ORDER BY dist LIMIT 10;
+ </programlisting>
+    This can be implemented quite efficiently by GiST indexes, but not
+    by GIN indexes.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#26Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Artur Zakirov (#25)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 02.02.2016 15:45, Artur Zakirov wrote:

On 01.02.2016 20:12, Artur Zakirov wrote:

I have changed the patch:
1 - trgm2.data was corrected, duplicates were deleted.
2 - I have added operators <<-> and <->> with GiST index supporting. A
regression test will pass only with the patch
/messages/by-id/CAPpHfdt19FwQXarYjkzxb3oxmv-KAn3FLuZrooARE_U3H3CV9g@mail.gmail.com

3 - the function substring_similarity() was renamed to
subword_similarity().

But there is not a function substring_similarity_pos() yet. It is not
trivial.

Sorry, in the previous patch was a typo. Here is the fixed patch.

I have attached a new version of the patch. It fixes error of operators
<->> and %>:
- operator <->> did not pass the regression test in CentOS 32 bit (gcc
4.4.7 20120313).
- operator %> did not pass the regression test in FreeBSD 32 bit (gcc
4.2.1 20070831).

It was because of variable optimization by gcc.

In this patch pg_trgm documentation was corrected. Now operators were
wrote as %> and <->> (not <% and <<->).

There is a problem in adding the substring_similarity_pos() function. It
can bring additional overhead. Because we need to store characters
position including spaces in addition. Spaces between words are lost in
current implementation.
Does it actually need?

In conclusion, this patch introduces:
1 - functions:
- subword_similarity()
2 - operators:
- %>
- <->>
3 - GUC variables:
- pg_trgm.sml_limit
- pg_trgm.subword_limit

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

pg_trgm_guc_v2.patchtext/x-patch; name=pg_trgm_guc_v2.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.sml_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double trgm_sml_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 206,213 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 283,289 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 284,291 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= trgm_sml_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 294,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 294,301 ----
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 309,315 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		trgm_sml_limit = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,44 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
! 	trgm_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  static int
--- 26,77 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.sml_limit",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_sml_limit,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
! 	trgm_sml_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.sml_limit" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_sml_limit);
  }
  
  static int
***************
*** 720,724 **** similarity_op(PG_FUNCTION_ARGS)
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_limit);
  }
--- 753,757 ----
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.sml_limit</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-sml-limit" xreflabel="pg_trgm.sml_limit">
+     <term>
+      <varname>pg_trgm.sml_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.sml_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
pg_trgm_subword_v7.patchtext/x-patch; name=pg_trgm_subword_v7.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_subword_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,696 ----
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala Park
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Purba Kalmegha
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Bikalabwa
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Bumba-Kalumba
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bambakala
+ Bakalou
+ Tsibakala
+ Kimbakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baimalang Donggang
+ Baikangshuoma
+ Baitaliao
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baiwale
+ Baikangnei
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baimalin
+ Subaika
+ Gabakkale
+ Barkallou
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Desa Bakalan
+ Kebakkalang
+ Ngambakalang
+ Mota Sabakal
+ Bakalan Lor
+ Babakalo
+ Buyu Rapanbakalai
+ Kalimundubakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Desa Bakalrejo
+ Bakalan Kidul
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Gunung Bakalan
+ Kalibakal
+ Bakaljaya
+ Trobakal
+ Bakalan Wetan
+ Desa Bakal
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Sampangbakalan
+ Bakalam
+ Desa Bakalankrapyak
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakalan Tengah
+ Kali Bakalan
+ Desa Cemengbakalan
+ Desa Bakalanpule
+ Gunung Bakal
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Desa Bakalanrayung
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Desa Bakalankrajan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Barat
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkali
+ Baidal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakkalmal
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Bakalica
+ Bakalnica
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Maikali
+ Bakalum
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Barkalden
+ Bakkalia
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakalsen
+ Baiyaldi
+ Naikala
+ Baikanda
+ Barkalne
+ Bakalipur
+ Bakaldum
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Bakal Tres
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakalovskaya Ferma
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Bakalda
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Prud Novyy Baykal
+ Bakaleyka
+ Bakalka
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Bakalinskiy Leskhoz
+ Bikalikha
+ Kordon Barkalo
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakalaale
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Ambakali
+ Ba Kaliin
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_subword_trgm.out
***************
*** 0 ****
--- 1,1044 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+                    QUERY PLAN                   
+ ------------------------------------------------
+  Limit
+    ->  Index Scan using trgm_idx2 on test_trgm2
+          Order By: (t <->> 'Kabankala'::text)
+ (3 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,74 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION subword_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE FUNCTION subword_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.subword_limit
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 51,56 **** CREATE OPERATOR <-> (
--- 84,113 ----
          COMMUTATOR = '<->'
  );
  
+ CREATE FUNCTION subword_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION subword_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = subword_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  -- gist key
  CREATE FUNCTION gtrgm_in(cstring)
  RETURNS gtrgm
***************
*** 140,145 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
--- 197,208 ----
          OPERATOR        5       pg_catalog.~ (text, text),
          OPERATOR        6       pg_catalog.~* (text, text);
  
+ -- Add operators that are new in 9.6 (pg_trgm 1.2).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
  RETURNS internal
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
--- 250,254 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text),
          FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_subword_trgm.sql
***************
*** 0 ****
--- 1,42 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.5;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.subword_limit" to 0.3;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,subword_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,subword_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,38 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
! 
  
  typedef char trgm[3];
  
--- 26,39 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber		1
! #define DistanceStrategyNumber			2
! #define LikeStrategyNumber				3
! #define ILikeStrategyNumber				4
! #define RegExpStrategyNumber			5
! #define RegExpICaseStrategyNumber		6
! #define SubwordSimilarityStrategyNumber	7
! #define SubwordDistanceStrategyNumber	8
  
  typedef char trgm[3];
  
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double trgm_sml_limit;
+ extern double trgm_subword_limit;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 176,181 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 177,183 ----
  	bool		res;
  	int32		i,
  				ntrue;
+ 	double		nlimit;
  
  	/* All cases served by this function are inexact */
  	*recheck = true;
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 185,194 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				trgm_sml_limit : trgm_subword_limit;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 207,213 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= trgm_sml_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 213,219 ----
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				(((((float4) ntrue) / ((float4) nkeys))) >= nlimit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 269,278 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 275,289 ----
  	int32		i,
  				ntrue;
  	bool	   *boolcheck;
+ 	double		nlimit;
  
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case SubwordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				trgm_sml_limit : trgm_subword_limit;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 285,291 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
  			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= trgm_sml_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 296,302 ----
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
  			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= nlimit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case SubwordSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,301 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_sml_limit
! 						|| tmpsml > trgm_sml_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,310 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case SubwordSimilarityStrategyNumber:
! 			/* Similarity search is exact. Subword similarity search is inexact */
! 			*recheck = (strategy == SubwordSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ?
! 				trgm_sml_limit : trgm_subword_limit;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the tmpsml variable using volatile
! 				 * keyword. Otherwise comparison of nlimit and tmpsml may give
! 				 * wrong results.
! 				 */
! 				float4 volatile tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 309,315 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_sml_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 318,324 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 427,432 **** gtrgm_distance(PG_FUNCTION_ARGS)
--- 436,442 ----
  	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
  
  	/* Oid		subtype = PG_GETARG_OID(3); */
+ 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
  	TRGM	   *key = (TRGM *) DatumGetPointer(entry->key);
  	TRGM	   *qtrg;
  	float8		res;
***************
*** 462,470 **** gtrgm_distance(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 472,488 ----
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
+ 		case SubwordDistanceStrategyNumber:
+ 			*recheck = strategy == SubwordDistanceStrategyNumber;
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the sml variable using volatile
! 				 * keyword. Otherwise res can differ from the
! 				 * subword_similarity_dist_op() function.
! 				 */
! 				float4 volatile sml = cnt_sml(qtrg, key, *recheck);
! 				res = 1.0 - sml;
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		trgm_sml_limit = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double trgm_sml_limit = 0.3f;
! double trgm_subword_limit = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,43 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(subword_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_commutator_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_op);
+ PG_FUNCTION_INFO_V1(subword_similarity_dist_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,50 **** _PG_init(void)
--- 58,75 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.subword_limit",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&trgm_subword_limit,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 224,251 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 285,331 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 343,625 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       word which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with word in
+  * the string. But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ iterate_subword_similarity(int *trg2indexes,
+ 							 bool *found,
+ 							 int ulen1,
+ 							 int len2,
+ 							 int len,
+ 							 bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that subword similarity is greater than
+ 				 * pg_trgm.subword_limit we do not need to calculate a
+ 				 * maximum similarity
+ 				 */
+ 				if (check_only && smlr_cur >= trgm_subword_limit)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that subword similarity is greater than
+ 			 * pg_trgm.subword_limit we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= trgm_subword_limit)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate subword similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate subword similarity using iterate_subword_similarity().
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a word, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in text
+  *
+  * Returns subword similarity.
+  */
+ static float4
+ calc_subword_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required word.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with subword */
+ 	result = iterate_subword_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 791,797 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 912,918 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 946,960 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1049,1055 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1060,1081 ----
  }
  
  Datum
+ subword_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1094,1160 ----
  
  	PG_RETURN_BOOL(res >= trgm_sml_limit);
  }
+ 
+ Datum
+ subword_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= trgm_subword_limit);
+ }
+ 
+ Datum
+ subword_similarity_dist_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
+ 
+ Datum
+ subword_similarity_dist_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_subword_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 									VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 									false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,101 ----
        </entry>
       </row>
       <row>
+       <entry><function>subword_similarity(text, text)</function><indexterm><primary>subword_similarity</primary></indexterm></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar word of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to one of the word of the second string).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 149,163 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its arguments have a subword similarity
+        that is greater than the current subword similarity threshold set by
+        <varname>pg_trgm.subword_limit</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 145,150 ****
--- 165,178 ----
         one minus the <function>similarity()</> value.
        </entry>
       </row>
+      <row>
+       <entry><type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</></entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the <quote>distance</> between the arguments, that is
+        one minus the <function>subword_similarity()</> value.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 168,173 ****
--- 196,217 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-subword-limit" xreflabel="pg_trgm.subword_limit">
+     <term>
+      <varname>pg_trgm.subword_limit</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.subword_limit</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current subword similarity threshold that is used by
+       the <literal>&lt;%</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 270,301 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for subword
+    similarity.  For example:
+ <programlisting>
+ SELECT t, subword_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE '<replaceable>word</>' &lt;% t
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a word
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
+    A variant of the above query is
+ <programlisting>
+ SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
+   FROM test_trgm
+   ORDER BY dist LIMIT 10;
+ </programlisting>
+    This can be implemented quite efficiently by GiST indexes, but not
+    by GIN indexes.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#27Teodor Sigaev
teodor@sigaev.ru
In reply to: Alvaro Herrera (#22)
Re: Fuzzy substring searching with the pg_trgm extension

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog pound') ;
substring_similarity
----------------------
1

Hmm, this behavior looks too much like magic to me. I mean, a substring
is a substring -- why are we treating the space as a special character
here?

Because it isn't a regex for substring search. Since implementing, pg_trgm
works over words in string.
contrib_regression=# select similarity('block hole', 'hole black');
similarity
------------
0.571429
contrib_regression=# select similarity('block hole', 'black hole');
similarity
------------
0.571429

It ignores spaces between words and word's order.

I agree, that substring_similarity is confusing name, but actually it search
most similar word in second arg to first arg and returns their similarity.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#28Teodor Sigaev
teodor@sigaev.ru
In reply to: Artur Zakirov (#26)
Re: Fuzzy substring searching with the pg_trgm extension

I have attached a new version of the patch. It fixes error of operators <->> and
%>:
- operator <->> did not pass the regression test in CentOS 32 bit (gcc 4.4.7
20120313).
- operator %> did not pass the regression test in FreeBSD 32 bit (gcc 4.2.1
20070831).

It was because of variable optimization by gcc.

Fixed with volatile modifier, right?

I'm close to push this patches, but I still doubt in names, and I'd like to see
comment from English speackers:
1 sml_limit GUC variable (options: similarity_limit, sml_threshold)
2 subword_similarity(). Actually, it finds most similar word (not substring!)
from whole string. word_similarity? word_in_string_similarity?

substring_similarity_pos() could be a separate patch.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#29Mike Rylander
mrylander@gmail.com
In reply to: Teodor Sigaev (#28)
Re: Fuzzy substring searching with the pg_trgm extension

On Thu, Feb 11, 2016 at 8:11 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

I have attached a new version of the patch. It fixes error of operators
<->> and
%>:
- operator <->> did not pass the regression test in CentOS 32 bit (gcc
4.4.7
20120313).
- operator %> did not pass the regression test in FreeBSD 32 bit (gcc
4.2.1
20070831).

It was because of variable optimization by gcc.

Fixed with volatile modifier, right?

I'm close to push this patches, but I still doubt in names, and I'd like to
see comment from English speackers:
1 sml_limit GUC variable (options: similarity_limit, sml_threshold)
2 subword_similarity(). Actually, it finds most similar word (not
substring!) from whole string. word_similarity? word_in_string_similarity?

At least for this English speaker, substring_similarity is not
confusing even if it's not internally accurate, but English is a
strange language.

Because I want the bike shed to be blue, how does
query_string_similarity sound instead? If that's overly precise, then
word_similarity would be fine with me.

Thanks,

--
Mike Rylander

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#30Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Teodor Sigaev (#28)
Re: Fuzzy substring searching with the pg_trgm extension

On 11.02.2016 16:11, Teodor Sigaev wrote:

I have attached a new version of the patch. It fixes error of
operators <->> and
%>:
- operator <->> did not pass the regression test in CentOS 32 bit (gcc
4.4.7
20120313).
- operator %> did not pass the regression test in FreeBSD 32 bit (gcc
4.2.1
20070831).

It was because of variable optimization by gcc.

Fixed with volatile modifier, right?

Yes, it was fixes with volatile modifier.

I'm close to push this patches, but I still doubt in names, and I'd like
to see comment from English speackers:
1 sml_limit GUC variable (options: similarity_limit, sml_threshold)
2 subword_similarity(). Actually, it finds most similar word (not
substring!) from whole string. word_similarity? word_in_string_similarity?

substring_similarity_pos() could be a separate patch.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#31Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Mike Rylander (#29)
Re: Fuzzy substring searching with the pg_trgm extension

On 11.02.2016 16:35, Mike Rylander wrote:

On Thu, Feb 11, 2016 at 8:11 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

I have attached a new version of the patch. It fixes error of operators
<->> and
%>:
- operator <->> did not pass the regression test in CentOS 32 bit (gcc
4.4.7
20120313).
- operator %> did not pass the regression test in FreeBSD 32 bit (gcc
4.2.1
20070831).

It was because of variable optimization by gcc.

Fixed with volatile modifier, right?

I'm close to push this patches, but I still doubt in names, and I'd like to
see comment from English speackers:
1 sml_limit GUC variable (options: similarity_limit, sml_threshold)
2 subword_similarity(). Actually, it finds most similar word (not
substring!) from whole string. word_similarity? word_in_string_similarity?

At least for this English speaker, substring_similarity is not
confusing even if it's not internally accurate, but English is a
strange language.

Because I want the bike shed to be blue, how does
query_string_similarity sound instead? If that's overly precise, then
word_similarity would be fine with me.

Thanks,

--
Mike Rylander

Great. I can change names:
1 - sml_limit to similarity_limit. sml_threshold is difficult to write I
think, similarity_limit is more simple.
2 - subword_similarity() to word_similarity().

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#32Teodor Sigaev
teodor@sigaev.ru
In reply to: Artur Zakirov (#31)
Re: Fuzzy substring searching with the pg_trgm extension

1 - sml_limit to similarity_limit. sml_threshold is difficult to write I think,
similarity_limit is more simple.

It seems to me that threshold is right word by meaning. sml_threshold is my choice.

2 - subword_similarity() to word_similarity().

Agree, according to Mike Rylander opinion in this thread

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#33Robert Haas
robertmhaas@gmail.com
In reply to: Teodor Sigaev (#32)
Re: Fuzzy substring searching with the pg_trgm extension

On Thu, Feb 11, 2016 at 9:56 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

1 - sml_limit to similarity_limit. sml_threshold is difficult to write I
think,
similarity_limit is more simple.

It seems to me that threshold is right word by meaning. sml_threshold is my
choice.

Why abbreviate it like that? Nobody's going to know that "sml" stands
for "similarity" without consulting the documentation, and that sucks.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#34Teodor Sigaev
teodor@sigaev.ru
In reply to: Robert Haas (#33)
Re: Fuzzy substring searching with the pg_trgm extension

On Thu, Feb 11, 2016 at 9:56 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

1 - sml_limit to similarity_limit. sml_threshold is difficult to write I
think,
similarity_limit is more simple.

It seems to me that threshold is right word by meaning. sml_threshold is my
choice.

Why abbreviate it like that? Nobody's going to know that "sml" stands
for "similarity" without consulting the documentation, and that sucks.

Ok, I don't have an objections. I worked a lot on various similarity
modules and sml becomes usual for me. That's why I was asking.

--
Teodor Sigaev E-mail: teodor@sigaev.ru
WWW: http://www.sigaev.ru/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#35Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Teodor Sigaev (#34)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 12.02.2016 20:56, Teodor Sigaev wrote:

On Thu, Feb 11, 2016 at 9:56 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

1 - sml_limit to similarity_limit. sml_threshold is difficult to
write I
think,
similarity_limit is more simple.

It seems to me that threshold is right word by meaning. sml_threshold
is my
choice.

Why abbreviate it like that? Nobody's going to know that "sml" stands
for "similarity" without consulting the documentation, and that sucks.

Ok, I don't have an objections. I worked a lot on various similarity
modules and sml becomes usual for me. That's why I was asking.

Hi!

I attached new version of the patch. It fixes names of GUC variables and
functions.

Now the patch introduces:
1 - functions:
- word_similarity()
2 - operators:
- %> (and <%)
- <->> (and <<->)
3 - GUC variables:
- pg_trgm.similarity_threshold
- pg_trgm.word_similarity_threshold

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

0002-pg_trgm_word_v8.patchtext/x-patch; name=0002-pg_trgm_word_v8.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_word_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,696 ----
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala Park
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Purba Kalmegha
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Bikalabwa
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Bumba-Kalumba
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bambakala
+ Bakalou
+ Tsibakala
+ Kimbakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baimalang Donggang
+ Baikangshuoma
+ Baitaliao
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baiwale
+ Baikangnei
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baimalin
+ Subaika
+ Gabakkale
+ Barkallou
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Desa Bakalan
+ Kebakkalang
+ Ngambakalang
+ Mota Sabakal
+ Bakalan Lor
+ Babakalo
+ Buyu Rapanbakalai
+ Kalimundubakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Desa Bakalrejo
+ Bakalan Kidul
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Gunung Bakalan
+ Kalibakal
+ Bakaljaya
+ Trobakal
+ Bakalan Wetan
+ Desa Bakal
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Sampangbakalan
+ Bakalam
+ Desa Bakalankrapyak
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakalan Tengah
+ Kali Bakalan
+ Desa Cemengbakalan
+ Desa Bakalanpule
+ Gunung Bakal
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Desa Bakalanrayung
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Desa Bakalankrajan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Barat
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkali
+ Baidal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakkalmal
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Bakalica
+ Bakalnica
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Maikali
+ Bakalum
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Barkalden
+ Bakkalia
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakalsen
+ Baiyaldi
+ Naikala
+ Baikanda
+ Barkalne
+ Bakalipur
+ Bakaldum
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Bakal Tres
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakalovskaya Ferma
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Bakalda
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Prud Novyy Baykal
+ Bakaleyka
+ Bakalka
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Bakalinskiy Leskhoz
+ Bikalikha
+ Kordon Barkalo
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakalaale
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Ambakali
+ Ba Kaliin
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_word_trgm.out
***************
*** 0 ****
--- 1,1044 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+                    QUERY PLAN                   
+ ------------------------------------------------
+  Limit
+    ->  Index Scan using trgm_idx2 on test_trgm2
+          Order By: (t <->> 'Kabankala'::text)
+ (3 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.5;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.3;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,74 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION word_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION word_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 51,56 **** CREATE OPERATOR <-> (
--- 84,113 ----
          COMMUTATOR = '<->'
  );
  
+ CREATE FUNCTION word_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  -- gist key
  CREATE FUNCTION gtrgm_in(cstring)
  RETURNS gtrgm
***************
*** 140,145 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
--- 197,208 ----
          OPERATOR        5       pg_catalog.~ (text, text),
          OPERATOR        6       pg_catalog.~* (text, text);
  
+ -- Add operators that are new in 9.6 (pg_trgm 1.2).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
  RETURNS internal
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
--- 250,254 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text),
          FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_word_trgm.sql
***************
*** 0 ****
--- 1,42 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.5;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.3;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,38 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
! 
  
  typedef char trgm[3];
  
--- 26,39 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber		1
! #define DistanceStrategyNumber			2
! #define LikeStrategyNumber				3
! #define ILikeStrategyNumber				4
! #define RegExpStrategyNumber			5
! #define RegExpICaseStrategyNumber		6
! #define WordSimilarityStrategyNumber	7
! #define WordDistanceStrategyNumber		8
  
  typedef char trgm[3];
  
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double similarity_threshold;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double similarity_threshold;
+ extern double word_similarity_threshold;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 176,181 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 177,183 ----
  	bool		res;
  	int32		i,
  				ntrue;
+ 	double		nlimit;
  
  	/* All cases served by this function are inexact */
  	*recheck = true;
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 185,194 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				similarity_threshold : word_similarity_threshold;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 207,214 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= similarity_threshold)
! 					? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 213,219 ----
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				(((((float4) ntrue) / ((float4) nkeys))) >= nlimit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 270,279 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 275,289 ----
  	int32		i,
  				ntrue;
  	bool	   *boolcheck;
+ 	double		nlimit;
  
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				similarity_threshold : word_similarity_threshold;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 285,293 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= similarity_threshold)
! 					? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 295,303 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0)
! 				? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= nlimit)
! 							? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case WordSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,301 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &similarity_threshold
! 						|| tmpsml > similarity_threshold) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,310 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case WordSimilarityStrategyNumber:
! 			/* Similarity search is exact. Word similarity search is inexact */
! 			*recheck = (strategy == WordSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ?
! 				similarity_threshold : word_similarity_threshold;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the tmpsml variable using volatile
! 				 * keyword. Otherwise comparison of nlimit and tmpsml may give
! 				 * wrong results.
! 				 */
! 				float4 volatile tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 309,316 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= similarity_threshold)
! 							? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 318,324 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 428,433 **** gtrgm_distance(PG_FUNCTION_ARGS)
--- 436,442 ----
  	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
  
  	/* Oid		subtype = PG_GETARG_OID(3); */
+ 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
  	TRGM	   *key = (TRGM *) DatumGetPointer(entry->key);
  	TRGM	   *qtrg;
  	float8		res;
***************
*** 463,471 **** gtrgm_distance(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 472,488 ----
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
+ 		case WordDistanceStrategyNumber:
+ 			*recheck = strategy == WordDistanceStrategyNumber;
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the sml variable using volatile
! 				 * keyword. Otherwise res can differ from the
! 				 * word_similarity_dist_op() function.
! 				 */
! 				float4 volatile sml = cnt_sml(qtrg, key, *recheck);
! 				res = 1.0 - sml;
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		similarity_threshold = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double similarity_threshold = 0.3f;
! double word_similarity_threshold = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,43 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(word_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(word_similarity_op);
+ PG_FUNCTION_INFO_V1(word_similarity_commutator_op);
+ PG_FUNCTION_INFO_V1(word_similarity_dist_op);
+ PG_FUNCTION_INFO_V1(word_similarity_dist_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,55 **** _PG_init(void)
  							NULL,
  							NULL,
  							NULL);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
   */
  Datum
  set_limit(PG_FUNCTION_ARGS)
--- 58,80 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.word_similarity_threshold",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&word_similarity_threshold,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function.
   */
  Datum
  set_limit(PG_FUNCTION_ARGS)
***************
*** 59,72 **** set_limit(PG_FUNCTION_ARGS)
  	if (nlimit < 0 || nlimit > 1.0)
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
  	similarity_threshold = nlimit;
  	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
   */
  Datum
  show_limit(PG_FUNCTION_ARGS)
--- 84,97 ----
  	if (nlimit < 0 || nlimit > 1.0)
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong threshold, should be between 0 and 1")));
  	similarity_threshold = nlimit;
  	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function.
   */
  Datum
  show_limit(PG_FUNCTION_ARGS)
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 224,251 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 285,331 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 343,627 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       word which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with word in
+  * the string. But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in
+  *             text.
+  *
+  * Returns word similarity.
+  */
+ static float4
+ iterate_word_similarity(int *trg2indexes,
+ 						bool *found,
+ 						int ulen1,
+ 						int len2,
+ 						int len,
+ 						bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that word similarity is greater than
+ 				 * pg_trgm.word_similarity_threshold we do not need to calculate
+ 				 * a maximum similarity.
+ 				 */
+ 				if (check_only && smlr_cur >= word_similarity_threshold)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that word similarity is greater than
+ 			 * pg_trgm.word_similarity_threshold we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= word_similarity_threshold)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate word similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate word similarity using iterate_word_similarity().
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a word, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in
+  *             text.
+  *
+  * Returns word similarity.
+  */
+ static float4
+ calc_word_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required word.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with word */
+ 	result = iterate_word_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 793,799 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 914,920 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 948,962 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1051,1057 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1062,1083 ----
  }
  
  Datum
+ word_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1096,1162 ----
  
  	PG_RETURN_BOOL(res >= similarity_threshold);
  }
+ 
+ Datum
+ word_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= word_similarity_threshold);
+ }
+ 
+ Datum
+ word_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= word_similarity_threshold);
+ }
+ 
+ Datum
+ word_similarity_dist_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
+ 
+ Datum
+ word_similarity_dist_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,104 ----
        </entry>
       </row>
       <row>
+       <entry>
+        <function>word_similarity(text, text)</function>
+        <indexterm><primary>word_similarity</primary></indexterm>
+       </entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar word of the second string.  The range of
+        the result is zero (indicating that the two strings are completely
+        dissimilar) to one (indicating that the first string is identical
+        to one of the word of the second string).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 152,167 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>%&gt;</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its first argument have a word which is the
+        similar word to the second argument and they have a similarity
+        that is greater than the current word similarity threshold set by
+        <varname>pg_trgm.word_similarity_threshold</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 145,150 ****
--- 169,184 ----
         one minus the <function>similarity()</> value.
        </entry>
       </row>
+      <row>
+       <entry>
+        <type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</>
+       </entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the <quote>distance</> between the arguments, that is
+        one minus the <function>word_similarity()</> value.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 158,164 ****
      <term>
       <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
       <indexterm>
!       <primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary>
       </indexterm>
      </term>
      <listitem>
--- 192,200 ----
      <term>
       <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
       <indexterm>
!       <primary>
!        <varname>pg_trgm.similarity_threshold</> configuration parameter
!       </primary>
       </indexterm>
      </term>
      <listitem>
***************
*** 168,173 ****
--- 204,227 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold">
+     <term>
+      <varname>pg_trgm.word_similarity_threshold</> (<type>real</type>)
+      <indexterm>
+       <primary>
+        <varname>pg_trgm.word_similarity_threshold</> configuration parameter
+       </primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current word similarity threshold that is used by
+       the <literal>%&gt;</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 280,311 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for word
+    similarity.  For example:
+ <programlisting>
+ SELECT t, word_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE t %&gt; '<replaceable>word</>'
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a word
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
+    A variant of the above query is
+ <programlisting>
+ SELECT t, t &lt;-&gt;&gt; '<replaceable>word</>' AS dist
+   FROM test_trgm
+   ORDER BY dist LIMIT 10;
+ </programlisting>
+    This can be implemented quite efficiently by GiST indexes, but not
+    by GIN indexes.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
0001-pg_trgm_guc_v3.patchtext/x-patch; name=0001-pg_trgm_guc_v3.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.similarity_threshold
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double similarity_threshold;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 206,214 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= similarity_threshold)
! 					? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 283,289 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 285,293 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= similarity_threshold)
! 					? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 294,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 294,301 ----
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &similarity_threshold
! 						|| tmpsml > similarity_threshold) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 309,316 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= similarity_threshold)
! 							? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		similarity_threshold = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,44 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
! 	trgm_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  static int
--- 26,77 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.similarity_threshold",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&similarity_threshold,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
! 	similarity_threshold = nlimit;
! 	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  static int
***************
*** 720,724 **** similarity_op(PG_FUNCTION_ARGS)
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_limit);
  }
--- 753,757 ----
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= similarity_threshold);
  }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.similarity_threshold</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold">
+     <term>
+      <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
#36Jeff Janes
jeff.janes@gmail.com
In reply to: Teodor Sigaev (#20)
Re: Fuzzy substring searching with the pg_trgm extension

On Fri, Jan 29, 2016 at 6:15 AM, Teodor Sigaev <teodor@sigaev.ru> wrote:

The behavior of this function is surprising to me.

select substring_similarity('dog' , 'hotdogpound') ;

substring_similarity
----------------------
0.25

Substring search was desined to search similar word in string:
contrib_regression=# select substring_similarity('dog' , 'hot dogpound') ;
substring_similarity
----------------------
0.75

contrib_regression=# select substring_similarity('dog' , 'hot dog pound') ;
substring_similarity
----------------------
1
It seems to me that users search words in long string. But I'm agree that
more detailed explanation needed and, may be, we need to change feature name
to fuzzywordsearch or something else, I can't imagine how.

If we implement my proposed behavior, and I wanted the existing
behavior instead, I could just do:

select substring_similarity(' dog ' , 'hotdogpound');

But with the existing implementation, there isn't anything I could to
switch to the one I want instead. So treating is purely as a substring
is more flexible than treating it as a word match.

The reason I like the option of not treating word boundaries as
special in this case is that often in scientific vocabulary, and in
catalog part numbers, people are pretty inconsistent about whether
they included spaces. "HEK 293", "HEK293", and "HEK-293" could be all
the same thing. So I like to strip out spaces and punctuation on both
sides of operator. Of course I can't do that if there are invisible
un-removable spaces on the substring side.

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

Cheers,

Jeff

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#37David Steele
david@pgmasters.net
In reply to: Jeff Janes (#36)
Re: Fuzzy substring searching with the pg_trgm extension

Hi Jeff,

On 2/25/16 5:00 PM, Jeff Janes wrote:

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

It's not clear to me if you are requesting more documentation here or
stating that you are happy with it as-is. Care to elaborate?

Other than that I think this patch looks to be ready for committer. Any
objections?

--
-David
david@pgmasters.net

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#38Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: David Steele (#37)
2 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

On 14.03.2016 18:48, David Steele wrote:

Hi Jeff,

On 2/25/16 5:00 PM, Jeff Janes wrote:

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

It's not clear to me if you are requesting more documentation here or
stating that you are happy with it as-is. Care to elaborate?

Other than that I think this patch looks to be ready for committer. Any
objections?

There was some comments about the word-boundary subtlety. But I think it
was not enough.

I rephrased the explanation of word_similarity() and %>. It is better now.

But if it is not correct I can change the explanation.

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

0001-pg_trgm_guc_v3.patchtext/x-patch; name=0001-pg_trgm_guc_v3.patchDownload
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 3,13 ****
--- 3,15 ----
  -- complain if script is sourced in psql, rather than via CREATE EXTENSION
  \echo Use "CREATE EXTENSION pg_trgm" to load this file. \quit
  
+ -- Deprecated function
  CREATE FUNCTION set_limit(float4)
  RETURNS float4
  AS 'MODULE_PATHNAME'
  LANGUAGE C STRICT VOLATILE;
  
+ -- Deprecated function
  CREATE FUNCTION show_limit()
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 26,32 **** LANGUAGE C STRICT IMMUTABLE;
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on trgm_limit
  
  CREATE OPERATOR % (
          LEFTARG = text,
--- 28,34 ----
  CREATE FUNCTION similarity_op(text,text)
  RETURNS bool
  AS 'MODULE_PATHNAME'
! LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.similarity_threshold
  
  CREATE OPERATOR % (
          LEFTARG = text,
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 105,111 **** typedef char *BITVECP;
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern float4 trgm_limit;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
--- 105,111 ----
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
! extern double similarity_threshold;
  
  extern uint32 trgm2int(trgm *ptr);
  extern void compact_trigram(trgm *tptr, char *str, int bytelen);
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 206,212 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 206,214 ----
  			 * similarity is just c / len1.
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
! 			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= similarity_threshold)
! 					? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 283,289 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 285,293 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= similarity_threshold)
! 					? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 294,300 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &trgm_limit || tmpsml > trgm_limit) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 294,301 ----
  				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &similarity_threshold
! 						|| tmpsml > similarity_threshold) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 308,314 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= trgm_limit) ? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 309,316 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= similarity_threshold)
! 							? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 14,20 ****
  
  PG_MODULE_MAGIC;
  
! float4		trgm_limit = 0.3f;
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
--- 14,23 ----
  
  PG_MODULE_MAGIC;
  
! /* GUC variables */
! double		similarity_threshold = 0.3f;
! 
! void		_PG_init(void);
  
  PG_FUNCTION_INFO_V1(set_limit);
  PG_FUNCTION_INFO_V1(show_limit);
***************
*** 23,44 **** PG_FUNCTION_INFO_V1(similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
  
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		elog(ERROR, "wrong limit, should be between 0 and 1");
! 	trgm_limit = nlimit;
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(trgm_limit);
  }
  
  static int
--- 26,77 ----
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
  
+ /*
+  * Module load callback
+  */
+ void
+ _PG_init(void)
+ {
+ 	/* Define custom GUC variables. */
+ 	DefineCustomRealVariable("pg_trgm.similarity_threshold",
+ 							"Sets the threshold used by the %% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&similarity_threshold,
+ 							0.3,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
+ }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
+  */
  Datum
  set_limit(PG_FUNCTION_ARGS)
  {
  	float4		nlimit = PG_GETARG_FLOAT4(0);
  
  	if (nlimit < 0 || nlimit > 1.0)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
! 	similarity_threshold = nlimit;
! 	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
+ /*
+  * Deprecated function.
+  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
+  */
  Datum
  show_limit(PG_FUNCTION_ARGS)
  {
! 	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  static int
***************
*** 720,724 **** similarity_op(PG_FUNCTION_ARGS)
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= trgm_limit);
  }
--- 753,757 ----
  														 PG_GETARG_DATUM(0),
  														 PG_GETARG_DATUM(1)));
  
! 	PG_RETURN_BOOL(res >= similarity_threshold);
  }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 99,105 ****
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example.
        </entry>
       </row>
       <row>
--- 99,106 ----
         Returns the current similarity threshold used by the <literal>%</>
         operator.  This sets the minimum similarity between
         two words for them to be considered similar enough to
!        be misspellings of each other, for example
!        (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
       <row>
***************
*** 108,114 ****
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in.
        </entry>
       </row>
      </tbody>
--- 109,115 ----
        <entry>
         Sets the current similarity threshold that is used by the <literal>%</>
         operator.  The threshold must be between 0 and 1 (default is 0.3).
!        Returns the same value passed in (<emphasis>deprecated</emphasis>).
        </entry>
       </row>
      </tbody>
***************
*** 133,139 ****
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <function>set_limit</>.
        </entry>
       </row>
       <row>
--- 134,140 ----
        <entry>
         Returns <literal>true</> if its arguments have a similarity that is
         greater than the current similarity threshold set by
!        <varname>pg_trgm.similarity_threshold</>.
        </entry>
       </row>
       <row>
***************
*** 150,155 ****
--- 151,177 ----
   </sect2>
  
   <sect2>
+   <title>GUC Parameters</title>
+ 
+   <variablelist>
+    <varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold">
+     <term>
+      <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
+      <indexterm>
+       <primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current similarity threshold that is used by the <literal>%</>
+       operator.  The threshold must be between 0 and 1 (default is 0.3).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect2>
+ 
+  <sect2>
    <title>Index Support</title>
  
    <para>
0002-pg_trgm_word_v9.patchtext/x-patch; name=0002-pg_trgm_word_v9.patchDownload
*** a/contrib/pg_trgm/Makefile
--- b/contrib/pg_trgm/Makefile
***************
*** 7,13 **** EXTENSION = pg_trgm
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
--- 7,13 ----
  DATA = pg_trgm--1.2.sql pg_trgm--1.0--1.1.sql pg_trgm--1.1--1.2.sql pg_trgm--unpackaged--1.0.sql
  PGFILEDESC = "pg_trgm - trigram matching"
  
! REGRESS = pg_trgm pg_word_trgm
  
  ifdef USE_PGXS
  PG_CONFIG = pg_config
*** /dev/null
--- b/contrib/pg_trgm/data/trgm2.data
***************
*** 0 ****
--- 1,696 ----
+ Baikal
+ Baikaluobbal
+ Lake Baikal
+ Baikalakko
+ Baikal Business Centre
+ Baikal Listvyanka Hotel
+ Baikal Airfield
+ Baikalovo
+ Transbaikalia
+ Baikal Mountains
+ Baikal Hotel Moscow
+ Zabaikalie
+ Pribaikalskaya
+ Baikal Plaza
+ Rubaikale
+ Tandobai Algad
+ Daikalay
+ Bakall
+ Stubaital
+ Neustift im Stubaital
+ Anonyme Appartments Stubaital
+ Barkaladja Pool
+ Awabakal Nature Reserve
+ Awabakal Field Studies Centre
+ Barkala
+ Bailallie
+ Barkala Park
+ Purba Kalaujan
+ Nabakalas
+ Barkal
+ Baikanthapur
+ Baikarjhuti
+ Baika
+ Baikari
+ Bakalia Char
+ Dakshin Bakalia
+ Purba Kalmegha
+ Efreytor-Bakalovo
+ Baykalsko
+ Baykal
+ Baskaltsi
+ Bakalite
+ Bajkal
+ Efrejtor Bakalovo
+ Kampong Bakaladong
+ Riacho do Sambaibal
+ Sambaibal
+ Barkalabava
+ Zabaykal
+ Bakalar Lake
+ Kaikalahun Indian Reserve 25
+ Tumba-Kalamba
+ Kamba-Kalele
+ Boyagbakala
+ Bombakalo
+ Batikalengbe
+ Bakalukudu
+ Bakalawa
+ Bakala
+ Matamba-Kalenge
+ Kusu-Bakali
+ Kambakala
+ Bakali
+ Abakalu
+ Bonagbakala
+ Bakalua
+ Bikala Madila
+ Bikala
+ Bumba-Kaloki
+ Tumba-Kalunga
+ Kabankala
+ Mambakala
+ Tumba-Kalumba
+ Kabakala
+ Bikalabwa
+ Bomba-Kalende
+ Mwalaba-Kalamba
+ Matamba-Kalenga
+ Bumba-Kalumba
+ Bikalange
+ Kabikala
+ Mubikale
+ Kanampumba-Kalawa
+ Tshiabakale
+ Bakaly
+ Bakalongo
+ Bakale
+ Bakala Koupi
+ Bambakala
+ Bakalou
+ Tsibakala
+ Kimbakala
+ Dabakalakoro
+ Dabakala
+ Bakalafoulou
+ Ngao Bakala
+ Mobaika
+ Baimalou
+ Xibaitaling
+ Baikai
+ Baikang
+ Baitaling
+ Baikan
+ Baimaling Linchang
+ Baimalong
+ Baikanzui
+ Baiyali
+ Baimaling
+ Baimalang Donggang
+ Baikangshuoma
+ Baitaliao
+ Taikale
+ Babainale
+ Bailale
+ Baibale
+ Baiwale
+ Baikangnei
+ Baitali
+ Xiabaikan
+ Bailalong
+ Baimaluo
+ Baikacun
+ Baisala
+ Bailalin
+ Baimala
+ Baidalong
+ Dabaika
+ Caikalong
+ Cuobaikacun
+ Baikadangcun
+ Baimalin
+ Subaika
+ Gabakkale
+ Barkallou
+ Embatkala
+ Bodega Tabaibal
+ Golba Kalo
+ Haikala
+ Kaikale
+ Waikaloulevu
+ Waikalou Creek
+ Waikalou
+ Ndelaikalou
+ Ndelaikalokalo
+ Bay of Backaland
+ Bankali
+ Ker Samba Kalla
+ Demba Kali
+ Bakalarr
+ Baipal
+ Kalibakalako
+ Dalabakala
+ Bikal
+ Sembaikan
+ Praikalogu
+ Tanjung Ompaikalio
+ Bonebabakal
+ Tanjung Batikala
+ Pulau Bakalanpauno
+ Teluk Bakalan
+ Bakaltua Bank
+ Bakalrejo
+ Bakalan
+ Sungai Bakaladiyan
+ Bakal
+ Buku Baikole
+ Pulau Baika
+ Tanjung Bakalinga
+ Pulau Bakalan
+ Desa Bakalan
+ Kebakkalang
+ Ngambakalang
+ Mota Sabakal
+ Bakalan Lor
+ Babakalo
+ Buyu Rapanbakalai
+ Kalimundubakalan
+ Bakalpokok
+ Bakaldukuh
+ Tanabakal
+ Tanjung Aikaluin
+ Desa Bakalrejo
+ Bakalan Kidul
+ Desa Kebakalan
+ Kebakalan
+ Bakalan Kulon
+ Gunung Bakalan
+ Kalibakal
+ Bakaljaya
+ Trobakal
+ Bakalan Wetan
+ Desa Bakal
+ Alue Bakkala
+ Uruk Bakal
+ Bakalbuah
+ Kwala Bakala
+ Bakal Lama
+ Bakal Julu
+ Bakal Batu
+ Moncong Baika
+ Sampangbakalan
+ Bakalam
+ Desa Bakalankrapyak
+ Lebakkalapa Tonggoh
+ Trembakal
+ Bakalan Tengah
+ Kali Bakalan
+ Desa Cemengbakalan
+ Desa Bakalanpule
+ Gunung Bakal
+ Desa Tambakkalisogo
+ Tambakkalisogo
+ Desa Bakalanrayung
+ Salu Bakalaeng
+ Bakalaeng
+ Danau Bakalan
+ Selat Bakalan
+ Selat Bakalanpauno
+ Laikalanda
+ Bakalinga
+ Tanjung Mbakalang
+ Desa Bakalankrajan
+ Bakalan Dua
+ Kali Purbakala
+ Desa Bakalanwringinpitu
+ Tukad Kubakal
+ Praikalangga
+ Banjar Kubakal
+ Eat Bakal
+ Sungai Bakala
+ Kombakalada
+ Sori Rabakalo
+ Kahambikalela
+ Baikarara
+ Baikapaka
+ Tukad Bakalan
+ Teluk Haludubakal
+ Yabakalewa
+ Praikalumbang
+ Waikalowo
+ Praikalubu
+ Loko Praikalubu
+ Ramuk Ombakalada
+ Praikalebung
+ Praikaleka
+ Andabakal
+ Praikalau
+ Praikalokat
+ Praikalimbung
+ Bambakalo
+ Leubakkalian
+ Pematang Baitalimbangan
+ Lebakalil
+ Gereba Kaler
+ Krajan Bakalan
+ Bakalan Barat
+ Muarabakal
+ Umbulan Maharobakal
+ Bakaldalam
+ Talang Bakal
+ Pematang Bakalpanang
+ Baidaloen
+ Jatibakal
+ Tubu Bakalekuk
+ Dola Peimambakal
+ Bakalang
+ Teluk Bakalang
+ Salu Baidale
+ Bakalerek
+ Ile Bakalibu
+ Parbakalan
+ Praikalembu
+ Palindi Laikali
+ Praikalu
+ Sori Labakalate
+ Air Bakal-kecil
+ Sungaikalung
+ Sungaikalong
+ Pematang Bakalpanjang
+ Payabakal
+ Waikala
+ Sungaikali
+ Sungai Pebakalan
+ Parit Membakal
+ Bakalpakebo
+ Baikat Abu Jaraban
+ Maikalganj
+ Maikala Range
+ Bakalha
+ Baitalpur
+ Baikanthpur
+ Baihal
+ Barkala Reserved Forest
+ Babaipalli
+ Kaikalapettai
+ Kambainallur
+ Bakkalale
+ Kaikalui
+ Baijalpur
+ Nehalla Bankalah Reserved Forest
+ Barkala Rao
+ Barkali
+ Baidal
+ Barkaleh
+ Darreh Pumba Kal
+ Bahkalleh
+ Wibakale
+ Gaikali
+ Gagaba Kalo
+ Barkalare
+ Bakkalmal
+ Gora Bakalyadyr
+ Rodnik Bakalybulak
+ Urochishche Bakaly
+ Sopka Bakaly
+ Gory Bakaly
+ Bugor Arba-Kalgan
+ Ozero Baykal
+ Kolodets Tabakkalgan
+ Walangivattu Vaikal
+ Vattevaikal Anicut
+ Vaikali Tevar Kulam
+ Vaikalitevan Kulam
+ Vaikaladichchenai
+ Uchchodaikallu
+ Sellapattu Vaikal
+ Savata Vaikal
+ Puttadivali Vaikal
+ Palukadu Vaikal
+ Mulaikallu Kulam
+ Koraikallimadu
+ Koraikalapu Kulam
+ Karaiyamullivaikal
+ Karaivaikal Kulam
+ Kanawali Vaikal
+ Habakkala
+ Chalam Vaikal Aru
+ Ambakala Wewa
+ Alaikallupoddakulam
+ Alaikallupodda Alankulam
+ Akamadi Vaikal
+ Alaikalluppodda Kulam
+ Vaikaliththevakulam
+ Baikole
+ Sidi Mohammed el Bakali
+ Sidi Mohammed Bakkal
+ Sidi Bakal
+ Oulad el Bakkal
+ Zaouia Oulad Bakal
+ Azib el Bakkali
+ Tombakala
+ Malaikaly
+ Ambadikala
+ Bakalica
+ Bakalnica
+ Abankala
+ Kombakala
+ Bawkalut
+ Bakaleko
+ Bawkalut Chaung
+ Baukala
+ Cerro Bainaltzin
+ Sungai Bakal
+ Bukit Ubaibalih
+ Kampong Sombakal
+ Kampung Lebai Ali
+ Batikal
+ Bakalalan Airport
+ Maikali
+ Bakalum
+ Bakalambani
+ Abakaliki
+ Tsaunin Maikalaji
+ Baikaha
+ Llano Limbaika
+ Barkald
+ Barkald stasjon
+ Barkaleitet
+ Barkaldfossen
+ Barkaldvola
+ Bakkalegskardet
+ Baikajavri
+ Barkalden
+ Bakkalia
+ Siljabaika
+ Aikaluokta
+ Blombakkali
+ Bavkalasis
+ Baikajohka
+ Bakkalykkja
+ Bakalauri
+ Bakalauri1
+ Bakalauri2
+ Bakalauri3
+ Bakalauri4
+ Bakalauri5
+ Bakalauri6
+ Bakalauri7
+ Bakalauri8
+ Bakalauri9
+ Bakalsen
+ Baiyaldi
+ Naikala
+ Baikanda
+ Barkalne
+ Bakalipur
+ Bakaldum
+ Raikal
+ Baikatte
+ Maikal
+ Bakalbhar
+ Waikalabubu Bay
+ Baikai Island
+ Abikal
+ Boikalakalawa Bay
+ Maikal River
+ Bakalao Asibi Point
+ Bankal
+ Bakalod Island
+ Bakalao Point
+ Bakalan River
+ Bakal Dos
+ Bakal Uno
+ Daang Bakal
+ Bankal School
+ Bakal Tres
+ Kabankalan City Public Plaza
+ Ranra Tabai Algad
+ Bairkal Jabal
+ Bairkal Dhora
+ Bairkal
+ Zaibai Algad
+ Gulba Kalle
+ Ragha Bakalzai
+ Dabbarkal Sar
+ Tabai Algad
+ Haikalzai
+ Wuchobai Algad
+ Jabba Kalai
+ Goth Soba Kaloi
+ Baikar Tsarai
+ Dudgaikal
+ Baixale Kamar
+ Zebai Algad
+ Bakal Khel
+ Goth Haikal
+ Haikal
+ Jaba Kalle
+ Bakalovina
+ Salabaikasy
+ Guba Kalita
+ Guba Kalgalaksha
+ Guba Kaldo
+ Bakalovo
+ Baykalovo
+ Baskalino
+ Sopka Barkaleptskaya
+ Bakalovskaya Ferma
+ Bakalinskiy Rayon
+ Sovkhoz Bakalinskiy
+ Bakalinskiy
+ Bakaldy
+ Bakaldinskoye
+ Urochishche Bakaldikha
+ Zabaykalovskiy
+ Barkalova
+ Barkalovka
+ Gora Barkalova
+ Gora Barkalyu
+ Bikalamakhi
+ Stantsiya Bakal
+ Baykalovskiy Rayon
+ Baykalovskiy
+ Baykalovsk
+ Bakalda
+ Boloto Malyy Baykal
+ Boloto Baykal
+ Zabaykalka
+ Stantsiya Baykal
+ Baykalo-Amurskaya Zheleznaya Doroga
+ Kolkhoz Krasnyy Baykal
+ Zaliv Baykal
+ Bakalino
+ Ovrag Bakalda
+ Bakaldovshchina
+ Prud Novyy Baykal
+ Bakaleyka
+ Bakalka
+ Bakaly TV Mast
+ Urochishche Bakalovo
+ Kambaika
+ Maloye Baykalovo
+ Bakalinskiy Leskhoz
+ Bikalikha
+ Kordon Barkalo
+ Sanatoriy Baykal
+ Port Baykal
+ Baykalikha
+ Polevoy Stan Baykal
+ Bakalovka
+ Ramada Makkah Shubaika
+ Mount Tohebakala
+ Tambakale Island
+ Mbanitambaika Island
+ Mbakalaka Island
+ Kumbakale
+ Kaikaloka
+ Kelesaikal
+ Nasb Gabakallah
+ Jabal Barkal
+ Jabal Abakallah
+ Al Barkali
+ Shabakal Abbass
+ Mabaikuli
+ Bambakalema
+ Bambakalia
+ Baiwala
+ Babakalia
+ Baikama
+ Bankalol
+ Kundebakali
+ Yumbaikamadu
+ Tabakali
+ Daba Kalharereh
+ Barkale
+ Bakalshile
+ Bakaloolay
+ Buur Bakaley
+ Bakaley
+ Buur Bakale
+ Bakalaale
+ Jabal Mobakali
+ Khor Bakallii
+ Korombaital
+ Ambakali
+ Ba Kaliin
+ Mbay Bakala
+ Tagobikala
+ Fayzabadkala
+ Aghbai Allazy
+ Aghbai Alikagar
+ Gora Fayzabadkala
+ Daraikalot
+ Aghbai Alakisirak
+ Beikala
+ Foho Berbakalau
+ Mota Caicabaisala
+ Sungai Utabailale
+ Urochishche Bakalarnyn-Ayasy
+ Urochishche Batkali
+ Khrebet Batkali
+ Ras Barkallah
+ Babakale
+ Fabrikalar
+ Bakalukalu Shan
+ Bakalukalu
+ Laikala
+ Waikalakaka
+ Columbus Bakalar Municipal Airport
+ Bakalar Library
+ Bakkala Cemetery
+ Clifton T Barkalow Elementary School
+ Barkalow Hollow
+ Kailuapuhi Waikalua Homesteads
+ Kawaikalia Gulch
+ Waikalae
+ Waikaloa Stream
+ Waikalua-Loko Fish Pond
+ Halekou Waikaluakai Homesteads
+ East Waikalua
+ Omar Haikal Islamic Academy
+ Bakalar Air Force Base (historical)
+ Koshbakaly
+ Bagkalen
+ Gora Baikara
+ Mfumbaika
+ Mbakalungu
+ Chumbaika
+ Ntombankala School
+ Bakalabwa Pans
+ Khobai al Janhra
+ Holiday Inn Dubai Al Barsha
+ Novotel Dubai Al Barsha
+ Doubletree Res.Dubai-Al Barsha
+ Doubletree By Hilton Hotel and Apartments Dubai Al Barsha
+ Doubletree By Hilton Dubai Al Barsha Hotel and Res
+ Park Inn By Radisson Dubai Al Barsha
+ Ramee Rose Hotel Dubai Al Barsha
+ Aparthotel Adagio Premium Dubai Al Barsha
+ Ataikala
+ Selman Marrakech
+ Riad Ain Marrakech
+ Taj Palace Marrakech
+ Delano Marrakech
+ Pullman Marrakech Palmeraie Resort And Spa
+ Lalla Calipau Marrakech
+ Hotel Fashion Marrakech
+ Four Seasons Resort Marrakech
+ Adama Resort Marrakech
+ Pullman Marrakech Palmeraie Re
+ Ramada Resort Marrakech Douar Al Hana
+ Hotel Zahia Marrakech
+ Hotel Marrakech Le Tichka
+ Le Chems Marrakech
+ Beachcomber Royal Palm Marrakech
+ Residence Marrakech
+ Riad Hermes Marrakech
+ Riad La Lune De Marrakech
+ Hotel Marrakech Le Sangho Privilege
+ Tempoo Hotel Marrakech
+ Ag Hotel & Spa Marrakech
+ Palm Appart Club Marrakech
+ Hotel Ibis Moussafir Marrakech Palmeraie
+ Ibis Marrakech Gare Voyageurs
+ Marrakech Ryads Parc And Spa
+ Terra Mia Marrakech Riad
+ Residence Dar Lamia Marrakech
+ Pullman Marrakech Palmeraie Rs
+ Moussaf Marrakech Centre Gare
+ Tempoo Hotel Marrakech Adults Only
+ Sahara Palace Marrakech
+ Moroccan House Marrakech
+ El Andalouss And Spa Marrakech
+ Suite Novotel Marrakech Rs
+ Dar Catalina Marrakech Hotel Non Refundable Room
+ Marrakech Hotel
+ Oued Tammarrakech
+ Tammarrakech
+ Cercle de Marrakech-Banlieue
+ Marrakech-Tensift-Al Haouz
+ Koudia Marrakech
+ Hotel Tichka Salam Marrakech
+ L'Atlas Marrakech
+ Royal Mirage Deluxe Marrakech
+ Golden Tulip Farah Marrakech
+ Ryad Mogador Marrakech
+ Coralia Club Marrakech Palmariva
+ La Sultana Marrakech
+ Marrakech-Medina
+ Marrakech
+ Museum of Marrakech
+ Douar Marrakechiyinc
+ Ibis Marrakech Centre Gare
+ Golden Tulip Rawabi Marrakech
+ Murano Resort Marrakech
+ Marrakech Garden Hotel
+ Pullman Marrakech Palmerai Resort & Spa
+ The Pearl Marrakech
+ Palais Calipau Marrakech
+ Hostal Equity Point Marrakech
+ Sofitel Marrakech Lounge And Spa
+ Pullman Marrakech Hotel And Spa
+ Sofitel Marrakech Palais Imperial
+ Hotel Ibis Moussafir Marrakech Centre Gare
+ Red Hotel Marrakech
+ Riad Zenith Marrakech
+ Ksar Catalina Marrakech Hotel
+ Blue Sea Hotel Marrakech Ryads Parc & Spa
+ Bluebay Marrakech
+ Pullman Marrakech Palmeraie Resort & Spa Hotel
+ Riad Litzy Marrakech
+ Sultana Hotel & Spa Marrakech
+ Albatros Club Marrakech
+ Hotel Sangho Club Marrakech
+ Suite Novotel Marrakech Hotel
+ Riad Utopia Suites & Spa Marrakech
+ Riad Fatinat Marrakech
+ Riad Dar El Aila Marrakech
+ Es Saadi And Casino De Marrakech
+ Dar Catalina Marrakech Hotel
+ Grace Marrakech
+ Marrakesh Apartments
+ Marrakesh Country Club
+ Koudiat Lmerrakechiyine
+ Sidi Mohammed el Marrakchi
+ Marrakesh
+ Marrakchien
+ Marrakchia
+ Marrakesh Menara Airport
+ Marrakesh Hua Hin Resort & Spa
+ Marrakesh Hua Hin Resort And Spa
+ Marrakesh Resort And Spa (Pool Suite)
+ Marrakesh Huahin Resort & Spa
+ Ibis Moussafir Marrakesh Centre Gare Hotel
+ Maerak-chi
+ Dar Hammou Ben Merrakchi
+ Lalla el Marakchia
+ Khrebet Marrakh
+ Sungai Maru Kechil
+ Marrache
+ Goth Marracha
+ Maramech Hill
+ Maramech Woods Nature Preserve
+ Oued Karakech
+ Samarra School
+ Jangal-e Marakeh Sar
*** a/contrib/pg_trgm/expected/pg_trgm.out
--- b/contrib/pg_trgm/expected/pg_trgm.out
***************
*** 59,65 **** select similarity('---', '####---');
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text);
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
--- 59,65 ----
            0
  (1 row)
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  \copy test_trgm from 'data/trgm.data'
  select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
        t      |   sml    
***************
*** 3467,3473 **** select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu198
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 3467,3473 ----
   qwertyu0988 | 0.333333
  (1 row)
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/expected/pg_word_trgm.out
***************
*** 0 ****
--- 1,1044 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ \copy test_trgm2 from 'data/trgm2.data'
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+                    QUERY PLAN                   
+ ------------------------------------------------
+  Limit
+    ->  Index Scan using trgm_idx2 on test_trgm2
+          Order By: (t <->> 'Kabankala'::text)
+ (3 rows)
+ 
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+  ?column? |                t                 
+ ----------+----------------------------------
+         0 | Kabankala
+       0.1 | Kabankalan City Public Plaza
+       0.3 | Abankala
+       0.4 | Ntombankala School
+  0.416667 | Kabakala
+       0.5 | Nehalla Bankalah Reserved Forest
+  0.538462 | Kabikala
+ (7 rows)
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+ (20 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+               t               | sml 
+ ------------------------------+-----
+  Kabankala                    |   1
+  Kabankalan City Public Plaza | 0.9
+  Abankala                     | 0.7
+  Ntombankala School           | 0.6
+ (4 rows)
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.5;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                   t                  |   sml    
+ -------------------------------------+----------
+  Baykal                              |        1
+  Boloto Baykal                       |        1
+  Boloto Malyy Baykal                 |        1
+  Kolkhoz Krasnyy Baykal              |        1
+  Ozero Baykal                        |        1
+  Polevoy Stan Baykal                 |        1
+  Port Baykal                         |        1
+  Prud Novyy Baykal                   |        1
+  Sanatoriy Baykal                    |        1
+  Stantsiya Baykal                    |        1
+  Zaliv Baykal                        |        1
+  Baykalikha                          | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga | 0.857143
+  Baykalovo                           | 0.857143
+  Baykalovsk                          | 0.857143
+  Baykalovskiy                        | 0.857143
+  Baykalovskiy Rayon                  | 0.857143
+  Baykalsko                           | 0.857143
+  Maloye Baykalovo                    | 0.857143
+  Zabaykal                            | 0.714286
+  Bakal Batu                          | 0.571429
+  Zabaykalka                          | 0.571429
+  Zabaykalovskiy                      | 0.571429
+ (23 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+ (6 rows)
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.3;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+                              t                             |   sml    
+ -----------------------------------------------------------+----------
+  Baykal                                                    |        1
+  Boloto Baykal                                             |        1
+  Boloto Malyy Baykal                                       |        1
+  Kolkhoz Krasnyy Baykal                                    |        1
+  Ozero Baykal                                              |        1
+  Polevoy Stan Baykal                                       |        1
+  Port Baykal                                               |        1
+  Prud Novyy Baykal                                         |        1
+  Sanatoriy Baykal                                          |        1
+  Stantsiya Baykal                                          |        1
+  Zaliv Baykal                                              |        1
+  Baykalikha                                                | 0.857143
+  Baykalo-Amurskaya Zheleznaya Doroga                       | 0.857143
+  Baykalovo                                                 | 0.857143
+  Baykalovsk                                                | 0.857143
+  Baykalovskiy                                              | 0.857143
+  Baykalovskiy Rayon                                        | 0.857143
+  Baykalsko                                                 | 0.857143
+  Maloye Baykalovo                                          | 0.857143
+  Zabaykal                                                  | 0.714286
+  Bakal Batu                                                | 0.571429
+  Zabaykalka                                                | 0.571429
+  Zabaykalovskiy                                            | 0.571429
+  Air Bakal-kecil                                           | 0.444444
+  Bakal                                                     | 0.444444
+  Bakal Dos                                                 | 0.444444
+  Bakal Julu                                                | 0.444444
+  Bakal Khel                                                | 0.444444
+  Bakal Lama                                                | 0.444444
+  Bakal Tres                                                | 0.444444
+  Bakal Uno                                                 | 0.444444
+  Daang Bakal                                               | 0.444444
+  Desa Bakal                                                | 0.444444
+  Eat Bakal                                                 | 0.444444
+  Gunung Bakal                                              | 0.444444
+  Sidi Bakal                                                | 0.444444
+  Stantsiya Bakal                                           | 0.444444
+  Sungai Bakal                                              | 0.444444
+  Talang Bakal                                              | 0.444444
+  Uruk Bakal                                                | 0.444444
+  Zaouia Oulad Bakal                                        | 0.444444
+  Al Barkali                                                | 0.428571
+  Aparthotel Adagio Premium Dubai Al Barsha                 | 0.428571
+  Baikal Business Centre                                    | 0.428571
+  Bay of Backaland                                          | 0.428571
+  Boikalakalawa Bay                                         | 0.428571
+  Doubletree By Hilton Dubai Al Barsha Hotel and Res        | 0.428571
+  Doubletree By Hilton Hotel and Apartments Dubai Al Barsha | 0.428571
+  Doubletree Res.Dubai-Al Barsha                            | 0.428571
+  Holiday Inn Dubai Al Barsha                               | 0.428571
+  Jabal Barkal                                              | 0.428571
+  Novotel Dubai Al Barsha                                   | 0.428571
+  Park Inn By Radisson Dubai Al Barsha                      | 0.428571
+  Ramee Rose Hotel Dubai Al Barsha                          | 0.428571
+  Waikalabubu Bay                                           | 0.428571
+  Baikal                                                    |      0.4
+  Baikal Airfield                                           |      0.4
+  Baikal Hotel Moscow                                       |      0.4
+  Baikal Listvyanka Hotel                                   |      0.4
+  Baikal Mountains                                          |      0.4
+  Baikal Plaza                                              |      0.4
+  Bajkal                                                    |      0.4
+  Bankal                                                    |      0.4
+  Bankal School                                             |      0.4
+  Barkal                                                    |      0.4
+  Lake Baikal                                               |      0.4
+  Mbay Bakala                                               |      0.4
+  Oulad el Bakkal                                           |      0.4
+  Sidi Mohammed Bakkal                                      |      0.4
+  Bairkal                                                   | 0.363636
+  Bairkal Dhora                                             | 0.363636
+  Bairkal Jabal                                             | 0.363636
+  Batikal                                                   | 0.363636
+  Bakala                                                    | 0.333333
+  Bakala Koupi                                              | 0.333333
+  Bakalaale                                                 | 0.333333
+  Bakalabwa Pans                                            | 0.333333
+  Bakalaeng                                                 | 0.333333
+  Bakalafoulou                                              | 0.333333
+  Bakalalan Airport                                         | 0.333333
+  Bakalam                                                   | 0.333333
+  Bakalambani                                               | 0.333333
+  Bakalan                                                   | 0.333333
+  Bakalan Barat                                             | 0.333333
+  Bakalan Dua                                               | 0.333333
+  Bakalan Kidul                                             | 0.333333
+  Bakalan Kulon                                             | 0.333333
+  Bakalan Lor                                               | 0.333333
+  Bakalan River                                             | 0.333333
+  Bakalan Tengah                                            | 0.333333
+  Bakalan Wetan                                             | 0.333333
+  Bakalang                                                  | 0.333333
+  Bakalao Asibi Point                                       | 0.333333
+  Bakalao Point                                             | 0.333333
+  Bakalar Air Force Base (historical)                       | 0.333333
+  Bakalar Lake                                              | 0.333333
+  Bakalar Library                                           | 0.333333
+  Bakalarr                                                  | 0.333333
+  Bakalauri                                                 | 0.333333
+  Bakalauri1                                                | 0.333333
+  Bakalauri2                                                | 0.333333
+  Bakalauri3                                                | 0.333333
+  Bakalauri4                                                | 0.333333
+  Bakalauri5                                                | 0.333333
+  Bakalauri6                                                | 0.333333
+  Bakalauri7                                                | 0.333333
+  Bakalauri8                                                | 0.333333
+  Bakalauri9                                                | 0.333333
+  Bakalawa                                                  | 0.333333
+  Bakalbhar                                                 | 0.333333
+  Bakalbuah                                                 | 0.333333
+  Bakalda                                                   | 0.333333
+  Bakaldalam                                                | 0.333333
+  Bakaldinskoye                                             | 0.333333
+  Bakaldovshchina                                           | 0.333333
+  Bakaldukuh                                                | 0.333333
+  Bakaldum                                                  | 0.333333
+  Bakaldy                                                   | 0.333333
+  Bakale                                                    | 0.333333
+  Bakaleko                                                  | 0.333333
+  Bakalerek                                                 | 0.333333
+  Bakaley                                                   | 0.333333
+  Bakaleyka                                                 | 0.333333
+  Bakalha                                                   | 0.333333
+  Bakali                                                    | 0.333333
+  Bakalia Char                                              | 0.333333
+  Bakalica                                                  | 0.333333
+  Bakalinga                                                 | 0.333333
+  Bakalino                                                  | 0.333333
+  Bakalinskiy                                               | 0.333333
+  Bakalinskiy Leskhoz                                       | 0.333333
+  Bakalinskiy Rayon                                         | 0.333333
+  Bakalipur                                                 | 0.333333
+  Bakalite                                                  | 0.333333
+  Bakaljaya                                                 | 0.333333
+  Bakalka                                                   | 0.333333
+  Bakall                                                    | 0.333333
+  Bakalnica                                                 | 0.333333
+  Bakalod Island                                            | 0.333333
+  Bakalongo                                                 | 0.333333
+  Bakaloolay                                                | 0.333333
+  Bakalou                                                   | 0.333333
+  Bakalovina                                                | 0.333333
+  Bakalovka                                                 | 0.333333
+  Bakalovo                                                  | 0.333333
+  Bakalovskaya Ferma                                        | 0.333333
+  Bakalpakebo                                               | 0.333333
+  Bakalpokok                                                | 0.333333
+  Bakalrejo                                                 | 0.333333
+  Bakalsen                                                  | 0.333333
+  Bakalshile                                                | 0.333333
+  Bakaltua Bank                                             | 0.333333
+  Bakalua                                                   | 0.333333
+  Bakalukalu                                                | 0.333333
+  Bakalukalu Shan                                           | 0.333333
+  Bakalukudu                                                | 0.333333
+  Bakalum                                                   | 0.333333
+  Bakaly                                                    | 0.333333
+  Bakaly TV Mast                                            | 0.333333
+  Buur Bakale                                               | 0.333333
+  Buur Bakaley                                              | 0.333333
+  Columbus Bakalar Municipal Airport                        | 0.333333
+  Dakshin Bakalia                                           | 0.333333
+  Danau Bakalan                                             | 0.333333
+  Desa Bakalan                                              | 0.333333
+  Desa Bakalankrajan                                        | 0.333333
+  Desa Bakalankrapyak                                       | 0.333333
+  Desa Bakalanpule                                          | 0.333333
+  Desa Bakalanrayung                                        | 0.333333
+  Desa Bakalanwringinpitu                                   | 0.333333
+  Desa Bakalrejo                                            | 0.333333
+  Efrejtor Bakalovo                                         | 0.333333
+  Efreytor-Bakalovo                                         | 0.333333
+  Gora Bakalyadyr                                           | 0.333333
+  Gory Bakaly                                               | 0.333333
+  Gunung Bakalan                                            | 0.333333
+  Ile Bakalibu                                              | 0.333333
+  Kali Bakalan                                              | 0.333333
+  Kampong Bakaladong                                        | 0.333333
+  Khor Bakallii                                             | 0.333333
+  Krajan Bakalan                                            | 0.333333
+  Kusu-Bakali                                               | 0.333333
+  Kwala Bakala                                              | 0.333333
+  Ngao Bakala                                               | 0.333333
+  Ovrag Bakalda                                             | 0.333333
+  Pematang Bakalpanang                                      | 0.333333
+  Pematang Bakalpanjang                                     | 0.333333
+  Pulau Bakalan                                             | 0.333333
+  Pulau Bakalanpauno                                        | 0.333333
+  Ragha Bakalzai                                            | 0.333333
+  Rodnik Bakalybulak                                        | 0.333333
+  Salu Bakalaeng                                            | 0.333333
+  Selat Bakalan                                             | 0.333333
+  Selat Bakalanpauno                                        | 0.333333
+  Sidi Mohammed el Bakali                                   | 0.333333
+  Sopka Bakaly                                              | 0.333333
+  Sovkhoz Bakalinskiy                                       | 0.333333
+  Sungai Bakala                                             | 0.333333
+  Sungai Bakaladiyan                                        | 0.333333
+  Tanjung Bakalinga                                         | 0.333333
+  Teluk Bakalan                                             | 0.333333
+  Teluk Bakalang                                            | 0.333333
+  Tubu Bakalekuk                                            | 0.333333
+  Tukad Bakalan                                             | 0.333333
+  Urochishche Bakalarnyn-Ayasy                              | 0.333333
+  Urochishche Bakaldikha                                    | 0.333333
+  Urochishche Bakalovo                                      | 0.333333
+  Urochishche Bakaly                                        | 0.333333
+  Bakkalmal                                                 | 0.307692
+  Alue Bakkala                                              |      0.3
+  Azib el Bakkali                                           |      0.3
+  Ba Kaliin                                                 |      0.3
+  Bagkalen                                                  |      0.3
+  Bahkalleh                                                 |      0.3
+  Baikalakko                                                |      0.3
+  Baikalovo                                                 |      0.3
+  Baikaluobbal                                              |      0.3
+  Bakkala Cemetery                                          |      0.3
+  Bakkalale                                                 |      0.3
+  Bakkalegskardet                                           |      0.3
+  Bakkalia                                                  |      0.3
+  Bakkalykkja                                               |      0.3
+  Bankali                                                   |      0.3
+  Bankalol                                                  |      0.3
+  Barkala                                                   |      0.3
+  Barkala Park                                              |      0.3
+  Barkala Rao                                               |      0.3
+  Barkala Reserved Forest                                   |      0.3
+  Barkalabava                                               |      0.3
+  Barkaladja Pool                                           |      0.3
+  Barkalare                                                 |      0.3
+  Barkald                                                   |      0.3
+  Barkald stasjon                                           |      0.3
+  Barkalden                                                 |      0.3
+  Barkaldfossen                                             |      0.3
+  Barkaldvola                                               |      0.3
+  Barkale                                                   |      0.3
+  Barkaleh                                                  |      0.3
+  Barkaleitet                                               |      0.3
+  Barkali                                                   |      0.3
+  Barkallou                                                 |      0.3
+  Barkalne                                                  |      0.3
+  Barkalova                                                 |      0.3
+  Barkalovka                                                |      0.3
+  Barkalow Hollow                                           |      0.3
+  Baskalino                                                 |      0.3
+  Baskaltsi                                                 |      0.3
+  Baukala                                                   |      0.3
+  Bavkalasis                                                |      0.3
+  Bawkalut                                                  |      0.3
+  Bawkalut Chaung                                           |      0.3
+  Bikal                                                     |      0.3
+  Clifton T Barkalow Elementary School                      |      0.3
+  Gora Barkalova                                            |      0.3
+  Gora Barkalyu                                             |      0.3
+  Khrebet Batkali                                           |      0.3
+  Kordon Barkalo                                            |      0.3
+  Nehalla Bankalah Reserved Forest                          |      0.3
+  Ras Barkallah                                             |      0.3
+  Sopka Barkaleptskaya                                      |      0.3
+  Urochishche Batkali                                       |      0.3
+ (261 rows)
+ 
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+                 t                 |   sml    
+ ----------------------------------+----------
+  Kabankala                        |        1
+  Kabankalan City Public Plaza     |      0.9
+  Abankala                         |      0.7
+  Ntombankala School               |      0.6
+  Kabakala                         | 0.583333
+  Nehalla Bankalah Reserved Forest |      0.5
+  Kabikala                         | 0.461538
+  Mwalaba-Kalamba                  | 0.454545
+  Bakala Koupi                     |      0.4
+  Bankal                           |      0.4
+  Bankal School                    |      0.4
+  Bankali                          |      0.4
+  Bankalol                         |      0.4
+  Jabba Kalai                      |      0.4
+  Kanampumba-Kalawa                |      0.4
+  Purba Kalaujan                   |      0.4
+  Tumba-Kalamba                    |      0.4
+  Daba Kalharereh                  | 0.363636
+  Gagaba Kalo                      | 0.363636
+  Jaba Kalle                       | 0.363636
+  Dabakala                         | 0.333333
+  Dalabakala                       | 0.333333
+  Kambakala                        | 0.333333
+  Ker Samba Kalla                  | 0.333333
+  Fayzabadkala                     | 0.307692
+  Gora Fayzabadkala                | 0.307692
+  Guba Kalgalaksha                 | 0.307692
+  Habakkala                        | 0.307692
+  Kaikalahun Indian Reserve 25     | 0.307692
+  Kaikalapettai                    | 0.307692
+  Alue Bakkala                     |      0.3
+  Ambadikala                       |      0.3
+  Ambakala Wewa                    |      0.3
+  Ataikala                         |      0.3
+  Ba Kaliin                        |      0.3
+  Bakala                           |      0.3
+  Bakkala Cemetery                 |      0.3
+  Bambakala                        |      0.3
+  Barkala                          |      0.3
+  Barkala Park                     |      0.3
+  Barkala Rao                      |      0.3
+  Barkala Reserved Forest          |      0.3
+  Baukala                          |      0.3
+  Beikala                          |      0.3
+  Bikala                           |      0.3
+  Bikala Madila                    |      0.3
+  Bomba-Kalende                    |      0.3
+  Bonagbakala                      |      0.3
+  Boyagbakala                      |      0.3
+  Bugor Arba-Kalgan                |      0.3
+  Bumba-Kaloki                     |      0.3
+  Bumba-Kalumba                    |      0.3
+  Darreh Pumba Kal                 |      0.3
+  Demba Kali                       |      0.3
+  Embatkala                        |      0.3
+  Gereba Kaler                     |      0.3
+  Golba Kalo                       |      0.3
+  Goth Soba Kaloi                  |      0.3
+  Guba Kaldo                       |      0.3
+  Guba Kalita                      |      0.3
+  Gulba Kalle                      |      0.3
+  Haikala                          |      0.3
+  Kali Bakalan                     |      0.3
+  Kali Purbakala                   |      0.3
+  Kalibakal                        |      0.3
+  Kalibakalako                     |      0.3
+  Kalimundubakalan                 |      0.3
+  Kamba-Kalele                     |      0.3
+  Kimbakala                        |      0.3
+  Kombakala                        |      0.3
+  Kwala Bakala                     |      0.3
+  Laikala                          |      0.3
+  Maikala Range                    |      0.3
+  Mambakala                        |      0.3
+  Matamba-Kalenga                  |      0.3
+  Matamba-Kalenge                  |      0.3
+  Mbay Bakala                      |      0.3
+  Mount Tohebakala                 |      0.3
+  Naikala                          |      0.3
+  Ngao Bakala                      |      0.3
+  Purba Kalmegha                   |      0.3
+  Sungai Bakala                    |      0.3
+  Tagobikala                       |      0.3
+  Tanjung Batikala                 |      0.3
+  Tombakala                        |      0.3
+  Tsibakala                        |      0.3
+  Tumba-Kalumba                    |      0.3
+  Tumba-Kalunga                    |      0.3
+  Waikala                          |      0.3
+ (89 rows)
+ 
*** a/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.1--1.2.sql
***************
*** 3,12 ****
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         FUNCTION        6    (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
--- 3,74 ----
  -- complain if script is sourced in psql, rather than via ALTER EXTENSION
  \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.2'" to load this file. \quit
  
+ CREATE FUNCTION word_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  CREATE FUNCTION gin_trgm_triconsistent(internal, int2, text, int4, internal, internal, internal)
  RETURNS "char"
  AS 'MODULE_PATHNAME'
  LANGUAGE C IMMUTABLE STRICT;
  
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
!         OPERATOR        7       %> (text, text),
!         FUNCTION        6      (text, text)   gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/pg_trgm--1.2.sql
--- b/contrib/pg_trgm/pg_trgm--1.2.sql
***************
*** 39,44 **** CREATE OPERATOR % (
--- 39,77 ----
          JOIN = contjoinsel
  );
  
+ CREATE FUNCTION word_similarity(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE FUNCTION word_similarity_commutator_op(text,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT STABLE;  -- stable because depends on pg_trgm.word_similarity_threshold
+ 
+ CREATE OPERATOR <% (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_op,
+         COMMUTATOR = '%>',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
+ CREATE OPERATOR %> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_commutator_op,
+         COMMUTATOR = '<%',
+         RESTRICT = contsel,
+         JOIN = contjoinsel
+ );
+ 
  CREATE FUNCTION similarity_dist(text,text)
  RETURNS float4
  AS 'MODULE_PATHNAME'
***************
*** 51,56 **** CREATE OPERATOR <-> (
--- 84,113 ----
          COMMUTATOR = '<->'
  );
  
+ CREATE FUNCTION word_similarity_dist_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE FUNCTION word_similarity_dist_commutator_op(text,text)
+ RETURNS float4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OPERATOR <<-> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_op,
+         COMMUTATOR = '<->>'
+ );
+ 
+ CREATE OPERATOR <->> (
+         LEFTARG = text,
+         RIGHTARG = text,
+         PROCEDURE = word_similarity_dist_commutator_op,
+         COMMUTATOR = '<<->'
+ );
+ 
  -- gist key
  CREATE FUNCTION gtrgm_in(cstring)
  RETURNS gtrgm
***************
*** 140,145 **** ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
--- 197,208 ----
          OPERATOR        5       pg_catalog.~ (text, text),
          OPERATOR        6       pg_catalog.~* (text, text);
  
+ -- Add operators that are new in 9.6 (pg_trgm 1.2).
+ 
+ ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD
+         OPERATOR        7       %> (text, text),
+         OPERATOR        8       <->> (text, text) FOR ORDER BY pg_catalog.float_ops;
+ 
  -- support functions for gin
  CREATE FUNCTION gin_extract_value_trgm(text, internal)
  RETURNS internal
***************
*** 187,190 **** AS 'MODULE_PATHNAME'
--- 250,254 ----
  LANGUAGE C IMMUTABLE STRICT;
  
  ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD
+         OPERATOR        7       %> (text, text),
          FUNCTION        6      (text,text) gin_trgm_triconsistent (internal, int2, text, int4, internal, internal, internal);
*** a/contrib/pg_trgm/sql/pg_trgm.sql
--- b/contrib/pg_trgm/sql/pg_trgm.sql
***************
*** 13,19 **** select similarity('wow',' WOW ');
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text);
  
  \copy test_trgm from 'data/trgm.data'
  
--- 13,19 ----
  
  select similarity('---', '####---');
  
! CREATE TABLE test_trgm(t text COLLATE "C");
  
  \copy test_trgm from 'data/trgm.data'
  
***************
*** 40,46 **** select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu098
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text);
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
--- 40,46 ----
  select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
  select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;
  
! create table test2(t text COLLATE "C");
  insert into test2 values ('abcdef');
  insert into test2 values ('quark');
  insert into test2 values ('  z foo bar');
*** /dev/null
--- b/contrib/pg_trgm/sql/pg_word_trgm.sql
***************
*** 0 ****
--- 1,42 ----
+ CREATE TABLE test_trgm2(t text COLLATE "C");
+ 
+ \copy test_trgm2 from 'data/trgm2.data'
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ create index trgm_idx2 on test_trgm2 using gist (t gist_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ explain (costs off)
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ select t <->> 'Kabankala', t from test_trgm2 order by t <->> 'Kabankala' limit 7;
+ 
+ drop index trgm_idx2;
+ create index trgm_idx2 on test_trgm2 using gin (t gin_trgm_ops);
+ set enable_seqscan=off;
+ 
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.5;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
+ 
+ set "pg_trgm.word_similarity_threshold" to 0.3;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t;
+ select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t;
+ select t,word_similarity('Kabankala',t) as sml from test_trgm2 where t %> 'Kabankala' order by sml desc, t;
*** a/contrib/pg_trgm/trgm.h
--- b/contrib/pg_trgm/trgm.h
***************
*** 26,38 ****
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber	1
! #define DistanceStrategyNumber		2
! #define LikeStrategyNumber			3
! #define ILikeStrategyNumber			4
! #define RegExpStrategyNumber		5
! #define RegExpICaseStrategyNumber	6
! 
  
  typedef char trgm[3];
  
--- 26,39 ----
  #define DIVUNION
  
  /* operator strategy numbers */
! #define SimilarityStrategyNumber		1
! #define DistanceStrategyNumber			2
! #define LikeStrategyNumber				3
! #define ILikeStrategyNumber				4
! #define RegExpStrategyNumber			5
! #define RegExpICaseStrategyNumber		6
! #define WordSimilarityStrategyNumber	7
! #define WordDistanceStrategyNumber		8
  
  typedef char trgm[3];
  
***************
*** 103,117 **** typedef char *BITVECP;
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double similarity_threshold;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
--- 104,131 ----
  #define GETARR(x)		( (trgm*)( (char*)x+TRGMHDRSIZE ) )
  #define ARRNELEM(x) ( ( VARSIZE(x) - TRGMHDRSIZE )/sizeof(trgm) )
  
+ /*
+  * 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
+ 
  typedef struct TrgmPackedGraph TrgmPackedGraph;
  
  extern double similarity_threshold;
+ extern double word_similarity_threshold;
  
  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);
! extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact);
  extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2);
  extern bool *trgm_presence_map(TRGM *query, TRGM *key);
  extern TRGM *createTrgmNFA(text *text_re, Oid collation,
*** a/contrib/pg_trgm/trgm_gin.c
--- b/contrib/pg_trgm/trgm_gin.c
***************
*** 89,94 **** gin_extract_query_trgm(PG_FUNCTION_ARGS)
--- 89,95 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
  			trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
  			break;
  		case ILikeStrategyNumber:
***************
*** 176,181 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 177,183 ----
  	bool		res;
  	int32		i,
  				ntrue;
+ 	double		nlimit;
  
  	/* All cases served by this function are inexact */
  	*recheck = true;
***************
*** 183,188 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
--- 185,194 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				similarity_threshold : word_similarity_threshold;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 207,214 **** gin_trgm_consistent(PG_FUNCTION_ARGS)
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				((((((float4) ntrue) / ((float4) nkeys))) >= similarity_threshold)
! 					? true : false);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 213,219 ----
  			 * So, independly on DIVUNION the upper bound formula is the same.
  			 */
  			res = (nkeys == 0) ? false :
! 				(((((float4) ntrue) / ((float4) nkeys))) >= nlimit);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
***************
*** 270,279 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
--- 275,289 ----
  	int32		i,
  				ntrue;
  	bool	   *boolcheck;
+ 	double		nlimit;
  
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
+ 		case WordSimilarityStrategyNumber:
+ 			nlimit = (strategy == SimilarityStrategyNumber) ?
+ 				similarity_threshold : word_similarity_threshold;
+ 
  			/* Count the matches */
  			ntrue = 0;
  			for (i = 0; i < nkeys; i++)
***************
*** 285,293 **** gin_trgm_triconsistent(PG_FUNCTION_ARGS)
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0) ? GIN_FALSE :
! 				(((((float4) ntrue) / ((float4) nkeys)) >= similarity_threshold)
! 					? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
--- 295,303 ----
  			/*
  			 * See comment in gin_trgm_consistent() about * upper bound formula
  			 */
! 			res = (nkeys == 0)
! 				? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= nlimit)
! 							? GIN_MAYBE : GIN_FALSE);
  			break;
  		case ILikeStrategyNumber:
  #ifndef IGNORECASE
*** a/contrib/pg_trgm/trgm_gist.c
--- b/contrib/pg_trgm/trgm_gist.c
***************
*** 191,196 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 191,197 ----
  	bool		res;
  	Size		querysize = VARSIZE(query);
  	gtrgm_consistent_cache *cache;
+ 	double		nlimit;
  
  	/*
  	 * We keep the extracted trigrams in cache, because trigram extraction is
***************
*** 218,223 **** gtrgm_consistent(PG_FUNCTION_ARGS)
--- 219,225 ----
  		switch (strategy)
  		{
  			case SimilarityStrategyNumber:
+ 			case WordSimilarityStrategyNumber:
  				qtrg = generate_trgm(VARDATA(query),
  									 querysize - VARHDRSZ);
  				break;
***************
*** 286,301 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 			/* Similarity search is exact */
! 			*recheck = false;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				float4		tmpsml = cnt_sml(key, qtrg);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &similarity_threshold
! 						|| tmpsml > similarity_threshold) ? true : false;
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
--- 288,310 ----
  	switch (strategy)
  	{
  		case SimilarityStrategyNumber:
! 		case WordSimilarityStrategyNumber:
! 			/* Similarity search is exact. Word similarity search is inexact */
! 			*recheck = (strategy == WordSimilarityStrategyNumber);
! 			nlimit = (strategy == SimilarityStrategyNumber) ?
! 				similarity_threshold : word_similarity_threshold;
  
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the tmpsml variable using volatile
! 				 * keyword. Otherwise comparison of nlimit and tmpsml may give
! 				 * wrong results.
! 				 */
! 				float4 volatile tmpsml = cnt_sml(qtrg, key, *recheck);
  
  				/* strange bug at freebsd 5.2.1 and gcc 3.3.3 */
! 				res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit);
  			}
  			else if (ISALLTRUE(key))
  			{					/* non-leaf contains signature */
***************
*** 309,316 **** gtrgm_consistent(PG_FUNCTION_ARGS)
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= similarity_threshold)
! 							? true : false;
  			}
  			break;
  		case ILikeStrategyNumber:
--- 318,324 ----
  				if (len == 0)
  					res = false;
  				else
! 					res = (((((float8) count) / ((float8) len))) >= nlimit);
  			}
  			break;
  		case ILikeStrategyNumber:
***************
*** 428,433 **** gtrgm_distance(PG_FUNCTION_ARGS)
--- 436,442 ----
  	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
  
  	/* Oid		subtype = PG_GETARG_OID(3); */
+ 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
  	TRGM	   *key = (TRGM *) DatumGetPointer(entry->key);
  	TRGM	   *qtrg;
  	float8		res;
***************
*** 463,471 **** gtrgm_distance(PG_FUNCTION_ARGS)
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				res = 1.0 - cnt_sml(key, qtrg);
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
--- 472,488 ----
  	switch (strategy)
  	{
  		case DistanceStrategyNumber:
+ 		case WordDistanceStrategyNumber:
+ 			*recheck = strategy == WordDistanceStrategyNumber;
  			if (GIST_LEAF(entry))
  			{					/* all leafs contains orig trgm */
! 				/*
! 				 * Prevent gcc optimizing the sml variable using volatile
! 				 * keyword. Otherwise res can differ from the
! 				 * word_similarity_dist_op() function.
! 				 */
! 				float4 volatile sml = cnt_sml(qtrg, key, *recheck);
! 				res = 1.0 - sml;
  			}
  			else if (ISALLTRUE(key))
  			{					/* all leafs contains orig trgm */
*** a/contrib/pg_trgm/trgm_op.c
--- b/contrib/pg_trgm/trgm_op.c
***************
*** 15,21 ****
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double		similarity_threshold = 0.3f;
  
  void		_PG_init(void);
  
--- 15,22 ----
  PG_MODULE_MAGIC;
  
  /* GUC variables */
! double similarity_threshold = 0.3f;
! double word_similarity_threshold = 0.6f;
  
  void		_PG_init(void);
  
***************
*** 23,30 **** PG_FUNCTION_INFO_V1(set_limit);
--- 24,43 ----
  PG_FUNCTION_INFO_V1(show_limit);
  PG_FUNCTION_INFO_V1(show_trgm);
  PG_FUNCTION_INFO_V1(similarity);
+ PG_FUNCTION_INFO_V1(word_similarity);
  PG_FUNCTION_INFO_V1(similarity_dist);
  PG_FUNCTION_INFO_V1(similarity_op);
+ PG_FUNCTION_INFO_V1(word_similarity_op);
+ PG_FUNCTION_INFO_V1(word_similarity_commutator_op);
+ PG_FUNCTION_INFO_V1(word_similarity_dist_op);
+ PG_FUNCTION_INFO_V1(word_similarity_dist_commutator_op);
+ 
+ /* Trigram with position */
+ typedef struct
+ {
+ 	trgm	trg;
+ 	int		index;
+ } pos_trgm;
  
  /*
   * Module load callback
***************
*** 45,55 **** _PG_init(void)
  							NULL,
  							NULL,
  							NULL);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
   */
  Datum
  set_limit(PG_FUNCTION_ARGS)
--- 58,80 ----
  							NULL,
  							NULL,
  							NULL);
+ 	DefineCustomRealVariable("pg_trgm.word_similarity_threshold",
+ 							"Sets the threshold used by the <%% operator.",
+ 							"Valid range is 0.0 .. 1.0.",
+ 							&word_similarity_threshold,
+ 							0.6,
+ 							0.0,
+ 							1.0,
+ 							PGC_USERSET,
+ 							0,
+ 							NULL,
+ 							NULL,
+ 							NULL);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function.
   */
  Datum
  set_limit(PG_FUNCTION_ARGS)
***************
*** 59,72 **** set_limit(PG_FUNCTION_ARGS)
  	if (nlimit < 0 || nlimit > 1.0)
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong limit, should be between 0 and 1")));
  	similarity_threshold = nlimit;
  	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function
   */
  Datum
  show_limit(PG_FUNCTION_ARGS)
--- 84,97 ----
  	if (nlimit < 0 || nlimit > 1.0)
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("wrong threshold, should be between 0 and 1")));
  	similarity_threshold = nlimit;
  	PG_RETURN_FLOAT4(similarity_threshold);
  }
  
  /*
   * Deprecated function.
!  * Use "pg_trgm.similarity_threshold" GUC variable instead of this function.
   */
  Datum
  show_limit(PG_FUNCTION_ARGS)
***************
*** 199,236 **** make_trigrams(trgm *tptr, char *str, int bytelen, int charlen)
  	return tptr;
  }
  
! TRGM *
! generate_trgm(char *str, int slen)
  {
! 	TRGM	   *trg;
  	char	   *buf;
! 	trgm	   *tptr;
! 	int			len,
! 				charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
- 	/*
- 	 * Guard against possible overflow in the palloc requests below.  (We
- 	 * don't worry about the additive constants, since palloc can detect
- 	 * requests that are a little above MaxAllocSize --- we just need to
- 	 * prevent integer overflow in the multiplications.)
- 	 */
- 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
- 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
- 		ereport(ERROR,
- 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- 				 errmsg("out of memory")));
- 
- 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
- 	trg->flag = ARRKEY;
- 	SET_VARSIZE(trg, TRGMHDRSIZE);
- 
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return trg;
  
! 	tptr = GETARR(trg);
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
--- 224,251 ----
  	return tptr;
  }
  
! /*
!  * Make array of trigrams without sorting and removing duplicate items.
!  *
!  * trg: where to return the array of trigrams.
!  * str: source string, of length slen bytes.
!  *
!  * Returns length of the generated array.
!  */
! static int
! generate_trgm_only(trgm *trg, char *str, int slen)
  {
! 	trgm	   *tptr;
  	char	   *buf;
! 	int			charlen,
  				bytelen;
  	char	   *bword,
  			   *eword;
  
  	if (slen + LPADDING + RPADDING < 3 || slen == 0)
! 		return 0;
  
! 	tptr = trg;
  
  	/* Allocate a buffer for case-folded, blank-padded words */
  	buf = (char *) palloc(slen * pg_database_encoding_max_length() + 4);
***************
*** 270,276 **** generate_trgm(char *str, int slen)
  
  	pfree(buf);
  
! 	if ((len = tptr - GETARR(trg)) == 0)
  		return trg;
  
  	/*
--- 285,331 ----
  
  	pfree(buf);
  
! 	return tptr - trg;
! }
! 
! /*
!  * Guard against possible overflow in the palloc requests below.  (We
!  * don't worry about the additive constants, since palloc can detect
!  * requests that are a little above MaxAllocSize --- we just need to
!  * prevent integer overflow in the multiplications.)
!  */
! static void
! protect_out_of_mem(int slen)
! {
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
! }
! 
! /*
!  * Make array of trigrams with sorting and removing duplicate items.
!  *
!  * str: source string, of length slen bytes.
!  *
!  * Returns the sorted array of unique trigrams.
!  */
! TRGM *
! generate_trgm(char *str, int slen)
! {
! 	TRGM	   *trg;
! 	int			len;
! 
! 	protect_out_of_mem(slen);
! 
! 	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
! 	trg->flag = ARRKEY;
! 
! 	len = generate_trgm_only(GETARR(trg), str, slen);
! 	SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
! 
! 	if (len == 0)
  		return trg;
  
  	/*
***************
*** 288,293 **** generate_trgm(char *str, int slen)
--- 343,627 ----
  }
  
  /*
+  * Make array of positional trigrams from two trigram arrays trg1 and trg2.
+  *
+  * trg1: trigram array of search pattern, of length len1. trg1 is required
+  *       word which positions don't matter and replaced with -1.
+  * trg2: trigram array of text, of length len2. trg2 is haystack where we
+  *       search and have to store its positions.
+  *
+  * Returns concatenated trigram array.
+  */
+ static pos_trgm *
+ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2)
+ {
+ 	pos_trgm   *result;
+ 	int			i, len = len1 + len2;
+ 
+ 	result = (pos_trgm *) palloc(sizeof(pos_trgm) * len);
+ 
+ 	for (i = 0; i < len1; i++)
+ 	{
+ 		memcpy(&result[i].trg, &trg1[i], sizeof(trgm));
+ 		result[i].index = -1;
+ 	}
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		memcpy(&result[i + len1].trg, &trg2[i], sizeof(trgm));
+ 		result[i + len1].index = i;
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * Compare position trigrams: compare trigrams first and position second.
+  */
+ static int
+ comp_ptrgm(const void *v1, const void *v2)
+ {
+ 	const pos_trgm *p1 = (const pos_trgm *)v1;
+ 	const pos_trgm *p2 = (const pos_trgm *)v2;
+ 	int				cmp;
+ 
+ 	cmp = CMPTRGM(p1->trg, p2->trg);
+ 	if (cmp != 0)
+ 		return cmp;
+ 
+ 	if (p1->index < p2->index)
+ 		return -1;
+ 	else if (p1->index == p2->index)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ 
+ /*
+  * Iterative search function which calculates maximum similarity with word in
+  * the string. But maximum similarity is calculated only if check_only == false.
+  *
+  * trg2indexes: array which stores indexes of the array "found".
+  * found: array which stores true of false values.
+  * ulen1: count of unique trigrams of array "trg1".
+  * len2: length of array "trg2" and array "trg2indexes".
+  * len: length of the array "found".
+  * check_only: if true then only check existaince of similar search pattern in
+  *             text.
+  *
+  * Returns word similarity.
+  */
+ static float4
+ iterate_word_similarity(int *trg2indexes,
+ 						bool *found,
+ 						int ulen1,
+ 						int len2,
+ 						int len,
+ 						bool check_only)
+ {
+ 	int		   *lastpos,
+ 				i,
+ 				ulen2 = 0,
+ 				count = 0,
+ 				upper = -1,
+ 				lower = -1;
+ 	float4		smlr_cur,
+ 				smlr_max = 0.0f;
+ 
+ 	/* Memorise last position of each trigram */
+ 	lastpos = (int *) palloc(sizeof(int) * len);
+ 	memset(lastpos, -1, sizeof(int) * len);
+ 
+ 	for (i = 0; i < len2; i++)
+ 	{
+ 		/* Get index of next trigram */
+ 		int	trgindex = trg2indexes[i];
+ 
+ 		/* Update last position of this trigram */
+ 		if (lower >= 0 || found[trgindex])
+ 		{
+ 			if (lastpos[trgindex] < 0)
+ 			{
+ 				ulen2++;
+ 				if (found[trgindex])
+ 					count++;
+ 			}
+ 			lastpos[trgindex] = i;
+ 		}
+ 
+ 		/* Adjust lower bound if this trigram is present in required substing */
+ 		if (found[trgindex])
+ 		{
+ 			int		prev_lower,
+ 					tmp_ulen2,
+ 					tmp_lower,
+ 					tmp_count;
+ 
+ 			upper = i;
+ 			if (lower == -1)
+ 			{
+ 				lower = i;
+ 				ulen2 = 1;
+ 			}
+ 
+ 			smlr_cur = CALCSML(count, ulen1, ulen2);
+ 
+ 			/* Also try to adjust upper bound for greater similarity */
+ 			tmp_count = count;
+ 			tmp_ulen2 = ulen2;
+ 			prev_lower = lower;
+ 			for (tmp_lower = lower; tmp_lower <= upper; tmp_lower++)
+ 			{
+ 				float	smlr_tmp = CALCSML(tmp_count, ulen1, tmp_ulen2);
+ 				int		tmp_trgindex;
+ 
+ 				if (smlr_tmp > smlr_cur)
+ 				{
+ 					smlr_cur = smlr_tmp;
+ 					ulen2 = tmp_ulen2;
+ 					lower = tmp_lower;
+ 					count = tmp_count;
+ 				}
+ 				/*
+ 				 * if we only check that word similarity is greater than
+ 				 * pg_trgm.word_similarity_threshold we do not need to calculate
+ 				 * a maximum similarity.
+ 				 */
+ 				if (check_only && smlr_cur >= word_similarity_threshold)
+ 					break;
+ 
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 				{
+ 					tmp_ulen2--;
+ 					if (found[tmp_trgindex])
+ 						tmp_count--;
+ 				}
+ 			}
+ 
+ 			smlr_max = Max(smlr_max, smlr_cur);
+ 			/*
+ 			 * if we only check that word similarity is greater than
+ 			 * pg_trgm.word_similarity_threshold we do not need to calculate a
+ 			 * maximum similarity
+ 			 */
+ 			if (check_only && smlr_max >= word_similarity_threshold)
+ 				break;
+ 
+ 			for (tmp_lower = prev_lower; tmp_lower < lower; tmp_lower++)
+ 			{
+ 				int		tmp_trgindex;
+ 				tmp_trgindex = trg2indexes[tmp_lower];
+ 				if (lastpos[tmp_trgindex] == tmp_lower)
+ 					lastpos[tmp_trgindex] = -1;
+ 			}
+ 		}
+ 	}
+ 
+ 	pfree(lastpos);
+ 
+ 	return smlr_max;
+ }
+ 
+ /*
+  * Calculate word similarity.
+  * This function prepare two arrays: "trg2indexes" and "found". Then this arrays
+  * are used to calculate word similarity using iterate_word_similarity().
+  *
+  * "trg2indexes" is array which stores indexes of the array "found".
+  * In other words:
+  * trg2indexes[j] = i;
+  * found[i] = true (or false);
+  * If found[i] == true then there is trigram trg2[j] in array "trg1".
+  * If found[i] == false then there is not trigram trg2[j] in array "trg1".
+  *
+  * str1: search pattern string, of length slen1 bytes.
+  * str2: text in which we are looking for a word, of length slen2 bytes.
+  * check_only: if true then only check existaince of similar search pattern in
+  *             text.
+  *
+  * Returns word similarity.
+  */
+ static float4
+ calc_word_similarity(char *str1, int slen1, char *str2, int slen2,
+ 						  bool check_only)
+ {
+ 	bool	   *found;
+ 	pos_trgm   *ptrg;
+ 	trgm	   *trg1;
+ 	trgm	   *trg2;
+ 	int			len1,
+ 				len2,
+ 				len,
+ 				i,
+ 				j,
+ 				ulen1;
+ 	int		   *trg2indexes;
+ 	float4		result;
+ 
+ 	protect_out_of_mem(slen1 + slen2);
+ 
+ 	/* Make positional trigrams */
+ 	trg1 = (trgm *) palloc(sizeof(trgm) * (slen1 / 2 + 1) * 3);
+ 	trg2 = (trgm *) palloc(sizeof(trgm) * (slen2 / 2 + 1) * 3);
+ 
+ 	len1 = generate_trgm_only(trg1, str1, slen1);
+ 	len2 = generate_trgm_only(trg2, str2, slen2);
+ 
+ 	ptrg = make_positional_trgm(trg1, len1, trg2, len2);
+ 	len = len1 + len2;
+ 	qsort(ptrg, len, sizeof(pos_trgm), comp_ptrgm);
+ 
+ 	pfree(trg1);
+ 	pfree(trg2);
+ 
+ 	/*
+ 	 * Merge positional trigrams array: enumerate each trigram and find its
+ 	 * presence in required word.
+ 	 */
+ 	trg2indexes = (int *) palloc(sizeof(int) * len2);
+ 	found = (bool *) palloc0(sizeof(bool) * len);
+ 
+ 	ulen1 = 0;
+ 	j = 0;
+ 	for (i = 0; i < len; i++)
+ 	{
+ 		if (i > 0)
+ 		{
+ 			int cmp = CMPTRGM(ptrg[i - 1].trg, ptrg[i].trg);
+ 			if (cmp != 0)
+ 			{
+ 				if (found[j])
+ 					ulen1++;
+ 				j++;
+ 			}
+ 		}
+ 
+ 		if (ptrg[i].index >= 0)
+ 		{
+ 			trg2indexes[ptrg[i].index] = j;
+ 		}
+ 		else
+ 		{
+ 			found[j] = true;
+ 		}
+ 	}
+ 	if (found[j])
+ 		ulen1++;
+ 
+ 	/* Run iterative procedure to find maximum similarity with word */
+ 	result = iterate_word_similarity(trg2indexes, found, ulen1, len2, len,
+ 										  check_only);
+ 
+ 	pfree(trg2indexes);
+ 	pfree(found);
+ 	pfree(ptrg);
+ 
+ 	return result;
+ }
+ 
+ 
+ /*
   * Extract the next non-wildcard part of a search string, ie, a word bounded
   * by '_' or '%' meta-characters, non-word characters or string end.
   *
***************
*** 459,475 **** generate_wildcard_trgm(const char *str, int slen)
  				bytelen;
  	const char *eword;
  
! 	/*
! 	 * Guard against possible overflow in the palloc requests below.  (We
! 	 * don't worry about the additive constants, since palloc can detect
! 	 * requests that are a little above MaxAllocSize --- we just need to
! 	 * prevent integer overflow in the multiplications.)
! 	 */
! 	if ((Size) (slen / 2) >= (MaxAllocSize / (sizeof(trgm) * 3)) ||
! 		(Size) slen >= (MaxAllocSize / pg_database_encoding_max_length()))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
! 				 errmsg("out of memory")));
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
--- 793,799 ----
  				bytelen;
  	const char *eword;
  
! 	protect_out_of_mem(slen);
  
  	trg = (TRGM *) palloc(TRGMHDRSIZE + sizeof(trgm) * (slen / 2 + 1) *3);
  	trg->flag = ARRKEY;
***************
*** 590,596 **** show_trgm(PG_FUNCTION_ARGS)
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2)
  {
  	trgm	   *ptr1,
  			   *ptr2;
--- 914,920 ----
  }
  
  float4
! cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
  {
  	trgm	   *ptr1,
  			   *ptr2;
***************
*** 624,637 **** cnt_sml(TRGM *trg1, TRGM *trg2)
  		}
  	}
  
! #ifdef DIVUNION
! 	return ((float4) count) / ((float4) (len1 + len2 - count));
! #else
! 	return ((float4) count) / ((float4) ((len1 > len2) ? len1 : len2));
! #endif
! 
  }
  
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
--- 948,962 ----
  		}
  	}
  
! 	/*
! 	 * If inexact then len2 is equal to count, because we don't know actual
! 	 * length of second string in inexact search and we can assume that count
! 	 * is a lower bound of len2.
! 	 */
! 	return CALCSML(count, len1, inexact ? count : len2);
  }
  
+ 
  /*
   * Returns whether trg2 contains all trigrams in trg1.
   * This relies on the trigram arrays being sorted.
***************
*** 726,732 **** similarity(PG_FUNCTION_ARGS)
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2);
  
  	pfree(trg1);
  	pfree(trg2);
--- 1051,1057 ----
  	trg1 = generate_trgm(VARDATA(in1), VARSIZE(in1) - VARHDRSZ);
  	trg2 = generate_trgm(VARDATA(in2), VARSIZE(in2) - VARHDRSZ);
  
! 	res = cnt_sml(trg1, trg2, false);
  
  	pfree(trg1);
  	pfree(trg2);
***************
*** 737,742 **** similarity(PG_FUNCTION_ARGS)
--- 1062,1083 ----
  }
  
  Datum
+ word_similarity(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(res);
+ }
+ 
+ Datum
  similarity_dist(PG_FUNCTION_ARGS)
  {
  	float4		res = DatumGetFloat4(DirectFunctionCall2(similarity,
***************
*** 755,757 **** similarity_op(PG_FUNCTION_ARGS)
--- 1096,1162 ----
  
  	PG_RETURN_BOOL(res >= similarity_threshold);
  }
+ 
+ Datum
+ word_similarity_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= word_similarity_threshold);
+ }
+ 
+ Datum
+ word_similarity_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								true);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_BOOL(res >= word_similarity_threshold);
+ }
+ 
+ Datum
+ word_similarity_dist_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
+ 
+ Datum
+ word_similarity_dist_commutator_op(PG_FUNCTION_ARGS)
+ {
+ 	text	   *in1 = PG_GETARG_TEXT_PP(0);
+ 	text	   *in2 = PG_GETARG_TEXT_PP(1);
+ 	float4		res;
+ 
+ 	res = calc_word_similarity(VARDATA_ANY(in2), VARSIZE_ANY_EXHDR(in2),
+ 								VARDATA_ANY(in1), VARSIZE_ANY_EXHDR(in1),
+ 								false);
+ 
+ 	PG_FREE_IF_COPY(in1, 0);
+ 	PG_FREE_IF_COPY(in2, 1);
+ 	PG_RETURN_FLOAT4(1.0 - res);
+ }
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 85,90 ****
--- 85,104 ----
        </entry>
       </row>
       <row>
+       <entry>
+        <function>word_similarity(text, text)</function>
+        <indexterm><primary>word_similarity</primary></indexterm>
+       </entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns a number that indicates how similar the first string
+        to the most similar word of the second string. The function searches in
+        the second string a most similar word not a most similar substring.  The
+        range of the result is zero (indicating that the two strings are
+        completely dissimilar) to one (indicating that the first string is
+        identical to one of the word of the second string).
+       </entry>
+      </row>
+      <row>
        <entry><function>show_trgm(text)</function><indexterm><primary>show_trgm</primary></indexterm></entry>
        <entry><type>text[]</type></entry>
        <entry>
***************
*** 138,143 ****
--- 152,167 ----
        </entry>
       </row>
       <row>
+       <entry><type>text</> <literal>%&gt;</literal> <type>text</></entry>
+       <entry><type>boolean</type></entry>
+       <entry>
+        Returns <literal>true</> if its first argument has the similar word in
+        the second argument and they have a similarity that is greater than the
+        current word similarity threshold set by
+        <varname>pg_trgm.word_similarity_threshold</> parameter.
+       </entry>
+      </row>
+      <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
        <entry>
***************
*** 145,150 ****
--- 169,184 ----
         one minus the <function>similarity()</> value.
        </entry>
       </row>
+      <row>
+       <entry>
+        <type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</>
+       </entry>
+       <entry><type>real</type></entry>
+       <entry>
+        Returns the <quote>distance</> between the arguments, that is
+        one minus the <function>word_similarity()</> value.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
***************
*** 158,164 ****
      <term>
       <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
       <indexterm>
!       <primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary>
       </indexterm>
      </term>
      <listitem>
--- 192,200 ----
      <term>
       <varname>pg_trgm.similarity_threshold</> (<type>real</type>)
       <indexterm>
!       <primary>
!        <varname>pg_trgm.similarity_threshold</> configuration parameter
!       </primary>
       </indexterm>
      </term>
      <listitem>
***************
*** 168,173 ****
--- 204,227 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold">
+     <term>
+      <varname>pg_trgm.word_similarity_threshold</> (<type>real</type>)
+      <indexterm>
+       <primary>
+        <varname>pg_trgm.word_similarity_threshold</> configuration parameter
+       </primary>
+      </indexterm>
+     </term>
+     <listitem>
+      <para>
+       Sets the current word similarity threshold that is used by
+       the <literal>%&gt;</> operator.  The threshold must be between
+       0 and 1 (default is 0.6).
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </sect2>
  
***************
*** 226,231 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
--- 280,311 ----
    </para>
  
    <para>
+    Also you can use an index on the <structfield>t</> column for word
+    similarity.  For example:
+ <programlisting>
+ SELECT t, word_similarity('<replaceable>word</>', t) AS sml
+   FROM test_trgm
+   WHERE t %&gt; '<replaceable>word</>'
+   ORDER BY sml DESC, t;
+ </programlisting>
+    This will return all values in the text column that have a word
+    which sufficiently similar to <replaceable>word</>, sorted from best
+    match to worst.  The index will be used to make this a fast operation
+    even over very large data sets.
+   </para>
+ 
+   <para>
+    A variant of the above query is
+ <programlisting>
+ SELECT t, t &lt;-&gt;&gt; '<replaceable>word</>' AS dist
+   FROM test_trgm
+   ORDER BY dist LIMIT 10;
+ </programlisting>
+    This can be implemented quite efficiently by GiST indexes, but not
+    by GIN indexes.
+   </para>
+ 
+   <para>
     Beginning in <productname>PostgreSQL</> 9.1, these index types also support
     index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
  <programlisting>
#39David Steele
david@pgmasters.net
In reply to: Artur Zakirov (#38)
Re: Fuzzy substring searching with the pg_trgm extension

On 3/14/16 12:27 PM, Artur Zakirov wrote:

On 14.03.2016 18:48, David Steele wrote:

Hi Jeff,

On 2/25/16 5:00 PM, Jeff Janes wrote:

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

It's not clear to me if you are requesting more documentation here or
stating that you are happy with it as-is. Care to elaborate?

Other than that I think this patch looks to be ready for committer. Any
objections?

There was some comments about the word-boundary subtlety. But I think it
was not enough.

I rephrased the explanation of word_similarity() and %>. It is better now.

But if it is not correct I can change the explanation.

Since to only change in the latest patch is to documentation I have
marked this "ready for committer".

--
-David
david@pgmasters.net

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#40Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: David Steele (#39)
Re: Fuzzy substring searching with the pg_trgm extension

On 15.03.2016 17:28, David Steele wrote:

On 3/14/16 12:27 PM, Artur Zakirov wrote:

On 14.03.2016 18:48, David Steele wrote:

Hi Jeff,

On 2/25/16 5:00 PM, Jeff Janes wrote:

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

It's not clear to me if you are requesting more documentation here or
stating that you are happy with it as-is. Care to elaborate?

Other than that I think this patch looks to be ready for committer. Any
objections?

There was some comments about the word-boundary subtlety. But I think it
was not enough.

I rephrased the explanation of word_similarity() and %>. It is better now.

But if it is not correct I can change the explanation.

Since to only change in the latest patch is to documentation I have
marked this "ready for committer".

Thank you!

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#41Jeff Janes
jeff.janes@gmail.com
In reply to: Artur Zakirov (#38)
Re: Fuzzy substring searching with the pg_trgm extension

On Mon, Mar 14, 2016 at 9:27 AM, Artur Zakirov <a.zakirov@postgrespro.ru> wrote:

On 14.03.2016 18:48, David Steele wrote:

Hi Jeff,

On 2/25/16 5:00 PM, Jeff Janes wrote:

But, It doesn't sound like I am going to win that debate. Given that,
I don't think we need a different name for the function. I'm fine with
explaining the word-boundary subtlety in the documentation, and
keeping the function name itself simple.

It's not clear to me if you are requesting more documentation here or
stating that you are happy with it as-is. Care to elaborate?

Other than that I think this patch looks to be ready for committer. Any
objections?

There was some comments about the word-boundary subtlety. But I think it was
not enough.

I rephrased the explanation of word_similarity() and %>. It is better now.

But if it is not correct I can change the explanation.

<% and <<-> are not documented at all. Is that a deliberate choice?
Since they were added as convenience functions for the user, I think
they really need to be in the user documentation.

Also, the documentation should probably include <% and <<-> as the
"parent" operators and use them in the examples, and only mention %>
and <->> in passing, as the commutators. That is because <% and <<->
take their arguments in the same order as word_similarity does. It
would be less confusing if the documentation and the examples didn't
need to keep changing the argument orders.

Cheers,

Jeff

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#42Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Jeff Janes (#41)
Re: Fuzzy substring searching with the pg_trgm extension

2016-03-18 23:46 GMT+03:00 Jeff Janes <jeff.janes@gmail.com>:

<% and <<-> are not documented at all. Is that a deliberate choice?
Since they were added as convenience functions for the user, I think
they really need to be in the user documentation.

I can send a patch a little bit later. I documented %>
and <->> because examples of other operators have the following order:

SELECT t, t <-> 'word' AS dist
FROM test_trgm
ORDER BY dist LIMIT 10;

and

SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';

I did not include <% and <<-> because I did not know how to document
commutators. But I can fix it.

And honestly the following order:

SELECT 'word' <% t FROM test_trgm;

is more convenient to me too.

Do you know how do not break the line in the operators table in the first
column? Now I see:

Operator | Returns
----------------|------------------
text % | boolean
text |

But the following is better:

Operator | Returns
----------------|------------------
text % text | boolean

Also, the documentation should probably include <% and <<-> as the
"parent" operators and use them in the examples, and only mention %>
and <->> in passing, as the commutators. That is because <% and <<->
take their arguments in the same order as word_similarity does. It
would be less confusing if the documentation and the examples didn't
need to keep changing the argument orders.

Cheers,

Jeff

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

#43Artur Zakirov
a.zakirov@postgrespro.ru
In reply to: Artur Zakirov (#42)
1 attachment(s)
Re: Fuzzy substring searching with the pg_trgm extension

I attached the patch, which fixes the pg_trgm documentation.

On 19.03.2016 01:18, Artur Zakirov wrote:

2016-03-18 23:46 GMT+03:00 Jeff Janes <jeff.janes@gmail.com
<mailto:jeff.janes@gmail.com>>:

<% and <<-> are not documented at all. Is that a deliberate choice?
Since they were added as convenience functions for the user, I think
they really need to be in the user documentation.

I can send a patch a little bit later. I documented %>
and <->> because examples of other operators have the following order:

SELECT t, t <-> 'word' AS dist
FROM test_trgm
ORDER BY dist LIMIT 10;

and

SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';

I did not include <% and <<-> because I did not know how to document
commutators. But I can fix it.

And honestly the following order:

SELECT 'word' <% t FROM test_trgm;

is more convenient to me too.

Do you know how do not break the line in the operators table in the
first column? Now I see:

Operator| Returns
----------------|------------------
text % | boolean
text |

But the following is better:

Operator| Returns
----------------|------------------
text % text | boolean

Also, the documentation should probably include <% and <<-> as the
"parent" operators and use them in the examples, and only mention %>
and <->> in passing, as the commutators. That is because <% and <<->
take their arguments in the same order as word_similarity does. It
would be less confusing if the documentation and the examples didn't
need to keep changing the argument orders.

Cheers,

Jeff

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

--
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachments:

pg-trgm-word-doc.patchtext/x-patch; name=pg-trgm-word-doc.patchDownload
*** a/doc/src/sgml/pgtrgm.sgml
--- b/doc/src/sgml/pgtrgm.sgml
***************
*** 153,167 ****
        </entry>
       </row>
       <row>
!        <entry><type>text</> <literal>%&gt;</literal> <type>text</></entry>
!        <entry><type>boolean</type></entry>
!        <entry>
!         Returns <literal>true</> if its first argument has the similar word in
!         the second argument and they have a similarity that is greater than the
!         current word similarity threshold set by
!         <varname>pg_trgm.word_similarity_threshold</> parameter.
!        </entry>
!       </row>
       <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
--- 153,174 ----
        </entry>
       </row>
       <row>
!       <entry><type>text</> <literal>&lt;%</literal> <type>text</></entry>
!       <entry><type>boolean</type></entry>
!       <entry>
!        Returns <literal>true</> if its first argument has the similar word in
!        the second argument and they have a similarity that is greater than the
!        current word similarity threshold set by
!        <varname>pg_trgm.word_similarity_threshold</> parameter.
!       </entry>
!      </row>
!      <row>
!       <entry><type>text</> <literal>%&gt;</literal> <type>text</></entry>
!       <entry><type>boolean</type></entry>
!       <entry>
!        Commutator of the <literal>&lt;%</> operator.
!       </entry>
!      </row>
       <row>
        <entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry>
        <entry><type>real</type></entry>
***************
*** 171,184 ****
        </entry>
       </row>
       <row>
!        <entry>
!         <type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</>
!        </entry>
!        <entry><type>real</type></entry>
!        <entry>
!         Returns the <quote>distance</> between the arguments, that is
!         one minus the <function>word_similarity()</> value.
!        </entry>
       </row>
      </tbody>
     </tgroup>
--- 178,200 ----
        </entry>
       </row>
       <row>
!       <entry>
!        <type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</>
!       </entry>
!       <entry><type>real</type></entry>
!       <entry>
!        Returns the <quote>distance</> between the arguments, that is
!        one minus the <function>word_similarity()</> value.
!       </entry>
!      </row>
!      <row>
!       <entry>
!        <type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</>
!       </entry>
!       <entry><type>real</type></entry>
!       <entry>
!        Commutator of the <literal>&lt;&lt;-&gt;</> operator.
!       </entry>
       </row>
      </tbody>
     </tgroup>
***************
*** 215,221 ****
       <listitem>
        <para>
         Sets the current word similarity threshold that is used by
!        the <literal>%&gt;</> operator.  The threshold must be between
         0 and 1 (default is 0.6).
        </para>
       </listitem>
--- 231,237 ----
       <listitem>
        <para>
         Sets the current word similarity threshold that is used by
!        the <literal>&lt;%</> operator.  The threshold must be between
         0 and 1 (default is 0.6).
        </para>
       </listitem>
***************
*** 283,289 **** SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
  <programlisting>
  SELECT t, word_similarity('<replaceable>word</>', t) AS sml
    FROM test_trgm
!   WHERE t %&gt; '<replaceable>word</>'
    ORDER BY sml DESC, t;
  </programlisting>
     This will return all values in the text column that have a word
--- 299,305 ----
  <programlisting>
  SELECT t, word_similarity('<replaceable>word</>', t) AS sml
    FROM test_trgm
!   WHERE '<replaceable>word</>' &lt;% t
    ORDER BY sml DESC, t;
  </programlisting>
     This will return all values in the text column that have a word
***************
*** 295,301 **** SELECT t, word_similarity('<replaceable>word</>', t) AS sml
    <para>
     A variant of the above query is
  <programlisting>
! SELECT t, t &lt;-&gt;&gt; '<replaceable>word</>' AS dist
    FROM test_trgm
    ORDER BY dist LIMIT 10;
  </programlisting>
--- 311,317 ----
    <para>
     A variant of the above query is
  <programlisting>
! SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
    FROM test_trgm
    ORDER BY dist LIMIT 10;
  </programlisting>