[prev in list] [next in list] [prev in thread] [next in thread] List: postgresql-general Subject: Re: Packages and inner subprograms for PL/pgSQL From: Bryn Llewellyn <bryn () yugabyte ! com> Date: 2022-01-27 1:54:22 Message-ID: F5FCCC22-B03D-418F-879B-88FB90F22267 () yugabyte ! com [Download RAW message or body] > > Thread start URL: \ > > https://www.postgresql.org/message-id/48A5C07D-6A66-4B96-A48C-75C530CB9DCF@yugabyte.com > > On 16-Dec-2021, bryn@yugabyte.com wrote: > > > > Folks who develop applications for Oracle Database have had the features that the \ > > subject line of this email lists since the arrival of PL/SQL in the early \ > > nineties. The advantages are self-evident to these programmers; and their lack \ > > comes as a shocking disappointment when they start to write application code for \ > > PostgreSQL*. The absence of packages and inner subprograms is huge. The absence \ > > of parameterizable anonymous blocks is a smaller limitation. > > Notice that this point is entirely separable from the endeavor of migrating an \ > > extant application. It has first and foremost to do with how you think of \ > > designing code. > > I've heard rumors that some contributors to the PostgreSQL implementation are \ > > interested in bringing the PL/pgSQL features that I mentioned. If there is any \ > > such thinking, please let me know. I'm not a C coder but I'd be very interested \ > > in reading any ordinary prose that describes how these features might be exposed \ > > to the PostgreSQL application developer. \ > > ________________________________________________________________________________ > > * Full disclosure: I was the product manager for PL/SQL, working at Oracle HQ, \ > > from about 2000 through 2019 when I started with Yugabyte Inc. At least some \ > > people on this list have heard of YugabyteDB and know that it uses Postgres's SQL \ > > processing code "as is" (currently Version 11.2, but presently Version 13) on top \ > > of its own implementation of a distributed storage layer (inspired by Google \ > > Spanner). > > ⦠> > On 23-Dec-2021, pavel.stehule@gmail.com wrote: > > I am sure packages have some advantages â this is an important feature of ADA \ > language. The possibility of private objects is important and interesting. \ > Possibility to sharing code is interesting too. > But Postgres already has schemas (a little bit different from Oracle) and \ > extensions. And internal implementation of PL/pgSQL disallow any sharing across \ > databases. So introduction of packages to Postgres is introducing some not trivial \ > and partially redundant concept. Currently, Postgres is relatively small and very \ > very consistent software â and I believe so is one of the reasons why Postgres is \ > popular. It is easy to learn, easy to use. The internal complexity is well solved \ > and hidden. This is a long goal for community Postgres. The compatibility with \ > Oracle should not be important after 20 years (although it is very important for a \ > lot of current users and for users who can leave Oracle). If we miss some feature \ > in Postgres, we should to implement it, but with respect to current features. My message, sent six weeks ago, started a thread. I believe that Pavel's message, \ sent about a week later, is the most recent. In this turn, I've tried to copy \ everybody who contributed to the thread. In one of the turns, I promised a proper write-up of my case for PL/pgSQL packages. \ It took me some time because of the usual reasons (the Holiday period and ordinary \ work). It's done nowâattached as case-for-plpgsql-packages.zip. I decided to \ exclude the "parameterizable anonymous blocks" part of what I wrote to start this \ thread from my write-up. It's an entirely separable notion. I allowed myself to \ change the "Subject" of this reply to reflect this.. The .zip contains these files: case-for-plpgsql-packages.pdf â the prose write-up. It describes a use-case that is \ nicely implemented using a package (and package state). It presents the elided code \ of a working PL/SQL implementation. It transliterates this code naïvely into a \ strawman PL/pgSQL package. And it presents runnable the code that emulates the \ package like the PG doc section " Porting from Oracle PL/SQL" recommends (except that \ I use a user-defined run-time parameter rather than a temporary table for the state.) \ The complete, non-ellided code is provided in the following .sql files. orcl----run-me-in-Oracle-Database.sql strawman-pg----pseudocode-cannot-be-run.sql runnable-pg----run-me-in-PostgreSQL.sql I'd be delighted to hear suggestions for a better runnable PL/pgSQL \ implementationâand happy to revise my code and write-up to use this. I'd also \ welcome general feedback (ordinarily in email, of course) and I'd be happy to revise \ my work and make a new .zip. Finally, here are snippets from some of the responses. I hope that my essay, taken in \ its entirety, addresses all of these questions. pg@bowt.ie wrote: Why are those things huge? It's not self-evident to me. I can only \ speak for myself, but throwing around terms like "shocking disappointment" is never \ going to convince me of anything. You can make similar statements about many other \ things. pavel.stehule@gmail.com wrote: There are a lot of successful migrations from Oracle \ to Postgres that shows so that the absence of mentioned features isn't too huge. \ Postgres is just not compatible with Oracle. The compatibility with Oracle is not \ possible without monstrous increasing size and complexity, and this is a benefit just \ for a small part of users. A lot of packages and concepts in Oracle are obsolete, or \ maybe not too well designed (from today's perspective). After my experience I think \ there are a lot of things that are possible in stored procedures, but I am sure it is \ not good to do it, and I don't think we need to promote these patterns in Postgres. gogala.mladen@gmail.com wrote: ORAFCE uses schemas as the package names. However, one \ very practical thing is missing: session variables. Yes, you can emulate those with \ ON COMMIT PRESERVE ROWS temporary tables, but that's a rather ugly hack. On the other \ hand, packages can easily be emulated by using Python. Having packages would make \ PLPg/SQL programming much prettier. It would be much prettier to group related \ routines into a package than to have them laying around without anything indicating \ that the routines are related. On the plus side, packages would make it much easier \ to migrate from Oracle to Postgres. laurenz.albe@cybertec.at wote: I am not trying to belittle this, but when you are \ used to system A and start working with system B you always miss some features of A, \ until you get to know B better and figure out how to do things there. bryn@yugabyte.com wrote: I firmly believe that the intrinsic value of all of this has \ nothing to do with Oracle Database, with migrating from it to PG, or with Ada. It's \ just that Oracle's PL/SQL has a working implementation. And many people find it \ easier to think when they can experiment with something concrete rather than trying \ to hold, and run, a pretty big abstract model entirely in their head. pg@bowt.ie wrote: Maybe you should explain your position by way of a motivating \ example, involving a real world use case. Something that makes the issues concrete. \ Are these items compelling because of how they allow an organization to deploy a \ program in a production environment, complete with version control? Does it have \ something to do with decoupling the mutable business data stored in tables from the \ programs contained/run in the same database? [Attachment #3 (multipart/mixed)] [Attachment #5 (unknown)] <html><head><meta http-equiv="Content-Type" content="text/html; \ charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; \ line-break: after-white-space;" class=""><blockquote type="cite" \ class=""></blockquote><div class=""><blockquote type="cite" class=""><div \ class=""></div></blockquote><blockquote type="cite" class=""><blockquote type="cite" \ class=""><div class=""><font color="#000000" class=""><i class="">Thread start \ URL: </i><i class=""><a \ href="https://www.postgresql.org/message-id/48A5C07D-6A66-4B96-A48C-75C530CB9DCF@yugabyte.com" \ class="">https://www.postgresql.org/message-id/48A5C07D-6A66-4B96-A48C-75C530CB9DCF@yugabyte.com</a></i></font></div><div \ class=""><font color="#000000" class=""><i class="">On 16-Dec-2021, <a \ href="mailto:bryn@yugabyte.com" class="">bryn@yugabyte.com</a> wrote:</i><br \ class=""><br class="">Folks who develop applications for Oracle Database have had the \ features that the subject line of this email lists since the arrival of PL/SQL \ in the early nineties. The advantages are self-evident to these programmers; and \ their lack comes as a shocking disappointment when they start to write \ application code for PostgreSQL*. The absence of packages and inner subprograms \ is huge. The absence of parameterizable anonymous blocks is a smaller \ limitation. <br class=""><br class="">Notice that this point is entirely \ separable from the endeavor of migrating an extant application. It has first and \ foremost to do with how you think of designing code.<br class=""><br \ class="">I've heard rumors that some contributors to the PostgreSQL implementation \ are interested in bringing the PL/pgSQL features that I mentioned. If there is \ any such thinking, please let me know. I'm not a C coder but I'd be very interested \ in reading any ordinary prose that describes how these features might be exposed \ to the PostgreSQL application developer.<br \ class="">________________________________________________________________________________<br \ class=""><br class="">* Full disclosure: I was the product manager for PL/SQL, \ working at Oracle HQ, from about 2000 through 2019 when I started with Yugabyte \ Inc. At least some people on this list have heard of YugabyteDB and know that it uses \ Postgres's SQL processing code "as is" (currently Version 11.2, but presently \ Version 13) on top of its own implementation of a distributed storage \ layer (inspired by Google Spanner).<br class=""></font></div></blockquote><div \ class=""></div><font color="#000000" class=""><br class="">â¦</font><div \ class=""><font color="#000000" class=""><br class=""></font><div><div class=""><i \ class=""><font color="#000000" class="">On 23-Dec-2021, <a \ href="mailto:pavel.stehule@gmail.com" class="">pavel.stehule@gmail.com</a> \ wrote:</font></i></div><font color="#000000" class=""><br \ class="Apple-interchange-newline"></font><div class=""><div dir="ltr" class=""><div \ dir="ltr" class=""><font color="#000000" class="">I am sure packages have some \ advantages <span style="font-size: 17px;" class="">â</span> this is an important \ feature of ADA language. The possibility of private objects is important and \ interesting. Possibility to sharing code is interesting too.</font></div><div \ class="gmail_quote"><div class=""><font color="#000000" class=""><br \ class=""></font></div><div class=""><font color="#000000" class="">But Postgres \ already has schemas (a little bit different from Oracle) and extensions. And internal \ implementation of PL/pgSQL disallow any sharing across databases. So introduction of \ packages to Postgres is introducing some not trivial and partially redundant concept. \ Currently, Postgres is relatively small and very very consistent software â and I \ believe so is one of the reasons why Postgres is popular. It is easy to learn, easy \ to use. The internal complexity is well solved and hidden. This is a long goal for \ community Postgres. The compatibility with Oracle should not be important after 20 \ years (although it is very important for a lot of current users and for users who can \ leave Oracle). If we miss some feature in Postgres, we should to implement it, but \ with respect to current \ features.</font></div></div></div></div></div></div></blockquote><div \ class=""><div><div class=""><div dir="ltr" class=""><div \ class="gmail_quote"></div></div></div></div></div></div><br class=""><div \ class=""><div><div class=""><div dir="ltr" class=""><div \ class="gmail_quote"></div></div></div></div></div><div class="">My message, sent six \ weeks ago, started a thread. I believe that Pavel's message, sent about a week later, \ is the most recent. In this turn, I've tried to copy everybody who contributed to the \ thread.</div><div class=""><br class=""></div><div class="">In one of the turns, I \ promised a proper write-up of my case for PL/pgSQL packages. It took me some time \ because of the usual reasons (the Holiday period and ordinary work). It's done \ nowâattached as <i class="">case-for-plpgsql-packages.zip</i>. I decided to \ exclude the "parameterizable anonymous blocks" part of what I wrote to start this \ thread from my write-up. It's an entirely separable notion. I allowed myself to \ change the "Subject" of this reply to reflect this..</div><div class=""><br \ class=""></div><div class="">The <i class="">.zip</i> contains these files:</div><div \ class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; \ padding: 0px;" class=""><div class=""><b class="">case-for-plpgsql-packages.pdf</b> \ â the prose write-up. It describes a use-case that is nicely implemented using a \ package (and package state). It presents the elided code of a working PL/SQL \ implementation. It transliterates this code naïvely into a strawman PL/pgSQL \ package. And it presents runnable the code that emulates the package like the PG doc \ section " Porting from Oracle PL/SQL" recommends (except that I use a \ user-defined run-time parameter rather than a temporary table for the state.) The \ complete, non-ellided code is provided in the following <i class="">.sql</i> \ files.</div><div class=""><br class=""></div><div class=""><b \ class="">orcl----run-me-in-Oracle-Database.sql</b></div><div class=""><b \ class="">strawman-pg----pseudocode-cannot-be-run.sql</b></div><div class=""><b \ class="">runnable-pg----run-me-in-PostgreSQL.sql</b></div></blockquote><div \ class=""><br class=""></div><div class="">I'd be delighted to hear suggestions for a \ better runnable PL/pgSQL implementationâand happy to revise my code and write-up to \ use this. I'd also welcome general feedback (ordinarily in email, of course) and I'd \ be happy to revise my work and make a new <i class="">.zip</i>.</div><div \ class=""><br class=""></div><div class="">Finally, here are snippets from some of the \ responses. I hope that my essay, taken in its entirety, addresses all of these \ questions.</div><div class=""><br class=""></div><div class=""><i class=""><a \ href="mailto:pg@bowt.ie" class="">pg@bowt.ie</a> wrote:</i> Why are those things \ huge? It's not self-evident to me. I can only speak for myself, but throwing around \ terms like "shocking disappointment" is never going to convince me of anything. You \ can make similar statements about many other things.</div><div class=""><br \ class=""></div><div class=""><i class=""><a href="mailto:pavel.stehule@gmail.com" \ class="">pavel.stehule@gmail.com</a> wrote:</i> There are a lot of successful \ migrations from Oracle to Postgres that shows so that the absence of mentioned \ features isn't too huge. Postgres is just not compatible with Oracle. The \ compatibility with Oracle is not possible without monstrous increasing size and \ complexity, and this is a benefit just for a small part of users. A lot of \ packages and concepts in Oracle are obsolete, or maybe not too well designed (from \ today's perspective). After my experience I think there are a lot of things that \ are possible in stored procedures, but I am sure it is not good to do it, and I don't \ think we need to promote these patterns in Postgres.</div><div class=""><br \ class=""></div><div class=""><i class=""><a href="mailto:gogala.mladen@gmail.com" \ class="">gogala.mladen@gmail.com</a> wrote:</i> ORAFCE uses schemas as the package \ names. However, one very practical thing is missing: session variables. Yes, you can \ emulate those with ON COMMIT PRESERVE ROWS temporary tables, but that's a rather \ ugly hack. On the other hand, packages can easily be emulated by using Python. Having \ packages would make PLPg/SQL programming much prettier. It would be much \ prettier to group related routines into a package than to have them laying around \ without anything indicating that the routines are related. On the plus side, \ packages would make it much easier to migrate from Oracle to Postgres.</div><div \ class=""><br class=""></div><div class=""><i class=""><a \ href="mailto:laurenz.albe@cybertec.at" class="">laurenz.albe@cybertec.at</a> \ wote:</i> I am not trying to belittle this, but when you are used to system A and \ start working with system B you always miss some features of A, until you get to know \ B better and figure out how to do things there.</div><div class=""><br \ class=""></div><div class=""><i class=""><a href="mailto:bryn@yugabyte.com" \ class="">bryn@yugabyte.com</a> wrote:</i> I firmly believe that the intrinsic value \ of all of this has nothing to do with Oracle Database, with migrating from it to PG, \ or with Ada. It's just that Oracle's PL/SQL has a working implementation. \ And many people find it easier to think when they can experiment with something \ concrete rather than trying to hold, and run, a pretty big abstract model \ entirely in their head.</div><div class=""><br class=""></div><div class=""><i \ class=""><a href="mailto:pg@bowt.ie" class="">pg@bowt.ie</a> wrote:</i> Maybe you \ should explain your position by way of a motivating example, involving a real world \ use case. Something that makes the issues concrete. Are these items compelling \ because of how they allow an organization to deploy a program in a production \ environment, complete with version control? Does it have <span \ style="font-style: normal;" class="">something to do with decoupling the mutable \ business data stored in tables from the programs contained/run in the \ same database?</span></div><div class=""><span style="font-style: normal;" \ class=""><br class=""></span></div><div class=""><span style="font-style: normal;" \ class=""></span></div></body></html> ["case-for-plpgsql-packages.zip" (case-for-plpgsql-packages.zip)] PK ف:T�� L0� � case-for-plpgsql-packages.pdf�ZXTQ�AZ�E �If�CA�%�FBi E�ERER@P$�SZ�%��DptWw��6����y����{�9�?��7�p�����T�3]�T�`!! �hfC%* T�v@�0�w� 0P �`0P Fr 0 �@�7`P�$����p Ln$.N�v�8��CE�A��9T�����N� ��b`A0���@Oc�)L?��OcHЩ9 \ ��v��� �#!@�0z C��0!�1=� �A�0�.���rܲ�DB!��AP�?`p(;�� \ �1!�?ꌄ��~^�n`�!�0A����p�)Lqj<�8�A�Nc0�i���N������Š���*r\�i�b ���X X \ 7@��p��@�l�����9$R�������BB䤅dp���pY)�����,)$+�II���!rP9iTZ���A��D+B��.X�3"AT�r��T�c�� 0� \ P���� ��PX�,��� T�\��Apy�`��@��� G5PD\��A��ȭ��LMMo���״��`����䣼���I��(b�atm�9d _�$�Jr\�g� �wSS+.d�ˍXBi�DL������O��</���$��>�?���ܩ7\�s�2�o�r5�ݲ���rz���A�}��bϲ�"ݮ�E��!{?� Lv,��IR������������IyB���M��7V�K��\$�-�*�A�o�Lg�W��t@G�w!�/ܷ����Ӟ�?��eq��$,�ka�a��z���0�Y�{��S}�|�0���b/���[� \ z����$��n:���l�b9ĥ���O��SM`� AZ �]g d��(�n*��"ǥݟ��k>��.r��B;pU�X� \ �±~²�({� �OZ�Nh)s����!.�@z� �;vv�����w�v��~�O!5�%Ze��s� \ ��rLm�_�O�c艈��(������c�vCc�p�Dc��'J����SpZ�6I�u�~Zq��4�X;aq�����^?�5����*([4��������uM.n���)�Ck��q@e��M�-#���u�yV�dF���퀳�i���I�����L8n+D \ !F�%��F�B�P8/g����vq����5�O��W ���'��S+�?��M����q��b�\��@�����������K�q�d�Ơ�֮h \ '��%���l�(��G�h�;�ݟR���@iG�sb ���9���z�-�K�p!�P����Y��D�~�S{����yl)�� \ � ƹ����q�ŁZZ�ONR*��Յ~�qu�:�8A�S_�5�NJ@-�;�︁�=�4�}<PFQJNZ�W�3���_ Giks��.W�,�Z;H9�X�-o�q��X�0 (�DO�O����q�G\������-��K��Nz�ƶ�Z�BA��� \ �I�A�-0 ��L��Q9��=&� \ p�/D�� �\�3zRq��CB�:�$B���ɜ�,(��OF:~�?�_8�@��r���;r����0��X>F�59�*;��YA~��l�`�z�����O.��f�/��n��o�G �E���2��Fcn���4U��Wf�b��D�b��AI�PRJ�W c���iw<'N�=~���$��~��d�K>�X~���p��Q������${�V��P�W�R�[�>��y��O恡���,z��G~�u��O���E� \ �8����qu���x��������*����(�qw<�_�H��8�k �OH�����3�`B��q�ʱ�'�����$V�u?��q�Dw(Ž� ��3��W�'��c{O�q �M���Qw�@U5�m��WQ�U�WSS AN�� Ԗ��������@�������"��� ������ ?=>[� �B'ܑ>ޓ�!8�Cq��<�DB�Nʣ��<��Jf� \ ���Q�d3:A��#�b�8y��;�aͭ�71�(�H�n0�SP��� \ �5�h{\V BO�����e ����1����=��^+J���6�ͻ!<bJ�//��mCy�&S%2��8������Ar&�؎g5iDŸ�- ���o�.T�&�ٰ`�Ï|��/3҆|�M�*�~�H�ChE!�/�4�|�%P�ݘ�}Y[vK� �4�7c��,�J���֣�m��ۦj��f� ���$=wҾ������Snd�����4��Ü/�-�>��ǚ��sa�a�B��KL�S��j2U�G빫J��K�6�y�u�7��2*��&�o�T�f���8��p�$:���T�7G��,WB Yʛ����si�z� �;q���D]3_a:����}{$����Pob&<�����Ԏ�_�)��?H �"q����{����I ��)�1�l��",����͇B�0�o���C \ ~�.!�R�]�w��ڈ����퇞����?z������$ !�4�g&�E�T�W��Lfi�y���7$6|��V!eo�B�Ջg)f \ ��DEq�H]���0�sm7�J���#I9k�5DRp�]�'��$�Q�U�k����]�����T-�"72_���� ������,�vШ�<��гK���E��ꟻ����0�Ѻh��\J���V�@����w���� 2�� t�~��u���Hg�ʵ{U� l���Ǟ��!s�4�R*��?"J �{|g9�=��=�W�n �v�R�.̨�E���p��ڧ�/�o�mhދg�v��j+| �Ia��� G�����|�D��Z�S*:4�"�2�y�R�$~q�ީg�iF��]+z]l�/���_�.n��s%ܾw.��@�Ma�Y��ش�U�a �S&�ʃ{�3/MIvb��dy�T]_� \ =�|n�> �z=���x ��D�#�����o�����}��B�L�L�����o�}�x���l�<!7��;&�z;�:SG��_q�e8 \ �{��C+���1T�)j�3^�|�uA�'�jq�@�L�&f@�y�74g��vm����̮�6��!^��%�V䁻5���h�~97q]?�`�H�$.�4�^>��#�j*[��`�ma`�Yps���*ͽ&+^���|c٪�G�(2��r�����H��?O!H�QW�AYf��\T�)� o��mb0x�XI������Ֆ>ȋ�rD�2Q�dɔ���$~�m�g�5�b]m��&�2�p]?G��p�2 m�&��7=r�������4�ʙ��:�f!�V�Κm�B��|����(I���Rҭ�k-�ۻC릃�d��?T,]}E�<p�1a�ئBOL���~D�y<����W�"�|�����y����Ϊz����c��0�YZVG�7��C��T�+7�ɝ��'�QkvOd����U ��%K_z�% ��|Thj{y..�k6��'v:��Ϲ�����m��y⸨2���)H��x, > ��7@J���99�}�X�m%���B�R�Բ���I��C�j���RB:,��?ؙ �ξ��Y=���6(q���G����ÄYDK=�Y�Ӫ:��|��4 ���!u�0�$>8��PzU��î,Oh�D��o_�A�]��S���)'���� \ �Y���JFS2��/_О�.[����S��po�(�|^Z3�&:��:��_h�`*�a���~����/�2$H�XzK��V�(��̢X��wo \ oO��(��Iѻgb��x$tzG�ݞ�Ϥ����QM/=�UK`��� 9��=^Y����\�M��&��P���9�#��46�0�K{�S~�D�a�>f=�o6�b'���}�lFLy~��}{G������'�o�an�P4pQ%!�V \ �Ic�YE� ��,�̝Yx� ��i���L�叢X��V�SE���A�43������ޖ%�9��XV�@��T�f�:��X�F�k��~F� \ �^b@��o����TM��zf0�ց�%媮A�4**o����,�g��&�.=� ?�M�A� �� �b>qb_/xb_�rX��}S��yt����9-�6<Э(u�'ϊ��~R]8��;.ֽ�N�$�[�V_ �XdY�<0,эz2�o]�Y�p�}0��)��=�V���s�� m<���5��>:?�����#�����N���\�*G�O�ree�������ͤ \ f�F�#�2g�@��6>Vy�a�\�7�o!��4��}1K�����E����3÷\�\N�3ant��9��T[�:���2^��k�O�= \ �3��*&�u�%E\���m)��?<��NY/??$]��hOP p�6��XRm�����5R�f~ע}��� \�M�]W�TjU�zy�/���� \ =k��;�tb�����֯���y��/S���v�}z��8nś6=5=J���h�>��<�[xQ�:��O������Dڑ��a�$~��I \ ��}�QqA�������"�L?��P����L�[�;���yIs�TO��7���n��~da-�9�bUʮ��x��]ؑ��/W�eI�����ߋn��ևud��3�=�_ړ^��~��&�LI \ ��x�&�BԵŎ�JNC�_^q]L�Lw��b�9�d���ΪɎ�y]�.�a}7fht�A��rP}9i���as�ɸ3�J�hɮ��D$�~~%�� \ ���'c�lݸ%`;ufƻ��Q�eY~�����р��ˉ�#%�f�0n�.�4Z��T{\�5�%�=?>V����1�!�Qe��i���oDn1�D���$/�@<�yHR$��h]���K���>pm�c��ʦg/"V�'.Ӗ������پ�XK��A�s�����!L���8�i ���̻gL�����#�9�-Qʮ�9��װ'�\�Wv�b}D�q� 5 \ ��ip_��y�I�#m����������ҁP�a�:/<>{?Q��9����Й|0������7��H�H�S���}�e�3�K���컉��.�fk�U��!S�9���B��ЮFcn<5��$��w�f�6��צ)4[�&V�2)W~G1��x�M_���ƆG \ ��y��W��ɻ8�WXAR�[c��x��,n=.3��w�[on��71f��ܚMOa�2�r�?38v^�!��h�^u��T[U\J~|� \ A��ЙsV�����L&���a`��D��x5euTi!O���-�)3C���ۮZ�8/��i?�ig�"���zeNG����g1&�O��E��k�ta���aP(o�a�&�U8J+���/ۗLX����8��L��5�R�s �/~�j7T� P�j��I�QW�9��eh3k��yF��1�}����_x�3��� <�����s��U��D��u"p���d��ک9k��5�$&Ae��90_ն���YК6��*tյ�3��Jb�r�M�k��k�Zq>OY� ��.�k^p pV�d��/WH�e�ߎ�C�Ŗ��'o.��PB/��,�' ���3X�|�FՕ��2�BJ˩�uq�r,:�tޡ&�ߪ9�(vm>��3 \ 1?��Y5�x��ŐF���T��[�KP0�r�Xg�VY�o��*��_���q�j7��;u�`$�-�X_C�����1�B�<���6�� \ �L�d&}5���I�T��9�θ>u�w8�/�I`�{r�3��k��K����c��A�Ab�������MϘ�G����w�ۊ��PZ�)V \ ����;��u�e��Y�Y��fìR���\��$����̇�<�G��{����ξ#o�#q��6�m�ZO�~��~���:iԼXAZ�Ĕ-QTC�F�,?}�b*G��8�+uA\����]�/�8w�(����8v���?|z���hRkv���YÆ�����&��2�� ���ώ�c�h�p�H�U%j�FR�X��GW�>?��"<��?�ol��\�S���x&�,ީmV�o�mfIs��l�2粱8Sux>�Z�Q�W,�+�g�����Xd� 键����ٞ��̤ϓ��iä묷�+�u�D�1�����.�<ST0�ӑΏ6�Й"J�+)�l9��7�i[k��z��,m&��Nę�K��,[P�Mj] \ N!cZm�:�^��o�Ak3��E�;�g�Y�B?�6�Ŷc����.�=2��PV�bQ0�O1�j��`'��H_�O0ʼn�+T��5,_/] \ ]'�w�,{8e�H�� ��8���o��ҹr�o�]O�����8Zs�־�Mq�U�����f�1ZY����!�e�{�^+2�w���G�".��3����ϥp�Q����Բ~��3!S} \ �k�[|~z�.�<\�I|�;���Pٝdpz�hר�%z��G9� \ l�j�hmWTu��f���ΜO�Y���ff���*[]�)k���Z�ԕ�^�����r(�*���8f��5Zq���1�7�" ���=����(}�ū��}n�A�V,�Q�s�/b \ U�/.�h�($��\�{@�_�+δP{���fpZ7h��et�F�~�n"�f��WF[��Hw����S� Ҏf�d����S�q�yV2�p�5i�*G9���ӒFԘ�p�� \ ��9�G2��L巖t��_ި*�+��ܳ��<\����V�|_e@���|a��5�Ew�y���E���;�7����۩q79�x�S\,의W�>�QZ���9^���!�;B�w�/�x�fԋ���`[�}W^Fs�||�г7͢"��ǍY:��f&�E������ˇE�g�Ģ#��En� �ɰ�4��o�P[�w]�{��ni ��V�BCɼ�@�pe����Ƀ\;;X�\����[�S,9nڬ:�>jz�0+��V��3U�(�GG�"aģ�~V�țϮ�9eZ[��y�m��l���ibթB!r>5#:�:�Dz)��_5<nVZ�B ʊe�R��_,�,s`l�"u;�3�QB?/�Y3��{�Ȓz��t�:�nIQ% >�M�,!%?M�H�A�K�}����LFt78^�gn�53 \ o����)(�|�8�o�6Ͷ�y�����ArK;)������(����f�������+�|�������z`3����*|6O�&�����4 \ �p��X���Ͻ��D?�[xv����\p2�f2���,̧`گ{�)��3y/�R!����x���2�'�����q�(`��6E�³zd:g/qV$ \ ��_�<�����2՝*�NkAU���^�KѸ®�Z�� P&�m�.,3��'_�h�����CǭiZ_�tֈV�Gi٣�l��h ���M�����+ �jÕ�e����1�[�oU�&�D����V$Y�(��_�6-��Co(g i8'� ��E= �lx� ŭ�n���K��,�Xi���b� c,����%:���L��3^L�Y���� s1O��!�GA���<��|�@4��j����&� � �^`�'%z�g��ź�q���H��\^��_�KQl������t��Z� ǣ��U���H! zK��D�اԶ]�^-�wYH��ڿ+�{�Z'Y���䵮:MJ��_�amw�#\?��q�2�%$-(�<Ӥ8-P2����{�����w�˙��˚\ӔŅ. \ ԑ�]�L�%��b9os���K�+M�IR�'�.Iy����{_�У�@��T,,!=�X[���?��J�C�^:~O����Q_D��+�jW�ۨ��Eܝd7��ɣ]��f�c���*�o�K��P�r��e�#2M����� G��&�@�Խ��.i�n��+s-wZ<����NL��z�y�m�17&[j���V�5탋/sd4��2y���ӷ�١^9��~K��M �E� ���y�L��Tћ�~���{��s����NhG�N��n�2w�w�پ���2�*�rQ&�s6�`]ov��Vl?鉝A�gn��M��ث�nu \ i���i��\ ,�С�l���[��H�@c�-���W��2rW'��+* ���nZKQ}�Uq��MuG������H�'�?��i�����+�<C�F.���U�kf���s�'] �M�ܗu������p� \ �+�}��^7�h&4��PoSr�� �Jk\�`�4��X(÷�%��5٦j�h�c��3�Pv�����f+|"��o�:� ��KU)kY���z�� �� g�A���$FLk׆5[I+^ͪ�d�U��PH�D~���uF�>5�$ޠ�(�� \ ]�Z��s��Vx>�#iT���+i��Z��ƍ���5�:Q���DFz��1Y���U�x��,�e�*��ڇ�Aoi���ۄm�X� oϺQG6�/��[R7�m��{��S�ݟ��C��/�8'l �mu�X�������-l��'a��Թ�� 9�l���H��U+��#���Dw�*��w�վ9q7�?q�d��y��\�Q�?�n�� \ *|؎�>�Ԉ�É����`Y�%XӶ�W6�-UdIH+<K.]px�p��8�h��Yȫ��N_0[�7!QG�M��sv�lc���cJ�y�ʶ��F:�D;�9nlr�G#x�s�$�g�Uz+K5K� > ] ��*vz����h�rqr���♗D�v�����Y������� Q��{mK[c�ۺj>`_��!3;���l�=�=k�D�v���� uR���cS�ǘ��"�g1���&�Y�!���9�h.����_Ө�f[��}�:��Ցoz ��ÊG�^������vd�h�\���ʨ��槼��_���h0�N��K� �P�u�m�����\�S�Z�t���j�E��T�5u`�Y��� �;�C!�$\�g���ϕM(�$>�#�&c����1l�E��&˓�0�q�~�<�b���^Jp�����?�fac�9g\Qr�- u' %��_:f�2'�����}���g���j�t��(�BpCk���.������i�I���^xT�H/�Aw���{�Ϧ��J儳�w�E%��v�,V��$�Gۢ�ҩӍ��Gj�zd�6��D�G�m)^f)�ݴv������ŕL�[���Mǝ� �7<�'N �PxffR̀!������i����T�ߋI83���u-���k��MlvB����g�˞�!����1�t�����O<��TS� �3�p,&�V[ \ z�(�{Z/��7���=D2lym[��Mi���t��/�3lF����A*��ؾ)VMF��ޡ�He������Ͼ�:ci��V+Wz��~�O����.�"eƢT��ۼ��f��;?��hۂ�>y�+���?9�6���%)j9��pU�����̉o����:�,� s>)Z��A�vߡ�b-�|�����v�[�5�$���3����G�s���ĩGr�[�>�*�HDB���}`I|&�I�i�n.�T�������mQ>�y�ԟ��u�q R���e���U�eބ���X�t��<�m`�z�b$Z�! \ ��a]RY+�a[����ڈ�EN-@�Њ�ӌpD�����0��a����&��&:�W4��ԅ�)��kj1�I1����8��r�l��`�d� \ �t���a�����z�`��}�#R�������&�Ůp,�e�â�JDdso����i}�;�&¦ܵuex&Xdyt�qɱ�%�2�o���B��� \ /C~ߙ���+4��ц]O��F�g�0E��s���kr,h�FJ}V�r \x����|O#��n���;,c���/�{�}d4���5LklBy�<���e]��~��� ����H�O�1�4�7d�/|����~�:^L����*�tg+�W�#��F����06n��TKؚ�,�zI$��s�w//�O�wo���rE��5��b�����4�JZ:��pw;���u�����ש�r�e����rz� \ W�n6�l6�,~�m�������c�Aď�.�s?�nd�=j�<(�d�xIB�� ;�>�cY幒�,�;�S��z�3ֹ���F�=CDj� ���R��a[�+ː��\68D�e@tO6k��eœ%�����!�`߱ \ (�*<�H.�Q!0;vIYjo���5���ۥy��g��������'tЩ��p�����_�A� \ ��R��3��V��_�*�� =G+�D� \ �uh�,f�.�z2�L;*&�o�l��$i3��=3���V1~�!�dS����w����n�Y���$���\cz�F�J�F���`,�6C����j�V�FMM��ʾZ��E��j�e}qP \ ��t��`�p���1�~ ��j�j��܉e�)��u�e� \ ���r��qq�z� ����wZnb�0�;�.L�O'��Ҧ2��C�!��5K���j:�tՙn���[7���H�E��Pȼ,Fek����a�Jչ-�ww���#?��Ŕ�3^�&8�Y��T��j%/��' -f ~�q7��St���Ǒ���g�oS�sY�B�����?��,Y�6���(H�,��$H���«z/]頻.i'wu����W3��uG M(�K��*���fK��9ů�j�]2$4ٳ&}�2�_�Ws��S،}bK��2�qI���������Ya���<����t�du��n< \ ��x��AR�ɴ�~�bLc{����lb�D� q@��L�B����T+T�������EH�SߣNYą���&}�x֘9g�����f� \ |#�I]�d��@��:���^��dfx��P��p8IyTb|[<Q����;����Hث˩�I�� � \ K�#y��(��wM����x�'�,�8�>̤��ژS�z�<;G���#����@Exנ~�Uu�?'a6�Ϝ-�;����1�I���n�8��W���f$��w�m��r� �W�j�yķ- n��guwM6} ���M^b�����E�� �Ի�C���"�cd=��*��㈹�3nevQ�F�*�f�Tg(�YK2��5�-�<�f���/�_}�k�8up�QS�2\7���œA�@#�3\�O_�:~���v�Qjl�\��Ǫs4���&L \ 9���2Ժ��E��5�a�K��L��^M�V��{dJ�s��K˗����y�0Nz�-��1|h�ҥ�v�ʙ�~D�+�[�佘~tq��?���P� \ f�0�0ʢ��"x�'������>�}9�5���ˬ��� ����;�-/3�fe�<_�����ܪ3��LG�h2-]97��,�%Q�w��V�� \ NS�\~B��LIE�����ag�r�{��[M��k5��z��]K�CxrP,��yN�Ђ��#Q�^����Z��\�*�����jd�r���PF��& \ S��\2a�D��DO|Yf��'�t���f�g�3&�O�K���;��g9�}�^�_�[h�U�`��>�B�v�)�U�����R�K��n2��\^V���)��k�/�IM9O�]d <��������E䫤n���\4�L���4t�2�zF����v�ýZ�� ��ݝƖ��٠ƻ�4foL�v,�����4g�C����#�#�%; \ z��a|-Y����1f,��~N7-��o�(�Rax~T�d�j���Rɡ����g͜�7o�,��~ނEw?���+�����5K&o{P���f(6��0̶�N�oXmX�n� \ "@Y�\�<i��]� �$}7I?".nĈx����j���H�喰�!����讠 G78�(�<ry�T턢�E��~������L ��ՑC��slX(�Ys3 �*> ��,OE\xqԈ_ݼdy�3����z� M����oJʛl��ι��*,��Y)�Ms�͟�1+���<m�=��W�jb��aƬ�)I�-7�����h#_�N��3�+4@ R���� �^o�t:��Ѡ'��g=��PAF���ag��Okw��t���iPR0E � \ 6��b�0��@���@���upm���Wk����S�R����k�� �-�YA�Ǝ�j�0�+�b��L!S�`������}�y`����j�����wb?x�{��<�+Y \ �p�ߕ�l��Faf�}�xsDr���"X���d�Fᆴh<+�$Y�:�a������>�����S�_s�o%!��$9�ժ�ȑ��%5��Br)OQj*�1�%+����; ]@��U��qLK\h I�j3�r���\�?r�^��W�_y~[Su���1Q�E��:�$x_ ���}g*�� ]���Sr1W�>� r`��*����B�����eB�S{�0�teXM�&f2%dK5p1��Z$FFj��l��$�M� ��:Sl���l;�ǨMb 'r���3^1^nh�@�A��o�z��pٟ�)�eQGQ@��1 %���+��W��h��*4.�1h�F拾��ҫOl�Q+ JL^Mڜ�]���?xG��=�źY'I��ۧޯ�-K'�܅!��JM!�.8�d�l. \ z��{��N���Wύ������tODd$O��v���!@�|�"��i]�m��G�8�-]���Wȹ��WD�e����Ƒ<ҹݳ�P�e� ��xe���9��Mjb���P�lG#SCGED*[gF��4��1]�Rљ!�d�^֚�Œ&��3�$ȁ������~p��� �|��\X�r���Mt6]B��"�"H:�%�x \ ��(�ccGg�/�R��PCvW��K;��9���j��{X��Jz�~S/f�������Vhkm@���;l�ܜ��|�}�b \ p�'h�ݹ���;�Jl��-�9��hB�B���kƍY^���QT�`ƒ=�l���W�u�켴q��84��]�5���:\W9����C�7�_]���C��C�M�Jr`�Kem�&n�� \ ���L0ᝮ���)�,66�^�)۠�@������^�]��.ں�؉vڰ�z"��#���q�a���^��J \ ��߯�~8���;=��w�K*�c@}�YA��l�3�ƥO�YC� w��Y'� \ ���U{���!�NO�o�� �\2y�o�Il�g�t�=�6o��� M1&�|�|W�#!���pHp���9hX���5��g�}T<�`xC�(��Gsar�˕:��|ar����(f��E���K�>�Z861��E'6y+�di'��8��Y<J KAO������dFE��[ ��eeM�� [sr����w0��<�sE%��$��3�L+.���m\�===@[u{��LeQ ~wb��*w�{":zf�ڸn�x�&=<�F�0�u��5OQd�Aa�&��Ug{����$t�z���^� ���� ���f,�'�eMb�B2��g�FP 3Q�r�@T�I5wx� Y݄��Ծ�$�a���C�7O}�]��K����]]P�M��w�_���߽����wO�h�89�r�V�.�3ڞ�8� \ eʘ�䂍;,�U�S�ֿ���&��q�cw�+o�7W��x�0������5�"�1�=Oz��ʟ}�g���ŭ���W�LY}���p�'��ka�$`� \ ]�ϥo�8���._� ����y��;����=��рM=�����z��l�ٙ=��ԝ�sn����7����Ov|��Z�5�ef��f�[��8� \ u���!iF��F�Ò��%ے-��S��K6�c����D1�@8 �� N��6i���P����&9M�Y��=I��4��7]��isr� \ �b�?��.iI#i~Y�ソ��ӛ�g��;��h�l�c;�;�<{=������s�9�s�=�<���]�G\&�O]��0W�+���e���-�K� \ �D/1K�rI��^��%͒�j�U�U�w���9r����9vN9��S�i���lZ��ڠ������[�>2s�(1�\T�?66���ls�D�A��76���6h �~�l�Գ�g����,�,L�U]]�T0ړڙ ����85�=��7��y�����rsj|/����6�n�}s��Y�=�:�7���s��gߛ�x��f�����P������e)�'`L�,�\�-9�q 2`�_���]����߭�a�����wgo�A�ډc��c�i'A��>0 ��! K[zL�@�w�Ɂ��!r!T.�2�e� ]�`@%R>�H����t p@�+s�����*�aU��@ g��V��upa��|���@E�rP"�V��� \ pm����ە�^cn1��z����'��R*�$� \ � �R����p'��oS�`)�8bqՖ�p�E @YT���I�:���u�U�E���Hg��J���Z9�2�jT���DQ=kx�+�m!8 \ U���{�T(2v�:WP���Q������.��7r-n�A�ng�����ߨ�1�WQ<(��r3S(�FYZ �V�P$ �O*Zo3m`�$�2���� �kU��o�8-�(Q�K@�(к<p|���r�u��c�\ \ 2gȹ�)֏�w)+^-їsD]YU�уO<s�w��:��~����S_|a����7�<�^�G�~t�3*|'��=���2=6{䥙C?D�1u�y7(���n����{��DО��ˉ�N|~)?N$��x�_"՟ z�!�w��5�wL�>7nS��l� ;fڏ&��^�''��g&!�a.����E�?�fZ��f~� P� \ �^�H3s1]�Y��O<