Extensions, patch v16

Started by Dimitri Fontaineabout 15 years ago88 messages
#1Dimitri Fontaine
dimitri@2ndQuadrant.fr
1 attachment(s)

Hi,

Please find attached revision 16 of the extension patch, with the
following additions over the previous one:

- added documentation as proposed by David Wheeler, you can browse it
online if reading SGML ain't your thing

http://pgsql.tapoueh.org/extensions/doc/html/extend-extension.html

- renamed pg_extensions system view to pg_available_extensions

- add ALTER EXTENSION SET SCHEMA command

so that I'm going to mark the patch for that as rejected, where it's
in fact deprecated: it turned out we already need it as part of the
main patch here

- add support for 'relocatable' boolean property in the control file,
as discussed on list

this controls what happens at create extension time, by doing a
relocation of the extension objects when the extension is relocatable
and the asked schema isn't the first of the search_path (you can't
relocate an object to a schema where it already is)

when the extension is not relocatable, the mechanism used is the
@extschema@ replacement in the script so that the user still has a
say, but at create time only

- adapt all contrib

the SET search_path TO public, which became TO @extschema@, is now
removed

2 contribs are not relocatable: adminpack installs its functions
directly into pg_catalog and earthdistance depends on cube.

As we said we won't support extension dependencies in the first cut,
there's no guard in the dependency recursion that would allow us not
to relocate cube objects when relocating earthdistance. The easiest
solution seemed to me to mark the earthdistance extension as not
relocatable.

- nothing is done for the psql commands \dx and \dx+, here's an idea:

\dx lists only installed extensions
\dx+ <extension> lists the objects, calling pg_extension_objects()
\dX lists available extensions (and installed too)

- we still depend on extension authors providing a control file. Do we
want to spend some efforts on trying to get rid of this file? I know
David desperately want to, but that's at the cost of making it much
harder to manage more than one extension in a single directory, for
once, and the Makefile mechanisms to make than happen (include a rule
depending on the presence of some variables, keep track of it for the
cleaning, etc) doesn't seem to me to worth it.

- this patch still includes the current version of pg_execute_from_file
patch, and the next thing I'm going to do is have it change
underneath us to remove some SQL visible functions that shouldn't
exists. Please don't focus on that part of the changes.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

Attachments:

extension.v16.patch.gzapplication/octet-streamDownload
��8Mextension.v16.patch��{_G�0�7�)��nF$�&�9
�����"9�<I~zis,i�������o]�:�#��m�gI�L_���������slt��$�.7��0���������
�?�����Y��?�]���U���q�]�\N��D��v%�m@-C�m��$�(���Q:	��[\����O�i%��Z������)��K������F�2�Z�w?4.�K��@�����]��9��<8�9:;}�|��W�u?����h��@z�W�\����>��4��^�ac4
�fFO��A%ya�I�v�e	�5�gQ�����8	Gi��y7�y�
D�$	&��P����
��'�<N'WI����
��&Xk@��$��`\Bx�)-��*��$;W��U<|��n��;�+�7�.���<����6���A�g��/��(�q��0���}�VK���z	T'���I�q">I�:H���������1��k���0��_
���O��2���[o��"���q2!t�W�?��q����PG��0/N�; �$��������I��^|+�����x.�7"�o��
l����1��R���I4��XH���0	�-�����$W�qIL�^�O���hC=���8�\��O/Q��{8�h��
qv;���~������`<r3@g)lnX���0�2���F�� ���'�����O���E�����%.�x W~�W�h	��c�O���m�J<�.��j���R����"�NZg�iph�R�	W�z&~�u������M�������"�/��l~=�������u^����; <����]���a�N�Iv	/�������?6ob��k�jU5qu�q=8�'���n�^�	6�`~�`86�&����>������������;y�L:�o�`��z����<�������s�3�������k���~4����v'����B��If
,r��D��)��8��E}��2���z1�l%����'�e��T�}�3��TL��O;�B*�N�K����&3��l)��|��q�RyP��0����{�~�i��{=[�����]��y�7:d��rb}�Mn������[��^e��;�>�!�gp_����=�;Y�=�Zp��� \Z
{K��I��'[v��3���������x���������`�N'��(b�!v����&i8���upu#��
wT��V;���G!�U5y�R[��8���T5��x�����aH���w�����{��Bu)����H��Y��~��q��<�"w�:����KG	m�Bb���m�We�]��59�<s7�`�aT[����0��j�nK� ��z�G��(V��T��W���q�+���<.�;�[�%&����Z����$s<7��f����T��0R���A���U�Pp����s��i�\����D�M�%(�crB���O���8�/�Nb6:�cR��^��\������E������#���E�st��#Gv[�����(Y"��#�
-yMx8���N��mCH8L[�-f���H�qG\�p:�D�h�����j?T��3��n��w��2U?+�&��0�1M�d�4���!{�nC�2�21������Y�s���B�p�*X~2���v'@.hQ�Q�_$2���v�w�I�i4s������~������_��b�]��z��M|��o���\��g^a�q�����W

��n=�e�.�����>*�����c��(���.��X����*lk���Tq��,vT�A���,����I�G#�x�����l�=��.�����CqW7�~�0�����G�Y�O�U���*w�Q@�7��bk����)m���������������	��&�����>���������pK����5���dt�/��u�Mc�a0�'��C���M����4g��b��w'
�R��f-e���
|��?�Z�$��x�
(X��VW����v���"���8�h��_�$���	��` 1GD�1@��s@B��og�.���.�����n��s�_9��;��	r9��o��+e�W�o��fvw^��A��*��N�pd����P�8����oBU^�m�)�0O��Wc�����t_NK���������/>��[�	���
�{�k$]H��0�u��3�x ������**v�����a�����E��}��pU&~��LfK��pQj��kv��4q�Z-� ����������J+�+e��S���m��*�����{�#O�%tNX@�@�t^.P����4���c��}��O���z��cz;�y��
���e��;5��)�q��	��F���{���:)��d:���9�E�����g������������[�;��F���K��x�-M�=Ai�����_�����)0�����g#Y�`���$���6"�xNPH�7�����C�-`���v���~�n\4p��7i�P�F����R�\��k4��.�o^"����zfa����O�g�?�m�E�3����<���#�����G���r��O�u�C������`�'���jprL�{0>�n��QA�;X�;-,fd��b3V�������>��iuZ'�h�����=�)w���Aw
,�W��n�tQ�&�����C���tC��P4���5U/o�@��y���=��l�[�6T�QX.�[EK�%��>`��a8R!.B���8�aw���j������X��{���T���f�mtg��4��pK��"t���%�$�E�����&A�y�z����8��������,�B6�X]������?>CV�����4?����l�[!��D�?��?o�IB�X�TPh6�$#\9u+��
�I0��e��^J�\n�W_��CO����=Y,����xL! �P�0I4�B��W����O4v�{�����y��*,�V�o�i����p�^OBP�.k�����B��%V$�������6V�+V��Y���}���v���Zs�gQT�=��/{Q��N)x3����{��wA���i/��cX�H��n�r5�/Q��4{Z���pz���@h��xl>S0���|��K�)XZ7�n�$}� D
�y�������>z����;n��- ������e��Z9[[���Y���I��Z����~�N/2����<9�]���!�!�����i	�<�=��j�^��e��#D:���H*bAK����;��xvO�jM�0�����_�����7/�x�Jm��_�xvh�01
���q�]o�@�6�R|(��-,x���7Xu0����A(P��t2�*��1��cipa�
�a�O����K�/3�<)V�u��\�0I������<Hf�'������h"`q"���2t�����4� zh�)w�^>�[dq��W������B���<}�U������d�B��3j��~W�?�!�J��� ��������w�7
q$�o��#+�C��V��y�>�0��2�Q�5/��;9Y������_�CS��\�CC{*�9Y�N� s��N$��m�e�}�����L�.�A4��}�V&����p$y�q)�?�H���X�g�g�qqqvaY���7.�m`��n���8i�n�/��%&]4�|�}v~qv�8~w���������i�g6���4�?v�1��wG�� ��\�)��xL�����Us����3j>$\$1(��*a�o���g��*)���������W@eH�cx���<_�y:j	w�<��S�Nu4����^1F���!���'��2��$\}�)�sJ��vB���`���q��0�o��F�����b]o��y#_�/ti�?�����8�T�p����t)z�Z.,���Q���A���NF�����Z�Z��&G�@����~��0
����<�I��>��`�:Sm{�V��0�H!���lb������;����$So
�+�Z��";W`n�/�p{�G�l��`e���'��E�,nZhv���-���QRK�-R>A�-o�0�E77��Wm���/���
����@�f��	�$�M���2d}�����K�L�����'�S��:B7������|4�A�D��5����Y�� .����� ��5q���o�������s[��]1F�"�I�\���1�a���b��jq\��}�X�wk�~U*�@#�l0��&���3q#c�����	y�#EQM����[(F���EO��e~n���I����b�4�>������G,4}��p��x"=�{}&E���������wK=��Q�����
/���&�~b��O���@�r���)�������KQ�q	���xg��c�uo���+O|s{��.�������x��������&KK/E�`u� 	�1��)|�<�K?���z��A����q�<!�,�Ge���a�f���=���DVM��89dT)���y$��D����m����wN���������ju`K��f�P�.��~�t��u!�YTj�"_����iLj�Uq��f�R_�t!���}w��J�OZ]Z��A��T����
��{p���;q�*w��4�y�"!Z;��[R���l��o�n�>�x�8���`<c7��-�����d�x�V��j����\����f��3�TL@9Qz�z���-<sFE�x�Jw��4�7�g/Y�y��<��/�������%��!�of17��z��������Q�����.��������;I��{D��c����5T����[5c5
��ao�n������ �pGw�� MI�[��	+x�<>B������=
�f�Wf�����O�o�4����V��$-^�N�i�f���o�-&��,2��`���\�b�\
g.���0I6������$J�u����R+i��J^S=�������U2���jd-��oh���6��O������s�-	������c��R-���A��OB��7�-9,S�Q
��s-b��Ev&TD{}��De=
<
�6���'%N�n����"���Y�w9��������I�m�>&�������g�������f��wyw���l.�&��T�T��0���7�@�.�M?J�E�����CZ����j�$�8���x�s8��)������n���Uv���[���N�HU�G����
��K�>����x��?}��Rt���Sd�� {�D
�����`*���$�&tL���QG�l�I���{$����=[��:|��}�K��������3!���U������z�g�\p�����o��D�4���?�P��N�0�l�s�c����d��yxn�G�5�`7��/���l��':�$�'���$����~��0_b�ksSu���)jT�K�}x�������fpoz�Z��Y_cF ���Y�\.7�j4B
�G�]c�H?���&U@�g�Q/n�iv3�R�AH>������i��^���<./-�����t�i��x0��Sd����Vb����6��9��%W�k�������uG��	����u�U�����)������cg5�T����MK��������y��m;��M���@��HF����jiX�����m�mdu��3�����?�"a��e����E.NcK_{~�{�!��B+�6�jv���
�g���B���8�{�H�f��'8&�d�0�E@��
��!:Iw���q4����`���UM�{�f^.~|�?�=�\�zt�/�(��WMh�g *(�}`��>\{�;�jH�)���������8*�T�W�[�}���,�f�&�����q��d�Ad�@rq6v�������_�y��gm�R
z�t��G��l9O"����d^�����}qv�--�V�t�R����Ne����y�c|�0�a��@��W@��`!Q������@��A���b���M#��U#������k���!������D�w	wq����N�T&M7�@����\@}!�!H'�Tl��>o����=�d�Y��E���y��p�Pp{��*_��T�������J�n|u&3�$��c�@+(x7��y@��m1`��B)��6��X�t�T��������=�S)�O��aG�������|$�!��,\�����Bq�
|����r�����8u���w�����L/�y�>Ot_Lp������2��p�fP��2w��\���fXw>q�^U����������P�
|���_�e����}�,\=�ok��K1��v� =�2�h�ND�>oz�ff��V�Bw�W���!h:�Hi�08�J&]����E��J�����H+�����l|s?�����������G�Mk��#�:{n������}&��i��������[����7���m�o�EK�zHg����/�iMmEI{���:��`��:���4gFx_�SS8��D��x�Z))d��{J�(�'&<�S���)p�%�"�������zO�?I�y����1�o��0��_�w�������f�N`	�������T[��U��`��Y����
2sTZ�����T�jR�O���M�LI!�^?�!�J��}wQg�����D��~�j\H��_2���0�O�HH'�g^.\�I%8��^��-�W�aw��L~�B���),R���1Pb�@�������#[g���������������z!�HR�sO&%�y��������d#x�B"���:T��bt8��A�x�����9��T<����g,(~Z^a�~�	��&�����z|�C��c�Sa���#�c���Z�-���jV���,M�\��#�`���������!�U��;����ZB=���P��r(�:0]Wil�/9��	(�Pi�������*cr���PE���=4�y�H��a�����9�:���"�^��`��)@����|7Le�Fn'�L��tf ��(�va������9R��QU��PV���;g���������p�����utZ�Yq���Z��l^��Df���("��w������I��ZY_���n��6_C[�������S������iapU�1�X~����B=��Q�[��G�5�����'j�����W ���C��}X:��OaQ���\�F3�d�p��������F�:{�������0�6�{�]j~�������aQOC��UJ�+pbI����G�4���iZ��S`~=G3�[�F��}��	�Z'����U�Y�u�y��y��k�������L���L5����p���B�.n"�-~�m����i�%�(!��2����w[q�;���F����QuF�k��g����A�n�}���rU����z3a��q)UY['�}��=���AD�q����z���P�!�$l���3�;�eiE>�� W����`��e����n���}��9�W��i�d�y������}���b��u�|��_�X�������w��x{b����(a������x�1���N�N�{�&>��u�I�b�i�i���F*y����9�.��C��u�^�UTCt&O���i����
,1���
~��Q�7���N��v�4������n���+�'b
��^.�>�[��/��B��I4����\��\|��.���npa�k���	�?�������V�e�WO��
���hI �h�7�!�H'qn9&pK�;A2�aO�&*�S�P|�1�w����z�L�{����qs�pD�T6���9-5	r��y�%���t8J����WI<~����
���:z���6�o��-��)t����k���]h�{Q���7
�-���5����e���=n	'r{~P�<��E���^qy�XX��yC��y���v��K�s�����3�A�8N��B@j\+#�'���\����`:����#LWf	�� �i��d0��T��(���x����e��\�[�`��2�E���7{�j�]����,'�2���+(+�*�����*��F�_U�8���m�	�F;^KCG4���tx�?�0���y�&	��0Y~��bB$+t�BGV��	���
�7��2��3�����><���{�t|��(w]>D�
�+���V�����\t!C^��\hy��I�'��sn�����h�s���3G�i�*�Y/�]?���c��a�,|�f1 ��}X���=K��� .2{�f0"���d�����������C�8	�IJ����)k����D�������!.�~l}��32w�,8�/(�O��M�x�4���l���X�����sY0XOC� ���pB�BZ
@�f7�[#
������O3[�|�I3�!�$J�-,^>E���O�=}wrb
b)������[���.`���A��@�0zzV(���rP�k�(�ACpM;�����Y7QZ}>����L�&����wx������U��G���q��MX�.�����Z�������\��X,����s.��b�s��OY�M(}�$�
q�_H��M(��g�S)���'Ez/G�`��Mp��
F�T�D�������V�����$�_��~�l�T��"���sFf���������T�:����0�3��p����������-�d����:b�8&eJr��j���mY����=N�2[�E8��Oxh�+"��Lx����(�������B ������FW��'i%�F�q�Z�pfl�� �L`��S��%E"�[�l����Bk�sp\vW��K��yN���7���p����1��(�Q��:gX~|�X��
�;2G#(DEkZ�B���P�y��)�7��9�,�:���:z�k�<�)���wk��]g�7�zyf��S�$Y��E��H4-����u��o�u�,�����W�FF�FL��d�wF�>A}	�� ���mp���E��y�T�fd}�����3�!�c!��o���H$�&!
�0K/���#H.�D�*��R�h��J��)0*X,�L�Rfv��!!*�XI�M3�L�rlL�����Z�m�N��������ik�C0��+�r��0��2��d�R����e0����A�����?��=��['�B>��[��M0�9�2�1CE�`6����4%6AMu�P�C
i�%��!4������H����u�e��G%����i��h:�\0�����T�z��a��t�F�bav�e������$xp�} YX�
K��!>�
��*���"6��?����<H��'=���}�P8A�8�k$�V{E+���P�����j4
{�<�=���3O�+�������07�����HP�"2u�_�!����4�\����f��b���6�=�W�!yx�;_��Bx�p���%G�1���J6�No9�B�������R?	�\X�n�|l�� K��R�M�n��CJT%J��P`�U�Q~�e��nN��������m���mr��������C�C+�e92�%{U��)�$3@������1�
b8����@��L���U�uV���c��n"`~�NF���I:d��>�i=���/��J{�UV Wk�,���GC��9rosw���N���{�nR�^����E�m5��%�9��p��B��yVFy�<������zL�z�_d@��F�B�e�+���_@�U�#��>rY
/��W���D��)I�����4��1��t�F	�#������C;������o#�������2<r�~(\	%���+���.����RD����2c��"~�9������`5>,�\�$KK�u&��^����~�n\X������v4T�@]��xLc�L��x`{nZ���]�Li�T>qk3Q�u9�S�T���_Z:8W,�OY\���W��p�9b�q�F��!�n�,��v���L�<#&�xnU
��R��z��
�������F�]xP����Vn��=Q`P`IA�.���Q�o�uqH+��B$mG����9���	3��5^m�	k��Xu���"d�"�#���*m��"
&y�OO�2��k�����w=_�����5�-�"�m����,%{�"�S�����w����k16
H��c�5K����R�.��aCnGQ��0�]&*84���*|�V��:�����[�:�1�AH7�j�����o��{������ntk0�����J5c[���M��
l)N#�T���f�"dJ�=����j-���bL���!���e���������7�&_]�W�@3����dD	3����C��U7���������$�srJ���U�2�g����%F�q��k���}��O��o���4Z�c@i�4~q�c�/���Km��,��`�<L����������N�~�����7.�m���{%J'������V�]]4�|/�s>�8;j��h���I�1�=���*w�x�=p��Y�_�Q?o��01A�/R=z��y������QZ5��Q����Xb3��?C�qL����rWw����u4
�e}9[��� 	���{]0g���ha�sg=W7+�J�w��Q�/�Ium1'�5i9����hu���T��h�^V�xm�L"���z��F����on�e�/�b�������&.R��|���m�y�N��P��h��Ss�yy��)fH[������+X�1����nT37��XLL��e�1L����#UX���^g��mt���Unj�I�t�"/E}���W��/}��W�4����
+����x[2��3_�I<����z������>	��U[��C�������]�p18�'sz�/�UL/�m����,����T*�~5���E���e��+�n��H�/���=�/��"��8����u��u�~?
'%xl���RNi�����>3}m7�l.@�hE��nm�P�)�
G���R<DS�2A!W���{J}����R���L2�`�z ,U1�p�M��!���8�-�|��`@hO�U�x��l�I4J!���K��.�"�Ye��qvm�^F������9kK};	�"K��v`�&<.Y#����` �!��`�;|p:�)�\`@�.�(]����2��)�� �!~]��q����
��!��(��3����f�,/�)p�����h����rO����-���������RXN���x>�����y���
	�8r
�v���0"�x�.� �~0��z��w�Ls\�Nhu7���C��!����x2s!;xl{g����Z���;��2��D���N�G���Ja�Bi������&l-�T����/�V+d����O�Vz^=��Y���/���FdJS�t�Mw^�q��-��h��p��_aY����h
fu��6w2||��2^%�%E�c�EZ��a�F�0��&�1���f��96�Y=�L��g�X�f�;s����`�����
S�2C{:����m*~E��z�x��A����V�N��R�W�b}�`�,V����
i������/
-�?�������^�z��l�G��J��E�W�
�P34��N'��#���	�����$[R��O/��B�Bz�R���6R�G%��\Q����j�����N�=�>�y�e���f�s}����^��P���K69�����������>"�vV	Y&��_4�h��yLbQZ6���O�2W�3!2����P��	��u9].��I;�|����j}�x[��I0����B�#��~x[�Ar����Ji4)�����ge`(��A��1����i����$�����/]�>�7#�6�t������'����n��/A]	l����Q���0z�-P������]7�CO�|[36�f���<j��t�����iw(����e���&�r���/��L���S#����LR���[�$4�����l��������J.�w/���E�	bD��"��e����'��x
��"��aTSs���o�����a] �
�{�1��A$B�EmO�������@���@���
r�?g$fK�������dj{_=T{���l��5�1[��x�V�����|�����rq�Sl���4(
�hT���H��J�f��G�E�;��+�!��y����k2�Y|z�I3@]���Vg��6�.]"U�$�RO�E�X�+��}_)tG]P�;g�9m�_���q�'(�u�HY��?3��"26Iq�{��{��0<��a2<������4Y�@�p�K���prj��-	($m���������86�a�9e!{^�8���P�����X���%�#L�N�"d��
Rp���es7���&�wR���B�$i���C$Jo�$� !��R��E�X3Z��<�IY�<�h���4�!/��G���-�>%�i�'�
�-����/��e77+�Dd��sI��aND)�OQP�&����\iY��)]��s�iD���YZp��g����l��Thg[��}3N0V�s��9p��@�9�W���yo�*��}E��W�d�`��T������I1*A�+<$?6����3�Rq![A������������8��9���Z� 5��E6�g�/���5�4O�o���������S�\��20�C�1�xZ9�"44!$��=���AT�����.��D�N�������k��\�'����>�D�aag���^�V�l��9"�+�3�~e9(��(�S�;��0
�]�H F�f����5���:Q��Qx��S)r�("[���G���6Sp��kh�2D�>`��Fv4#<T�=�=����y���tk��}X�\D���^r���qr�i
����W����o��������|>9Sk,)���;5T�������U�����f��p��g���%�J��h�K�{�����R�t�[|�S5���p
��
�5��-��lJ2e.�������H9���i����������f^�%�����3|��3��5��9Vw���(L�X�Wu�L���y�����'��9�L}~���-Q^U���V������it8��F�)��5��F���3-��J6���g$Z�XP�
i���'�KU�a��Ayg��0eg�����>[���P�Z��_u���g�\���L��&+���\� ����L�Y�Ef��lcA���H�m�I���%��s�d���HX��[>����g��#f��j6�`	���g`UuH�j~�[�~�ga��TA�����i�/��K;��Y��e��L��1?�
�*�
��?��&������J��.�o1�6�����Z���P�q�F�J����'s�s`�>���t�j��
�E78N�'Q���$]M��-49���)�ai�q�q��n���L�L�A�]n<M�q����vDu\G��p���z V��,��X��%��(m��������q���o�w�=����B����4 E���?��� x�J�7����������~���r�]��|{��������EZ����6���������r��[��R&���	[ ��
��fq�"Lt���;���z$H�XF�'���*���������\�,� *R�dnAu��@�	��O:@nJ��D��j
�}A�a��Fb���}]���+w.��S>\�����^��5?����p��n�>�w��vX��uS)v���j�C�:�A�,�6��8���u�s�h�&����*��TIg��}�����;���U�L�I%r~OTC�������'x���t�����o���=_��I|�!���pItb+�5]�ul�[���zI'<�/�����]����y1Y]���Bz�5:V[:���
r��O �_�(�.��Q�L�wn]+ e���q[���.oM\"O04I�S�PC��{J�@���B�l>��e�T�JO���s|�� �3�����M7n�FA�T<k
�m���	D��\|j�v���e@�@y��L�EK�r.�5Y���So5�V��UV���y^Y�iVCH��yr�x]w�v�"J��w���JxFbh6PV^$�!�c4�����kC0�c����->:��A%�����p�YR9�yEhe�������1�1�
�L�N�3"u�5� �;6�.-�����<����1�PK��r\T�
mb�{��(�����Q=��eAl!���9��0���W�����Qf�4;��� �z����E'�z389��C%*r)�e���*�3�(�i�n�"�%�������1���+�m4��-���
YvnM�I-Pq��v3M7e��E�����z����hM1Z4��f��\�� F������s\@��.v�o�v��v;�8;���
�?q��g�~�[ciq�p
[f+������]s�?��G��V�%�����E�m����-�CKG�����_�s�}�<j~�UZ��
,c����-g����0��a��m����R��*��P��c�n�,�
Qf,3����O�bMQNO$����l����,������s.rs���$���K�������!�A�?��D]r�%s��V#�[���#��Ad��"��, �'�F-�/1�'���6�{��+]w�� v���l�+��o}��)bv��]�}�b�W&sL�
_�Z��\lL���&�@r��r��Kr����a�U
u�4��:�=��W_x�|�<}��oq�~Qq��1��1>���rym������mi}3	�I���7WiH��w�����������_z^�;�I1�,9 /��,���g�`��a���"RW�P��NN(%�>�|���|�3N7�g�������u�:)	n��P�����������hz���H�n��N��7e���;Oj�)I����uX�4T>���l3o����@J�@]%[��zT����[���j��9Q�6�j�������\#9�v����MR��Y;�.�M�{P�[�����B�����y���t�������k������
�yH�A�������kf>{��};x�7Y��C�yv�����K��-Z<�V�}:c>�j��!F=�v���7�����4;cV�f������gb�v���,���qf�������k����V���g��N-�����r��U��j�%j�r
&vY
i
/�����F��m�bZ�xv�k�*�z�Z�������3q��tj���	��h�?����� �v�l�X�l�������v~I��l���q�J����G���dr�W���*���Z7����$���|5}t��
J���F������h����a�+'�eq~�y�w) }��C�G�v�`�U`-�u��2����BsHx2�P	����Y���c�����5��g���qK��{re��t��a_)���wT���Z���l�"]�(�b(�e'��	���a������8t��O�j��jD���F������yX�,7�
����fO�W*��<Uf������V��E����o�N��N���`K2���z�E�*�$i����K��Z�>I;c��M*�����gx��,�5����
��3�\B!�5�(���;�r A;���1��7��5�wR��&���`<�+����.�vy���B�������:��Us8Ue�x�\X����R84,��/`�����-�����@^a�vv������ny����2�!S��:T�{�: Qa��������b`�puqZ��*�;�1��~�������=�(8��3.r������	�\�����p�aJV�2�%V*t:��!S������%:�����\G������5�>Q���F=��I���`���sG����r�S��L��*H��Vf����/�T���<	x�jj~�
�O�i�;�[jii	���C���\\F�a��'�L�"�:?bQJK��-���=<�F��*�.z
���'��F!���;�����y��m�%�T���{��q�����sv�|�<��,m~�����p��)� ���z4� AFo#�go�	n�Fm�8��@�0������m���}&����������<m7.�d�s��QU2�E0�8F��E�m�xE-����k�����/_�1ZnvWz��>��u{Nh�
_52�:}wr�W
xFF����h:4�r����[F*=R��0����F��'w��I�4��6MdH�NEn�r����^��L���$	aP|
T������n��NZ(��Vvl1���vj���>�;H�.���H�'T!K~[�G�����j�
����)�5d�m��V��y}�#]Ui�Ag��
�]4�oN;������;8�2S��Iw�����*=KR!U�L�
�p*��*��N���O��r�e�L�������.l�.d���*��;�8?9�a�$B�TB�	��2"aH�P�~.a��?�/d��qz�8=�IS������G6{�)���<�.�������Akan���c(Ef��2B�����Zui�<Eal�]<?��2:
�=;��K��(��F�M��^�Q���e�v�X����C��$��F�_m���U���P�~6��Q��T!���`�7k�|�
�T[2�����3���N� �)��9J�6����jf9�0����t�%s�����B�
��!'�h�`���6I���~������jc�|��5A�9~�-
0��33Qy�RLNo�	lNs�����j�*x�*t�A|�Rx�������L��\���u��6l������x���L4�W��D
�n�YHpA����m�W�Z�2�%@Y�%�0kB����^�v����f���hh����{��d=:Yd�^����v~I�;�av��6����}���g]�+��9���9��;/��VV� ��e��d��jkz��bS���B/�9N8z8��heB.a�[{�C��S��H���e)��v������G������g	�,�� �D]�I .-�Kl�5}+D?�8�t�U�t	���R������*�.������X��o��p��.�U�%Q�2��^����Q?.}s9�����SZ�ZK�W��u]]���g���;i����~����\(
y���F~�)�}cO��T��N������z�:������#�;��0�g�a���i��w�K]��w&q����95���@��P�]`E�"�k
V6��F�Yfeol��y&Z�I��) m: �K�=��j��M�.��Q���}$����:�������3!��P�
����3�[��)��k����+�4c�LH�k�-�A���x�o�"o�qAo�x�3�a�&J)k����e��l�*8�lH� E��c7�f�;G�,�T:	�����`�����qQb�X2���o*�	��jnR�.)MG�H��I1��f/$�Q��Ig8��-�PQFy0@��-R��3ql�����V�\�&�UkNr0�P�K����^�8Zq�MY�2S���l���,� "��,��Q�:���QK�M1t�]��AX�Qx#wO'PhU�c������3��^���D�p8������G����*����t�����Sz��Y�A��%~S�P���m�������z�K/�ZP��Q���$"N�S�H|��l�����hm���O�A\����nu�+�dWKj�����?oE��Pv��v$�y�qggA�aZ|��6��K�
�������J���A����!|���J�M��9��M
�:�y�C�@���7�FE4���AMr~�8��e�S����g �U&�T1V��6����x�c����H2
���
6G���e�.1�M�A_��h���<q/����9GD�r
�.�}S����� �����jG�2�'@�����P�:nB<OV&|�d���%v�����_�F	�Z��=P\���N��<=���=?k5��N������b=�g�V����;]�Y3�N�v�/����K�x
4�Y��������U�����_�F��5:�*�J��#�K)���S�Z���|<v7��nW:�OA9�W�w�Y���[~�A���5����O�2�e��O,p���KD��N�Z��1���}(��E�|i����Y��a����Q9Z�2��.@3����4Z&{A����	W��2W'
]T'��.o��g?*d�9��D^��Q(C����a���u�)}���+	��O{H���6�����d�n�t�
"�7t�/9� ��P/���7.���-�K���q�������IZ.q=I�b�xh�z�g �J�'�9r��%��}�}�-IF��z����5U�*�4	��#z��������`2��z��<b��(�������Z@�iE[��������j�&�<�L�+[��y(om��n�d�f�`V��F���L�lS��"��JYr�Rt&��7|��ny�j���W���;�������%�[\$����.�KyQ�-��4��|!�)����0B�LnD�2!�k��Z��omB���S�'��n'�ARe�����H��S�+e�w��q���a�w�V��� �7��4[	��4,���������P������rm�Z��t��Z�5�X�.�����}
��4�.��C���Q�K�:��#w���\�B�eYA���@p���Ll�����������`��s���P���G]�����Vu;��6��}�eA�����i��V�p��J�Z(}�h��sur�����R���6s�k3vkn��#m�*�|\h�P
^x��C�����������S���~Xi�i�w� �����&�n��K�:��C^br~9k,b���2�h��p���z-PKG��������E�D��S����Y�UyV��`������3��LA�f�*��-���<��p����%�x�������l�A��
����!?��S�v����P]A��cG��j!�v�g������<^�Tv�o6!U���o�����2G��<i�*���"L�!�l����9x��|�6-��_-s�����K�{�(�0��9�tO�����hP!�9z�>3�FKN��&����ru���<��a���������q{:�o�	�_�L����	q<�����t����5e��-dhX�u���w�mPKj>��h�`X���J���L:���c���F�\��"��^��2^A�����i�v�<g���W	p��� �M��(<]vwF�����
_�I��3e���I�d��e�lH*��Q�*�'���v_|�j�[������w6� �r������ ���) ���AIa��&>����|��C�5� �^�5���� �R~���f8���-�X���I6&��y�W~|������t���7�����	�ZE���4?�E�8�oDI���FN�������hR�'���V���HG��@��v����Ixu{*����o���*u&(
@j:,��[]=���:c&��J�`��Cp��p@���0���V-3jG�qV�4�����t���"^�������v����8P��(�����,��:$��[��F�f�^2������(6B#$�*��#6��-�!})J��U���n�/��� ��kx��Z�������7��Jx�6*��I�8�6kk� �.����8�I<��<I��������\w��)o�U�Y��(u�����L�Z�o���W�3��?��^d\h1�c�A���3�DC�S`�;�<��^i����6Y�R�;co/���2H��	��L��U����w��e�s��&�1r+Y$����TOK�b�B��$oI5�\Zz#����E6����y���)k4���4[I^b������J����62{)�]?o��$-�q�c����<EZ|�d�|��������*w�Oc���.�Sk���q�!�m�]��8�����i�(G���^�E� �-%�{�>�f@������Jd�%�	���9^�+R�j(��5z��ul�5.���v��r��z	XG��O���&��a���#������^�A�f���;���E+�qQ%���(,�Q�&�
��I8���'������M�F=�*�T�RH��N�������lh��\��V���"=����1�P�>-u��#W����:�6`!����M�������e�kF����um~���G�wR�����M������6o�[��z	T+X��=4s��)���W�~�;��7e��tg���|�Q$9�s<����(H���4aw����w����9�=��R��LAXK�i�Z �����&���aY��U��6�)^a����X�L�N�"Gs��W�U��14&����d�w��j��!��[�A���������q�cd�=%dcjMl�����!�O�pX���spV����������3}MFV7����vk���?7f��6�J����e4
���t|�����IG�#o�/����C~
�j�]u�&!�Qu��0�/��N���]���s����I0����w��3���m^�\F�;�	�
��4O���kO�,v��a�;��&�����:W�"g�\�n:������
����bQ�
j��LQ��<�P�/Z���Q�/����U("�$��iD��X!���5��������Ve��^�c��i��W(PA������+�h�+�Z�OvJh����d��=+�Z��L)+}k����(��2�UC��l�[�H�:`�j�r5�/����w�C=j["��):V�����?C���������N���GR�nAc��X��*p��:X��1GU�zH��|��?�v��(�PG��J���. ������_Iv�+b\�` ����O��V����BG����M)�x,������?|�����X���Y~���B�T��\�������U��G&&��T_{hJ�i�K��w����j�XQGX���E��&�I��T<O���������T���h6���T����o�0�lf_�[���X��wS���Qq^X�QQ�gw�v��n�����&?�����-�����(��t�W�dt#��I�1Fd�,=��K��Obn����O_1��ra
��Gw��:-3��n�4X��R%�G��,��bt��e�Wfq�3>�UT�r��U>1\�E�*�_��x�z�t�������`=����j5��=�$��$�?��X�d������b��!zRQt1���(��]�2�x�,��S^G��"�2����YF���w:���Q�0T=F�P~�95��K�B�*2�U�>�2�$��W5����D�E�1���=��gAN^���l�1��>��D=�Kl��b`!*����.��G)_���N�n�=QDd�A'�*:�v�)$7A}E:S�����z���{QI}����Z���������)�-e��	��!,@����"WX��`�~��/.��"dR������[�^L��lKz��������/�T�fBd�X�����I���Q�Gz(T�A)�����j���Iz'ql��P*����{C�W��Ot��������GU��T�c��U��5���&�\��4B{�����LE��40C�n��f�0��(H,�V�Y
d��s�|~qv$��)~����<XkQ���;��4����8����$��(�2L5�]*�&(Cd8�<d���������������lB}��j���PC��/��Fe+f�V:��kwtv*����G�x���7.�����.�E�#vh�[_D�����������{����m��y���((�'M�#vx�<j��SU��q�f��c���x{~Ro7����YW�SvO�7_�r�&��)�{��M���s]�t�$45����3#����g?����'� �����=����9R:���#S�����������2�T��r��a���X
��d����q��<m�{��y�l���dj��<i�i�yL�=L�J�$�^�&92�r�B���b�
�����z7'c�	�{(�*J/�UK�S}�/>��;����]]]������3 {�ER#�������qYK�1����*G�A�����w(z�~t����:�g��bY�������l�s��sP0S�+�������3��<����d>b�Wv��|��-�.	�H��3�T��9I�4���>|����������j69�+5>��c�`c{�I��*��Oc�-c�.��,?@n���rX���Y���Q�8����!���<a�i�+��=
E�<���l�)�;`9�=�������I����\W,'o���z,��"(��u�(
_G
[D��^�ac4fQ s�'>VR�*z��X������c�r�����P��R�l5��S���l�V�����F������;|�����(N0F��GI�Z+��P�C	oIW��Y����l{@!��f��	XY|PR`0�����R`���A�7������KCN�a��5]u�
j!i�L�2������v�����A��H�r����p������<^p_�L���L�\�cZ��6��Af"�2�2%��m���"���(���X��j�� +��K	��$���1f^r�IT����<N`F2&�T���i6qyU>T6����2Sf��I�"JF��t]�(�������9��$�s4���w�a�Q<�M(ao��*������f���7d8 �1I<&&���kj��]�NM�f�ED��~�c���(
�����1�xM`��m�-��9����Zl8W�cL�W���o�#8�{��W�ST�����2QK}/�	��N����q����7��R����t0�$E��v&/	�W����	�S:����������Z)#������a���a����2��F?+i��4�+��dmfP��[@.����v�/���>��J�{m&��V��R��fr���~w�Q������[z�*Pb]�i�����A,L��C�n���K/���L�f���.c8Q���p|7VX���R&\42�(��4��������6����FZ�3	L�M�t)�`��
Q��5yv����*�9z�*>%\��p\RE�b��L��MfC�����|�
����X�V*+T��{�W��{��t7��'����]�����0�Y>�vR|��:�����UW���_�S�o�����k�j��+�k��s�%��7����t���F������]�O`-^,��-)�e\��|5���d�J���+�@J���*�C�T�\������M}�o�0l�0�h�V&V1
����@���4Ko��8s^o/�T1
'%Y&���JYdKpF���)F��o������%!���,� ��y6R),@�DRPBiB���Y"�_�����:P��`�@�=P��8�� WK_`z�1%Sb�B ��q�G���,���+i�&It��m��Aflw�woI�u���k����EY!�\��10��m�N��Az��)�q�OA���h�DMq�L?D[S&���? !�i<@I�w]�����|��a@����[J�]Q�����
�>2����?�#��z��0�B`g,�"����kK2+�<�����q�C�P��t����j�2jZD�=��Y��DC�������pg���Ot�'S�	�s���Q9�2'�I�a�L��@�f����d}��Q�
�����&.�_��w�~z�~n�C�H=�����,�0#G.�]be�,;�Z�y����&��W�cSQ�.+@$pw�e)UO�W@����7��(�b
��M�� =���4��T���8���JL5rI��LSP���#v��N|x<@6�C�\��w [*y�_S�8T�p�2�z���A�g�%����UdJ��d��$�\bE��F���U�����m�)�����W@q���=�����pF#6�;�%E��sY<h�r`4L�����R��:;�|����fw���B�)-*U�s�	�M�#��H�%��qGF.	9���P����`8�sEY�C[1�������
�Y7��8E@D1d��J��L6������'N��Y�e6�*�vAe�d2NY\�v���f!�����.v|��*�J5��7H�O������M:�����f���n��m��\q���J����:)Lp����Z�7��;�eR��
'l�p�y�&a�U�i��g3gI�.#1io5d�bY+��_��-B���Q�Z����v�5��2���]8�%�=#N5m��w�5��|��%�'�	Eh,�y!o=��Lx#R��y0����S���q��Q�c��pGC�:nD�8�&��V6J��z��[
hoOB^|������q�j�u3t�	b@2�l�t���C�����gLH
_�\�9��?D���2�P��7��������'�G�<�qup�a�/��9���[������������1�X��/z�PT�"x,U���
�����/�*9aI�|�$E�
��:�G�p������L@�������6��y�����jY:�����U��^�1��tS�t����N�
��A�S^������|vC��8l�l��b;xN�����G�w���f@_���d���Kl4��B?UV�#�$;�Y�.[P`5�#��q�/�z5;J30*�	
�i��L�!�����p/D��4Q�o:�5O�?u.VW]��k����:gZ�����!��C�4N��x���1��2-�$�/�_�V�c#;j� {E�����+[
����1��A�����&=(%�Tg�����/��t�8���H{GL��d9��Q����'����E��8��kF���W��2����fm:�ea!7@[��^I��(�H�����>�+��3�R�g�������V���t�(�c{�1z�V�����fz?jw+�6��!���������r[������F�YMi���Ld`b���b����(��5��0������^yV���\��^�������i�����>x�5Ef
	N h�B�H�=9|�M����(��=�t������������!ir5���t"��ek����U��Y�H��i��KI*�<0bW�:���[���!��S�F��K��r,jEWm��9�9i����
a����XDG��n���l^i�s�n8����{t��:X��N���1�����x���X�4E�!�����{+�9U�%=�
�@�i�'�pkh���X�\�V�!
F�`���+��a��#�-��3*C��d�f)����K��A���|�d?�b�jn��AM���A�������	RE����]�Y�.�@�����%WL�
����1f�AZH|R1dPx"?&]�MN@��\V8T�~���X����\I����yE�I������&��m�5F�^�oj�P�])���,��e�����&%�4�s��T�X�!��L6��mD��vDh
��4k��{6|p��l�,����I�b:Q�A��]o�u�j��o���\W~����@�b���R��J o�\�"/�s��Sn��e��E�+�M����G������#i�Q��X�X�zu�C��[��~��F������=*->n����N�-I�w)
�Q��O�)bP����@�B�<�L.�^��:{���+eV#E^t��fql��*��
��>���
�|XS����"�[�}�-;�V.>�Km�0�l�8����SI�f��;$wZ�������
P��T�/X���6�&�{k�������-��rU^��!5���o%&F���v������5���SPd~'^>�c�[�<���h�O�)��J5���������!�7H��4P��6�������U��o�!����J5�-��C]Z�������P�������n�@�����;�<6\���&Hz_�K�����k���h�ZW���E�=�E/���:X� �c���LaZ�������V�p�O-^p>��FO���������nD}�>��r;����	��a-����U�.�z�����5�]�|#����hG��u�E�O���R��DVX���P.��| �=��(��3���w�Q��<��^��n��1���m�~c��}�s�J�Z�-"�����$�k�}&��+������@F���y_�
�H�����O�S�~��K�����4rW]06AQ�i���������~4���{��Y�:�����7	�0��$�����EL����,�&8��;S��_�����0����<�"���(oC�Z�
3���+��z�zv��O:��>����%]��w<Y����mY�;p�_r�!�a1�,6�"PIh�S!_��w����l��L(#&A'2��&VvA�h�d�j,)ZzH��#:��>%;��3_g��������;?Ag�FVw�q#��:P�Y^VQ�\��J,��3sE��CVZI�/�Y1G�d��i���	Q��R���I��
"������!�x�6�~��
�8���3�!yJ�A2��D��*;��;sc8�������$���Ze;|	h�x��VqZ����������K��cI���X������K�x�}�
�^�}uoEp���T����)�S������n���xT<��]��B�g���f�{�+}<=��Z�q\o��a���y�F���W�_�����A�������-���sB�}b�K���U1 ��l�{�F�0�O_���aZ�d����3�~:m����b�;\��2��kx����0��Z1\��f1�V!7Mf	�������5�r����u���_t������-��3,�����DN�F�# ��r��7��%��e�l5�@�m�E�1��;�
A gS:�e3��%�Wn�o��U��S���T5t*�������R�����r�n���J
�e���
{�	��G��\��]��y�!"�[s�*�g-3�X}3@�]i��J������Z3��2m����
W���K�����[��lT�t��$���Jz�XW�r�9�a��='��/�;
�t�������Wxq�m9�z�w�^��������=3W`���,k����~���n9]�Z�v5��&z��Y�oU����kO�L���U|V�7x���s��14���i*v0���b����'�|��V��3TP�X�M�����T��V=��ul�<�	��K-��&���-�3�VA�����2��-���JUH���/3ID�7G����d1����;<��l��
r$	X�/�pE�z�@�SN#4�	��SRw���pV����Gj��%�G�F����!p�2����J[�!�Ka�m���N�(���#�y�vK-�W�
J�Z^���e�E�Wi��*q�(�%,�4%��:�l�8bnw�!��%Z����o9
�Y���J�>�XG�����]��>`f����+n��������cw����S��S�T_`����s���w:� ����v���<HK
����#="B�:}�b`�p&�(2;e�\�|�6��u[0�zy��$(�Q��h�V�LZ��[^z{;g��XK�E��T��P�������q���i�Rte������r�h�*/�R��O���������z�8����5���]�����	��u^#4����b&t,�y��fG���L�Al�+�?;>�K�Xn��*��1�N3?���]!l�Osm�Q���xq�&,���������e�y��1��
�:N���aj��Q9�J�G����������,v��i��v�O1�� 7�*�Z����A��X
��^I�f *���B.�r��$�����;JG��B�E
�"#^lU��]��A��pr���K��}\�����Q�]�^�	T�b���*Zt�k��KK�����JxX���������i����)���ugV���b��;��Q��y3����%����bu���k�����h3�?��<�,:�,����S�Nwv���G�)�#6R��Y���t��H_BG�9�i_�$�����_p"o/lfQ7�B��j��j����vN
X��XQJ�q�
C�;�X��@R�&�h�<w3f��>���C���TbSv�TyF����t;�P@���:��i��.�_��0<�����?&gG(uP�+q�{M�/��	|���L�R�R [�wTP�I�P
�j,Ud,��:�D����z�����i�c����wOK.��0g����tT]��5?z5H��_]��".ZS.��TN}������p�#�v�=�T�D�>�yk6e]�D[�c@�E��m�����h��C3�n�!�A��^�s9�e�!B���^ ��$3���$��)iE?{���U1��K�Z���a�1�&����k
L5��jC��8~?�d�V�8'�^w���k�(e���p���jG�������B�[��U�������+r�uj��=�m�l�����E��i�=
����8��W+��*����������.xVSN���N���w���%DlYa�sE��Y~�m�`�a�akD������3Y�If`�J��R��c�w�.����&��>y|�����j�����fujNW:��l0%�����E�0��U�gZ��Pq���[�<r���i��G�;�����KX���iq���8����c��8������s�TH�e����DMg�D<476�(k��gK~�d�;��,ia?rH�:���Tr����Ey������y;w�YF~A�[��f����>�{&��i�@O�|�����N-H�2IP����Y���������c��.k���!��-o�j���������X�o�-^Qq&5 V3�33���I�K�pM�X��]h���k�~�$�]o�
�2��k7T���n�W5���U��v����~u{:^�y��sZ�h�]��*�[���:T��`\�>n����,��!���w�Nq���{�_�R��}z�����Vi9�aS���9��,��9�pz�1)����7�?����|S�+M���
1��G���()��5 FL5S5�
`)��/H
���2e]��z���2���p��*����A8q���-�,�g)��"��(���1��qX���s����X/v��|$dt`%��}av��8���&�
5�n��lTD�~<�*��	�i&(����_��{��{�wsv�8����|����Z�A�I~��������')�0�t)�g����_:���aE�����y����++�'���v��\�U?�s)�����Y���UVm�<E�@��d�S#cmb�E-jt!o�)���d��2�ZtI�F�S�����$�RnaX�\(o7����$��2*�\k*�L��o�K;�#�]���k��(�����ky|I�$`����h�9f@���(���C(U���~xC���E�7q�=H�F��� ���Z�����T���g���O��n:	%A�G-��T�������T^�u8-"�v,�G �_
��a��VV�����7%{+���!=�!=�������(���
��x��>6�qz�i
f_�"��]D��d�BQ��"����jUd�9���p0���n�=E8����?��+��s�`��bFn�o����I���>��l�s�j+aBG��d���
q��lZ��@�#�S�|� ��kX40��}�M����-e.Sx�vr��g���C�����k;3~(f�N�����a6uEO-cT��o5H�
��kJ<��xt�<�$N�5����'qo��wr����b#+e��R�4���
���)��z�2��`��F���7���N�0f�~���$�z���Y$Vp�����r*�NcG|1A�d_u�N��.�}w@���w�����NJs,0����w��w#!�\�l�\�W����X��e�B��&���jN�DY�8yx�z�P�#@�^W��o��� Y4����y�>D���;���Rn�,�j�0��q24�TD=��L��GM���#��B�^f��)�������	:�&$�x�o��5Z�o�^��>��I��b����IxE/uk��g��AP��H�����zZ�������=��	���jP�2x��Ti��� �WA�0�A��?K�8!��Y��hBJG������v_�\OV�LX��i*�8�=����y�K�8��4,�]�>kov�Z���;}�����D�v������{}�i��[���v���~Rd/`�,h���~6�L��>��f�0BK�����M4��sCZ�Y��eA�Y��
����.4�l�d�$3M�b�����I�M{vDJ��od�5 )�Hw����p[�����3��&�2J�������b*x�|��)Q��h���j��z��G=FE��v�2��1��[��
Se���C�D�5�R���������E� �^�#=��������v���#>�4S�(��5x@��_��S��"�������V�����AX){�4�M���z<H��*��{_f^��>�F�w���RTk���EV������j����WPIV������)�Za�!�a���p���
n��j�z������r��-��o��`�_�!,�;����������Un��Kg���-�����V�
R/�jv��;�8��>�v�Xp�*��=�����"�}r��g%�u�tiE�i��P�t��g=�=~�����Q�N�tc6C��R�B���B�F{�k76}Psc5!�&*������������F�:���i�qcYF'��Fh��	�X�A���]42m�x#']�HoSL��!
o�DdJfLM�B�A7d��^���L9)-��-]��Z���s\���#��d�-z���{��t��CA�!�j�I�}��h�h�M�i� W�(��4[����V��~rR����R~9z]�����2xx��K�xYNLc����@ap�w�t�--��LwP�J���u;.�f���&Q��'���cCK�������v8���Ai����/P�@)�$�(���Y������L��h�����Y�r99�:�wnvkF��G�f�J����-k<rF�,���d@�������07�Yx����!����d���'M1��!e'
&���k�,���h�K}��<��8�iV@�*:���y	�sU�A�J�z)��S�LL�_���D�r��.b�[�\�0�\�D�pb+�LZ9���GAH+@����4��%��%i��"h�F�������=1X��$+m�P��@��I���o�akn��L���$p�C��LX�������W�����SX�#�xcJ�D;V�y���L�	�����p8���r��*�(��P���1��Zg������V:�j>A�5������e��N*;a��pFw�g�V���!`�"q�$r�aw,�C���0.�����jsFP�;oP��0������l�A&���#����d����������^�l��.���1iN-	�����S]�Sfd����jA���tM�w9*Y9G�L2L�6�/�6��3��|�
P�oE���i�2�jB���U%4Z[cUL&Q�'�����q���[v���
���a���������S`�T��c<�#�� ���9���
���>>;m��}�p��m{�	
���PT�W�5d�q�8js.���lR+OpL������[��K�YZ���mv��q]��J��=�w{n.���/mJx� s]���F(s����~OO"�~�DF��
	�7G'�V�ab��I�ih�aR!�#���m���"�$�<?���j�,c��y-fP5���Vq7\N��.^�h���uV2�,$tk����������/I��.���7��VR���`��uQ]Lv�L�Kf���1j����k��F%4]
��Q'������[�^X�k%� �F�����s�GX@��+�l{���HpQ	�0'��b�l4f�Y?'��F�c��;���m���d���u��s+��z���:U��V�����e5��=�{g���Fg3bnem����X���jW�Qxc��X���U�����Q:����)�%��W �r�x������g������*7���K��� @fzd����fd~6�	i�m5�OdS �=���P;asb�;T':������_0d�1w����_������Q������;�w��g���g�t���'s[;��C�����a�S&�e�����-E���M�QfU��c�(������xi*����m�oC��	/���mA�Z��������8�� ������D�����3R�nm��?(U;)w��&~�Do�LF+,&n��y�E�h,�EO���I����
�R���
��eD�����"Y�N�Eaw8�)FV3��~�A�4�H �cf;o�"����J�p�I{WO]��0�.�G��F@��w�����z�%���=����(l��b�-3}"?�5�~ur��DJ����0��|>;e�m�R!�Q.����^�R�z��������9���<q��f3,����E��&�
�RaU����n`���j���J�Oh�y�H������U������h��'!����i/��I4H7�m�
��e�k8|�/�jk�[=L�������s������vu��,5:�y����c��$���u������n��k�j�hn��}3��=;K�w#3������uZ��Hk�[�8*�oL�Y��/F�v�z'�����wp�0�"�y�u�!����}v3`��o�7�����,�[���jyos���-��T�<�.���~y���w�s;�`���;X�����)\�����U��	�9��u��"��7�N����'��qB8U���d5���{�S:�_~�jw�&����d����`o�|��i/�;���"M�rO��x��_>880;t=�e�E�
��mzMxz�n�g�f:��i���5Ac����J���Y���H�}8���>����w�at��%�v������<W�'��'V��S���!��R�f���L�F?$��7g�` x������	����[��L~9��Q�NJ�cv��:{5�D~�I�����O�*���?���.���(��v�*Z�}����}�0:��v�OtLe��(
�����B����w,�j�qwIJZWO,�I�R�����=�.?�����C�����V��O��,�������7M�9�2�ZC���i�Y�X.�AA"���&�u�����m(��c��;=�*W�[f���.v(�^�~tR���H�;���qQ������q�����^Cv��������Mt_�hn������S��]��.C�/���J�.��pi��K2��p����]
�u�!�?����.���.0�,y������2:�4�Q1,0�G�*��tQ�:(������G�8J[�������Z)B���7��q����L�8I�	�K���;�����xl�C6L��S��T�L�f*��j�F�U�	�e��	e����*�����rqP��"�G��3�*c�UUV[�j���=��N���Rr�������3�����Mq��Z�����.�v#������x�,�����m'����Z|�~����`{�����$�VkF[|��-�VV=�JR(�A���`S/���g��et_�������}H��F��c����^�z����)��,�1]q��+��^��vy���8�����������<(oU�m�l�:F�[ig��:}��}�J,�B�X1I����n��Y��U5������^�"��`T������u
�*����W�X��t������p�,����V��hXq�x_R8B�r:Q`'�j{�����;t�z��+��]^��@+Z��fm��l\���S>�� >�6����]�^�:�����Hf�1h�LN��f��iN<��9i2��/E!|�bQ��������VMF�"almQaL�������1�5��g���/�6����Z6�dUa
e��3f�24�y��8��v���L��w���+Y���^Dj�F�(q���$����W���w����Qk�]g�2��N��`��[�}��������qX�����k����~=;]�<��h���=����!��������@h�M������<���kgJ�ED��Wf��-o��;��+��u���glml{g��;3kc���l��l��6�<;1��p%�����}a����]��Je���hv�{�q����?���Q���5��R^Ys��]�������q����������*�N)@�\;8Y'�>�W��I$�b�m�v
'�����_��3�j�` ��/����,�r���O��b>t���_s��m�c���?�c������a�x�e����['P%,n0����-�S$�v�cF�Vn�j��Yo�h��(�h����d=������+���7s��])�ISr�(��qaT������Ms����
�����=_.gO,~�N~������p�w��-���R5����3U�T�-y�9�Z�V�S����Nu
�� U��������t��Av)8Tr���\�E)O	8��p�}=��`�
�\�Q���a�>D�|���w=;����<���9�I�-���c�3�Y��T��g�:NRT����A4
��[{��_�=,E
�!�B��b�����y����uKt'[�W��!m~"�^uzW�~����/Z��[���79���-�t
�������B9�=������#Z��LRGt����HEA�u��-F�@��=C
L������>��F���������������#X��2%�I���]����C@�2����U7�{[��%"��5!�E�t��������y���j��
��_3��S�PWf,���$�g���y���k��/��)�h5�G���]v/����	�L����,�ul����?���@����7�b.���"&��>0���CN�b���Tk�;�j���~��51�u�t�D������x{~Ros�To?��Ts�GL����
3J��'�Q
����,���x��oI!G��]M��,���m���l ���6�����&A����C��RVJEo��Yh�"��8��c� ��t�w����R|���,�@gPGd��8�	D�,�_R��R|f�0[�������n�X��PgQ�N^v�����-����4����t$��~tstv���&���{���G[�T��g��,V������$�]��{�|�����N�����"JbS�{����S���o���\���,�J8l�+X�.�������p(�H�����n��b`�J���N`��Gb�.ys=���b2�TC�'�N6�:������g�|�a"�&+b�f��1D���m��v���>F��!��gR�!��%��kB�zg���O�
���3po���E*C?����7��eiA�F���}y���%�$�0&�-�L�4�k|Q
��*����0W��^���)�P��F�|o��Z�u��k�?(������}�T�1��n����k_��|�;�pl��}��!OV>j��bk�c����{�
� ��U� ���'�[e�]m���y��$p�1*^c�����AWk\�e'8'8�	��]����������SCs������~8lt�r]z�4�����x�/@��lDW���$�� �����N��K���'8��j���?2�A
��A-+�N�(S��RS�����h�.[��S&*�q���4��T%���M�Q�ov�<5_Mv��-_M�8�|�=nug��v�,�7�I�J�g��)'���o]W����cK��2"47��G�����@��r�#9E�CO9
�����:��E��M�u�qr����XD�O)��)�U�]0=k�#�Y'��`��W%Oag������J�i����I�B�&Vdt�������Q���p���~�������}[�Wa�`���}�?%�y�mV�(�������jy��iE�����;H��L�`��O�u���Zg���%����H��z����
e7����5������G<O������@!<����RD�B4H�G��BZ�m�����U�,X��x�������Q��$�'��s������t�}~iH�����Ec�.�����'�R,g��(	�G���)TDf�M������W8[c^�$f��,&O��}��8�GR&�&�Tl��6��;y�d���F����qh��a$��e���I��iVdG<�<[C�lx8���
T6��`X��!�}A��rU��	�	+���L�#�p��s9��H��&a�M�G�q��`:��'��h^������:]�sY�Co��t����q2	�����g������`I#I[�D���n=����Q������!T���I����n��r��G5t�����h����")�*�
����.^XM���E
��1���^�`8/���_�j����
�7�~����	74�w)��;����8Qh�B�qJH�R�q���D��~�������@�}sZ� E���}��B�E��71�!�����o�<��>�+�G�_C�����q<P��:�t�uo��7��Ojh�9���'=G\��[9���n����i<���v�4�~����U��M��������_����������dD��tm�mO1���@��^���Y���Z�V�,<��m@��(��o2�5�4�c�3�����"���l����[��u�V�:����D���H�MA;2�Q����;�;,���G�2W���Vr�~y���
���I����s.����m~����d��f5��s�tT�8�����Q[���G��R�����<��d���sy���}/'��h����Gg� �������c�tL/���?��9�[8j��q�����cz�&~j5�g��w����?�'0����I���~���y]��@�.^7�0:���O�qP�>;99��y}v������|s�PP[���mp����T�u�Z����L���N ��+O�^���jyw_K�p`��X��|��H�WV@p��#�V7���,���'F�UlN�<�����2`Z�9���[��Vss�����[�\-f
�9\��TCc�<��+���GEsrX���c�;��ME���O`���km&���1���o�����q���|���2�#_�g���f�{�+}<=��Z�������
N]�?����*�_����k��n�C�QU�~=���}��<�����&�\�8����we���[��}R>ci���-��T����/��X�.fx����nI�a�.���gp�Y�0�d`�+��Z���C�=��\4����7��]��O�'�b�`�K9X���s� ��+�7�G)-S��^0	��HX�������x�X��0�Q������J93$�(N��o�L_2��_�<��mfzj�%�����|Xo������hw����w'�;��Fo�����T����T[0��~�����o�.x����w6�|��[	��OC'%������4�tE��}�����QCs!������~�����#��K�	6_#7��e�d�?�?������5��w�tH|j,����7!���yXk����o'gGd�.V6���zco��+��y\��{�oa�����%!��������/�X�Ze"�F
��� ��K�H��yz���m5.�G��m���O����f�G�/nP&�8;��qA(�/qR?}���Kb�z$
H�.���w���tD'�D�E�����[lE�=����/qq����]�1�x�$�+*�����p��������
����U9u��i���= n����?84&����|�E��2\�l�m;#��Y]�K���7�d��"��~��W���*�������\������Z�����oT��<_���{���=���M���TT������cM$^��J/<4~���f�S�[
�o���r��f�1o�,c�;4��A7W0w�g�����:��=g��Q!�I�����9	�p����B3��|����**���(� ,RK^����a�lF��qQ�t'�Ux�@s"����*���Z�w�����{�Q�v���������L��O���X�a������l����q��S�F�J��"�cT=�Y��%o��4I�hnE���u����,v~@�NB���,#���U�����'~���e4	�*p�N�7N�DM����E�u���n<����&����)�����[��W���<e^��n�����
�a�������Kf����pP�2��d��������i7M�0����V����e~�/����F�b��[���Y��V���+}����pd�\��3t���v�����&�E�����l������
����4 �cgg���k.����C�X��o�,@�v��V�;{��:{���bf��7%�=��0��5p\���y^�����a1s���Hf�\�]�����O���,�s����~��\*��wG���	������G;�*����&TrREM�+�u�1/�k���4��|���m����{.�g��,9�T����m��	�{��`_��0%o����V��1?���5�o���h��P���Nj�a����z�#Rosc���[0��VM���p"�u_�������]�j;6������M��`v|r?��4sw|���b�8gNy��#F���U8�G�4�+���-W����m��wD��$���3�*���^�mV7��*	[?o�%j�q%�1j��Z�����:N^��8� ����J|;�"����i�����x�J/|�^"G��I���M4��'�]��>
zhQV�'��.�������G&8���P�Z����-�����+6.X8�*���8��H�X������1,�0@Cd�.}^���Rh������/�B=���C�P�<�Rt8�a���1����'�r�s���9��x7/Hzz�1���!������N>��v�H'"�h��,p�H�����o�#�R�	X����<�����=as����@~�S�F�_�/��k��#w��(���6�#��'ZXopi8���x�{�@�TW%���S���C
��A��]^��X���Rp�O���c�n��I�������r�S�x�bG�gb	���P#��f��i��`5��������h��������N�����w�Tu�^�N��3�i0��5.�w���O���0���5@�^7Oz�n-5z��bg��q���yiu�C�gA��e���6O[�^o���E���M�d*-�T�#�2���&']���o�[/ga�Y�U{&���u=_����e�wMT�w.V),���dgL�>��5+���PW%�J\��h0���� �z3��*aCW@�?����V���rk�"�e�� �D?I<�f1d=�K�Pj5�4N�W�P�8D���C��v�CL8����7g�z� &JV� #��s#��0Y+��F�[y0����&��_�qD��~�Rl��9�:� %|(���6Wg����������;-���T��cs������U�xP2��T�'��U�L�`���O=1�U��u������p���
������N:H�hb�����4	���-*bc`4�m�"�;���{�������]��8�������C��J���F��7�.~�_||���~���g~��4�;������^���������M�t��)G8�c1��,\���<*��G�����|��=�
VC�+K�W�%�x��Z�����}<�SK�q���:(Ur_k��u�	�bxM�Bh����M/���C���b�nwmu��>525��MRG��5�G�=R6k�/���h��1/���R	��RX�f��*�%J�
J��jYTI��Z���.js41z�����������������S�>``��@������K842�f�����
�:X��V��6��*���$4���1|��L��s�h��8U4� ����dk���3R�a�*h�����V3���vw�E��	����m�,��e���JfD���Fc&�(���lsY����G�]�	P�$d�z�a����C[�K�E*�
=�t�}���s����g��1�.�CV>'���F��
�v�#��VI=��C�t��K���~���U���M���R��l^E\����A��rc�I-��Z4��/&����uxv7��\Z[K~��1�@��*�RV
�z�O�����|��/w�d��Bx��k.rk>���.��-��u�*�� ��W��Q���2�$�{m�/)&<�,�w?�u��w>o����>O#J�Hs�l�)���b<N`Ad&O�-
��y�1�(�����y��Cy��g�C}���o�A����0��II�&%��{?�m8���#����&��6�Q�;���j�W��.���!���c�$Z��7#�"3�K���D[*��J]����{�����]���:�	������V��Z���><^�������4���o�r��.^+�r|v�P���oHG�N-�7�^��R��o�cV[�6}R��&& z^S%:P�#��_�`����7&���t�C�������X����%S�7��
����i��q"����d�����kg8?�#A�Pc%hxu�{g&�V�?��W;�HI�!�=��K�n�.��5��QO1�G��b�����{M��h��"�U�G$���_.H��V�j�������F��o���N�@Z���l��Z4�4�Y|����������q�.���������@�	�l���6����$��k��l�u�&�2�	xz�%Ia-����=�(�� �E���9�w��I����TrN�`�2`��5za%hi�qoIW�N�1-�W�!�V
@�{�T�
�Y��0KE���[w��;�\������8�`h���P�E����������_����+�\����S��(o�\x��Q�^;f�)�/�w�+����@����J��qJ��S���X�t;���y'�D?����t9
��������V-�YL���#�^��\�/��z���I[�H���4Jx����W�f8@1JDe�9crU{��9]<zJb�s-��z���`�S����wB�0��
C���IO���5k�
�wk�y�y��(�\F��t�|,��fm������D�.��{���AqhZ�*�N��'��_h���D'.HD
�E�V�Cj���,PY�F�(U�39�6����$�'�I#��<x����f�_E���t��CI����Q���;2w���T�t�@�du������.��A*��2P<��%�!�����)N�!I-tr�Qc�i
���(�WJ�f��B��p�����n�4�����qi���nJ6� ��<�%s �'�S�~qQ�	��AP�.��2/2�CcU����)�Ty#��^�`-!�0}IB� ��dn[<�)�)�4R������l����@h���-0F_k������p���������`S��w�Ib;��bHX���S�\��]h�[��S��=�sQ
3�mA���q[0��Z������Z����f�����]�1�$�[��Ix~�������E��j�b�K`��<k���`wS%�5�(�5�73I2�v{���#�n	(4Jn��w�lX��?�8�0%��/!���������&^I�q���8�l�q�����R�7�T�2Sg��wo}-��CS�s���qR��$�E:�!E*,AS��I�-�V���	�q�z��B��P/���L��*����8��h�A�odI>���a9�r�5i2S�!�e4^�����K@��EyN�����[�(�� ���+��B�YJg��asbB��W���"X��C���p�k/EM����y����+��	8?G��ObMT�c4��QE1��("��:8y����8$���6bG����@��%�	��j�(Q)$���N6��?� ��r�n��m�D����(
IneF���e'�K�4���VqI���n���r��F0�\������p�3�7p��@Ec9�e{{��)����;��;Z&�j��}h�$�h�O#f��4��� �0
V�9���b!k�@���w���5N��
������vv<�z�
�S�Ot� �]�����x�N#�kM��e�A�p���I����Q��Ah1Ql���L1oX��%��\�#_���	~���W��~�xdo\M���e4(��r~��Z��)CI�v^'��z3���!!o��M2������Q���0KB
�
A��p6`z�j�V����AQJ:2V�]��a����isIK@��(Z����Hc<�1�+�Y[�
�P7��~��q�ry:�T�@7�y7DiG�F��0��+u�<��~����x�9�6�����^�����y�8������7Z��C�\�����n*3���h���k3�UuM��t�r�`4S��C'���Y�-\"�K�ywD��Ni�)|,����ZqG2v _�6&�
�����>���ot@q�I�e�� b���hS��D�H (�lL����p����5L+��.����R
������I�:#���3�fK�#"2R������e���"����������@��~�c �92K�D�
I�0�=��G�B8����hh�H@U�<q?�N�VD?�[*�%�;-�g��UNU���������'t�LB�������	�f��lW���~G�i��6�?�&�;w9]8F8�7�GV�j���$�,�N5���M����T���rX����=�`y������d�B
j��q�2���mZ�7��;�dLJ��Q��G"���R�+e���	7��7�Y3}�Mr��a��}.�0�s���������'�3�LV`v�y��M1�#.a �Y�5�b��V�B����_�?�)������"��q�r����	�&���������r��u4)���`�g��!�&��LJ�������gM��B/��^u�1��]��m�2�xp;i:�8)�������.�W���bh�A��xJ���!�(}g^�>��L��hZT�Aw�Lc������e
��j"��cG\	��>� ]�����%�1Q?
�N�jr������6g�m���pb�!��.|t�i:�����f���&�Z�����~�6~@�L���7Iu `�"����4f�<o*����&�K�T�j[�<�V���(�#����Q^�$%e������0��?��6&n6y��N���;�b��_�K��US���a1�r�S/���)�8�=f�H8�%��TPj�������]�%A�LYM�����������d��Tp��r��H�4)�gQ,����r�&����}g����>��H��3�s~:t�GY��1���r�,����,����go;gd���G !��Fq<.-���	�s4�e%���e�� ��?��9i������;������Y����
m�:%*����:��n�vPs�S~[
�q��0&t�B��������a�zw�:q�~:��]
��=��M���F��f)�`(&���� �x���>������Y��9���Jq�Sa��f����^k��:�C���Q�x���R+�1���v�q��&�����pV������zQ2�=d	����T����X0��\"w|'�EAL���A��US���������D29���H��K�!*�d��U�.��y!
��~���w��J3���=�1rCb��{RY�nP=���>��?��T#�0D�^�)��3�������tR�Q��!�W@��<����9�0�o��}y+j;�%X����j���}���pCl��;g#������LOt_�����k��<-���D�i��A����A����t8��-g86���q�X���/s������g,?d����L�������`��7�I���5[R�&��v�������Y��E
TRRyn��d���i5����f�����G�"�g��u���W���G&��E�j��l�>�Pj��}-	�j7���5I�l*��tKR�G�M�P��=�U�Rdy�_b�K�11)G5{k��(�����(��|������0����(�rN�D|F<���~M�/h�Yn�Nq���xt�u[�9���~%\L����g(Hp�$�D��(a�gD--��ibE4�P���T��� �{6�S�#^��%y��c���d���GR*k<���Y�D��|�?���`�������Z�4�.���������o����~?�F��O`��9���G�`�Fy���v8���������=���m��i�34��oW2������O�����-��b: ��k!4���9=���v������2���#-��C-���u����M��&�J�l�'�
��x�i��9��E��]&T��E���}�6E����Y��/�a�d��C!���G�������R��E��[��>����,��>����8�T�z�3��'���	��Mp��d��������hBa���h�2��d����M2L���.}�!�7��i���y��]5]����m<c0~��L��Q�ss��w}2`�������>{203]N�K�S<��]���[]]�o��v�	s�Xr]H3�
����x+��h�G#�v�����X�&�&�=u��G..6��
]��tp#�#�2
��KN�.G@�]��[��m�E�����E�$�4�� ���>���������k��
F.�d&u��L�����7a2�j�J�3%��I"���CI�>����f��p|��
-����nYiL��b1�F�%nei�D�1J	i�8;E�a���
�;�c�#tz9	��\��"�e�k/������)I�����j������7xe�X]��R�q�A���^'K�z����'����E��@����j����6��4�R3K�J.�jK�b��l�gdz��V`��tw4 �NAvn���MU�D���2G	��e������e?E�k�
��	���zK��)�o�%��/��>i��!	S�
y29��~�2M�m##�JQo:.Y��T��*�>/y�RV�4�T��s����OL.���
�&z��TxN�AsM"X��g�v�4���$�t���4��<���Mz�pP�9P{=J��e�fi������yRlG=�������I�JE1�t'�B���CY�#�d����<m{8����yc��������6�e�%o�l�V��x�������v�;3:��aogw`g#��M�O��[Y����Oc>�mMZ�K��CE&T�g��Mwv`�����>Z��Wck����gLK������`$-A����q+=��>b}r�9�~�~�3���4�a��	��2��C�Wt3�aj�����l�����| �
����!��3Nej�+C6��pV���#� O�0A#����Oz�RP�*�x ��dS��J�'+.���h%h�-s���_��ra'�l�P
����P��
�����Cm#V���m2��W��`���N<�����D�[8,#��o�9F�Z�6�x�H��3d��:����p��/z.E���|���]p�D����??G�����:�w�G��]r�f���R�|��bd���i�EG���UiN����Vbc}����Yl
�T��[I�jTt�
�inj?���(�<�|����"��B����\����lvl!�L����N����:��#��p]��9�N�c�u��c��^{�����V�~`���s�Q{���J���ECt��K�C�Yi_k=(�bs�����
e�v��$����g�Lz>I���]%�&��>\�Uo�
J�7��+z�<lpu��7G��y4���>hl������Dv����>�^�nt?�����u��p����C������~}��_��������_j�w�ZC����s
��sF�a����'iA��j�\�����v�Z3���#3����C1�.�TF����t8d�eu�S%�e�,c21��
'�o�8�VobVo)�Sv��Hjz2���W	��)���]i��
�������D
O+���� -�Q��u.�3d$�$A�������e�al�N6L~"��&9u='�����:+S���6H���=��=g����m�}�������J��X:���jx��W1�F����������kNn+~��������v���}e������$�Q��N(�L��=�{���;�f�;71�`�D����`�\�6���^�l?V�*��wf�����)��t�LI���-�e�G�Z��R�6�vk����Q��������8[���E#�J� 
<q)��uUQz��7RzZ#�h�d:N�QJ�l�c������M{�68����0��k���LF��>��r;O�U�z3;�j��J)�n�[�� 2��J�!?��7?��nnZl�_m���}�+6	��0t��,���8(&?�T�v��x���y9�4$�F�+�s�e����y�24�'�wH>����(t�0��#29S��8�����-k�^�K�G�Y�a�t/6�I8���'�Xaj�[���Q[|�(�)�g��l��X���o
��7[���"��N��������s�<�X�*C�����U�Q��8��*�*I��^���Y���#a8V^����N|]��b��B���vl������H\%
{ �R��@���4���?����S�c.�N���	�9�����u���k 	S+�"�qX���7����bVp^M2��>D��z%9*�$�bv	�"�R��]Rb���|i�gR�)n�����0_\�1���q��&A� �W��@�ls���3��v�-X��U,P�>�iG	��xh��WD��+hl~;VuR�!������4X���u�=�5��Y�9M���V�u�������g�!�B��������,�����&�m��jt�V����W�xV�������s���[��v��������������%�(���o�����=q�sOv=+>��qg;�%��g��(�5���(LVE�%�x�/5��B�pz8&��@#��2���K�-BZb�=R��b�wj�rmgo���{2�U�
�z�xA��x�c��IIL�o��D_����D��QS<���`t����Lb&���WW@Z�&�x�8�~�V������7�>�z���
Q5��B�J���A����5%pP��l(��p���JA~D�����j�R����B5@&g�c���=`S5��Y�]D�n���)�*�O~-��hU�&r�����-�������s>>i+����?�~%�����#��N1!:��OG�pQ���52���+���2��$��a���WV�+�Y�\G��G��n��R?6��������V���9�"�3�2j�>eA�*�����g��W,m����9u! 8Z���T|w���''���+4�qE���e���e��s��$
(��]�Cv��Y������#E�)��
�J�)yC),)���3�d���������������#���D/�g���
D��7g���w?Y�g�_��y�F���g���7��$�qE-��������	lp��i
p^`�Bd�~t��u���,��9+��������B���S~_�0��G=8��g�������.�W��1�6jc������U���!_%@���'K�[>s��+�������f�_F�e�4�����(�����1�ed�  [��f]
|������|��Mh�-���L�� >����IhgwGKB(�!��Y��
t�!����`��(�Q�����7R��%�-ruS���,��-i��	0	������p!���
����L=�xB]�n��L�J{<Nb��@xNG��Rz��Ar���v+�*������������l�p���A�JZb�c`7J���6����"�~��������j��"o�U(��onmnZ^Ow=M`���0����)�V|EH��A���X�{�Y9u�\-~bR��[�~���9\��������/^ ������$L2S���A���p��VF�2EP����n��e4
�e��H,����{8H5C��/3C�5��;�#��|����qG��xE��y|W:+$-�iS�~z�.�Z��1o[5jb�'a~���*}�@�R����6��;i�n��W'#p�C������������Z)�}���`Q7;9f�_4[t��|�U<��%���"�+��P"��7��l�|J��@��������;(mo�����E����cfl!�~^D���<JMm`vM}�w?a�%����!�q����p����M�A���`9�~����M7G!����|{��������M!�9
Q��yw�g����r���c�H4
6��A��|��Sm��O���	������?�����>�����.�����R��(�g���D�W�?T��*����W�+P��pt��g�?����(]5�+P?OV��0��L��9�d�A��
ZX
��s��|)dJ�����M���!�7�;���";AE�������ys�N�R�6|�J����y7��^s�jS`#����d�^�(����x�^��R�ac��Ny�i.6��VVU�����?�RuCO��f�E���-t5_t7/���3�	�0FW��������B��.c_�y���M�W�=���`U�[d�������'�%��/>�}�i�������mH�������y?�Z|rj�i����l�aNU��������������m?�pbh
N S�`�o��\���p������Gd�N�hq������>	��?q�����{1���]L?&kS�WU�.^Q�4i�?�moe��?��Y:E��CK�������V�F�!J�&SQ�>����/�+���l@=��k��nE�IB�E��L�'������$���Q!-R��u��n��,��<W�t2�`��+��[����Gg\y���Dl�}�.=��YJ%���������3Y�h��k���'�$�G�OSVW��K�ZL$�6��'4�~U��<��Xf��I,C,��@����C�x��gA9��I+]YA���<��h�����gU|\���J������]��u��Q���vW�7���9n�.�r��V��L]������i�k�b����3A����9��������������q��&?s���I�1+��k_����]7.������!�E��o���N���w�������c���B�h6~4%��������F���y�N,��;������������������5,p�=<���G	���0���WtU��}b1IE��'��
?Hr���p�:z�eR��N4J'a��U�v/1����'!Y����bV�o!f�)�����6�"�w�c����m��1��	Bf��'�_f�d� .�j��
�b��Zc�a6K���p�w�R1U��V����V��P��'�	XTc�BX�;�@��5�q<�$S�	=����*��dQ
_��5�{^��"
�0���'2�;S��������t<�AqO������H�����Rm}�B���������4h<e��2�	L�?���?�t��V��7�;�������h<2j�<rm��u\�����E��O���cU���weU�$�{�_����wv,g��y��4���S1'��A�@�&��C�������)	��r�M���<�H����m*�v����m%����w�y��P��E�����h�`Mi�*�e�-�.n�m�������.�����-����h�����}��-��_��hgww�����o�������m����U��`�6���\g�^���7Xd��`r���u�E$K=)����Zywss�+�L{��`�����%����klW5������X��j<���}�wS�sW/��g��'k���}P������v[������S��O���r��+��<W�+��?gs�j�?;_��������kw����t�,O%�@��%*X������F+��~;i�Vz�n��U����Y����JcS<~�d�]��'w��u���qO�$X@�8����Cw��;��������V�'5���]��z�������LLe�B����O�g���U����`V�������{*4����W�.)��g������"8�S	����k� �~qQ���%����2�&A�l��:oE���oS F�A4	�`P�e8�&�F���'�_�M����6}�E�y�=
��XD��
/��:j;p*�L6��*�m�
��?d��+/D���Qq.�"EH��,���1�a&V���/�����E0�k�������?�a��`7{�sV��.?��;M>�C���9jz(kJM�=$|��Z���:�q:�4�g��)-��:��vv��[�_��B?������qpA$$�G�O����$}���_�*���-����	���1��������\>�|��
����������Tj�3+$��������	)F�^�M��OJXn����$��0�P7HC'��N�&��������JK�I���������F��~�x�Fdn�I�h&��nTX�zA���U�_���������1i�$xt���;�#E�R��U`eD��]y�������U�E+&|�O"O������������mA�������2I`�}4F;B����D��d�2�9E����g������P5�[qr�%������Tk2�U8i�J�8L>+.@�h������H.��R�t������E��n8�e#i}�x[���g�]�q!������M��t^A9=�}4S�k�M�[�G�S����e>S}�<��+BO���e=X�������Z@��S���������)b�@V���3�Tp���c<��g�v*K��f3��x�A�I��g���Kj�e�P�������H�n���/�I��Y�s�K�V��
��I��PZ�c�.�
a2r������zN��k/=��/H�F�T�k��M���x��9�TN�<�zDU!�W�|�/?b��a�����gI�HYL�=��8�b�-�\�qN������}&q�>!)b�}���?�>��o���'���[�ruk�;_�9�8_��V�����+N�0q���}�t\���;��_Y�#s����Dh:���������b�����w�s;��~#3�<�8G�����WDn�#��Px��W�BeR���OF��Q�m%������W�r��i��y�0�2<M�i^
���T;U%�L�a7�C����M�������a�fh�e�U3,��D�VU��� ��UC9���(O��	��s���*�?^��r��c�.$�V��HOKNd�>
�Q�K��&��R�nhF��3Ns8�x��G(�K2;�%��r����[�����kMK���������3�.{�d`m=@�=b�w�{�9p�7�[�p��+����ru�&�n]��!��a7�%�\N�����W���Mh�d�p��;J]�N���_��d?��t�!J�;�'S�Z'��'}��!1�����x�Y�[����������y��7��[�^~��/�����m�(�����K�^����T|�J����K��<$�V>��0������� `��nH�{��XyL�(��t��_�i�@��N�`:�HH/���2���������������x�rJy����P���j�m��k{;�8���H��.�x ���7�c�����T5����	F��&��P	�kZ�����>��c9��H����?��������e�j@\f��
�t���'zF8�w����'bx���bbFe�u��Q���@����~��'3��{�������,c�y�Q=q��+��*���e�����QoiP�A4@�g8�4������Q��U�a�H�r����W�Rk�sT�Y�`����$���F1�!�������������������*
|a	���\���N��n�b��M��1fHD7���@����(�y���{�e����z�w=�	��a�R ��P`�U�"3�,r����zh�)��0L��B�
+h��`�C�.$HarsKE�5U���+��`p�;����W�h2@����QE����*���f;�&h�LDO\��C��LTH����
���
�j �����R	�4��	�����z�����w��;��D�Ir�ml>Y���vy�f$#����|��a���1�'�9?�~zH��V�/�R�{�����T�7�c�zP��d����]\��)L���6^�C��'�$�Z&Q_�q*� ����k��Z�U�|^o���2���"/�������V�?C#�V�x�H
��!
oTk�
|,���s�1�F�?�
F�E�\�8����-�~wz��j�%P\�	�`'=[�_�6�On#3�T�����	�w2+��<�6L2g��,V Q������P�&Z�����n��S���E��s�8o�7N�~�4O�����Rl�j�WS�l �u��Y��2��Z���K"J����FV��Jw�C�dTF�����.5m+"��|6���
	5L���=A�I1�*&��
���"�l�$�x @��������i���$�m���z�X�����r�����+e����	`����4F�~8	+B���)*c�.*M�vsv��0F,{�9M�c$������2|���)�4���������Op����<��t����jAQpM@xy�W�k{a
��>��B@bK��T�d�W�� ��bVc<
��?�y6p�x��8�'p�8����������I�M�����yZ?Y�����Ye��`]E��z4~������[h���Q	.;��C�f��!	��`]��v��`J�1���)�)5��\#�|x1���;��f�;!�&��_��� ���B��+8KQ����z���9�lz(|�����E�����-�_ *���4IBV _b
�>���i������B)]�b�#9�]�~����9'x$G(�1y���kn9��N��V���E�����j\���(�W;$��*x�y[??o����N�3��"�r�7^��N�R�HB))e:�(��=����r������t��RT�}�j�����e��/�!��W�*#�yZ�(���*��V3A�w�mR�&���Yr��&h�,���%^J�:O�LZn.:��q�p�x>
o:<�N���>����"]�@	X���UfA���o����SJ�n��2�w��:g�D�����^�V���P�}��r~�9���4��BH|"&���k�������kc|�����%oe�>PvE/<�4\��h���u�_�mn9�5�1��u0�
M��<l<���R�\���l���3i���5�]��3]�*
8k����w\�����0���3hVpq�$;Z���n'x.C%7�y�F����%�q�����Q�35��t	/��n��x����a��o���Q$J��K��&�m�][���!TI��C�ym�Cj��t�Z�m���j�j[�QC�0�~���C�(!���~�#�nH��Y�v���P .�����),Z��7��Y�7�P�ht��6����q�%���T�y>�`%gG=|���j�;�O1M����R.��)�#
�APtQ6��s��UE�IC>�r�f:P�
�:�S(�&r��`��������I��X�W,r+��`Gr�3��^��0�M�`
��&qp�!cxgf��GQC��0@=9j�o�(���co�0�5�*������-0��������%�.D�� ����r
zd�D�
Q��EK0?�e�!�m�����1N�y�h)m�F/������n�����������
Ce��c�Xwf��HU#�"���_����|f�9K�j5~�:	�G������(�DU=8�]�mV7�P"�\%a��'�� �q�8���'�.�MO����.�������X��"������#Xc��GQ`�l��1�O����4��v�>��kP0��,�����H(����*PXUG�>��Y)��Cj�#K��� �����q%�?G�JR�o�P����H�T����<\����Px{\Zr�������X�E��X�����7��k�n��x�Y�p!�h%P�]��������e|�/~��`�K�Dm�h	"�p�U�k�?�GA,�!U�A�B�y�Y�D�����l�[������ SQe�#P���toV4������	��J�[�������-=�rjp>�t�zd8�qL��2��a��FO��5)a��f�nI���<P����x���Iu��6y��^��u�w@M;O�	�t����m����;�\uf9���j����l���6�@gBK����J"}7P�f�d(�PF�4L��/��ci���?<�;�0%V5�����m�M��@@��L��������V��vt���HW/��DI��o
������9�~E�5Q�`S���	��D
��vd�p�G�������������`��_�3�tp,I8�0���@��@���,����$[�I�d>WO���1�������V0'�;<�@}
��u�<���s�	�1��!.g��{
`��~�������i�C�DA/�Oy���_Z���S�����V�K�(�!�]��Pc*o�p����s�)mg�4oV";���������5%��	���&��i��a��`���'FF�#�<�����}�����������Qh���;�->���GN[U'�f�m�������]�c�=�����LO2�,�sG�%��YV&���(1{��B��vBX���9�.�rYA�X.���O��WV5��3i'����-����O�%������&jawxY���]`������@@��;������x9����H��/��6�s�O�.0z.��$�����w�������\��O����l������"Twg���m�V	Jc�5�����f���z��A��C�
���t��E��o���l�q���\�:�3Q���\�z��M�6]F� �e�ZhOT���'�.E�M� �W����lj�l��A>���)���S8,0zaw��6L��f#+i'l������f�u���$a9��daoG�\;$M�R��\��������b�y��\/g�j�n�wN�"V�NKru�`���S��/>��n�s4����
]@X�����b"�BN��_��S��W.���~���x@��k���������-�e�����ZE<#X�[��� ��o������l��D�^|��=,3����;/�:�u����-��O�����4a�	���R<pET�.��'�$���&?L��������r������)A�5^dY(/\jY�H����c�)$n��&�g���q%("EYY	�%�F�&?0������>�VX'i�5[9P�85X��E��������`�y�Q��j%UF�j$����1���L����-���m������I�<�f��u�Dse�^��AOF���8��I�2�n�/���B*"/��C�w��z�v��e
��!�%��@�
y�u�$<��*���H��V����M��m���P|l����S�"E�jd-��g�V����$������I����f
;9*U��[��=cL�����\�Lac���O���rXchj�~��K%!�N�"����9e;Fe�������A��������"^�����44�"�,:�[�f�	S6 ���A�
�#Z�������w�H�EO~�1Al�tA���d8)���y
�m�q]��3es8v�������gN+VYiPY���[���-s[tP��*�Q:���V�R��l8_e>	���t:��]i��7��y�"l2;�	�c��{����Z����.�%F KCj�G��y!<���y!m��8�o�lg�pmm�d;�y+kV�f`9G��L�Y<>����,��1����$6W�k�U���MF�#�B�"<��c,��Qx##�����u�1$�4G�p��������>�	+�v�\���M,�1E��EOK���!��������4:z{���@��p8{�uo���^5���I<>.��>88�������mSN���A����C�?�����Q\]��L�k��M��Jg�*���Ix�~�?y�|p��y�+��P}�?�zBF������:���������e���q�n
U��ir�l����[�4�<E��M<��A�16�Us�#�.����0�4�/�Z���)Ro��O8�	0���U^�TE���D���G�L]��&���A/������Z�Z��	g���Br����!Hq/;G0`z���~�M�?$ft��������n��C62�p���!�6g
��O�d;�6�rV���x��������j:C����A<2�3����{��;t��A����?��s����
 C��I��J�ju�,��e�m�����*��4atr�V-��C��
�zl)�|~����������;�����g�+&�+�ka��a�$�1�	�9�lv�r����5�O\]��u�<4#�l��y���b�y����z^���Q'G�>
�,d�hK���p�m������������d,��RC�,
�p
'�(*c�p�@���������IY�K��}�^@���co������ �y=q�S����4��&I�.w�NK��g���G���N��"����H|�%#`J��;�d�yu��P��K�8F�d��
�q�IK[���R+U9�>�Fu���fT��X��{MF�j�����e���rI3��K�����w0����`��[_����9�����2/������l������E^��+�[���e�,���c
��� � :�mZQ��*����yh�	e�fl������L#o�9�d]����%�nx�1'�KC�j��]~d��oEw�O�O�$�U��a���������?#�nh�~gIH.���C���"o�bT����k|����C�F3�|nF�rV�f���U3 ��0��H�]!����r���x�W��r�T����Z���J���`4��G��
_�O�����>���qq�mr�5��T�p�h�i�����]��C	H&H��N���n�o��,2{�Z8����~��rb�kq����o���"�v�5B��u�tZ��-��y���C%S�D�J:�C��P)����(�m����`��[�Z��Y(%�������9�N��R���I���XZ�*�����Yg��(���[�yu�%���Z�A��]����	K�E��*������%��W*�M���
e�}�^�jL���Ts��I���n�1�'B���m�m��v/�&3��*7���:q����0dT>�����m����C>�d�I�L��"X�#����i��=��%�Vr/c#<��mJj�b�$�L��O�=�����������6B-�z��
L����\m;;{y<���R�;���;�����<<U�~'�Gk9�4y���%P��2��u���&yT���0�3b��@'�	�����_�
$9Y��ny�����/��	���d�[g�F��7lN�������K�*��6���6 o��W\�8<'��}�N��
H?m<��I�E���,sa�TD���n�����=v����l�k���>+��Q�\���rih��]��8�g?�//ym���Tt/�g��O��A�b8Z*��i��FZ�m�sF4)f<E�x|����t���\�QP��{�������-�w*T��n#�d�M+�\_-8nY[������(�+G`v�8Y9iL�l��Yqn�.��c0���D7�oQd�#��=�n����X�o�3����e�3�C���E�!ba0b�(��-2�.#qB�o������K��{E��2�m�V���"����(�����*J��2�FCf�`���S��J_j���w��/:]���
���`�������t{Gh�@"���;��o�^�;���8����:�EE<;�����v�b�%]	p��N�?�;��=��r��S�����)

k+�T%���a���U��s���'�+V�Q�k�����~Q�!�p�<��������
~���,cf��"v�Nm[;���5��mrj{us����=���
��+"�o0!��R���qg�������&"����2�����T�������
�%4��L>�J
�r�`��,�o��e{���#*i���njI�l����j�d��Z/k��xH��g���������������Y�rulb�I}]uv_�:d�j$���8:���w_�;�������Sof�
���u�O���$�q��;�T��%��Wa'C�����s�a��}�(�=�>���I4���u���,���Chd>�z�+�$��LQ�5���++��,.�Z<���*q��8��5!�'��8*�4 �*���R���"G��dY�
�-��j�Q���u�{Y�4�q�7��7�}&f��/PE��^m�����h��f��&��3���-8!�PA!BmC����5����N����gou��P���G��_���7Ju8����������z\f�!�r;c��5�q�W����������q�T{�:���c��U�
�������x7y3/�a��,��Z��R�*�����~)�����������Z����:g���"�����r����4>�67A �o��0O���+��9����q�.��G������/#
���Q�V������f�	�\e����q��m�b�i���[t�4�����V�n
���f�����N���W�j���r������,�����U���5����0U&>�\M)��7�b�nG�F<��1�n8����7���$P��Ik��D]�d��; �x�"�Q�(���m���k�TL)`���R��'?f���{�Q;��i�����2*�ADj������5�6H�wl���l���
�4O���M�\e"T�QCo%-@i2��J����:��U��~�"�5���
L����[���{N�Q�-1��i����H(�q1+A� �Xa�0	����d�$���y���y7G$������>C������h��y��f6%'�7�y���C���(���X,���^������
0<������:`]���HP��tq��=�)��?��T�J^�,�05�MQ�����"�����VZ�`�Jr`�5���*75q���
���Z�a�W"0C��� bh�� �e;��m�B%����sa~g�N�X��=�5�bA�,�t�����^�|�O�ll��{,z��8>��/9��m������-���������b�
Qp��Kt��`�~�����+�PEHA,�D�{n�}\��C���8��k`F-���S�&��n��M����7&*_m�\9�J�7"�g��Y��4+������G�SONX�s�I�A�R������_���y�I��7��4OOi:������,)�,�	��S
��
Y��6+�a���-�:��%D����c��yp�q0CUHI!��_���[J��>��3� =��k����+��+�I�1�?�M��tAf�1���^�GN�UQ&q��4��4{5����1�1��/J�U��?��K�@��g���Ywj�jK���z�������iQ-${��F�W�H�`�A�q��J5l�����^����#��|��U�hm����;j���B��r����xY�ll������x�\�������UB������A�Z�g$�A���m�P`A%��PZg�:DE������c�O0bB_����d!0_1m1�����h��+��������B����^O�T�x������$��������!���p�[!|�Q%�������v���Ug�&����vk�>�����#���o��3#����^�qE&����{V���)K�MR��y�YJy��yy^����yy^����yy^����y�u7}��W�S�����T����k���{/������'�����}F�i��O�����/P����P�"����o4x����D	�F���?�h��Ix�$~r�I�#��t*se��!���]��Rb�"oBk��O���=U�CN�<�)�"c�k^8��5q�/������'����BU0D5*��i��m�K�m<�� �G@5�x�K&T�=�'�����&������Q���:��I�JW��=h�;��RI�J6�:<(+ �uS���ip�������1��2������	�\�)��-����t����J4��[`
/������O�S�)�6v��D������3�qrQ0b�3(1�������$��2������x���i�x�j(��l�k�D-�{���K��b^1�<I6��U$��������:��)��@���~���mX��,=�`n�:�H	|O�h���{Mi _>�a|�N���!9tg�K�<A���W�!�^��K�.�k����F���5��������-~��b�x�v�4GY ���BV�*M��!I(rzy:�����]����~	cM�T.���A���W�DS��[O�)f�(������p;C��T����wE��"���hXQC������������v?�}!�02{�d���&�:��I����,�x�!r���w���f����`��������/AJ����1�E��9����)-r�0���sg3`?H�XB.�����'��M��y.���9�#���=�����P�����������On��3������C}��+]e*�������h1��T2q#Z�q,�.}(���g!V�*��-�L���vj=m���s8�
�Bw>�5d6;�BXgj���m��&���.'�'l	����i���M�'�x������n�������;u����m@a���3��A�,�aw���7�����O���n��)0K����������RV�p����\k{�v�^K�i?�2A�ax��
$l�� X��h9���0�/n#�J�B�
Y��
�G��eK�!uL�I���$n��7�@�D���L��`�1�c����+2�
i�{ETG���va0���j�����y�X�/j���W�?u�I:�
a[��&����!�_���}���(�SvB(���d�j1�����66��O`{�kv�m�9;����!k�nl0,H'�w��Q��=���7=����u% 3�k���9���E�������)F0������7�y� ]��������s��?4W}�<`�����+]�[p<��o4jN��cP�(yS�t��E~��
�*,�����UvkO�<w��%�Q+9X��s�@���N��(�+�m�g�����G��
#2David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#1)
Re: Extensions, patch v16

On Dec 9, 2010, at 12:34 PM, Dimitri Fontaine wrote:

- add support for 'relocatable' boolean property in the control file,
as discussed on list

this controls what happens at create extension time, by doing a
relocation of the extension objects when the extension is relocatable
and the asked schema isn't the first of the search_path (you can't
relocate an object to a schema where it already is)

when the extension is not relocatable, the mechanism used is the
@extschema@ replacement in the script so that the user still has a
say, but at create time only

This still isn't ideal, but I think it's a big improvement. Thanks.

- nothing is done for the psql commands \dx and \dx+, here's an idea:

\dx lists only installed extensions
\dx+ <extension> lists the objects, calling pg_extension_objects()
\dX lists available extensions (and installed too)

+1 I think that's much more like existing psql commands.

- we still depend on extension authors providing a control file. Do we
want to spend some efforts on trying to get rid of this file? I know
David desperately want to, but that's at the cost of making it much
harder to manage more than one extension in a single directory, for
once, and the Makefile mechanisms to make than happen (include a rule
depending on the presence of some variables, keep track of it for the
cleaning, etc) doesn't seem to me to worth it.

I don't think it makes it any harder to manage multiple extension in a single directory because one can create the control file explicitly (or perhaps rely on .control.in for that), just as they do now. Everyone else can do less work.

So:

* If $extension.control.in exists, use that
* If it doesn't, generate $extension.control from the Makefile variables
* Always remove $extension.control in the `clean` targets

Best,

David

#3Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#2)
Re: Extensions, patch v16

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 9, 2010, at 12:34 PM, Dimitri Fontaine wrote:

- add support for 'relocatable' boolean property in the control file,
as discussed on list

This still isn't ideal, but I think it's a big improvement. Thanks.

Glad you like it :) If you see any way to manage that better, please do
tell. Just be sure to review the past 18 months of on-list discussion
about the topic before to go thinking extension vs search_path is easy
to solve, or even possible to solve.

\dx lists only installed extensions
\dx+ <extension> lists the objects, calling pg_extension_objects()
\dX lists available extensions (and installed too)

+1 I think that's much more like existing psql commands.

Good, I'll have that in the next patch version, waiting for until your
review of the new one :)

So:

* If $extension.control.in exists, use that
* If it doesn't, generate $extension.control from the Makefile variables

What if $extension.control exists? Is it a byproduct of the .in file
from previous `make` run or a user file? What if we have both the .in
and the make variable because people are confused? Or both the make
variables and a .control and not .control.in? Etc...

* Always remove $extension.control in the `clean` targets

Hell no, as you can bypass the .in mechanism and provide directly the
.control file.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#3)
Re: Extensions, patch v16

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

"David E. Wheeler" <david@kineticode.com> writes:

What if $extension.control exists? Is it a byproduct of the .in file
from previous `make` run or a user file? What if we have both the .in
and the make variable because people are confused? Or both the make
variables and a .control and not .control.in? Etc...

* Always remove $extension.control in the `clean` targets

Hell no, as you can bypass the .in mechanism and provide directly the
.control file.

Are there any actual remaining use-cases for that sed step? It's
certainly vestigial as far as the contrib modules are concerned:
it would be simpler and more readable to replace MODULE_PATHNAME with
$libdir in the sources. Unless somebody can point to a real-world
use-case, I'd just as soon get rid of the .in files altogether while
we're having this flag day.

regards, tom lane

#5Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#4)
Re: Extensions, patch v16

Tom Lane <tgl@sss.pgh.pa.us> writes:

Are there any actual remaining use-cases for that sed step?

The goal here is to allow extension authors to maintain their version
number in the Makefile rather than in the Makefile and in the control
file separately. Having the same version number in more than one place
never eases maintenance.

Oh and in PostgreSQL sources cases, that would add like 36 spots where
to manually maintain our major version string. I'm not eager to do that.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#5)
Re: Extensions, patch v16

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

Tom Lane <tgl@sss.pgh.pa.us> writes:

Are there any actual remaining use-cases for that sed step?

The goal here is to allow extension authors to maintain their version
number in the Makefile rather than in the Makefile and in the control
file separately. Having the same version number in more than one place
never eases maintenance.

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

regards, tom lane

#7Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#6)
Re: Extensions, patch v16

Tom Lane <tgl@sss.pgh.pa.us> writes:

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

It's in the Makefile so that you find it in the control file later, then
in the extension catalog. We need the version number just because I'm
not able to name a single software that's not letting you know about its
version number once installed.

Well in fact I know about one, and I wish the situation would be quite
different there.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#7)
Re: Extensions, patch v16

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

Tom Lane <tgl@sss.pgh.pa.us> writes:

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

It's in the Makefile so that you find it in the control file later, then
in the extension catalog.

This doesn't answer my question of why it couldn't be done the other
way. Why does the makefile need to know it? If it does need to know
it, couldn't it get it out of the control file instead of vice versa?

We need the version number just because I'm
not able to name a single software that's not letting you know about its
version number once installed.

I'm not convinced that this is actually a requirement, or that doing it
this specific way is a good solution. In particular, keeping the
version number in the system catalogs seems pretty dubious. The common
method for upgrading an already-installed contrib module just involves
dropping in a new .so --- that's not going to change the system
catalogs. It would likely be better to keep the version ID inside the
.so file.

regards, tom lane

#9David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#3)
Re: Extensions, patch v16

On Dec 10, 2010, at 12:26 AM, Dimitri Fontaine wrote:

What if $extension.control exists? Is it a byproduct of the .in file
from previous `make` run or a user file? What if we have both the .in
and the make variable because people are confused? Or both the make
variables and a .control and not .control.in? Etc...

There are ways to deal with those issue, I'm sure.

* Always remove $extension.control in the `clean` targets

Hell no, as you can bypass the .in mechanism and provide directly the
.control file.

I'm saying disallow the .control file, only allow the control.in file.

David

#10David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#4)
Re: Extensions, patch v16

On Dec 10, 2010, at 7:32 AM, Tom Lane wrote:

Are there any actual remaining use-cases for that sed step? It's
certainly vestigial as far as the contrib modules are concerned:
it would be simpler and more readable to replace MODULE_PATHNAME with
$libdir in the sources. Unless somebody can point to a real-world
use-case, I'd just as soon get rid of the .in files altogether while
we're having this flag day.

I've made extensive use of them in pgTAP, but they don't depend on PGXS's doing its bit. So no. Unless we require control.in and not .control.

Best,

David

#11Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#8)
Re: Extensions, patch v16

On Fri, Dec 10, 2010 at 12:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not convinced that this is actually a requirement, or that doing it
this specific way is a good solution.  In particular, keeping the
version number in the system catalogs seems pretty dubious.  The common
method for upgrading an already-installed contrib module just involves
dropping in a new .so --- that's not going to change the system
catalogs.  It would likely be better to keep the version ID inside the
.so file.

This is an interesting point. There are really two things here: the
.so version, and the version of the system catalog entries. For
example, imagine that an extension provides a single function, called
foo(). So we load up the .so and CREATE FUNCTION statement to match.
Later, the extension is so successful that the author writes a second
function, bar(). The new .so can (at least possibly) be used with the
old schema definitions, but the new schema definitions aren't
compatible with the old .so. The logical upgrade process is to swap
out the .so first, and then add update the catalog definitions.

On the other hand, if you were dropping a deprecated function, you'd
need to do the steps in reverse order.

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

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#11)
Re: Extensions, patch v16

Robert Haas <robertmhaas@gmail.com> writes:

On Fri, Dec 10, 2010 at 12:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

... In particular, keeping the
version number in the system catalogs seems pretty dubious. �The common
method for upgrading an already-installed contrib module just involves
dropping in a new .so --- that's not going to change the system
catalogs. �It would likely be better to keep the version ID inside the
.so file.

This is an interesting point. There are really two things here: the
.so version, and the version of the system catalog entries.

True. Consider a situation like an RPM upgrade: it's going to drop in a
new .so version, *and nothing else*. It's pure fantasy to imagine that
the RPM script is going to find all your databases and execute some SQL
commands against them. Since a large number of bug-fix cases do require
only a .so update, not being able to track the .so version seems like
it's missing most of the argument for having version tracking at all.

(In the RPM case, the RPM infrastructure would be able to tell you
which version you had installed, so I'm not sold that PG needs to
duplicate that.)

regards, tom lane

#13David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#12)
Re: Extensions, patch v16

On Dec 10, 2010, at 10:20 AM, Tom Lane wrote:

True. Consider a situation like an RPM upgrade: it's going to drop in a
new .so version, *and nothing else*. It's pure fantasy to imagine that
the RPM script is going to find all your databases and execute some SQL
commands against them. Since a large number of bug-fix cases do require
only a .so update, not being able to track the .so version seems like
it's missing most of the argument for having version tracking at all.

Sometimes there will be changes to the SQL, too. How does that work with CREATE EXTENSION? Do I install the upgrade, then run CREATE EXTENSION to get the latest SQL script to run? But then all the objects already exist…

Best,

David

#14Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#8)
Re: Extensions, patch v16

Tom Lane <tgl@sss.pgh.pa.us> writes:

This doesn't answer my question of why it couldn't be done the other
way. Why does the makefile need to know it? If it does need to know
it, couldn't it get it out of the control file instead of vice versa?

Well the Makefile support is just a facility to fill in the control file
automatically for you, on the grounds that you're probably already
maintaining your version number in the Makefile. Or that it's easy to
get it there, as in:

EXTVERSION = $(shell dpkg-parsechangelog | awk -F '[:-]' '/^Version:/ { print substr($$2, 2) }')

That comes from a real world example that's yet to be adapted to being
an extension in 9.1, but still:

https://github.com/dimitri/pgfincore/blob/debian/Makefile

I'm not convinced that this is actually a requirement, or that doing it
this specific way is a good solution. In particular, keeping the
version number in the system catalogs seems pretty dubious. The common
method for upgrading an already-installed contrib module just involves
dropping in a new .so --- that's not going to change the system
catalogs. It would likely be better to keep the version ID inside the
.so file.

Upgrade are left for a future patch, did we decide. Still, it seems to
me that we will support some upgrade scripts so that author can decide
what to do knowing current and next version, and yes, knowing that the
module has already been taken care of by the OS-level packaging.

That means some extensions upgrades will break the database between the
OS-level package upgrade and the sql upgrade (support to come), but in
my experience that's seldom the case. And not by chance.

So in the case that only the module (.so) needs upgrading, we would
still provide for an upgrade path in the script / sql support so that
the version number has a chance of being upgraded too. As you say in
another mail, of course, the OS packaging system will not forcibly be
willing to care for that all by itself. I can imagine debian offering
the choice to the users and acting accordingly, though.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#15David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#14)
Re: Extensions, patch v16

On Dec 10, 2010, at 11:28 AM, Dimitri Fontaine wrote:

Well the Makefile support is just a facility to fill in the control file
automatically for you, on the grounds that you're probably already
maintaining your version number in the Makefile. Or that it's easy to
get it there, as in:

EXTVERSION = $(shell dpkg-parsechangelog | awk -F '[:-]' '/^Version:/ { print substr($$2, 2) }')

That comes from a real world example that's yet to be adapted to being
an extension in 9.1, but still:

https://github.com/dimitri/pgfincore/blob/debian/Makefile

I use that in pgTAP, too (line 23):

https://github.com/theory/pgtap/blob/master/Makefile

But I don't need core to support that. Frankly, if we're not going to generate the control file from Makefile variables, then I'd rather not have any control file Makefile variables at all.

Upgrade are left for a future patch, did we decide. Still, it seems to
me that we will support some upgrade scripts so that author can decide
what to do knowing current and next version, and yes, knowing that the
module has already been taken care of by the OS-level packaging.

Yeah, this will be needed ASAP.

Best,

David

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#15)
Re: Extensions, patch v16

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 11:28 AM, Dimitri Fontaine wrote:

Upgrade are left for a future patch, did we decide. Still, it seems to
me that we will support some upgrade scripts so that author can decide
what to do knowing current and next version, and yes, knowing that the
module has already been taken care of by the OS-level packaging.

Yeah, this will be needed ASAP.

I don't mind if we don't have an implementation of upgrade cases in
hand. But we had better have a design in hand, to make sure what we're
doing now doesn't foreclose upgrade cases.

regards, tom lane

#17Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#14)
Re: Extensions, patch v16

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

Tom Lane <tgl@sss.pgh.pa.us> writes:

This doesn't answer my question of why it couldn't be done the other
way. Why does the makefile need to know it? If it does need to know
it, couldn't it get it out of the control file instead of vice versa?

Well the Makefile support is just a facility to fill in the control file
automatically for you, on the grounds that you're probably already
maintaining your version number in the Makefile.

Why would you choose to maintain it in the Makefile? In most cases
makefiles are the least likely thing to be changing during a minor
update. I would think that the right place for it is in the C code
(if we're trying to version .so files) or the .sql file, if we're trying
to version the SQL objects. In particular, if the only reason the
makefile needs to know it is to inject it into the control file, it
seems completely silly to not just maintain it in the control file
instead.

regards, tom lane

#18David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#17)
Re: Extensions, patch v16

On Dec 10, 2010, at 11:47 AM, Tom Lane wrote:

Why would you choose to maintain it in the Makefile? In most cases
makefiles are the least likely thing to be changing during a minor
update. I would think that the right place for it is in the C code
(if we're trying to version .so files) or the .sql file, if we're trying
to version the SQL objects. In particular, if the only reason the
makefile needs to know it is to inject it into the control file, it
seems completely silly to not just maintain it in the control file
instead.

+1

David

#19Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#17)
ALTER EXTENSION ... UPGRADE; (was: Extensions, patch v16)

Tom Lane <tgl@sss.pgh.pa.us> writes:

Why would you choose to maintain it in the Makefile? In most cases
makefiles are the least likely thing to be changing during a minor
update.

I must have a packager skewed view of things here, but ok, point noted.

I would think that the right place for it is in the C code
(if we're trying to version .so files) or the .sql file, if we're trying
to version the SQL objects. In particular, if the only reason the
makefile needs to know it is to inject it into the control file, it
seems completely silly to not just maintain it in the control file
instead.

If we are after the a bare feature set, sure, the Makefile facility is
only about trying to be nice to the user. I accept that you think it's
counter productive rather than helping.

In the next patch, I will rename the control files to be straight
.control files, remove the implicit rule in the pgxs.mk file, remove the
note in the documentation and apply the following:

sed -i 's/EXTVERSION/9.1devel/' contrib/*/*.control

Or do we want contrib's specific version numbers that are not all the
same as the current PostgreSQL version number?

On to your question about the upgrade design, in order not to paint
ourselves into a corner. What I now have in mind is the following:

When there's an extension upgrade the user will have to install the new
files (.so, .sql, .control) and run an upgrade command in his databases:

ALTER EXTENSION pair UPGRADE;

The version we upgrade from is known from the catalog, the version we
upgrade to is read in the control file. So we are able to call the sql
script and offer a way for it to know about the versions. The simplest
way seems to be a new pair of functions:

pg_extension_upgrade() returns bool
pg_extension_versions() returns table(current text, next text)

Those are to be run only from the extension's script.

The first returns false when the user did CREATE EXTENSION and true when
the user did ALTER EXTENSION UPGRADE, which are the only two commands
that will run the script.

The second will return the versions we detailed above, and the
extension's author is free to compare them however he wants to and
decide what to do now. It's cool that we have DO blocks here, and
pg_execute_sql_file() to offer the same facility as \i for psql scripts.

Of course if calling the script succeeds, then the version number in the
pg_extension catalog is changed to the "next" one.

Now, it would be better if it were easy to compare version numbers, for
example with a -core datatype that handles that. Do we already want to
open this can of worms?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#20Josh Berkus
josh@agliodbs.com
In reply to: Dimitri Fontaine (#19)
Re: ALTER EXTENSION ... UPGRADE;

On 12/10/10 12:17 PM, Dimitri Fontaine wrote:

Or do we want contrib's specific version numbers that are not all the
same as the current PostgreSQL version number?

I think that each contrib needs its own version numbers. The reason
being that most minor updates don't touch contrib.

Also, once extensions and pgxn are operating full swing, I see contrib
going away anyway ...

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#21Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#20)
Re: ALTER EXTENSION ... UPGRADE;

Josh Berkus <josh@agliodbs.com> writes:

On 12/10/10 12:17 PM, Dimitri Fontaine wrote:

Or do we want contrib's specific version numbers that are not all the
same as the current PostgreSQL version number?

I think that each contrib needs its own version numbers. The reason
being that most minor updates don't touch contrib.

Certainly extensions that aren't part of contrib would need separate
version numbers.

regards, tom lane

#22Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Josh Berkus (#20)
Re: ALTER EXTENSION ... UPGRADE;

Josh Berkus <josh@agliodbs.com> writes:

I think that each contrib needs its own version numbers. The reason
being that most minor updates don't touch contrib.

Fair enough. What are the version numbers of each current contribs?

Also, once extensions and pgxn are operating full swing, I see contrib
going away anyway ...

No, not all of them. Most of them are in the tree as show cases or for
core developers to easily check they just didn't break an important part
of the system from an external viewpoint, or to give examples on how to
upgrade external extension code between major releases.

The part that will drop in interest is the one where customers are not
trusting the extension mechanism and third-party software enough to
grant them landing into their production environments. Maybe. Given some
years and a good track record.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#23Andrew Dunstan
andrew@dunslane.net
In reply to: Josh Berkus (#20)
Re: ALTER EXTENSION ... UPGRADE;

On 12/10/2010 03:24 PM, Josh Berkus wrote:

Also, once extensions and pgxn are operating full swing, I see contrib
going away anyway ...

We've heard this before, but I'm still quite skeptical about it. Quite
apart from anything else we should keep enough extensions in core to
test the extension mechanism, as well as to provide examples as part of
the base distribution. Some (e.g. hstore and citext) should probably
move into core. Others like pgcrypto are probably in just the right
place as they are.

cheers

andrew

#24Joshua D. Drake
jd@commandprompt.com
In reply to: Andrew Dunstan (#23)
Re: ALTER EXTENSION ... UPGRADE;

On Fri, 2010-12-10 at 15:42 -0500, Andrew Dunstan wrote:

On 12/10/2010 03:24 PM, Josh Berkus wrote:

Also, once extensions and pgxn are operating full swing, I see contrib
going away anyway ...

We've heard this before, but I'm still quite skeptical about it. Quite
apart from anything else we should keep enough extensions in core to
test the extension mechanism, as well as to provide examples as part of
the base distribution. Some (e.g. hstore and citext) should probably
move into core. Others like pgcrypto are probably in just the right
place as they are.

I hope that contrib goes away. I agree with your assertion that things
like hstore and citext shoudl be in core but it is my hope that with
extensions and pgxn, there will be no reason for contrib to exist at
all.

JD

--
PostgreSQL.org Major Contributor
Command Prompt, Inc: http://www.commandprompt.com/ - 509.416.6579
Consulting, Training, Support, Custom Development, Engineering
http://twitter.com/cmdpromptinc | http://identi.ca/commandprompt

#25Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#19)
Re: ALTER EXTENSION ... UPGRADE; (was: Extensions, patch v16)

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

On to your question about the upgrade design, in order not to paint
ourselves into a corner. What I now have in mind is the following:

When there's an extension upgrade the user will have to install the new
files (.so, .sql, .control) and run an upgrade command in his databases:

ALTER EXTENSION pair UPGRADE;

The version we upgrade from is known from the catalog, the version we
upgrade to is read in the control file. So we are able to call the sql
script and offer a way for it to know about the versions. The simplest
way seems to be a new pair of functions:

pg_extension_upgrade() returns bool
pg_extension_versions() returns table(current text, next text)

Those are to be run only from the extension's script.

The first returns false when the user did CREATE EXTENSION and true when
the user did ALTER EXTENSION UPGRADE, which are the only two commands
that will run the script.

The second will return the versions we detailed above, and the
extension's author is free to compare them however he wants to and
decide what to do now. It's cool that we have DO blocks here, and
pg_execute_sql_file() to offer the same facility as \i for psql scripts.

Hmm ...

I don't believe that extension SQL scripts should rely on DO blocks.
There is no requirement that plpgsql be installed, and we're not going
to create one as part of this feature. What this means is that the
design you offer above doesn't work at all, since it fundamentally
assumes that the SQL script can do conditional logic. What's more,
it fundamentally assumes that the script WILL do conditional logic
and support (in one lump) every possible combination of versions.
That's going to turn into buggy spaghetti-code very quickly.

I think that something that could work is more along the lines of the
extension containing different upgrade scripts for whatever set of cases
the author feels like supporting; for example the foo extension might
provide both
foo_upgrade.11.13.sql
foo_upgrade.12.13.sql
if the author is willing to support one-step upgrades from two preceding
versions to version 13. It would then be the responsibility of the
ALTER EXTENSION code to select and execute the correct upgrade script.
A missing script would be reported as an upgrade failure by ALTER
EXTENSION.

(Actually, we could probably assume that the target version is
implicitly "the current version", as identified from the control file,
and omit that from the script file names. That would avoid ambiguity
if version numbers can have more than one part.)

regards, tom lane

#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joshua D. Drake (#24)
Re: ALTER EXTENSION ... UPGRADE;

"Joshua D. Drake" <jd@commandprompt.com> writes:

On Fri, 2010-12-10 at 15:42 -0500, Andrew Dunstan wrote:

On 12/10/2010 03:24 PM, Josh Berkus wrote:

Also, once extensions and pgxn are operating full swing, I see contrib
going away anyway ...

We've heard this before, but I'm still quite skeptical about it. Quite
apart from anything else we should keep enough extensions in core to
test the extension mechanism, as well as to provide examples as part of
the base distribution. Some (e.g. hstore and citext) should probably
move into core. Others like pgcrypto are probably in just the right
place as they are.

I hope that contrib goes away. I agree with your assertion that things
like hstore and citext shoudl be in core but it is my hope that with
extensions and pgxn, there will be no reason for contrib to exist at
all.

I agree with Andrew --- we're going to need a collection of "standard
extensions" if only for testing purposes. It may someday not be called
contrib, but it'll still be there.

regards, tom lane

#27Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#25)
Re: ALTER EXTENSION ... UPGRADE;

Tom Lane <tgl@sss.pgh.pa.us> writes:

I don't believe that extension SQL scripts should rely on DO blocks.
There is no requirement that plpgsql be installed, and we're not going
to create one as part of this feature. What this means is that the
design you offer above doesn't work at all, since it fundamentally
assumes that the SQL script can do conditional logic. What's more,
it fundamentally assumes that the script WILL do conditional logic
and support (in one lump) every possible combination of versions.
That's going to turn into buggy spaghetti-code very quickly.

Yeah, I was picturing a main script that calls other ones by means of
PERFORM pg_execute_from_file('upgrade_script.sql');

Of course if plpgsql is not to be a requirement, the DO blocks hosting
the CASE logic won't fly and all that blows away.

I think that something that could work is more along the lines of the
extension containing different upgrade scripts for whatever set of cases
the author feels like supporting; for example the foo extension might
provide both
foo_upgrade.11.13.sql
foo_upgrade.12.13.sql
if the author is willing to support one-step upgrades from two preceding
versions to version 13. It would then be the responsibility of the
ALTER EXTENSION code to select and execute the correct upgrade script.
A missing script would be reported as an upgrade failure by ALTER
EXTENSION.

(Actually, we could probably assume that the target version is
implicitly "the current version", as identified from the control file,
and omit that from the script file names. That would avoid ambiguity
if version numbers can have more than one part.)

I don't think we can safely design around one part version numbers here,
because I'm yet to see that happening in any extension I've had my hands
on, which means a few already, as you can imagine.

Now, what about having the control file host an 'upgrade' property where
to put the script name? We would have to support a way for this filename
to depend on the already installed version, I'm thinking that %v might
be the easiest here (read: I want to avoid depending on any version
scheme).

version = '13'
script = 'foo.sql'
upgrade = 'foo_upgrade.%v.13.sql'

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#28Josh Berkus
josh@agliodbs.com
In reply to: Dimitri Fontaine (#22)
Re: ALTER EXTENSION ... UPGRADE;

On 12/10/10 12:34 PM, Dimitri Fontaine wrote:

Josh Berkus <josh@agliodbs.com> writes:

I think that each contrib needs its own version numbers. The reason
being that most minor updates don't touch contrib.

Fair enough. What are the version numbers of each current contribs?

I'd say that for anything in /contrib, it gets a new version with each
major version of postgresql, but not with each minor version. Thus,
say, dblink when 9.1.0 is release would be dblink 9.1-1. If in 9.1.4 we
fix a bug in dblink, then it becomes dblink 9.1-2.

This is confusing from a version number perpsective, but it prevents
admins from having to run extension upgrades when nothing has changed.

The alternative would be to match postgresql minor version numbering
exactly, and then come up with some way to have a "no-op" upgrade in the
frequent cases where the contrib module isn't changed during a minor
release. This would also require some kind of "upgrade all" command for
contrib.

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#29Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Josh Berkus (#28)
Re: ALTER EXTENSION ... UPGRADE;

Josh Berkus <josh@agliodbs.com> writes:

The alternative would be to match postgresql minor version numbering
exactly, and then come up with some way to have a "no-op" upgrade in the
frequent cases where the contrib module isn't changed during a minor
release. This would also require some kind of "upgrade all" command for
contrib.

That's as easy as having non-continuous version numbering. In your
example, we get from dblink version 9.1.0 to 9.1.4, but the 3 releases
before that it remains dblink 9.1.0.

Would it cut it?
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#30Aidan Van Dyk
aidan@highrise.ca
In reply to: Dimitri Fontaine (#27)
Re: ALTER EXTENSION ... UPGRADE;

On Fri, Dec 10, 2010 at 4:50 PM, Dimitri Fontaine
<dimitri@2ndquadrant.fr> wrote:

Now, what about having the control file host an 'upgrade' property where
to put the script name? We would have to support a way for this filename
to depend on the already installed version, I'm thinking that %v might
be the easiest here (read: I want to avoid depending on any version
scheme).

 version = '13'
 script  = 'foo.sql'
 upgrade = 'foo_upgrade.%v.13.sql'

If I was linking of putting bundling my "utiliites" up as an extension
(yes, I would that from a packaging/DB management perspective), I
think I'ld like a control like that, but with a bit of a "wildcard"
version matching, something like:
version = '3.12'
upgrade-1. = 'utils-upgrade-1.0.sql'
upgrade-2. = 'utils-upgrade-2..0.sql
upgrade-3. = 'nothing'

I'm thinking of a scheme where the upgrade-$VERSION uses a prefix
match, so 1.1, 1.2, 1.3 would all be matched by "1.". The 3.=nothing
is some way of specifing you don't need to do anything, becuase my n.X
release are all compatible sql->so wise. They would only be "bug
fixes" if I did something wrong in my stuff.. Anything not compatible
woudl bump the first number.

If it's a "prefix" type match, then the PG versionins woudl work too,
for intsance:
upgrade-9.0.=...
would match any pg 9.0.*

I guess you could use SQL like if that' more "consitent"...

a.

--
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

#31David E. Wheeler
david@kineticode.com
In reply to: Josh Berkus (#28)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 1:55 PM, Josh Berkus wrote:

I'd say that for anything in /contrib, it gets a new version with each
major version of postgresql, but not with each minor version. Thus,
say, dblink when 9.1.0 is release would be dblink 9.1-1. If in 9.1.4 we
fix a bug in dblink, then it becomes dblink 9.1-2.

Please don't add "-" to version numbers.

This is confusing from a version number perpsective, but it prevents
admins from having to run extension upgrades when nothing has changed.

The alternative would be to match postgresql minor version numbering
exactly, and then come up with some way to have a "no-op" upgrade in the
frequent cases where the contrib module isn't changed during a minor
release. This would also require some kind of "upgrade all" command for
contrib.

+1

David

#32David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#27)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 1:50 PM, Dimitri Fontaine wrote:

(Actually, we could probably assume that the target version is
implicitly "the current version", as identified from the control file,
and omit that from the script file names. That would avoid ambiguity
if version numbers can have more than one part.)

I don't think we can safely design around one part version numbers here,
because I'm yet to see that happening in any extension I've had my hands
on, which means a few already, as you can imagine.

Why not? Simplest thing, to my mind, is to have

upgrade/foo-1.12.sql
upgrade/foo-1.13.sql
upgrade/foo-1.15.sql

Since you know the existing version number, you just run all that come after. For example, if the current version is 1.12, then you know to run foo-1.13.sql and foo-1.15.sql.

Now, what about having the control file host an 'upgrade' property where
to put the script name? We would have to support a way for this filename
to depend on the already installed version, I'm thinking that %v might
be the easiest here (read: I want to avoid depending on any version
scheme).

version = '13'
script = 'foo.sql'
upgrade = 'foo_upgrade.%v.13.sql'

I think that's way more complicated than necessary.

Best,

David

#33Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#32)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 1:50 PM, Dimitri Fontaine wrote:

I don't think we can safely design around one part version numbers here,
because I'm yet to see that happening in any extension I've had my hands
on, which means a few already, as you can imagine.

Why not? Simplest thing, to my mind, is to have

upgrade/foo-1.12.sql
upgrade/foo-1.13.sql
upgrade/foo-1.15.sql

Since when is 1.12 a one part version number? :)

Since you know the existing version number, you just run all that come
after. For example, if the current version is 1.12, then you know to
run foo-1.13.sql and foo-1.15.sql.

I don't think imposing what version numbers must look like and what the
separators in the file names should be is a good idea.

version = '13'
script = 'foo.sql'
upgrade = 'foo_upgrade.%v.13.sql'

I think that's way more complicated than necessary.

It's just moving the complexity from the rules for the user to obey to
having them explain us by which rules they're playing. I personally very
much prefer the later, as you can imagine.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#34David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#33)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 2:32 PM, Dimitri Fontaine wrote:

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 1:50 PM, Dimitri Fontaine wrote:

I don't think we can safely design around one part version numbers here,
because I'm yet to see that happening in any extension I've had my hands
on, which means a few already, as you can imagine.

Why not? Simplest thing, to my mind, is to have

upgrade/foo-1.12.sql
upgrade/foo-1.13.sql
upgrade/foo-1.15.sql

Since when is 1.12 a one part version number? :)

What difference does it make how many parts there are? If it's a naming convention, you just match /$extension-(.+?)\.sql$/. Simple.

Since you know the existing version number, you just run all that come
after. For example, if the current version is 1.12, then you know to
run foo-1.13.sql and foo-1.15.sql.

I don't think imposing what version numbers must look like and what the
separators in the file names should be is a good idea.

The version numbers can be anything, so long as there *are* version numbers. And the rest of the file name should be just like the extension.

It's just moving the complexity from the rules for the user to obey to
having them explain us by which rules they're playing. I personally very
much prefer the later, as you can imagine.

You keep making extension authors have to do more work. I keep trying to make it so they can do less. We want the barrier to be as low as possible, which means a lot of DRY. Make it *possible* to do more complicated things, but don't *require* it.

Best,

David

#35Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#32)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 1:50 PM, Dimitri Fontaine wrote:
(Actually, we could probably assume that the target version is
implicitly "the current version", as identified from the control file,
and omit that from the script file names. That would avoid ambiguity
if version numbers can have more than one part.)

I don't think we can safely design around one part version numbers here,
because I'm yet to see that happening in any extension I've had my hands
on, which means a few already, as you can imagine.

Why not? Simplest thing, to my mind, is to have

upgrade/foo-1.12.sql
upgrade/foo-1.13.sql
upgrade/foo-1.15.sql

Since you know the existing version number, you just run all that come after. For example, if the current version is 1.12, then you know to run foo-1.13.sql and foo-1.15.sql.

If we assume the target is the current version, then we only need the
old-version number in the file name, so it doesn't matter how many
parts it has.

regards, tom lane

#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#28)
Re: ALTER EXTENSION ... UPGRADE;

Josh Berkus <josh@agliodbs.com> writes:

I'd say that for anything in /contrib, it gets a new version with each
major version of postgresql, but not with each minor version. Thus,
say, dblink when 9.1.0 is release would be dblink 9.1-1. If in 9.1.4 we
fix a bug in dblink, then it becomes dblink 9.1-2.
...
The alternative would be to match postgresql minor version numbering
exactly, and then come up with some way to have a "no-op" upgrade in the
frequent cases where the contrib module isn't changed during a minor
release. This would also require some kind of "upgrade all" command for
contrib.

99% of the time, "fix a bug" just means some C code changes. We should
not force DBAs to go through special upgrade commands unless there is
some change in the SQL objects created by the extension --- and just as
we discourage changes in the SQL objects created by the core during
minor releases, we should discourage such changes in minor extension
updates. So the case where ALTER EXTENSION UPGRADE is needed will be
the exception not the rule.

regards, tom lane

#37Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#34)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

You keep making extension authors have to do more work. I keep trying
to make it so they can do less. We want the barrier to be as low as
possible, which means a lot of DRY. Make it *possible* to do more
complicated things, but don't *require* it.

Sorry, imposing that - ain't part of the version number string won't
make any impression on me as far as getting simple is concerned. Go find
a single debian package not having - in its version number, and that's a
native software (developed to build debian).

For details, see the following, then explain me how RPM is so
differently simple, and then why I should care.

http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version

So really, using %v to say "put the current version number here" does
not seem like a problem for me, it allows me not to have to think about
*any* files naming rules nor version numbering scheme.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#38David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#35)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 2:40 PM, Tom Lane wrote:

Since you know the existing version number, you just run all that come after. For example, if the current version is 1.12, then you know to run foo-1.13.sql and foo-1.15.sql.

If we assume the target is the current version, then we only need the
old-version number in the file name, so it doesn't matter how many
parts it has.

Exactly.

Best,

David

#39David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#37)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 2:43 PM, Dimitri Fontaine wrote:

"David E. Wheeler" <david@kineticode.com> writes:

You keep making extension authors have to do more work. I keep trying
to make it so they can do less. We want the barrier to be as low as
possible, which means a lot of DRY. Make it *possible* to do more
complicated things, but don't *require* it.

Sorry, imposing that - ain't part of the version number string won't
make any impression on me as far as getting simple is concerned. Go find
a single debian package not having - in its version number, and that's a
native software (developed to build debian).

I'm making no such imposition. I'd rather it not be in contrib version numbers, because they should adhere to PostgreSQL-standard version numbering IMHO. YOu can use any characters you want in the version string. The upgrade file names simply start with "$extension-", so the format is "$extension-$version.sql". That's it.

For details, see the following, then explain me how RPM is so
differently simple, and then why I should care.

http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version

So really, using %v to say "put the current version number here" does
not seem like a problem for me, it allows me not to have to think about
*any* files naming rules nor version numbering scheme.

It's just not necessary.

Best,

David

#40Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#35)
Re: ALTER EXTENSION ... UPGRADE;

Tom Lane <tgl@sss.pgh.pa.us> writes:

If we assume the target is the current version, then we only need the
old-version number in the file name, so it doesn't matter how many
parts it has.

IIUC, that puts even more work on the shoulders of the extension
authors, because the file named foo-1.12.sql is the one used to upgrade
from 1.12. That means that at each release, it's a different file
content, it's there to upgrade to a newer release.

Well it works too, of course, and we don't care how many dashes we find
in the filename, it's extension-version.sql. I'd be ok with that too.

So, we have a sound proposal for the ALTER EXTENSION UPGRADE command,
which comes later. So we keep version numbers in the CREATE EXTENSION
patch and the control files, and remove the facility to get this number
from the Makefile. Is that right?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#41Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dimitri Fontaine (#37)
Re: ALTER EXTENSION ... UPGRADE;

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

"David E. Wheeler" <david@kineticode.com> writes:

You keep making extension authors have to do more work. I keep trying
to make it so they can do less. We want the barrier to be as low as
possible, which means a lot of DRY. Make it *possible* to do more
complicated things, but don't *require* it.

So really, using %v to say "put the current version number here" does
not seem like a problem for me, it allows me not to have to think about
*any* files naming rules nor version numbering scheme.

Maybe I misread David's meaning, but I thought he was saying that
there's no value in inventing all those control file entries in the
first place. Just hard-wire in ALTER EXTENSION UPGRADE the convention
that the name of an upgrade script to upgrade from prior version VVV is
EXTNAME-upgrade.VVV.sql (or any variant spelling of that you care for).
What is the point of letting/making extension authors invent their own
naming schemes? That has no benefit that I can perceive, and the
disadvantage that lack of uniformity will confuse users.

As for the question of what characters should be expected in version
numbers, +1 for digits and dots only. There's no good reason for
something else. Even the Debian document you quote points out that
hyphens in upstream version numbers give them problems, and Red Hat
style packaging rules flat out disallow hyphens. (hyphen-something is
for the packager to use, not the upstream software.)

regards, tom lane

#42David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#40)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 2:55 PM, Dimitri Fontaine wrote:

Tom Lane <tgl@sss.pgh.pa.us> writes:

If we assume the target is the current version, then we only need the
old-version number in the file name, so it doesn't matter how many
parts it has.

IIUC, that puts even more work on the shoulders of the extension
authors, because the file named foo-1.12.sql is the one used to upgrade
from 1.12. That means that at each release, it's a different file
content, it's there to upgrade to a newer release.

Yeah, it should be *to* 1.12. FWIW, this is how Bricolage upgrade scripts are handled: version-string-named directories with the appropriate scripts to upgrade *to* the named version number.

So, we have a sound proposal for the ALTER EXTENSION UPGRADE command,
which comes later. So we keep version numbers in the CREATE EXTENSION
patch and the control files, and remove the facility to get this number
from the Makefile. Is that right?

Yes. No new variables in Makefile at all IIUC.

Best,

David

#43David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#41)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 2:58 PM, Tom Lane wrote:

Maybe I misread David's meaning, but I thought he was saying that
there's no value in inventing all those control file entries in the
first place. Just hard-wire in ALTER EXTENSION UPGRADE the convention
that the name of an upgrade script to upgrade from prior version VVV is
EXTNAME-upgrade.VVV.sql (or any variant spelling of that you care for).
What is the point of letting/making extension authors invent their own
naming schemes? That has no benefit that I can perceive, and the
disadvantage that lack of uniformity will confuse users.

Yes, except that the version number in the file name should be the version it upgrades *to*, not *from*.

As for the question of what characters should be expected in version
numbers, +1 for digits and dots only. There's no good reason for
something else. Even the Debian document you quote points out that
hyphens in upstream version numbers give them problems, and Red Hat
style packaging rules flat out disallow hyphens. (hyphen-something is
for the packager to use, not the upstream software.)

I've mandated semantic versions for PGXN, mainly because it's simple and because it's close enough to the version numbers used in core.

http://semver.org/

If we're going to be comparing version strings in file names, we'll need *something* to use to compare what's higher than another number.

Best,

David

#44Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#42)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

Yeah, it should be *to* 1.12. FWIW, this is how Bricolage upgrade scripts are handled: version-string-named directories with the appropriate scripts to upgrade *to* the named version number.

But you still have to know what you're upgrading *from*.

If we use subdirectories then it'd work to put one number in the subdir
name and the other in the file name.

regards, tom lane

#45David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#44)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 3:03 PM, Tom Lane wrote:

Yeah, it should be *to* 1.12. FWIW, this is how Bricolage upgrade scripts are handled: version-string-named directories with the appropriate scripts to upgrade *to* the named version number.

But you still have to know what you're upgrading *from*.

Huh? It's in the pg_extension catalog.

Best,

David

#46Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#45)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 3:03 PM, Tom Lane wrote:

Yeah, it should be *to* 1.12. FWIW, this is how Bricolage upgrade scripts are handled: version-string-named directories with the appropriate scripts to upgrade *to* the named version number.

But you still have to know what you're upgrading *from*.

Huh? It's in the pg_extension catalog.

How do you select which upgrade script to apply?

regards, tom lane

#47David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#46)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 4:15 PM, Tom Lane wrote:

Huh? It's in the pg_extension catalog.

How do you select which upgrade script to apply?

You run all those that contain version numbers higher than the currently-installed one.

This of course assumes that one can correctly tell that one version number is higher than another.

Best,

David

#48Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#47)
Re: ALTER EXTENSION ... UPGRADE;

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 10, 2010, at 4:15 PM, Tom Lane wrote:

How do you select which upgrade script to apply?

You run all those that contain version numbers higher than the currently-installed one.

This of course assumes that one can correctly tell that one version number is higher than another.

This idea is not exactly free of disadvantages.

1. It assumes that the underlying .so supports not only the current
version, but every intermediate version of the SQL objects. For
example, say the previously installed version was 1.10, and we are
trying to go to 1.12. With your proposal we must pass through the
catalog state applicable to 1.11. What if that includes some SQL
function whose underlying C function is no longer there? The
CREATE FUNCTION command will fail, that's what, even though the
next update file would have deleted it or more likely replaced it
with a reference to some other underlying function.

2. It can't tell whether a missing update file means "no work is
required" or "no upgrade is possible"; in fact, without quite a lot of
assumptions about version numbers, it can't even tell that an
intermediate version update file is missing at all. I assume you expect
that the backend would treat a missing file as "no work is required",
but that carries a lot of risk of winding up in a bad state if a file
fails to get installed or fails to get read for some reason.

I'd much rather expect the extension author to explicitly support each
pair of (from, to) version numbers that he's prepared to deal with.
If he can build those update scripts as simple concatenations of
single-step scripts, great; but let's not hard-wire the assumption that
that approach MUST work.

regards, tom lane

#49David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#48)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 10, 2010, at 4:39 PM, Tom Lane wrote:

This idea is not exactly free of disadvantages.

1. It assumes that the underlying .so supports not only the current
version, but every intermediate version of the SQL objects. For
example, say the previously installed version was 1.10, and we are
trying to go to 1.12. With your proposal we must pass through the
catalog state applicable to 1.11. What if that includes some SQL
function whose underlying C function is no longer there? The
CREATE FUNCTION command will fail, that's what, even though the
next update file would have deleted it or more likely replaced it
with a reference to some other underlying function.

Yes, I always forget about shared objects, since most of the stuff I do isn't C.

2. It can't tell whether a missing update file means "no work is
required" or "no upgrade is possible"; in fact, without quite a lot of
assumptions about version numbers, it can't even tell that an
intermediate version update file is missing at all. I assume you expect
that the backend would treat a missing file as "no work is required",
but that carries a lot of risk of winding up in a bad state if a file
fails to get installed or fails to get read for some reason.

That seems relatively low-risk to me.

I'd much rather expect the extension author to explicitly support each
pair of (from, to) version numbers that he's prepared to deal with.
If he can build those update scripts as simple concatenations of
single-step scripts, great; but let's not hard-wire the assumption that
that approach MUST work.

This does eliminate the need for the core to mandate a version number scheme, but it could create a *lot* more maintenance work for a rapidly-evolving extension. I doubt I would ever have got very far with pgTAP if I'd had to do something like this.

Best,

David

#50Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#48)
Re: ALTER EXTENSION ... UPGRADE;

Tom,

I'd much rather expect the extension author to explicitly support each
pair of (from, to) version numbers that he's prepared to deal with.
If he can build those update scripts as simple concatenations of
single-step scripts, great; but let's not hard-wire the assumption that
that approach MUST work.

That's an n^2 problem.

However, I don't see any obvious way to avoid it.

We would want to support some wildcarding, though, just to avoid having
1,000 version-to-version files in every extension when a lot of the
upgrade actions might be generic. Of course, in order to do
wildcarding, we need to mandate a version numbering system ...

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#51Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#25)
Re: ALTER EXTENSION ... UPGRADE;

Tom,

I don't believe that extension SQL scripts should rely on DO blocks.
There is no requirement that plpgsql be installed, and we're not going
to create one as part of this feature. What this means is that the
design you offer above doesn't work at all, since it fundamentally
assumes that the SQL script can do conditional logic. What's more,
it fundamentally assumes that the script WILL do conditional logic
and support (in one lump) every possible combination of versions.
That's going to turn into buggy spaghetti-code very quickly.

I just noticed this response, and don't think it can stand as-is.

While I agree that it's not reasonable to have a single script which
supports every combination of versions, I also assert that it's
completely unreasonable to expect extension authors to write upgrade
scripts with no conditional logic. Your view would essentially be
requiring authors to write a completely seperate SQL script for every
single possible combination of two versions.

For an extension which has had 10 releases with SQL modifications, this
would be 45 separate upgrade files. That's a ridiculous thing to expect
of any contributor.

I, for one, have no problem whatsoever with requiring that users have
plpgsql installed in order to use extensions. It's installed by default.
If they need to uninstall plpgsql for some security reason, then fine;
they can write their own upgrade scripts. You are pushing making things
easy for 0.5% of our users at the expense of everyone else.

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#52Robert Haas
robertmhaas@gmail.com
In reply to: Josh Berkus (#51)
Re: ALTER EXTENSION ... UPGRADE;

On Fri, Dec 10, 2010 at 8:14 PM, Josh Berkus <josh@agliodbs.com> wrote:

I don't believe that extension SQL scripts should rely on DO blocks.
There is no requirement that plpgsql be installed, and we're not going
to create one as part of this feature.  What this means is that the
design you offer above doesn't work at all, since it fundamentally
assumes that the SQL script can do conditional logic.  What's more,
it fundamentally assumes that the script WILL do conditional logic
and support (in one lump) every possible combination of versions.
That's going to turn into buggy spaghetti-code very quickly.

I just noticed this response, and don't think it can stand as-is.

While I agree that it's not reasonable to have a single script which
supports every combination of versions, I also assert that it's
completely unreasonable to expect extension authors to write upgrade
scripts with no conditional logic.  Your view would essentially be
requiring authors to write a completely seperate SQL script for every
single possible combination of two versions.

For an extension which has had 10 releases with SQL modifications, this
would be 45 separate upgrade files.  That's a ridiculous thing to expect
of any contributor.

I, for one, have no problem whatsoever with requiring that users have
plpgsql installed in order to use extensions. It's installed by default.
If they need to uninstall plpgsql for some security reason, then fine;
they can write their own upgrade scripts.  You are pushing making things
easy for 0.5% of our users at the expense of everyone else.

Yea, verily. I share Tom's concern about depending on a procedural
language that isn't absolutely guaranteed to be there, but crippling
the extension mechanism is a bad solution. Conditional logic is
important, and we need to have it. If we're really bent on making
this watertight, we can either somehow nail down PL/pgsql so that it's
always present, or add conditional logic to straight SQL, or some
other magic I'm not thinking of. Or we can just suck up the fact that
people who uninstall PL/pgsql are not going to be able to install
extensions that depend on PL/pgsql, which isn't great, but I think it
beats the alternative.

In my not-inconsiderable experience writing upgrade scripts, most of
the time, you just add new objects. So if CREATE OR REPLACE or CREATE
IF NOT EXISTS is available, you only need one upgrade script to
upgrade from ANY prior version. And most of what people create with
these scripts are functions, which have CREATE OR REPLACE. However,
every once in a while you want to change the definition of an existing
object, at which point you enter what I like to call dependency hell.
If the object has no dependencies, you can just drop and recreate it,
but if it does, go directly to unspeakable agony. A further problem
with extensions is that we haven't got either COR or CINE for things
like types, operator classes, operator class members, etc. If we
decline to add that, then people are going to have to work around it
by writing the logic in PL/pgsql.... or else go with Tom's suggestion
of having a separate script for every to/from combination.

But I don't think that's really the right way to go. I think what
will quickly happen is that the conditional logic will move out of the
SQL script itself and into complicated Makefile hackery which will
generate a whole bunch of similar but not quite identical upgrade
scripts. Blech.

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

#53Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#41)
Re: ALTER EXTENSION ... UPGRADE;

Hi,

I've been reading through the entire thread and it seems like this is
the best mail to choose to answer.

Tom Lane <tgl@sss.pgh.pa.us> writes:

Maybe I misread David's meaning, but I thought he was saying that
there's no value in inventing all those control file entries in the
first place. Just hard-wire in ALTER EXTENSION UPGRADE the convention
that the name of an upgrade script to upgrade from prior version VVV is
EXTNAME-upgrade.VVV.sql (or any variant spelling of that you care for).

Yeah that works, as soon as VVV is the version we upgrade from.

That said, we need to find a way to lighten the process for extensions
where it's easy to have a single script to support upgrade from more
than once past release.

What about having the following keys supported in the control file:

upgrade_<version> = 'script.version.sql'
upgrade_all = 'script.sql'

Where the version here is the version you're upgrading *from* (to is
known and static when you distribute the files after all), and where
upgrade_all is applied last no matter what got applied before.

Also, do we want a subdirectory per extension to host all those files?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#54David Fetter
david@fetter.org
In reply to: Tom Lane (#6)
Re: Extensions, patch v16

On Fri, Dec 10, 2010 at 11:24:27AM -0500, Tom Lane wrote:

Dimitri Fontaine <dimitri@2ndQuadrant.fr> writes:

Tom Lane <tgl@sss.pgh.pa.us> writes:

Are there any actual remaining use-cases for that sed step?

The goal here is to allow extension authors to maintain their version
number in the Makefile rather than in the Makefile and in the control
file separately. Having the same version number in more than one place
never eases maintenance.

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

We *absolutely* need version numbers in extensions. People will want
to have a certain version, or a certain minimum version, etc., etc.,
etc., just as they do for any other software.

Seriously, are you OK?

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#55David E. Wheeler
david@kineticode.com
In reply to: David Fetter (#54)
Re: Extensions, patch v16

On Dec 11, 2010, at 1:09 PM, David Fetter wrote:

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

We *absolutely* need version numbers in extensions. People will want
to have a certain version, or a certain minimum version, etc., etc.,
etc., just as they do for any other software.

Seriously, are you OK?

One of the biggest mistakes in the creation of CPAN was allowing modules without extensions. It makes figuring out what to upgrade extremely difficult. Learning from that, PGXN requires version numbers for all extensions.

Best,

David

#56David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#53)
Re: ALTER EXTENSION ... UPGRADE;

On Dec 11, 2010, at 12:09 PM, Dimitri Fontaine wrote:

Yeah that works, as soon as VVV is the version we upgrade from.

That said, we need to find a way to lighten the process for extensions
where it's easy to have a single script to support upgrade from more
than once past release.

What about having the following keys supported in the control file:

upgrade_<version> = 'script.version.sql'
upgrade_all = 'script.sql'

Why not just use an upgrade script naming convention? Think: Convention over configuration.

Where the version here is the version you're upgrading *from* (to is
known and static when you distribute the files after all), and where
upgrade_all is applied last no matter what got applied before.

Also, do we want a subdirectory per extension to host all those files?

How are things currently arranged?

Best,

David

#57Oleg Bartunov
oleg@sai.msu.su
In reply to: David E. Wheeler (#55)
Re: Extensions, patch v16

Hi there,

it's clear we need versions, probably, major.minor would be enough. The problem
I see is how to keep .so in sync with .sql ? Should we store .sql in database ?

Also, we need permissions for extension, since we have open/closed
extensions.

Oleg

On Sat, 11 Dec 2010, David E. Wheeler wrote:

On Dec 11, 2010, at 1:09 PM, David Fetter wrote:

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

We *absolutely* need version numbers in extensions. People will want
to have a certain version, or a certain minimum version, etc., etc.,
etc., just as they do for any other software.

Seriously, are you OK?

One of the biggest mistakes in the creation of CPAN was allowing modules without extensions. It makes figuring out what to upgrade extremely difficult. Learning from that, PGXN requires version numbers for all extensions.

Best,

David

Regards,
Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

#58Aidan Van Dyk
aidan@highrise.ca
In reply to: David E. Wheeler (#56)
Re: ALTER EXTENSION ... UPGRADE;

On Sat, Dec 11, 2010 at 4:35 PM, David E. Wheeler <david@kineticode.com> wrote:

What about having the following keys supported in the control file:

 upgrade_<version> = 'script.version.sql'
 upgrade_all = 'script.sql'

Why not just use an upgrade script naming convention? Think: Convention over configuration.

Mainly, because of the situation where I have may versions that can
all be upgraded from the same script. I'ld much rather distribution
just 3 scripts (install + 2 upgrades), and a control file with
something like this (pretend I'm on version 2.6)
upgragde-1.0 = $EXT-upgrade-1.sql
upgragde-1.1 = $EXT-upgrade-1.sql
upgragde-1.1.1 = $EXT-upgrade-1.sql
upgragde-1.1.2 = $EXT-upgrade-1.sql
upgragde-1.2 = $EXT-upgrade-1.sql
upgragde-1.3 = $EXT-upgrade-1.sql
upgragde-1.4 = $EXT-upgrade-1.sql
upgragde-1.4.1 = $EXT-upgrade-1.sql
upgrade-2.0 = $EXT-upgrade-2.sql
upgrade-2.1 = $EXT-upgrade-2.sql
upgrade-2.2 = $EXT-upgrade-2.sql
upgrade-2.2.1 = $EXT-upgrade-2.sql
upgrade-2.3 = $EXT-upgrade-2.sql
upgrade-2.4 = $EXT-upgrade-2.sql
upgrade-2.5 = $EXT-upgrade-2.sql

Forcing convention on me to maitain/install an upgrade script for
every single version is way more than asking me to just specify an
upgrade script for versions.

Again, I'ld love for the "version" to support some sort of prefix or
wildcard matching, so I could do:
upgrade-1.* = $EXT-upgrade-1.sql
upgrade-2.* = $EXT-upgrade-2.sql

a.

--
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

#59Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Aidan Van Dyk (#58)
Re: ALTER EXTENSION ... UPGRADE;

Aidan Van Dyk <aidan@highrise.ca> writes:

Mainly, because of the situation where I have may versions that can
all be upgraded from the same script. I'ld much rather distribution
just 3 scripts (install + 2 upgrades), and a control file with
something like this (pretend I'm on version 2.6)
upgragde-1.0 = $EXT-upgrade-1.sql

[...]

upgrade-2.5 = $EXT-upgrade-2.sql

Thanks for the example.

Again, I'ld love for the "version" to support some sort of prefix or
wildcard matching, so I could do:
upgrade-1.* = $EXT-upgrade-1.sql
upgrade-2.* = $EXT-upgrade-2.sql

Problem is: what to do if a single upgrade matches more than one line?
The only safe answer is to error out and refuse to upgrade but that
ain't nice to the user. How much is that a problem here?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#60Aidan Van Dyk
aidan@highrise.ca
In reply to: Dimitri Fontaine (#59)
Re: ALTER EXTENSION ... UPGRADE;

On Mon, Dec 13, 2010 at 9:55 AM, Dimitri Fontaine
<dimitri@2ndquadrant.fr> wrote:

Again, I'ld love for the "version" to support some sort of prefix or
wildcard matching, so I could do:
    upgrade-1.* =  $EXT-upgrade-1.sql
    upgrade-2.* =  $EXT-upgrade-2.sql

Problem is: what to do if a single upgrade matches more than one line?
The only safe answer is to error out and refuse to upgrade but that
ain't nice to the user. How much is that a problem here?

To get a wildcard match (or a prefix match) for version upgrades, I'ld
be willing to have that error if I give a bad set of version matches.
If only have those 2 lines to manage, it's a lot more likely I won't
mess them up than if I have to manage 30 almost identical lines and
not miss/duplicate a version.

;-)

--
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

#61Tom Lane
tgl@sss.pgh.pa.us
In reply to: Aidan Van Dyk (#58)
Re: ALTER EXTENSION ... UPGRADE;

Aidan Van Dyk <aidan@highrise.ca> writes:

On Sat, Dec 11, 2010 at 4:35 PM, David E. Wheeler <david@kineticode.com> wrote:

Why not just use an upgrade script naming convention?

Mainly, because of the situation where I have may versions that can
all be upgraded from the same script. I'ld much rather distribution
just 3 scripts (install + 2 upgrades), and a control file with
something like this (pretend I'm on version 2.6)
upgragde-1.0 = $EXT-upgrade-1.sql
upgragde-1.1 = $EXT-upgrade-1.sql
upgragde-1.1.1 = $EXT-upgrade-1.sql
upgragde-1.1.2 = $EXT-upgrade-1.sql
upgragde-1.2 = $EXT-upgrade-1.sql
upgragde-1.3 = $EXT-upgrade-1.sql
upgragde-1.4 = $EXT-upgrade-1.sql
upgragde-1.4.1 = $EXT-upgrade-1.sql
upgrade-2.0 = $EXT-upgrade-2.sql
upgrade-2.1 = $EXT-upgrade-2.sql
upgrade-2.2 = $EXT-upgrade-2.sql
upgrade-2.2.1 = $EXT-upgrade-2.sql
upgrade-2.3 = $EXT-upgrade-2.sql
upgrade-2.4 = $EXT-upgrade-2.sql
upgrade-2.5 = $EXT-upgrade-2.sql

I see no advantage of this over a script per version combination, so
long as you allow scripts to \include each other.

regards, tom lane

#62Alvaro Herrera
alvherre@commandprompt.com
In reply to: Tom Lane (#61)
Re: ALTER EXTENSION ... UPGRADE;

Excerpts from Tom Lane's message of lun dic 13 12:50:43 -0300 2010:

I see no advantage of this over a script per version combination, so
long as you allow scripts to \include each other.

Hmm, are the upgrade scripts going to be run via SPI?

--
Álvaro Herrera <alvherre@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#63Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Tom Lane (#61)
Re: ALTER EXTENSION ... UPGRADE;

Tom Lane <tgl@sss.pgh.pa.us> writes:

I see no advantage of this over a script per version combination, so
long as you allow scripts to \include each other.

I guess the following should do:

SELECT pg_execute_sql_file('upgrade-1.sql');

But I rather prefer the 2-liner control file, myself:

upgrade-1.* = 'upgrade-1.sql'
upgrade-2.* = 'upgrade-2.sql'

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#64Bruce Momjian
bruce@momjian.us
In reply to: Oleg Bartunov (#57)
Re: Extensions, patch v16

Oleg Bartunov wrote:

Hi there,

it's clear we need versions, probably, major.minor would be enough. The problem
I see is how to keep .so in sync with .sql ? Should we store .sql in database ?

Also, we need permissions for extension, since we have open/closed
extensions.

Don't people normally define the version number in the Makefile and pass
the version string into the C code and perhaps a psql variable?

---------------------------------------------------------------------------

Oleg

On Sat, 11 Dec 2010, David E. Wheeler wrote:

On Dec 11, 2010, at 1:09 PM, David Fetter wrote:

Why is it in the makefile at all? If the makefile does need to know it,
why don't we have it scrape the number out of the control file? Or even
more to the point, since when do we need version numbers in extensions?

We *absolutely* need version numbers in extensions. People will want
to have a certain version, or a certain minimum version, etc., etc.,
etc., just as they do for any other software.

Seriously, are you OK?

One of the biggest mistakes in the creation of CPAN was allowing modules without extensions. It makes figuring out what to upgrade extremely difficult. Learning from that, PGXN requires version numbers for all extensions.

Best,

David

Regards,
Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

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

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#65David E. Wheeler
david@kineticode.com
In reply to: Bruce Momjian (#64)
Re: Extensions, patch v16

On Dec 29, 2010, at 12:00 PM, Bruce Momjian wrote:

Don't people normally define the version number in the Makefile and pass
the version string into the C code and perhaps a psql variable?

There is no standard pattern AFAIK. A best practice would be welcome here.

David

#66Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#64)
Re: Extensions, patch v16

Bruce Momjian <bruce@momjian.us> writes:

Oleg Bartunov wrote:

it's clear we need versions, probably, major.minor would be enough. The problem
I see is how to keep .so in sync with .sql ? Should we store .sql in database ?

Don't people normally define the version number in the Makefile and pass
the version string into the C code and perhaps a psql variable?

We had a long discussion upthread of what version numbers to keep where.
IMHO the Makefile is about the *least* useful place to put a version
number; the more so if you want more than one. What we seem to need is
a version number in the .sql file itself (so that we can tell whether we
need to take action to update the extension's catalog entries). I'm not
convinced yet whether there needs to be another version number embedded
in the .so file --- it may well be that the PG major version number
embedded with PG_MODULE_MAGIC is sufficient.

Personally I'd forget the notion of major.minor numbers here; all that
will accomplish is to complicate storage and comparison of the numbers.
We just need a simple integer that gets bumped whenever the extension's
SQL script changes.

regards, tom lane

#67David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#66)
Re: Extensions, patch v16

On Dec 29, 2010, at 12:23 PM, Tom Lane wrote:

We had a long discussion upthread of what version numbers to keep where.
IMHO the Makefile is about the *least* useful place to put a version
number; the more so if you want more than one. What we seem to need is
a version number in the .sql file itself (so that we can tell whether we
need to take action to update the extension's catalog entries). I'm not
convinced yet whether there needs to be another version number embedded
in the .so file --- it may well be that the PG major version number
embedded with PG_MODULE_MAGIC is sufficient.

For contrib maybe, but not 3rd-party extensions.

Personally I'd forget the notion of major.minor numbers here; all that
will accomplish is to complicate storage and comparison of the numbers.
We just need a simple integer that gets bumped whenever the extension's
SQL script changes.

That won't be very flexible for third-party extensions. FWIW, for PGXN I mandated symantic version numbers (http://semver.org/), mainly because they're quite close to Pg core version numbers. I also created a basic data type for them:

https://github.com/theory/pgxn-manager/blob/master/sql/02-types.sql#L70

Best,

David

#68Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#66)
Re: Extensions, patch v16

On Wed, Dec 29, 2010 at 3:23 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Bruce Momjian <bruce@momjian.us> writes:

Oleg Bartunov wrote:

it's clear we need versions, probably, major.minor would be enough. The problem
I see is how to keep .so in sync with .sql ? Should we store .sql in database ?

Don't people normally define the version number in the Makefile and pass
the version string into the C code and perhaps a psql variable?

We had a long discussion upthread of what version numbers to keep where.
IMHO the Makefile is about the *least* useful place to put a version
number; the more so if you want more than one.  What we seem to need is
a version number in the .sql file itself (so that we can tell whether we
need to take action to update the extension's catalog entries).  I'm not
convinced yet whether there needs to be another version number embedded
in the .so file --- it may well be that the PG major version number
embedded with PG_MODULE_MAGIC is sufficient.

Personally I'd forget the notion of major.minor numbers here; all that
will accomplish is to complicate storage and comparison of the numbers.
We just need a simple integer that gets bumped whenever the extension's
SQL script changes.

I think there are really two tasks here:

1. Identify whether a newer set of SQL definitions than the one
installed is available. If so, the extension is a candidate for an
upgrade.

2. Identify whether the installed version of the SQL definitions is
compatible with the installed shared object. If it's not, we'd like
the shared library load (or at a minimum, any use of the shared
library) to fail when attempted, rather than attempting to plunge
blindly onward and then crashing.

As to point #2, what an extension author would typically do (I hope)
is publish a new shared object is make it backward-compatible with
some number of previous versions of the SQL definitions, but not
necessarily all the way to the beginning of time. So the typical
upgrade sequence would be to install the new .so, and then upgrade the
SQL definitions. You'd want an interlock, though, in case someone
tried to use a set of SQL definitions that were either too new or too
old for the corresponding shared library. The "too new" case could
occur if someone installed a new version of the shared library,
upgraded the SQL definitions, and then put the old shared library file
back. The "too old" case could occur if the extension were upgraded
through many releases in a single step, such that whatever
backward-compatibility support existed in the shared library didn't
reach back far enough to cater to the ancient SQL definitions. In
either case, you want to chunk an error when someone tries to use the
module, rather than soldiering on blindly and crashing.

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

#69David E. Wheeler
david@kineticode.com
In reply to: Robert Haas (#68)
Re: Extensions, patch v16

On Dec 29, 2010, at 1:27 PM, Robert Haas wrote:

I think there are really two tasks here:

1. Identify whether a newer set of SQL definitions than the one
installed is available. If so, the extension is a candidate for an
upgrade.

2. Identify whether the installed version of the SQL definitions is
compatible with the installed shared object. If it's not, we'd like
the shared library load (or at a minimum, any use of the shared
library) to fail when attempted, rather than attempting to plunge
blindly onward and then crashing.

3. Check dependencies for one extension on other extensions.

As to point #2, what an extension author would typically do (I hope)
is publish a new shared object is make it backward-compatible with
some number of previous versions of the SQL definitions, but not
necessarily all the way to the beginning of time. So the typical
upgrade sequence would be to install the new .so, and then upgrade the
SQL definitions. You'd want an interlock, though, in case someone
tried to use a set of SQL definitions that were either too new or too
old for the corresponding shared library. The "too new" case could
occur if someone installed a new version of the shared library,
upgraded the SQL definitions, and then put the old shared library file
back. The "too old" case could occur if the extension were upgraded
through many releases in a single step, such that whatever
backward-compatibility support existed in the shared library didn't
reach back far enough to cater to the ancient SQL definitions. In
either case, you want to chunk an error when someone tries to use the
module, rather than soldiering on blindly and crashing.

Yeah, makes sense.

Best,

David

#70Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Robert Haas (#68)
Upgrading Extension, version numbers (was: Extensions, patch v16)

Robert Haas <robertmhaas@gmail.com> writes:

On Wed, Dec 29, 2010 at 3:23 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

We had a long discussion upthread of what version numbers to keep where.
IMHO the Makefile is about the *least* useful place to put a version
number; the more so if you want more than one.  What we seem to need is
a version number in the .sql file itself (so that we can tell whether we
need to take action to update the extension's catalog entries).  I'm not
convinced yet whether there needs to be another version number embedded
in the .so file --- it may well be that the PG major version number
embedded with PG_MODULE_MAGIC is sufficient.

In the .sql file? You mean something like:

ALTER EXTENSION ... SET VERSION '...';

It's currently managed in the .control file of the extension, which
allows us to list available extensions and their version number without
having to parse the .sql script from the C code...

Personally I'd forget the notion of major.minor numbers here; all that
will accomplish is to complicate storage and comparison of the numbers.
We just need a simple integer that gets bumped whenever the extension's
SQL script changes.

For contrib, as you wish. Now for third-party extensions, I don't see
us having any authority on what people will use internally in their
companies, etc.

1. Identify whether a newer set of SQL definitions than the one
installed is available. If so, the extension is a candidate for an
upgrade.

Well, it's currently (WIP in the upgrade branch of my repo) easier than
that, really. You have the control file on the file system and you have
the extension's entry in the catalogs.

http://git.postgresql.org/gitweb?p=postgresql-extension.git;a=shortlog;h=refs/heads/upgrade

What upgrade means here is running a given SQL script, that you choose
depending on the current and next version strings, following a scheme
that has been extensively discussed in another thread, and is currently
implemented like this:

# lo
comment = 'managing Large Objects'
version = '9.1devel'
relocatable = true
upgrade_from_null = 'null => lo.upgrade.sql'

Here, any property that begins with 'upgrade_from_' is considered as an
upgrade setup and the part after the prefix is not considered. The
value is meant to have two parts separated by '=>', first is either null
or a regexp matched against currently installed version number, second
part is the upgrade script name to use at ALTER EXTENSION ... UPGRADE.

We support 'null' version number to be able to "upgrade" from existing
code which is not organized as an extension yet. The aim is to be able
to:

CREATE EMPTY EXTENSION lo; -- version is null here
ALTER EXTENSION lo UPGRADE;

And run a script containing lines that will look like this:

alter domain @extschema@.lo set extension lo;
alter function @extschema@.lo_oid(lo) set extension lo;
alter function @extschema@.lo_manage() set extension lo;

Note that we always need to support the placeholder here, because of
course following dependencies at this point isn't possible.

2. Identify whether the installed version of the SQL definitions is
compatible with the installed shared object. If it's not, we'd like
the shared library load (or at a minimum, any use of the shared
library) to fail when attempted, rather than attempting to plunge
blindly onward and then crashing.

Well, the way I see things, it's already too late and there's nothing we
can easily do to prevent that. What I mean is that the user will
typically upgrade the OS-level package first, then apply the upgrade on
the database(s).

$ apt-get install postgresql-9.1-prefix
$ psql -U postgres -c 'alter extension prefix upgrade' somedb

At the time you tell PostgreSQL about the new extension, the shared
object file has been in place for some time already, and the upgrade SQL
script has not been ran yet.

What I hope extension authors will do is document whether any upgrade
requires a restart or will otherwise be responsible for instability in
the server for backend started with the newer .so before the upgrade
script has been run. So that users/DBA will know whether the upgrade
calls for a maintenance window.

I could see us trying to shoehorn such information into the control file
too, but would ERRORing out on LOAD be any better than taking the
compatibility chance? Knowing that the compatibility in most cases
depends a lot on the actual call paths?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#71David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#70)
Re: Upgrading Extension, version numbers (was: Extensions, patch v16)

On Dec 29, 2010, at 2:01 PM, Dimitri Fontaine wrote:

# lo
comment = 'managing Large Objects'
version = '9.1devel'
relocatable = true
upgrade_from_null = 'null => lo.upgrade.sql'

Here, any property that begins with 'upgrade_from_' is considered as an
upgrade setup and the part after the prefix is not considered. The
value is meant to have two parts separated by '=>', first is either null
or a regexp matched against currently installed version number, second
part is the upgrade script name to use at ALTER EXTENSION ... UPGRADE.

I thought we were going to try to avoid having entries for upgrades in the control file.

We support 'null' version number to be able to "upgrade" from existing
code which is not organized as an extension yet. The aim is to be able
to:

CREATE EMPTY EXTENSION lo; -- version is null here
ALTER EXTENSION lo UPGRADE;

And run a script containing lines that will look like this:

alter domain @extschema@.lo set extension lo;
alter function @extschema@.lo_oid(lo) set extension lo;
alter function @extschema@.lo_manage() set extension lo;

Note that we always need to support the placeholder here, because of
course following dependencies at this point isn't possible.

I thought placeholders were going away, too. Did I lose track?

Well, the way I see things, it's already too late and there's nothing we
can easily do to prevent that. What I mean is that the user will
typically upgrade the OS-level package first, then apply the upgrade on
the database(s).

$ apt-get install postgresql-9.1-prefix
$ psql -U postgres -c 'alter extension prefix upgrade' somedb

At the time you tell PostgreSQL about the new extension, the shared
object file has been in place for some time already, and the upgrade SQL
script has not been ran yet.

That sounds dangerous.

What I hope extension authors will do is document whether any upgrade
requires a restart or will otherwise be responsible for instability in
the server for backend started with the newer .so before the upgrade
script has been run. So that users/DBA will know whether the upgrade
calls for a maintenance window.

But if a new connection comes in, the .so will be loaded into the new child, no? Very dangerous.

I could see us trying to shoehorn such information into the control file
too, but would ERRORing out on LOAD be any better than taking the
compatibility chance? Knowing that the compatibility in most cases
depends a lot on the actual call paths?

The new .so should not be installed until the upgrade is been run.

Best,

David

#72Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#71)
Re: Upgrading Extension, version numbers (was: Extensions, patch v16)

"David E. Wheeler" <david@kineticode.com> writes:

On Dec 29, 2010, at 2:01 PM, Dimitri Fontaine wrote:

At the time you tell PostgreSQL about the new extension, the shared
object file has been in place for some time already, and the upgrade SQL
script has not been ran yet.

That sounds dangerous.

It is, but I don't see any alternative. As Dimitri said, the .so will
typically be installed by a packaging system, so we don't have any
opportunity to run SQL code beforehand. In any case ...

The new .so should not be installed until the upgrade is been run.

... that flat out doesn't work. If the upgrade script tries to add
functions that didn't exist in the old .so, it'll fail.

regards, tom lane

#73David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#72)
Re: Upgrading Extension, version numbers (was: Extensions, patch v16)

On Jan 3, 2011, at 11:42 AM, Tom Lane wrote:

It is, but I don't see any alternative. As Dimitri said, the .so will
typically be installed by a packaging system, so we don't have any
opportunity to run SQL code beforehand. In any case ...

The new .so should not be installed until the upgrade is been run.

... that flat out doesn't work. If the upgrade script tries to add
functions that didn't exist in the old .so, it'll fail.

Right, what I'm saying is that `ALTER EXTENSION foo UPGRADE;` should install the .so, too, just before it runs the upgrade scripts.

Best,

David

#74Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#71)
Re: Upgrading Extension, version numbers

"David E. Wheeler" <david@kineticode.com> writes:

I thought we were going to try to avoid having entries for upgrades in
the control file.

Not what I have understood.

http://archives.postgresql.org/pgsql-hackers/2010-12/msg01014.php
http://archives.postgresql.org/pgsql-hackers/2010-12/msg01045.php

AS there was no answer, the meaning for me is that it was ok to
proceed. On this list people agreeing often remain silent.

Note that we always need to support the placeholder here, because of
course following dependencies at this point isn't possible.

I thought placeholders were going away, too. Did I lose track?

Oh, dear, yes :) See the documentation for the relocatable parameter.
We know handle two kinds of extensions, some of them you can't offer
better than placeholders to allow users to define the schema where they
will land. Also, at upgrade time, I don't see any other way to solve
the problem. Do you?

http://pgsql.tapoueh.org/extensions/doc/html/extend-extension.html

At the time you tell PostgreSQL about the new extension, the shared
object file has been in place for some time already, and the upgrade SQL
script has not been ran yet.

That sounds dangerous.

Been doing that countless times. Yet to see a case where the new .so is
not compatible at all with the previous .sql and the author don't give
you any warning about the situation. In theory that's possible, in
practice we value upgrades high enough around here.

Other than that, I don't have another idea to make it work reliably.
I'm still reading, though. Meanwhile I've done what seems like a good
compromise and to follow practical use cases.

What I hope extension authors will do is document whether any upgrade
requires a restart or will otherwise be responsible for instability in
the server for backend started with the newer .so before the upgrade
script has been run. So that users/DBA will know whether the upgrade
calls for a maintenance window.

But if a new connection comes in, the .so will be loaded into the new child, no? Very dangerous.

Yeah. Before extension existed, it has always been working like that,
our users already depend on such a behavior, nothing new here. I just
don't see how extension could solve that is all I'm saying.

The new .so should not be installed until the upgrade is been run.

Nice statement. How do you make that happen?

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#75Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#73)
Re: Upgrading Extension, version numbers (was: Extensions, patch v16)

"David E. Wheeler" <david@kineticode.com> writes:

On Jan 3, 2011, at 11:42 AM, Tom Lane wrote:

... that flat out doesn't work. If the upgrade script tries to add
functions that didn't exist in the old .so, it'll fail.

Right, what I'm saying is that `ALTER EXTENSION foo UPGRADE;` should install the .so, too, just before it runs the upgrade scripts.

1. Doesn't work if you're upgrading an installation that has more than
one database using the extension. There's only one library directory.

2. Not possible from a permissions standpoint. Even if you think it'd
be smart to have the postgres daemon privileged enough to overwrite its
own executables, there is 0 chance of getting that past any distro.

regards, tom lane

#76David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#75)
Re: Upgrading Extension, version numbers (was: Extensions, patch v16)

On Jan 3, 2011, at 11:51 AM, Tom Lane wrote:

1. Doesn't work if you're upgrading an installation that has more than
one database using the extension. There's only one library directory.

2. Not possible from a permissions standpoint. Even if you think it'd
be smart to have the postgres daemon privileged enough to overwrite its
own executables, there is 0 chance of getting that past any distro.

Okay, got it.

Best,

David

#77David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#74)
Re: Upgrading Extension, version numbers

On Jan 3, 2011, at 11:46 AM, Dimitri Fontaine wrote:

Not what I have understood.

http://archives.postgresql.org/pgsql-hackers/2010-12/msg01014.php
http://archives.postgresql.org/pgsql-hackers/2010-12/msg01045.php

AS there was no answer, the meaning for me is that it was ok to
proceed. On this list people agreeing often remain silent.

There were several of us who were not silent.

http://archives.postgresql.org/pgsql-hackers/2010-12/msg00804.php
http://archives.postgresql.org/pgsql-hackers/2010-12/msg00796.php

The fact that the last two messages in the thread say something else does not mean that they represent the consensus.

Note that we always need to support the placeholder here, because of
course following dependencies at this point isn't possible.

I thought placeholders were going away, too. Did I lose track?

Oh, dear, yes :) See the documentation for the relocatable parameter.
We know handle two kinds of extensions, some of them you can't offer
better than placeholders to allow users to define the schema where they
will land. Also, at upgrade time, I don't see any other way to solve
the problem. Do you?

http://pgsql.tapoueh.org/extensions/doc/html/extend-extension.html

Right, I forgot about the relocatable parameter. I kind of expect that most extensions *would* be relocatable, though. Maybe it should be expected to be true if it's not present? Or perhaps require non-relocatable extensions to have a "fixed_schema" control key or something? Either will work, just trying to find the likely convention to avoid configuration in most cases. Maybe I'm wrong, though, and most extensions wouldn't be relocatable?

Yeah. Before extension existed, it has always been working like that,
our users already depend on such a behavior, nothing new here. I just
don't see how extension could solve that is all I'm saying.

Fair enough.

The new .so should not be installed until the upgrade is been run.

Nice statement. How do you make that happen?

Nope.

David

#78Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#77)
Re: Upgrading Extension, version numbers

"David E. Wheeler" <david@kineticode.com> writes:

The fact that the last two messages in the thread say something else
does not mean that they represent the consensus.

Yeah, but as I'm the one writing the code, I gave myself more than one
vote. And did consider the alternatives but didn't like them so much.

Right, I forgot about the relocatable parameter. I kind of expect that most extensions *would* be relocatable, though. Maybe it should be expected to be true if it's not present? Or perhaps require non-relocatable extensions to have a "fixed_schema" control key or something? Either will work, just trying to find the likely convention to avoid configuration in most cases. Maybe I'm wrong, though, and most extensions wouldn't be relocatable?

Most are, but it's not for granted. See adminpack. Or earthdistance
that I had to make not-relocatable for lack of dependency support, as it
depends on cube and ALTER EXTENSION earthdistance SET SCHEMA foo would
have relocated cube too. We said dependency can wait until v2.

I don't see the benefit of having the 'relocatable' property optional in
the control file, but I see a huge drawback. Requiring it will force
extension authors to at least have a glance at the docs to understand
how to set it. It's important not to overlook it.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#79David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#78)
Re: Upgrading Extension, version numbers

On Jan 3, 2011, at 12:23 PM, Dimitri Fontaine wrote:

"David E. Wheeler" <david@kineticode.com> writes:

The fact that the last two messages in the thread say something else
does not mean that they represent the consensus.

Yeah, but as I'm the one writing the code, I gave myself more than one
vote. And did consider the alternatives but didn't like them so much.

Just so long as you're aware that you might get more challenges on this going forward.

Most are, but it's not for granted. See adminpack. Or earthdistance
that I had to make not-relocatable for lack of dependency support, as it
depends on cube and ALTER EXTENSION earthdistance SET SCHEMA foo would
have relocated cube too. We said dependency can wait until v2.

I don't see the benefit of having the 'relocatable' property optional in
the control file, but I see a huge drawback. Requiring it will force
extension authors to at least have a glance at the docs to understand
how to set it. It's important not to overlook it.

I guess. I'll have to think about how to support it in PGXN, though. And the upgrade keys if they stay in.

David

#80Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#79)
Re: Upgrading Extension, version numbers

"David E. Wheeler" <david@kineticode.com> writes:

Just so long as you're aware that you might get more challenges on this going forward.

Sure, thanks for the reminder. That said I also remember the reaction
when I used to scan the SHARE/contrib directory to find the extension
control file having the right name property, and I don't see scanning
the same directory in order to find out which upgrade file to consider
depending on several parts of its name as so different.

Current code allows you to use the same upgrade script for more than one
source version, and does so in a way that it's easy to determine which
upgrade file to seek for.

I don't see the benefit of having the 'relocatable' property optional in
the control file, but I see a huge drawback. Requiring it will force
extension authors to at least have a glance at the docs to understand
how to set it. It's important not to overlook it.

I guess. I'll have to think about how to support it in PGXN, though. And the upgrade keys if they stay in.

Disclaimer: the following is based on my understanding of how you want
to bundle things, from several discussions we had together at pubs or
on IRC, please don't read further if you're changed your mind about
generating the control file from your PGXN YAML specification.

Well, I think you're having a dependency inversion problem here. PGXN
depends on extensions, not the other way round. Also, I really expect
the extension facility to be mainly used for internal proprietary code,
mainly procedure collections, and only occasionaly for publishing Open
Source components.

So you should be considering the control file as an input to your
processes, a source file, not something that your service will hide for
extension authors: there's no benefit that I can see in doing so.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#81David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#80)
Re: Upgrading Extension, version numbers

On Jan 4, 2011, at 12:46 AM, Dimitri Fontaine wrote:

"David E. Wheeler" <david@kineticode.com> writes:

Just so long as you're aware that you might get more challenges on this going forward.

Sure, thanks for the reminder. That said I also remember the reaction
when I used to scan the SHARE/contrib directory to find the extension
control file having the right name property, and I don't see scanning
the same directory in order to find out which upgrade file to consider
depending on several parts of its name as so different.

Silly programmer! You don't have to do that yourself! You can teach the computer to do it for you. It's very good at that sort of thing!

Current code allows you to use the same upgrade script for more than one
source version, and does so in a way that it's easy to determine which
upgrade file to seek for.

As Tom pointed out, you can do the same with naming conventions by having scripts \i each other as appropriate.

I guess. I'll have to think about how to support it in PGXN, though. And the upgrade keys if they stay in.

Disclaimer: the following is based on my understanding of how you want
to bundle things, from several discussions we had together at pubs or
on IRC, please don't read further if you're changed your mind about
generating the control file from your PGXN YAML specification.

s/YAML/JSON/, and okay. :-)

Well, I think you're having a dependency inversion problem here. PGXN
depends on extensions, not the other way round.

What? That makes no sense, so I must be misunderstanding what you're trying to say.

Also, I really expect
the extension facility to be mainly used for internal proprietary code,
mainly procedure collections, and only occasionaly for publishing Open
Source components.

This is because you're not a Perl programmer. See CPAN.

So you should be considering the control file as an input to your
processes, a source file, not something that your service will hide for
extension authors: there's no benefit that I can see in doing so.

I know, but then you're not a CPAN guy. You're a Debian package guy. It's hardly surprising that we'll have inverted views of this sort of thing. Frankly, I think that you might find StackBuilder a better fit with your world view.

http://pgfoundry.org/projects/stackbuilder/

Best,

David

#82Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#81)
Re: Upgrading Extension, version numbers

"David E. Wheeler" <david@kineticode.com> writes:

As Tom pointed out, you can do the same with naming conventions by having scripts \i each other as appropriate.

This is a deprecated idea, though. We're talking about the
pg_execute_from_file() patch that has been applied, but without the
pg_execute_sql_file() function. So that part is internal to the backend
extension code and not available from SQL anymore.

There's no consensus to publish a bakend \i like function. So there's
no support for this upgrade script organizing you're promoting. Unless
the consensus changes again (but a commit has been done).

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#83David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#82)
Re: Upgrading Extension, version numbers

On Jan 4, 2011, at 11:48 AM, Dimitri Fontaine wrote:

As Tom pointed out, you can do the same with naming conventions by having scripts \i each other as appropriate.

This is a deprecated idea, though. We're talking about the
pg_execute_from_file() patch that has been applied, but without the
pg_execute_sql_file() function. So that part is internal to the backend
extension code and not available from SQL anymore.

There's no consensus to publish a bakend \i like function. So there's
no support for this upgrade script organizing you're promoting. Unless
the consensus changes again (but a commit has been done).

To be clear, consensus was not reached, by my reading. It may be that it makes sense to restore pg_execute_sql_file(), perhaps to run only in the context of ALTER EXTENSION.

Just to be clear where I'm coming from, as an extension developer, I would like PostgreSQL extensions to:

* Prefer convention over configuration
* Not make me do more work that the computer can do

Best,

David

#84Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: David E. Wheeler (#83)
Re: Upgrading Extension, version numbers

"David E. Wheeler" <david@kineticode.com> writes:

* Prefer convention over configuration

The previous idea about the convention is not flying well with the very
recent proposal of ALTER EXTENSION ... UPGRADE TO VERSION ..., because
it would certainly require that the extension's name include its major
version number, like debian is doing for a number of packages.

Also, how are PostGIS 1.4 and 1.5 (and 2.0) packaged nowadays?

* Not make me do more work that the computer can do

No computer will guess reliably which upgrade file to apply given the
currently installed version and the newer one, as soon as the same file
can get used for more than a single combination of those two strings.

I much prefer to avoid shipping that many files, and thinks that even in
the worst case where you have to add a setup line per supported upgrade
setup, the control file support for that is better.

Now I perfectly understand that there's more to this world than my eyes
can see, that's why we're talking about alternatives.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#85David E. Wheeler
david@kineticode.com
In reply to: Dimitri Fontaine (#84)
Re: Upgrading Extension, version numbers

On Jan 4, 2011, at 12:05 PM, Dimitri Fontaine wrote:

"David E. Wheeler" <david@kineticode.com> writes:

* Prefer convention over configuration

The previous idea about the convention is not flying well with the very
recent proposal of ALTER EXTENSION ... UPGRADE TO VERSION ..., because
it would certainly require that the extension's name include its major
version number, like debian is doing for a number of packages.

No, just the file.

Also, how are PostGIS 1.4 and 1.5 (and 2.0) packaged nowadays?

Tarballs.

* Not make me do more work that the computer can do

No computer will guess reliably which upgrade file to apply given the
currently installed version and the newer one, as soon as the same file
can get used for more than a single combination of those two strings.

Why not? Version numbers would have to be part of the file names. The only wrinkle is being able to properly order version numbers, and we could address that by requiring a specific version format. Tom suggested integers; I suggested semantic versions.

I much prefer to avoid shipping that many files, and thinks that even in
the worst case where you have to add a setup line per supported upgrade
setup, the control file support for that is better.

Well, for a version that requires no upgrade script, there just wouldn't be one.

It's a matter of taste.

Now I perfectly understand that there's more to this world than my eyes
can see, that's why we're talking about alternatives.

You are?

Best,

David

#86Robert Haas
robertmhaas@gmail.com
In reply to: Dimitri Fontaine (#82)
Re: Upgrading Extension, version numbers

On Tue, Jan 4, 2011 at 2:48 PM, Dimitri Fontaine <dimitri@2ndquadrant.fr> wrote:

"David E. Wheeler" <david@kineticode.com> writes:

As Tom pointed out, you can do the same with naming conventions by having scripts \i each other as appropriate.

This is a deprecated idea, though.  We're talking about the
pg_execute_from_file() patch that has been applied, but without the
pg_execute_sql_file() function.  So that part is internal to the backend
extension code and not available from SQL anymore.

There's no consensus to publish a bakend \i like function.  So there's
no support for this upgrade script organizing you're promoting.  Unless
the consensus changes again (but a commit has been done).

My understanding of the consensus is that it wasn't felt necessary for
the purpose for which it was proposed. I think it could be
re-proposed with a different argument and very possibly accepted.

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

#87David E. Wheeler
david@kineticode.com
In reply to: Robert Haas (#86)
Re: Upgrading Extension, version numbers

On Jan 5, 2011, at 10:05 AM, Robert Haas wrote:

There's no consensus to publish a bakend \i like function. So there's
no support for this upgrade script organizing you're promoting. Unless
the consensus changes again (but a commit has been done).

My understanding of the consensus is that it wasn't felt necessary for
the purpose for which it was proposed. I think it could be
re-proposed with a different argument and very possibly accepted.

+1 Yes, exactly.

Best,

David

#88Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Robert Haas (#86)
Re: Upgrading Extension, version numbers

Robert Haas <robertmhaas@gmail.com> writes:

My understanding of the consensus is that it wasn't felt necessary for
the purpose for which it was proposed. I think it could be
re-proposed with a different argument and very possibly accepted.

Sure. I'd still prefer us to adopt the solution I've been promoting,
obviously, which I think has more merits. Namely no directory scanning,
easy to support extension names such as postgis-1.5, and easy to support
for a single upgrade file supporting upgrades from more than a single
version, and bypassing entirely the need to know what version numbering
scheme is in use: you just don't need to know how to compute previous or
next version number.

Now it's all about tradeoffs, and I'm just trying to explain what the
one I'm doing here seems to me to have lot of sense.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support