ECPG FETCH readahead

Started by Boszormenyi Zoltanover 15 years ago122 messages
#1Boszormenyi Zoltan
zb@cybertec.at
1 attachment(s)

Hi,

we improved ECPG quite a lot in 9.0 because we worked and
still working with an Informix to PostgreSQL migration project.

We came across a pretty big performance problem that can be seen in
every "naive" application that uses only FETCH 1, FETCH RELATIVE
or FETCH ABSOLUTE. These are almost the only FETCH variations
usable in Informix, i.e. it doesn't have the grammar for fetching N rows
at once. Instead, the Client SDK libraries do caching themselves
behind the scenes to reduce network turnaround time.

This is what we implemented for ECPG, so by default it fetches 256 rows
at once if possible and serves the application from memory. The number
of cached rows can be changed using the ECPGFETCHSZ environment
variable. The cursor readahead is activated by "ecpg -r fetch_readahead".

The implementation splits ECPGdo() and ecpg_execute() in ecpglib/execute.c
so the different parts are callable from the newly introduced cursor.c code.
Three new API calls are introduced: ECPGopen(), ECPGfetch() and
ECPGclose(). Obviously, OPEN and CLOSE use ECPGopen() and
ECPGclose(), respectively. They build and tear down the cache structures
besides calling the main ECPGdo() behind the scenes.

ECPGopen() also discovers the total number of records in the recordset,
so the previous ECPG "deficiency" (backend limitation) that sqlca.sqlerrd[2]
didn't report the (possibly estimated) number of rows in the resultset
is now
overcome. This slows down OPEN for cursors serving larger datasets
but it makes possible to position the readahead window using MOVE
ABSOLUTE no matter what FORWARD/BACKWARD/ABSOLUTE/RELATIVE
variants are used by the application. And the caching is more than
overweighs
the slowdown in OPEN it seems.

ECPGfetch() is the more interesting one, this handles FETCH and MOVE
statements and follows the absolute position of the cursor in the
client, too.

In Informix, the DECLARE statement is used for creating a cursor descriptor,
it can be OPENed/CLOSEd several times and the "FREE curname" statement
tears down the cursor descriptor. In our implementation, OPEN and CLOSE
sets up and tears down the caching structure, The DECLARE statement
didn't lose its declarative nature and the FREE statement is still only
usable
only for prepared statements. I chose this path because this way this
feature
can be used in native mode as well. It is usable even if the application
itself
uses FETCH N. The readahead window can be set externally to the
application to squeeze out more performance in batch programs.

The patch size is over 2MB because I introduced a new regression test
called fetch2.pgc that does a lot of work on a recordset having 400 rows.
It browses the recordset back and forth with:
- FETCH FORWARD 1/FETCH BACKWARD 1
- FETCH FORWARD 5/FETCH BACKWARD 5
- FETCH ABSOLUTE +N/FETCH ABSOLUTE -N
- FETCH FORWARD 3+MOVE FORWARD 7, also backwards
- FETCH RELATIVE +2/FETCH RELATIVE -2
This test is compiled both with and without "-r fetch_readahead", so
I was able to verify that the two runs produce the same output.
Also, fetch.pgc, dyntest.pgc and sqlda.pgc are also compiled with and
without "-r fetch_readahead", for verifying that both SQL and SQLDA
descriptors are working the same way as before. E.g. PGresult for
SQL descriptors are not simply assigned anymore, they are copied
using PQcopyResult() without tuples and a bunch of PQsetvalue() calls
to copy only the proper rows from the cache or all rows if no cache.

The split parts of ecpg_execute() are intentionally kept the original
wording (especially the "ecpg_execute" function name) in ecpg_log()
messages to eliminate any impact on other regression tests. If this is
not desired, a patch for this can come later.

Because of the patch size, the compressed version is attached.

Comments?

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

Attachments:

pg91-fetch-readahead-6-ctxdiff.patch.gzapplication/x-tar; name=pg91-fetch-readahead-6-ctxdiff.patch.gzDownload
#2Bruce Momjian
bruce@momjian.us
In reply to: Boszormenyi Zoltan (#1)
Re: ECPG FETCH readahead

Boszormenyi Zoltan wrote:

Hi,

we improved ECPG quite a lot in 9.0 because we worked and
still working with an Informix to PostgreSQL migration project.

We came across a pretty big performance problem that can be seen in
every "naive" application that uses only FETCH 1, FETCH RELATIVE
or FETCH ABSOLUTE. These are almost the only FETCH variations
usable in Informix, i.e. it doesn't have the grammar for fetching N rows
at once. Instead, the Client SDK libraries do caching themselves
behind the scenes to reduce network turnaround time.

I assume our ecpg version supports >1 fetch values, even in Informix
mode. Does it make sense to add lots of code to our ecpg then?

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

+ None of us is going to be here forever. +

In reply to: Bruce Momjian (#2)
Re: ECPG FETCH readahead

Hi,

2010-06-23 22:42 keltez�ssel, Bruce Momjian �rta:

Boszormenyi Zoltan wrote:

Hi,

we improved ECPG quite a lot in 9.0 because we worked and
still working with an Informix to PostgreSQL migration project.

We came across a pretty big performance problem that can be seen in
every "naive" application that uses only FETCH 1, FETCH RELATIVE
or FETCH ABSOLUTE. These are almost the only FETCH variations
usable in Informix, i.e. it doesn't have the grammar for fetching N rows
at once. Instead, the Client SDK libraries do caching themselves
behind the scenes to reduce network turnaround time.

I assume our ecpg version supports>1 fetch values, even in Informix
mode. Does it make sense to add lots of code to our ecpg then?

I think, yes, it does make sense. Because we are talking
about porting a whole lot of COBOL applications.
The ESQL/C or ECPG connector was already written
the Informix quirks in mind, so it fetches only one record
at a time passing it to the application. And similar performance
is expected from ECPG - which excpectation is not fulfilled
currently because libecpg doesn't do the same caching as
ESQL/C does.

And FYI, I haven't added a whole lot of code, most of the
code changes in the patch is execute.c refactoring.
ECPGdo() was split into several functions, the new parts
are still doing the same things.

I can make the test case much smaller, I only needed
to test crossing the readahead window boundary.
This would also make the patch much smaller.

And this readahead is not on by default, it's only activated
by "ecpg -r fetch_readahead".

Best regards,
Zolt�n B�sz�rm�nyi

#4Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Böszörményi Zoltán (#3)
Re: ECPG FETCH readahead

On 24/06/10 10:27, B�sz�rm�nyi Zolt�n wrote:

And this readahead is not on by default, it's only activated
by "ecpg -r fetch_readahead".

Is there a reason not to enable it by default? I'm a bit worried that it
will receive no testing if it's not always on.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

In reply to: Heikki Linnakangas (#4)
Re: ECPG FETCH readahead

2010-06-24 11:04 keltez�ssel, Heikki Linnakangas �rta:

On 24/06/10 10:27, B�sz�rm�nyi Zolt�n wrote:

And this readahead is not on by default, it's only activated
by "ecpg -r fetch_readahead".

Is there a reason not to enable it by default? I'm a bit worried that
it will receive no testing if it's not always on.

Because in the first step I wanted to minimize the impact
on regression test stderr results. This is what I mentioned
in the initial mail, I stuck to the original wording of ecpg_log()
messages in the split-up parts of the original ECPGdo() and
ecpg_execute() exactly for this reason. The usual policy for
ecpg_log() is to report the function name where it was issued.

I was also thinking about a new feature for pg_regress,
to compare stdout results of two regression tests automatically
so a difference can be reported as an error. It would be good
for automated testing of features in ECPG that can be toggled,
like auto-prepare and fetch readahead. It might come in handy
in other subsystems, too.

Best regards,
Zolt�n B�sz�rm�nyi

#6Michael Meskes
meskes@postgresql.org
In reply to: Bruce Momjian (#2)
Re: ECPG FETCH readahead

On Wed, Jun 23, 2010 at 04:42:37PM -0400, Bruce Momjian wrote:

I assume our ecpg version supports >1 fetch values, even in Informix
mode. Does it make sense to add lots of code to our ecpg then?

Yes, it does. The big question that zoltan and I haven't figured out yet, is
whether it makes sense to add all this even for native ecpg mode.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
ICQ 179140304, AIM/Yahoo/Skype michaelmeskes, Jabber meskes@jabber.org
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#7Michael Meskes
meskes@postgresql.org
In reply to: Böszörményi Zoltán (#3)
Re: ECPG FETCH readahead

I think, yes, it does make sense. Because we are talking
about porting a whole lot of COBOL applications.

COBOL???

The ESQL/C or ECPG connector was already written
the Informix quirks in mind, so it fetches only one record
at a time passing it to the application. And similar performance
is expected from ECPG - which excpectation is not fulfilled
currently because libecpg doesn't do the same caching as
ESQL/C does.

Eh, you are talking about a program you wrote for your customer or they wrote
themselves, right? I simply refuse to add this stuff only to fix this situation
for that one customer of yours if it only hits them. Now the thing to discuss
is how common is this situation.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
ICQ 179140304, AIM/Yahoo/Skype michaelmeskes, Jabber meskes@jabber.org
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#8Michael Meskes
meskes@postgresql.org
In reply to: Heikki Linnakangas (#4)
Re: ECPG FETCH readahead

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

Michael

--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
ICQ 179140304, AIM/Yahoo/Skype michaelmeskes, Jabber meskes@jabber.org
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

In reply to: Michael Meskes (#7)
Re: ECPG FETCH readahead

On Jun 24, 2010, at 2:13 PM, Michael Meskes wrote:

I think, yes, it does make sense. Because we are talking
about porting a whole lot of COBOL applications.

COBOL???

yes, COBOL :).
it is much more common than people think.
it is not the first COBOL request for PostgreSQL hitting my desk.
in our concrete example we are using a C module written with ECPG which is magically attached to tons of COBOL code ...

The ESQL/C or ECPG connector was already written
the Informix quirks in mind, so it fetches only one record
at a time passing it to the application. And similar performance
is expected from ECPG - which excpectation is not fulfilled
currently because libecpg doesn't do the same caching as
ESQL/C does.

Eh, you are talking about a program you wrote for your customer or they wrote
themselves, right? I simply refuse to add this stuff only to fix this situation
for that one customer of yours if it only hits them. Now the thing to discuss
is how common is this situation.

Michael

i think that this cursor issue is a pretty common thing for many codes.
people are usually not aware of the fact that network round trips and parsing which are naturally related to "FETCH 1" are a lot more expensive than fetching one row somewhere deep inside the DB engine.
out there there are many applications which fetch data row by row. if an app fetches data row by row in PostgreSQL it will be A LOT slower than in, say, Informix because most commercial database clients will cache data inside a cursor behind the scenes to avoid the problem we try to solve.

currently we are talking about a performance penalty of factor 5 or so. so - it is not a small thing; it is a big difference.

regards,

hans

--
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de

In reply to: Michael Meskes (#7)
Re: ECPG FETCH readahead

2010-06-24 14:13 keltezéssel, Michael Meskes írta:

I think, yes, it does make sense. Because we are talking
about porting a whole lot of COBOL applications.

COBOL???

Yes, OpenCOBOL...

The ESQL/C or ECPG connector was already written
the Informix quirks in mind, so it fetches only one record
at a time passing it to the application. And similar performance
is expected from ECPG - which excpectation is not fulfilled
currently because libecpg doesn't do the same caching as
ESQL/C does.

Eh, you are talking about a program you wrote for your customer or they wrote
themselves, right? I simply refuse to add this stuff only to fix this situation
for that one customer of yours if it only hits them. Now the thing to discuss
is how common is this situation.

The OpenCOBOL database connector was written by them
but the problem is more generic. There are many "naive"
applications (elsewhere, too) using cursors but fetching
one record at a time perhaps for portability reasons.
This patch provides a big performance boost for those.

Best regards,
Zoltán Böszörményi

#11Robert Haas
robertmhaas@gmail.com
In reply to: Michael Meskes (#8)
Re: ECPG FETCH readahead

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

So, who has the next action on this patch? Does Zoltan need to revise
it, or does Michael need to review it, or where are we?

Thanks,

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

#12Boszormenyi Zoltan
zb@cybertec.at
In reply to: Robert Haas (#11)
Re: ECPG FETCH readahead

Hi,

Robert Haas �rta:

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

So, who has the next action on this patch? Does Zoltan need to revise
it, or does Michael need to review it, or where are we?

Michael reviewed it shortly in private and I need to send
a new revision anyway, regardless of his comments.
I will refresh it ASAP.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#13Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#12)
1 attachment(s)
Re: ECPG FETCH readahead

2010-10-14 11:56 keltezéssel, Boszormenyi Zoltan írta:

Hi,

Robert Haas írta:

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

So, who has the next action on this patch? Does Zoltan need to revise
it, or does Michael need to review it, or where are we?

Michael reviewed it shortly in private and I need to send
a new revision anyway, regardless of his comments.
I will refresh it ASAP.

The ASAP took a little long. The attached patch is in git diff format,
because (1) the regression test intentionally doesn't do ECPGdebug()
so the patch isn't dominated by a 2MB stderr file, so this file is empty
and (2) regular diff cannot cope with empty new files.

Anyway, here is the new version with a new feature.
Implementation details:

- New ecpglib/cursor.c handles the client-side accounting of cursors.
- Functions in ecpglib/execute.c are split into smaller functions
so useful operations can be used by the new cursor.c
- ecpg -r fetch_readahead enables readahead by default for all cursors.
- Default readahead size is 256 rows, it can be modified by an environment
variable, ECPGFETCHSZ.
- *NEW FEATURE* Readahead can be individually enabled or disabled
by ECPG-side grammar:
DECLARE curname [ [ NO ] READAHEAD ] CURSOR FOR ...
Without [ NO ] READAHEAD, the default behaviour is used for cursors.
- Since the server and the client may disagree on the cursor position
if readahead is used, ECPG preprocessor throws an error if
WHERE CURRENT OF is used on such cursors.
- The default assumed behaviour of cursors with readahead is NO SCROLL.
If you want readahead and backward scrolling, SCROLL keyword is mandatory.

The regression test creates a table with 513 rows, so it spans 2 full and
1 incomplete readahead window. It reads the table with two cursors, one
with readahead and one without by 1 records forward and backward.
This is repeated with reading 5 records at a time. Then the whole table is
read into a chain of sqlda structures forward and backward. All other
regression tests pass as well.

The original regression tests also pass with these changes, the split of
execute.c was risky in this regard. Now the split is done more cleanly
than in the previous version, the file is not as rearranged as before.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.2-git-v2.patchtext/plain; name=ecpg-cursor-readahead-9.2-git-v2.patchDownload
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 68833ca..69b49e0 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -454,6 +454,32 @@ EXEC SQL COMMIT;
    details.
   </para>
 
+  <para>
+   ECPG may use cursor readahead to improve performance of programs
+   that use single-row FETCH statements. Option <literal>-r fetch_readahead</literal>
+   option for ECPG modifies the default for all cursors from <literal>NO READAHEAD</literal>
+   to <literal>READAHEAD</literal>. Explicit <literal>READAHEAD</literal> or
+   <literal>NO READAHEAD</literal> turns cursor readahead on or off for the specified cursor,
+   respectively. The default readahead size is 256 rows, this may be modified by setting
+   the <literal>ECPGFETCHSZ</literal> environment variable to a different value.
+  </para>
+
+  <para>
+   Scrolling behaviour differs from the documented one at <xref linkend="sql-declare">
+   when readahead is used for a cursor. ECPG treats cursors as <literal>NO SCROLL</literal>
+   when neither <literal>SCROLL</literal> nor <literal>NO SCROLL</literal> are specified.
+   When backward fetching or positioning is attempted on a <literal>NO SCROLL READAHEAD</literal>
+   cursor, error code 55000 (Object not in prerequisite state) is returned to the application.
+  </para>
+
+  <para>
+   For cursors used in <command>UPDATE</command> or <command>DELETE</command>
+   with the <literal>WHERE CURRENT OF</literal> clause, cursor readahead must be
+   turned off, otherwise <command>ecpg</command> throws an error. This restriction
+   is because when the client side uses readahead, the idea about the cursor position
+   in the dataset may differ between the server and the client.
+  </para>
+
    <note>
     <para>
      The ECPG <command>DECLARE</command> command does not actually
@@ -6583,8 +6609,8 @@ EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
 
    <refsynopsisdiv>
 <synopsis>
-DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">prepared_name</replaceable>
-DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">query</replaceable>
+DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] [ [ NO ] READAHEAD ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">prepared_name</replaceable>
+DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] [ [ NO ] READAHEAD ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">query</replaceable>
 </synopsis>
    </refsynopsisdiv>
 
@@ -6639,11 +6665,36 @@ DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ IN
       </listitem>
      </varlistentry>
     </variablelist>
+   </refsect1>
+
+   <refsect1>
+    <title>Cursor options</title>
 
     <para>
-     For the meaning of the cursor options,
-     see <xref linkend="sql-declare">.
+     For the meaning of other cursor options, see <xref linkend="sql-declare">.
     </para>
+
+    <variablelist>
+     <varlistentry>
+      <term><literal>READAHEAD</literal></term>   
+      <term><literal>NO READAHEAD</literal></term>   
+       <listitem>
+        <para>
+         <literal>READAHEAD</literal> makes the ECPG preprocessor and runtime library
+         use a client-side cursor accounting and data readahead during
+         <command>FETCH</command>. This improves performance for programs that use
+         single-row <command>FETCH</command> statements.
+        </para>
+
+        <para>
+         <literal>NO READAHEAD</literal> disables data readahead in case
+         <parameter>-r fetch_readahead</parameter> is used for compiling the file.
+        </para>
+       </listitem>
+      </varlistentry>
+
+    </variablelist>
+
    </refsect1>
 
    <refsect1>
diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml
index 9c13e93..22dfe44 100644
--- a/doc/src/sgml/ref/ecpg-ref.sgml
+++ b/doc/src/sgml/ref/ecpg-ref.sgml
@@ -166,6 +166,14 @@ PostgreSQL documentation
          </para>
          </listitem>
         </varlistentry>
+        <varlistentry>
+         <term><option>fetch_readahead</option></term>
+         <listitem>
+         <para>
+         Turn on cursor readahead by default.
+         </para>
+         </listitem>
+        </varlistentry>
        </variablelist></para>
      </listitem>
     </varlistentry>
diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile
index 2b2ffb6..1f46ff6 100644
--- a/src/interfaces/ecpg/ecpglib/Makefile
+++ b/src/interfaces/ecpg/ecpglib/Makefile
@@ -25,7 +25,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 LIBS := $(filter-out -lpgport, $(LIBS))
 
 OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
-	connect.o misc.o path.o pgstrcasecmp.o \
+	connect.o misc.o path.o pgstrcasecmp.o cursor.o \
 	$(filter snprintf.o strlcpy.o win32setlocale.o, $(LIBOBJS))
 
 # thread.c is needed only for non-WIN32 implementation of path.c
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 997046b..7eda052 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -456,6 +456,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 
 	this->cache_head = NULL;
 	this->prep_stmts = NULL;
+	this->cursor_desc = NULL;
 
 	if (all_connections == NULL)
 		this->next = NULL;
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
new file mode 100644
index 0000000..ff6e40d
--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,708 @@
+/*
+ * FETCH readahead support routines
+ */
+
+#define POSTGRES_ECPG_INTERNAL
+#include "postgres_fe.h"
+
+#include <limits.h>
+
+#include "ecpgtype.h"
+#include "ecpglib.h"
+#include "ecpgerrno.h"
+#include "extern.h"
+
+static struct cursor_descriptor *add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing);
+static struct cursor_descriptor *find_cursor(struct connection *con, const char *name);
+static void del_cursor(struct connection *con, const char *name);
+
+/* default fetch size, set on the first call to ECPGopen()  */
+#define DEFAULTFETCHSIZE	(256)
+static int	fetch_size = 0;
+
+/*
+ * Add a new cursor descriptor, maintain alphabetic order
+ */
+static struct cursor_descriptor *
+add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing)
+{
+	struct cursor_descriptor *desc,
+				*ptr, *prev = NULL;
+	bool	found = false;
+
+	if (!name || name[0] == '\0')
+	{
+		if (existing)
+			*existing = false;
+		return NULL;
+	}
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}
+
+	if (found)
+	{
+		if (existing)
+			*existing = true;
+		return ptr;
+	}
+
+	desc = (struct cursor_descriptor *)ecpg_alloc(sizeof(struct cursor_descriptor), lineno);
+	if (!desc)
+		return NULL;
+	desc->name = ecpg_strdup(name, lineno);
+	if (!desc->name)
+	desc->res = NULL;
+	desc->scrollable = scrollable;
+	desc->n_tuples = n_tuples;
+	desc->start_pos = 0;
+	desc->cache_pos = 0;
+	desc->next = ptr;
+
+	if (prev)
+		prev->next = desc;
+	else
+		con->cursor_desc = desc;
+
+	if (existing)
+		*existing = false;
+	return desc;
+}
+
+static struct cursor_descriptor *
+find_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *desc = con->cursor_desc;
+	bool	found = false;
+
+	if (!name)
+		return NULL;
+
+	while (desc)
+	{
+		int ret = strcasecmp(desc->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+		desc = desc->next;
+	}
+
+	return (found ? desc : NULL);
+}
+
+static void
+del_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *ptr, *prev = NULL;
+	bool	found = false;
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}
+
+	if (found)
+	{
+		if (prev)
+			prev->next = ptr->next;
+		else
+			con->cursor_desc = ptr->next;
+
+		ecpg_free(ptr->name);
+		if (ptr->res)
+			PQclear(ptr->res);
+		ecpg_free(ptr);
+	}
+}
+
+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");
+	scrollable = (noscroll == NULL) && (scroll != NULL) && (scroll < ptr);
+
+	new_query = ecpg_alloc(strlen(curname) + strlen(ptr) + (whold ? 10 : 0) + 32, lineno);
+	if (!new_query)
+		return false;
+	sprintf(new_query, "declare %s %s cursor %s%s",
+					(dollar0 && (dollar0 < ptr) ? "$0" : curname),
+					(scrollable ? "scroll" : "no scroll"),
+					(whold ? "with hold " : ""),
+					ptr);
+
+	/* Set the fetch size the first time we are called. */
+	if (fetch_size == 0)
+	{
+		char	   *fsize_str = getenv("ECPGFETCHSZ");
+		char	   *endptr = NULL;
+		int		fsize;
+
+		if (fsize_str)
+		{
+			fsize = strtoul(fsize_str, &endptr, 10);
+			if (endptr || (fsize < 4))
+				fetch_size = DEFAULTFETCHSIZE;
+			else
+				fetch_size = fsize;
+		}
+		else
+			fetch_size = DEFAULTFETCHSIZE;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, new_query, args);
+	va_end(args);
+
+	ecpg_free(new_query);
+
+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)
+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}
+
+		/* Add the cursor */
+		cur = add_cursor(lineno, con, curname, scrollable, n_tuples, &existing);
+
+		/*
+		 * Report the number of tuples for the [scrollable] cursor.
+		 * The server didn't do it for us.
+		 */
+		sqlca->sqlerrd[2] = (cur->n_tuples < LONG_MAX ? cur->n_tuples : LONG_MAX);
+	}
+
+	return ret;
+}
+
+static bool
+ecpg_cursor_execute(struct statement * stmt, struct cursor_descriptor *cur)
+{
+	char		tmp[64];
+	char	   *query;
+	int64		start_pos;
+
+	if ((cur->cache_pos >= cur->start_pos) && cur->res && (cur->cache_pos < cur->start_pos + PQntuples(cur->res)))
+	{
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}
+	else if (!cur->scrollable && cur->res && (PQntuples(cur->res) < fetch_size) && (cur->cache_pos >= cur->start_pos + PQntuples(cur->res)))
+	{
+		cur->endoftuples = true;
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}
+
+	if ((PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE) && !stmt->connection->autocommit)
+	{
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		{
+			ecpg_free_params(stmt, false, stmt->lineno);
+			return false;
+		}
+		PQclear(stmt->results);
+	}
+
+	/*
+	 * Compute the tuple position before the resultset. E.g.:
+	 * MOVE ABSOLUTE 0 + FETCH NEXT <fetch_size> will result
+	 * in a recordset having tuples 1 ... fetch_size
+	 */
+	start_pos = (cur->cache_pos - 1) / fetch_size;
+	start_pos *= fetch_size;
+
+	if (cur->scrollable)
+	{
+		sprintf(tmp, "%lld", (long long)start_pos);
+		query = ecpg_alloc(strlen(tmp) + strlen(cur->name) + 20, stmt->lineno);
+		sprintf(query, "move absolute %s in %s", tmp, cur->name);
+
+		ecpg_log("ecpg_cursor_execute on line %d: query: %s; on connection %s\n", stmt->lineno, query, stmt->connection->name);
+
+		stmt->results = PQexec(stmt->connection->connection, query);
+
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		{
+			ecpg_free_params(stmt, false, stmt->lineno);
+			return false;
+		}
+
+		PQclear(stmt->results);
+		ecpg_free(query);
+	}
+
+	sprintf(tmp, "%lld", (long long)fetch_size);
+	query = ecpg_alloc(strlen(tmp) + strlen(cur->name) + 24, stmt->lineno);
+	sprintf(query, "fetch forward %s from %s", tmp, cur->name);
+
+	if (cur->res)
+		PQclear(cur->res);
+
+	ecpg_log("ecpg_cursor_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, query, stmt->nparams, stmt->connection->name);
+
+	if (stmt->nparams == 0)
+	{
+		cur->res = PQexec(stmt->connection->connection, query);
+		ecpg_log("ecpg_cursor_execute on line %d: using PQexec\n", stmt->lineno);
+	}
+	else
+	{
+		/* shouldn't happen */
+		cur->res = PQexecParams(stmt->connection->connection, query, stmt->nparams, NULL, stmt->param_values, NULL, NULL, 0);
+		ecpg_log("ecpg_cursor_execute on line %d: using PQexecParams\n", stmt->lineno);
+	}
+
+	stmt->results = cur->res;
+
+	ecpg_free_params(stmt, true, stmt->lineno);
+
+	if (!ecpg_check_PQresult(cur->res, stmt->lineno, stmt->connection->connection, stmt->compat))
+	{
+		stmt->results = cur->res = NULL;
+		cur->start_pos = 0;
+		return false;
+	}
+
+	/* The tuple position in the cursor is 1 based. */
+	cur->start_pos = start_pos + 1;
+
+	if (!cur->scrollable && PQntuples(cur->res) == 0)
+		cur->endoftuples = true;
+
+	ecpg_free(query);
+
+	return true;
+}
+
+bool
+ECPGfetch(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, enum ECPG_cursor_direction direction, const char *amount,
+		const int st, const char *query, ...)
+{
+	struct cursor_descriptor *cur;
+	struct statement *stmt;
+	va_list			args;
+	bool			move, fetchall = false, negate = false;
+	const char	   *amount1 = amount;
+	int			step;
+	int64			n_amount, count, start_idx;
+	struct sqlca_t		   *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+
+	move = (strncmp(query, "move ", 5) == 0);
+
+	cur = find_cursor(ecpg_get_connection(connection_name), curname);
+	if (!cur)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_NAME, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+		return false;
+	}
+
+	va_start(args, query);
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name, questionmarks, (enum ECPG_statement_type) st, query, args, &stmt))
+		return false;
+
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		va_end(args);
+		return false;
+	}
+
+	if (amount[0] == '$')
+		amount1 = stmt->dollarzero[0];
+	else if (amount[0] == '-' || amount[0] == '+')
+	{
+		/*
+		 * Handle negative and explicitely positive constants in
+		 * FETCH/MOVE ABSOLUTE/RELATIVE const.
+		 * E.g. '-2' arrives as '- 2', '+2' arrives as '+ 2'.
+		 * strtoll() under Linux stops processing at the space.
+		 */
+		if (amount[0] == '-')
+			negate = true;
+		amount1 = amount + 1;
+		while (*amount1 == ' ')
+			amount1++;
+	}
+
+	if (strcmp(amount, "all") == 0)
+	{
+		fetchall = true;
+		if (cur->scrollable)
+		{
+			switch (direction)
+			{
+				case ECPGc_forward:
+					n_amount = cur->n_tuples - cur->cache_pos;
+					break;
+				case ECPGc_backward:
+					n_amount = cur->cache_pos;
+					break;
+				default:
+					ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+					return false;
+			}
+		}
+		else
+			n_amount = LONG_MAX;
+	}
+	else
+	{
+		char	   *endptr;
+
+		n_amount = strtoll(amount1, &endptr, 10);
+		if (negate)
+			n_amount = -n_amount;
+	}
+
+	switch (direction)
+	{
+		case ECPGc_absolute:
+			if (cur->scrollable)
+			{
+				if (n_amount < 0)
+					n_amount = 1 + cur->n_tuples + n_amount;
+				else if (n_amount > cur->n_tuples)
+					n_amount = cur->n_tuples + 1;
+			}
+			else
+			{
+				if (n_amount < 0)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					break;
+				}
+				if (n_amount < cur->cache_pos)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					break;
+				}
+			}
+			cur->cache_pos = n_amount;
+
+			if (!move)
+			{
+				if (cur->cache_pos > 0 && ((cur->scrollable && cur->cache_pos <= cur->n_tuples) || (!cur->scrollable && !cur->endoftuples)))
+				{
+					if (!ecpg_cursor_execute(stmt, cur))
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+
+					if (!cur->scrollable && cur->endoftuples)
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+						return false;
+					}
+
+					start_idx = cur->cache_pos - cur->start_pos;
+
+					if (!ecpg_process_output(stmt, start_idx, start_idx + 1, 0, true, false))
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+				}
+				else
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+				}
+			}
+			else
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+			}
+			sqlca->sqlerrd[2] = (cur->cache_pos && cur->cache_pos <= cur->n_tuples ? 1 : 0);
+			break;
+
+		case ECPGc_relative:
+relative:
+			if (!cur->scrollable)
+			{
+				if (n_amount < 0)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					break;
+				}
+			}
+
+			cur->cache_pos += n_amount;
+			if (cur->cache_pos < 0)
+				cur->cache_pos = 0;
+			else if (cur->cache_pos > cur->n_tuples)
+				cur->cache_pos = cur->n_tuples + 1;
+
+			if (!move)
+			{
+				if (cur->cache_pos > 0 && ((cur->scrollable && cur->cache_pos <= cur->n_tuples) || (!cur->scrollable && !cur->endoftuples)))
+				{
+					if (!ecpg_cursor_execute(stmt, cur))
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+
+					if (!cur->scrollable && cur->endoftuples)
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+						return false;
+					}
+
+					start_idx = cur->cache_pos - cur->start_pos;
+
+					if (!ecpg_process_output(stmt, start_idx, start_idx + 1, 0, true, false))
+					{
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+				}
+				else
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+				}
+			}
+			else
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+			}
+			sqlca->sqlerrd[2] = (cur->cache_pos && cur->cache_pos <= cur->n_tuples ? 1 : 0);
+			break;
+
+		case ECPGc_forward:
+		case ECPGc_backward:
+			if (n_amount == 0)
+				goto relative;
+
+			step = (n_amount > 0 ? 1 : -1);
+			if (direction == ECPGc_backward)
+				step = -step;
+			if (n_amount < 0)
+				n_amount = -n_amount;
+
+			if (!cur->scrollable && step < 0)
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+				ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+				break;
+			}
+
+			if (move)
+			{
+				int64 new_pos = cur->cache_pos + step * n_amount;
+				int64 diff;
+
+				if (new_pos < 1)
+					new_pos = 0;
+				if (new_pos > cur->n_tuples)
+					new_pos = cur->n_tuples + 1;
+
+				diff = new_pos - cur->cache_pos;
+				sqlca->sqlerrd[2] = (diff >= 0 ? diff : -diff);
+				cur->cache_pos = new_pos;
+
+				ecpg_free_params(stmt, true, stmt->lineno);
+				break;
+			}
+
+			for (count = 0; (cur->scrollable && count < n_amount) ||
+					(!cur->scrollable && ((fetchall && !cur->endoftuples) || (!fetchall && count < n_amount))); count++)
+			{
+				cur->cache_pos += step;
+				if (cur->cache_pos < 1)
+				{
+					cur->cache_pos = 0;
+					break;
+				}
+				else
+				{
+					if (cur->scrollable && cur->cache_pos > cur->n_tuples)
+					{
+						cur->cache_pos = cur->n_tuples + 1;
+						break;
+					}
+					else if (!cur->scrollable && cur->endoftuples)
+					{
+						break;
+					}
+				}
+
+				if (!ecpg_cursor_execute(stmt, cur))
+				{
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					return false;
+				}
+
+				if (!cur->scrollable && cur->endoftuples)
+					break;
+
+				start_idx = cur->cache_pos - cur->start_pos;
+
+				if (!ecpg_process_output(stmt, start_idx, start_idx + 1, count, true, (count > 0)))
+				{
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					return false;
+				}
+			}
+
+			if (count == 0)
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+				ecpg_do_epilogue(stmt);
+				va_end(args);
+				ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+				return false;
+			}
+
+			sqlca->sqlerrd[2] = count;
+
+			break;
+
+		default:
+			ecpg_free_params(stmt, true, stmt->lineno);
+			ecpg_do_epilogue(stmt);
+			va_end(args);
+			ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_DEFINITION, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+			return false;
+	}
+
+	ecpg_do_epilogue(stmt);
+	va_end(args);
+	return true;
+}
+
+bool
+ECPGclose(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	struct connection  *con;
+	va_list			args;
+	bool			ret;
+
+	con = ecpg_get_connection(connection_name);
+
+	if (!find_cursor(con, curname))
+	{
+		ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_NAME, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+		return false;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, query, args);
+	va_end(args);
+
+	del_cursor(con, curname);
+
+	return ret;
+}
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index fc04556..6cbf327 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -120,7 +120,7 @@ check_special_value(char *ptr, double *retval, char **endptr)
 }
 
 bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int var_index, int act_tuple, int act_field, int lineno,
 			  enum ECPGttype type, enum ECPGttype ind_type,
 			  char *var, char *ind, long varcharsize, long offset,
 			  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
@@ -167,20 +167,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	{
 		case ECPGt_short:
 		case ECPGt_unsigned_short:
-			*((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((short *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_int:
 		case ECPGt_unsigned_int:
-			*((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_long:
 		case ECPGt_unsigned_long:
-			*((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #ifdef HAVE_LONG_LONG_INT
 		case ECPGt_long_long:
 		case ECPGt_unsigned_long_long:
-			*((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long long int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #endif   /* HAVE_LONG_LONG_INT */
 		case ECPGt_NO_INDICATOR:
@@ -192,7 +192,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					 * Informix has an additional way to specify NULLs note
 					 * that this uses special values to denote NULL
 					 */
-					ECPGset_noind_null(type, var + offset * act_tuple);
+					ECPGset_noind_null(type, var + offset * var_index);
 				}
 				else
 				{
@@ -243,10 +243,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		if (binary)
 		{
 			if (varcharsize == 0 || varcharsize * offset >= size)
-				memcpy(var + offset * act_tuple, pval, size);
+				memcpy(var + offset * var_index, pval, size);
 			else
 			{
-				memcpy(var + offset * act_tuple, pval, varcharsize * offset);
+				memcpy(var + offset * var_index, pval, varcharsize * offset);
 
 				if (varcharsize * offset < size)
 				{
@@ -255,20 +255,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					{
 						case ECPGt_short:
 						case ECPGt_unsigned_short:
-							*((short *) (ind + ind_offset * act_tuple)) = size;
+							*((short *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_int:
 						case ECPGt_unsigned_int:
-							*((int *) (ind + ind_offset * act_tuple)) = size;
+							*((int *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_long:
 						case ECPGt_unsigned_long:
-							*((long *) (ind + ind_offset * act_tuple)) = size;
+							*((long *) (ind + ind_offset * var_index)) = size;
 							break;
 #ifdef HAVE_LONG_LONG_INT
 						case ECPGt_long_long:
 						case ECPGt_unsigned_long_long:
-							*((long long int *) (ind + ind_offset * act_tuple)) = size;
+							*((long long int *) (ind + ind_offset * var_index)) = size;
 							break;
 #endif   /* HAVE_LONG_LONG_INT */
 						default:
@@ -307,13 +307,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_short:
-							*((short *) (var + offset * act_tuple)) = (short) res;
+							*((short *) (var + offset * var_index)) = (short) res;
 							break;
 						case ECPGt_int:
-							*((int *) (var + offset * act_tuple)) = (int) res;
+							*((int *) (var + offset * var_index)) = (int) res;
 							break;
 						case ECPGt_long:
-							*((long *) (var + offset * act_tuple)) = (long) res;
+							*((long *) (var + offset * var_index)) = (long) res;
 							break;
 						default:
 							/* Cannot happen */
@@ -336,13 +336,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_unsigned_short:
-							*((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
+							*((unsigned short *) (var + offset * var_index)) = (unsigned short) ures;
 							break;
 						case ECPGt_unsigned_int:
-							*((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
+							*((unsigned int *) (var + offset * var_index)) = (unsigned int) ures;
 							break;
 						case ECPGt_unsigned_long:
-							*((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
+							*((unsigned long *) (var + offset * var_index)) = (unsigned long) ures;
 							break;
 						default:
 							/* Cannot happen */
@@ -353,7 +353,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #ifdef HAVE_LONG_LONG_INT
 #ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
-					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
+					*((long long int *) (var + offset * var_index)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, scan_length, compat))
 					{
 						ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -365,7 +365,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #endif   /* HAVE_STRTOLL */
 #ifdef HAVE_STRTOULL
 				case ECPGt_unsigned_long_long:
-					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
+					*((unsigned long long int *) (var + offset * var_index)) = strtoull(pval, &scan_length, 10);
 					if ((isarray && *scan_length != ',' && *scan_length != '}')
 						|| (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))		/* Garbage left */
 					{
@@ -400,10 +400,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_float:
-							*((float *) (var + offset * act_tuple)) = dres;
+							*((float *) (var + offset * var_index)) = dres;
 							break;
 						case ECPGt_double:
-							*((double *) (var + offset * act_tuple)) = dres;
+							*((double *) (var + offset * var_index)) = dres;
 							break;
 						default:
 							/* Cannot happen */
@@ -415,9 +415,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					if (pval[0] == 'f' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = false;
+							*((char *) (var + offset * var_index)) = false;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = false;
+							*((int *) (var + offset * var_index)) = false;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -427,16 +427,16 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					else if (pval[0] == 't' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = true;
+							*((char *) (var + offset * var_index)) = true;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = true;
+							*((int *) (var + offset * var_index)) = true;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
 									   NULL);
 						break;
 					}
-					else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
+					else if (pval[0] == '\0' && PQgetisnull(results, var_index, act_field))
 					{
 						/* NULL is valid */
 						break;
@@ -451,7 +451,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_unsigned_char:
 				case ECPGt_string:
 					{
-						char	   *str = (char *) (var + offset * act_tuple);
+						char	   *str = (char *) (var + offset * var_index);
 
 						if (varcharsize == 0 || varcharsize > size)
 						{
@@ -479,20 +479,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = size;
+										*((short *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = size;
+										*((int *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = size;
+										*((long *) (ind + ind_offset * var_index)) = size;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = size;
+										*((long long int *) (ind + ind_offset * var_index)) = size;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -508,7 +508,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_varchar:
 					{
 						struct ECPGgeneric_varchar *variable =
-						(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
+						(struct ECPGgeneric_varchar *) (var + offset * var_index);
 
 						variable->len = size;
 						if (varcharsize == 0)
@@ -524,20 +524,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + offset * act_tuple)) = variable->len;
+										*((short *) (ind + offset * var_index)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + offset * act_tuple)) = variable->len;
+										*((int *) (ind + offset * var_index)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + offset * act_tuple)) = variable->len;
+										*((long *) (ind + offset * var_index)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long long int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -604,9 +604,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					if (type == ECPGt_numeric)
-						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
+						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * var_index));
 					else
-						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
+						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * var_index));
 
 					PGTYPESnumeric_free(nres);
 					break;
@@ -657,7 +657,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					pval = scan_length;
 
-					PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
+					PGTYPESinterval_copy(ires, (interval *) (var + offset * var_index));
 					free(ires);
 					break;
 
@@ -701,7 +701,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((date *) (var + offset * act_tuple)) = ddres;
+					*((date *) (var + offset * var_index)) = ddres;
 					pval = scan_length;
 					break;
 
@@ -745,7 +745,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((timestamp *) (var + offset * act_tuple)) = tres;
+					*((timestamp *) (var + offset * var_index)) = tres;
 					pval = scan_length;
 					break;
 
@@ -762,6 +762,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
 				/* set array to next entry */
 				++act_tuple;
+				++var_index;
 
 				/* set pval to the next entry */
 
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 17a956e..2ec4922 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -438,7 +438,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desparate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index ee553fd..7148f50 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -268,6 +268,20 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
 					 ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
 			break;
 
+		case ECPG_INVALID_CURSOR:
+			if (strcmp(sqlstate, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE) == 0)
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+
+			/*
+			 * translator: this string will be truncated at 149 characters
+			 * expanded.
+			 */
+				ecpg_gettext("cursor can only scan forward"));
+			else
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), str);
+
+			break;
+
 		default:
 			snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
 
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index b8e48a3..12f34f6 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -109,6 +109,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -311,12 +312,12 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results, int start, int end, int act_field,
+				  const struct statement * stmt, struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
 	int			act_tuple,
-				ntuples = PQntuples(results);
+				ntuples = end - start;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -367,7 +368,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (act_tuple = start; act_tuple < end; act_tuple++)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -376,7 +377,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (act_tuple = start; act_tuple < end; act_tuple++)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -397,7 +398,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (act_tuple = start; act_tuple < end; act_tuple++)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -433,11 +434,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (act_tuple = start; act_tuple < end && status; act_tuple++, var_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, var_index, act_tuple, act_field, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -454,9 +455,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (act_tuple = start; act_tuple < end && status; act_tuple++, var_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, var_index, act_tuple, act_field, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1082,18 +1083,26 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 	return true;
 }
 
-static void
-free_params(const char **paramValues, int nParams, bool print, int lineno)
+void
+ecpg_free_params(struct statement *stmt, bool print, int lineno)
 {
 	int			n;
 
-	for (n = 0; n < nParams; n++)
+	for (n = 0; n < stmt->nparams; n++)
 	{
 		if (print)
-			ecpg_log("free_params on line %d: parameter %d = %s\n", lineno, n + 1, paramValues[n] ? paramValues[n] : "null");
-		ecpg_free((void *) (paramValues[n]));
+			ecpg_log("free_params on line %d: parameter %d = %s\n", lineno, n + 1, stmt->param_values[n] ? stmt->param_values[n] : "null");
+		ecpg_free((void *) (stmt->param_values[n]));
 	}
-	ecpg_free(paramValues);
+	ecpg_free(stmt->param_values);
+	stmt->nparams = 0;
+	stmt->param_values = NULL;
+
+	for (n = 0; n < stmt->ndollarzero; n++)
+		ecpg_free((void *) (stmt->dollarzero[n]));
+	ecpg_free(stmt->dollarzero);
+	stmt->ndollarzero = 0;
+	stmt->dollarzero = NULL;
 }
 
 
@@ -1129,20 +1138,12 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGresult   *results;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
-	const char **paramValues = NULL;
-	int			nParams = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1342,7 +1343,7 @@ ecpg_execute(struct statement * stmt)
 			ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS,
 					   ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS,
 					   NULL);
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false, stmt->lineno);
 			return false;
 		}
 
@@ -1357,7 +1358,7 @@ ecpg_execute(struct statement * stmt)
 
 			if (!insert_tobeinserted(position, ph_len, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false, stmt->lineno);
 				return false;
 			}
 			tobeinserted = NULL;
@@ -1370,23 +1371,38 @@ ecpg_execute(struct statement * stmt)
 		 */
 		else if (stmt->command[position] == '0')
 		{
+			const char **dollarzero;
+
+			if (!(dollarzero = (const char **) ecpg_realloc(stmt->dollarzero, sizeof(const char *) * (stmt->ndollarzero + 1), stmt->lineno)))
+			{
+				ecpg_free_params(stmt, false, stmt->lineno);
+				return false;
+			}
+			stmt->ndollarzero++;
+			stmt->dollarzero = dollarzero;
+			stmt->dollarzero[stmt->ndollarzero - 1] = strdup(tobeinserted);
+
 			if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false, stmt->lineno);
 				return false;
 			}
 			tobeinserted = NULL;
 		}
 		else
 		{
-			nParams++;
-			if (!(paramValues = (const char **) ecpg_realloc(paramValues, sizeof(const char *) * nParams, stmt->lineno)))
+			const char **paramValues;
+		
+			if (!(paramValues = (const char **) ecpg_realloc(stmt->param_values, sizeof(const char *) * (stmt->nparams + 1), stmt->lineno)))
 			{
 				ecpg_free(paramValues);
 				return false;
 			}
 
-			paramValues[nParams - 1] = tobeinserted;
+			stmt->nparams++;
+			stmt->param_values = paramValues;
+
+			stmt->param_values[stmt->nparams - 1] = tobeinserted;
 
 			/* let's see if this was an old style placeholder */
 			if (stmt->command[position] == '?')
@@ -1397,7 +1413,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false, stmt->lineno);
 					return false;
 				}
 
@@ -1405,7 +1421,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false, stmt->lineno);
 					return false;
 				}
 				tobeinserted = NULL;
@@ -1421,58 +1437,76 @@ ecpg_execute(struct statement * stmt)
 	{
 		ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
 				 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
-		free_params(paramValues, nParams, false, stmt->lineno);
+		ecpg_free_params(stmt, false, stmt->lineno);
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
+
 
+static bool
+ecpg_execute(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false, stmt->lineno);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
-	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, nParams, stmt->connection->name);
+	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, nParams, paramValues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, stmt->param_values, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
-		if (nParams == 0)
+		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, nParams, NULL, paramValues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, stmt->param_values, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
-	free_params(paramValues, nParams, true, stmt->lineno);
+	ecpg_free_params(stmt, true, stmt->lineno);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return (true);
+}
+
+bool
+ecpg_process_output(struct statement * stmt, int start, int end, int var_index, bool keep_result, bool append_result)
+{
+	char		*cmdstat;
+	PGnotify	*notify;
+	bool		status = false;
+	struct variable *var;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] += ntuples = (end - start);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1494,12 +1528,34 @@ ecpg_execute(struct statement * stmt)
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = results;
-					clear_result = false;
+					int	row, srcrow, col;
+
+					if (append_result)
+						row = PQntuples(desc->result);
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = PQcopyResult(stmt->results, PG_COPYRES_ATTRS | PG_COPYRES_EVENTS | PG_COPYRES_NOTICEHOOKS);
+						row = 0;
+					}
+
+					for (srcrow = start; srcrow < end; srcrow++, row++)
+						for (col = 0; col < nfields; col++)
+						{
+							bool	isnull = PQgetisnull(stmt->results, srcrow, col);
+							if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, srcrow, col),
+										isnull ? -1 : PQgetlength(stmt->results, srcrow, col)))
+							{
+								ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+								status = false;
+								break;
+							}
+						}
+
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1509,36 +1565,52 @@ ecpg_execute(struct statement * stmt)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
-					struct sqlda_compat *sqlda_new;
+					struct sqlda_compat *sqlda_last, *sqlda_new = NULL;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_last = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_last;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
+					}
+					for (i = end - 1; i >= start; i--)
 					{
+						struct sqlda_compat *tmp;
+
 						/*
-						 * Build a new sqlda structure. Note that only
-						 * fetching 1 record is supported
+						 * Build a new sqlda structure. 
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						tmp = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
-						if (!sqlda_new)
+						if (!tmp)
 						{
 							/* cleanup all SQLDAs we created up */
+							while (sqlda_new)
+							{
+								tmp = sqlda_new->desc_next;
+								free(sqlda_new);
+								sqlda_new = tmp;
+							}
 							while (sqlda)
 							{
-								sqlda_new = sqlda->desc_next;
+								tmp = sqlda->desc_next;
 								free(sqlda);
-								sqlda = sqlda_new;
+								sqlda = tmp;
 							}
 							*_sqlda = NULL;
 
@@ -1550,51 +1622,74 @@ ecpg_execute(struct statement * stmt)
 						{
 							ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_new == NULL)
+								sqlda_new = tmp;
+							else
+							{
+								tmp->desc_next = sqlda_new;
+								sqlda_new = tmp;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &tmp, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
+									 stmt->lineno, PQnfields(stmt->results));
 						}
 					}
+					if (sqlda_last)
+						sqlda_last->desc_next = sqlda_new;
+					else
+						*_sqlda = sqlda_new;
 				}
 				else
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
-					struct sqlda_struct *sqlda_new;
+					struct sqlda_struct *sqlda_last, *sqlda_new = NULL;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					else
 					{
 						/*
-						 * Build a new sqlda structure. Note that only
-						 * fetching 1 record is supported
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						while (sqlda)
+						{
+							sqlda_last = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_last;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
+					}
+					for (i = end - 1; i >= start; i--)
+					{
+						struct sqlda_struct *tmp;
+
+						/*
+						 * Build a new sqlda structure. 
+						 */
+						tmp = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
-						if (!sqlda_new)
+						if (!tmp)
 						{
 							/* cleanup all SQLDAs we created up */
+							while (sqlda_new)
+							{
+								tmp = sqlda_new->desc_next;
+								free(sqlda_new);
+								sqlda_new = tmp;
+							}
 							while (sqlda)
 							{
-								sqlda_new = sqlda->desc_next;
+								tmp = sqlda->desc_next;
 								free(sqlda);
-								sqlda = sqlda_new;
+								sqlda = tmp;
 							}
 							*_sqlda = NULL;
 
@@ -1606,16 +1701,23 @@ ecpg_execute(struct statement * stmt)
 						{
 							ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_new == NULL)
+								sqlda_new = tmp;
+							else
+							{
+								tmp->desc_next = sqlda_new;
+								sqlda_new = tmp;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &tmp, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
+									 stmt->lineno, PQnfields(stmt->results));
 						}
 					}
+					if (sqlda_last)
+						sqlda_last->desc_next = sqlda_new;
+					else
+						*_sqlda = sqlda_new;
 				}
 
 				var = var->next;
@@ -1625,7 +1727,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, end, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1644,9 +1746,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1670,12 +1772,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1687,12 +1789,12 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
-	if (clear_result)
-		PQclear(results);
+	if (!keep_result)
+		PQclear(stmt->results);
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
@@ -1707,46 +1809,20 @@ ecpg_execute(struct statement * stmt)
 }
 
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		enum ECPG_statement_type statement_type, const char *query,
+		va_list args, struct statement **stmt_out)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
-	char	   *prepname;
-
-	if (!query)
-	{
-		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
-		return (false);
-	}
-
-	/* Make sure we do NOT honor the locale for numeric input/output */
-	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
-	setlocale(LC_NUMERIC, "C");
-
-#ifdef ENABLE_THREAD_SAFETY
-	ecpg_pthreads_init();
-#endif
-
-	con = ecpg_get_connection(connection_name);
-
-	if (!ecpg_init(con, connection_name, lineno))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		return (false);
-	}
+	char	*prepname;
 
-	/* construct statement in our own structure */
-	va_start(args, query);
+	*stmt_out = NULL;
 
-	/*
+    	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
 	 * an end marker. per variable we list: type - as defined in ecpgtype.h
@@ -1759,11 +1835,24 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
 	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
 		return false;
+
+	/* Make sure we do NOT honor the locale for numeric input/output */
+	/* since the database wants the standard decimal point */
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	setlocale(LC_NUMERIC, "C");
+
+#ifdef ENABLE_THREAD_SAFETY
+	ecpg_pthreads_init();
+#endif
+
+	con = ecpg_get_connection(connection_name);
+
+	if (!ecpg_init(con, connection_name, lineno))
+	{
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
+		return (false);
 	}
 
 	/*
@@ -1774,9 +1863,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
-			va_end(args);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
+			free_statement(stmt);
 			return (false);
 		}
 
@@ -1805,9 +1893,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
-			va_end(args);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
+			free_statement(stmt);
 			return (false);
 		}
 	}
@@ -1834,10 +1921,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1892,10 +1977,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1910,29 +1993,80 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
+
+	return (true);
+}
+
+
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	/* reset locale value so our application is not affected */
+	setlocale(LC_NUMERIC, stmt->oldlocale);
 	free_statement(stmt);
+}
+
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement *stmt;
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name, questionmarks, (enum ECPG_statement_type) st, query, args, &stmt))
+		return false;
+
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), 0, false, false))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;  
+	}
+
+	ecpg_do_epilogue(stmt);
+
+	return true;
+}
+
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, query, args);
+	va_end(args);
 
-	return (status);
+	return ret;
 }
 
 /* old descriptor interface */
diff --git a/src/interfaces/ecpg/ecpglib/exports.txt b/src/interfaces/ecpg/ecpglib/exports.txt
index 69e9617..f05e4f1 100644
--- a/src/interfaces/ecpg/ecpglib/exports.txt
+++ b/src/interfaces/ecpg/ecpglib/exports.txt
@@ -29,3 +29,6 @@ ECPGget_PGconn			 26
 ECPGtransactionStatus		 27
 ECPGset_var			 28
 ECPGget_var			 29
+ECPGopen			 30
+ECPGfetch			 31
+ECPGclose			 32
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 96d49a4..2920a3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
 };
 
 /* structure to store prepared statements for a connection */
@@ -71,6 +77,17 @@ struct prepared_statement
 	struct prepared_statement *next;
 };
 
+struct cursor_descriptor {
+	char	   *name;
+	PGresult   *res;
+	bool		scrollable;
+	bool		endoftuples;	/* valid if ->scrollable == false and there is no more tuples */
+	int64		n_tuples;	/* valid if ->scrollable == true */
+	int64		start_pos;
+	int64		cache_pos;
+	struct cursor_descriptor *next;
+};
+
 /* structure to store connections */
 struct connection
 {
@@ -79,6 +96,7 @@ struct connection
 	bool		autocommit;
 	struct ECPGtype_information_cache *cache_head;
 	struct prepared_statement *prep_stmts;
+	struct cursor_descriptor *cursor_desc;
 	struct connection *next;
 };
 
@@ -126,7 +144,7 @@ struct variable
 /* Returns a pointer to a string containing a simple type name. */
 void		ecpg_add_mem(void *ptr, int lineno);
 
-bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
+bool ecpg_get_data(const PGresult *, int, int, int, int, enum ECPGttype type,
 			  enum ECPGttype, char *, char *, long, long, long,
 			  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
@@ -152,9 +170,16 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results, int start, int end, int act_field,
+				  const struct statement * stmt, struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list, struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_process_output(struct statement *, int, int, int, bool, bool);
+void		ecpg_free_params(struct statement *, bool, int);
+void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
@@ -191,6 +216,8 @@ void		ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int,
 #define ECPG_SQLSTATE_SYNTAX_ERROR			"42601"
 #define ECPG_SQLSTATE_DATATYPE_MISMATCH		"42804"
 #define ECPG_SQLSTATE_DUPLICATE_CURSOR		"42P03"
+#define ECPG_SQLSTATE_INVALID_CURSOR_DEFINITION	"42P11"
+#define ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE	"55000"
 
 /* implementation-defined internal errors of ecpg */
 #define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR	"YE000"
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index a1a0e18..aa37dee 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -389,7 +389,7 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, 0, row, i, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
@@ -571,7 +571,7 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, 0, row, i, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index 36b15b7..f21dad2 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -37,6 +37,7 @@
 #define ECPG_NOT_CONN			-221
 
 #define ECPG_INVALID_STMT		-230
+#define ECPG_INVALID_CURSOR		-231
 
 /* dynamic SQL related */
 #define ECPG_UNKNOWN_DESCRIPTOR		-240
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 3b8ed4c..236f797 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -63,6 +63,13 @@ PGTransactionStatusType ECPGtransactionStatus(const char *);
 
 char	   *ECPGerrmsg(void);
 
+/* Readahead cursor functions */
+bool		ECPGopen(const int, const int, const int, const char *, const bool, const char *, const int, const char *, ...);
+bool		ECPGfetch(const int, const int, const int, const char *, const bool,
+				const char *, enum ECPG_cursor_direction, const char *,
+				const int,const char *, ...);
+bool		ECPGclose(const int, const int, const int, const char *, const bool, const char *, const int, const char *, ...);
+
  /* print an error message */
 void		sqlprint(void);
 
diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h
index 7cc47e9..dc82457 100644
--- a/src/interfaces/ecpg/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -99,6 +99,14 @@ enum ECPG_statement_type
 	ECPGst_prepnormal
 };
 
+enum ECPG_cursor_direction
+{
+	ECPGc_absolute,
+	ECPGc_relative,
+	ECPGc_forward, 
+	ECPGc_backward 
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl
index 991c40c..8560eb0 100644
--- a/src/interfaces/ecpg/preproc/check_rules.pl
+++ b/src/interfaces/ecpg/preproc/check_rules.pl
@@ -43,7 +43,10 @@ my %replace_line = (
 		'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
 
 	'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
-		'PREPARE prepared_name prep_type_clause AS PreparableStmt'
+		'PREPARE prepared_name prep_type_clause AS PreparableStmt',
+
+	'DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt' =>
+		'DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR SelectStmt'
 );
 
 my $block        = '';
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index 23421df..40df82f 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -15,7 +15,10 @@ ECPG: stmtClosePortalStmt block
 			}
 		}
 
-		output_statement($1, 0, ECPGst_normal);
+		if (use_fetch_readahead)
+			output_close_statement($1, 0, ECPGst_normal);
+		else
+			output_statement($1, 0, ECPGst_normal);
 	}
 ECPG: stmtDeallocateStmt block
 	{
@@ -27,8 +30,14 @@ ECPG: stmtDeallocateStmt block
 ECPG: stmtDeclareCursorStmt block
 	{ output_simple_statement($1); }
 ECPG: stmtDiscardStmt block
-ECPG: stmtFetchStmt block
 	{ output_statement($1, 1, ECPGst_normal); }
+ECPG: stmtFetchStmt block
+	{
+		if (use_fetch_readahead)
+			output_fetch_statement($1, 1, ECPGst_normal);
+		else
+			output_statement($1, 1, ECPGst_normal);
+	}
 ECPG: stmtDeleteStmt block
 ECPG: stmtInsertStmt block
 ECPG: stmtSelectStmt block
@@ -137,7 +146,10 @@ ECPG: stmtViewStmt rule
 		if ((ptr = add_additional_variables($1, true)) != NULL)
 		{
 			connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
-			output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			if (use_fetch_readahead)
+				output_open_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			else
+				output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
 			ptr->opened = true;
 		}
 	}
@@ -195,6 +207,21 @@ ECPG: stmtViewStmt rule
 ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
+		struct cursor *ptr;
+
+		for (ptr = cur; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp(ptr->name, $4) == 0)
+				break;
+		}
+		if (!ptr)
+			mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", $4);
+
+		if (ptr->fetch_readahead)
+		{
+			mmerror(PARSE_ERROR, ET_ERROR,
+				"\"WHERE CURRENT OF\" is incompatible with a READAHEAD cursor\n");
+		}
 		$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
 	}
 ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromcopy_file_namecopy_delimiteropt_withcopy_options addon
@@ -215,31 +242,77 @@ ECPG: var_valueNumericOnly addon
 		}
 ECPG: fetch_argscursor_name addon
 		add_additional_variables($1, false);
+		set_cursor_readahead($1);
 		if ($1[0] == ':')
 		{
 			free($1);
 			$1 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsfrom_incursor_name addon
 		add_additional_variables($2, false);
+		set_cursor_readahead($2);
 		if ($2[0] == ':')
 		{
 			free($2);
 			$2 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsNEXTopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsPRIORopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1"); 
 ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsLAST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("-1");
 ECPG: fetch_argsALLopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		set_cursor_readahead($3);
 		if ($3[0] == ':')
 		{
 			free($3);
 			$3 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		set_cursor_readahead($3);
 		if ($3[0] == ':')
 		{
 			free($3);
@@ -250,19 +323,76 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 			free($1);
 			$1 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup($1);
 ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		set_cursor_readahead($4);
 		if ($4[0] == ':')
 		{
 			free($4);
 			$4 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_relative;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		set_cursor_readahead($4);
 		if ($4[0] == ':')
 		{
 			free($4);
@@ -273,7 +403,15 @@ ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 			free($2);
 			$2 = mm_strdup("$0");
 		}
-ECPG: cursor_namename rule
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup($2);
+ECPG: cursor_namename block
+		{
+			if (current_cursor)
+				free(current_cursor);
+			current_cursor = make3_str(mm_strdup("\""), mm_strdup($1), mm_strdup("\""));
+			$$ = $1;
+		}
 	| char_civar
 		{
 			char *curname = mm_alloc(strlen($1) + 2);
@@ -296,7 +434,7 @@ ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
 	}
 ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
 	{ $$ = $2; }
-ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block
+ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsopt_readaheadCURSORopt_holdFORSelectStmt block
 	{
 		struct cursor *ptr, *this;
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
@@ -321,7 +459,13 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		this->function = (current_function ? mm_strdup(current_function) : NULL);
 		this->connection = connection;
 		this->opened = false;
-		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7);
+		if (!strcmp($4, "1"))
+			this->fetch_readahead = true;
+		else if (!strcmp($4, "0"))
+			this->fetch_readahead = false;
+		else
+			this->fetch_readahead = fetch_readahead;
+		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $6, mm_strdup("for"), $8);
 		this->argsinsert = argsinsert;
 		this->argsinsert_oos = NULL;
 		this->argsresult = argsresult;
@@ -348,6 +492,8 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 ECPG: ClosePortalStmtCLOSEcursor_name block
 	{
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
+		if (!INFORMIX_MODE || pg_strcasecmp($2, "database") != 0)
+			set_cursor_readahead($2);
 		$$ = cat2_str(mm_strdup("close"), cursor_marker);
 	}
 ECPG: opt_hold block
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 6f73148..afb898b 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -18,7 +18,8 @@ bool		autocommit = false,
 			force_indicator = true,
 			questionmarks = false,
 			regression_mode = false,
-			auto_prepare = false;
+			auto_prepare = false,
+			fetch_readahead = false;
 
 char	   *output_filename;
 
@@ -51,7 +52,7 @@ help(const char *progname)
 	printf(_("  -I DIRECTORY   search DIRECTORY for include files\n"));
 	printf(_("  -o OUTFILE     write result to OUTFILE\n"));
 	printf(_("  -r OPTION      specify run-time behavior; OPTION can be:\n"
-	 "                 \"no_indicator\", \"prepare\", \"questionmarks\"\n"));
+	 "                 \"no_indicator\", \"prepare\", \"questionmarks\", \"fetch_readahead\"\n"));
 	printf(_("  --regression   run in regression testing mode\n"));
 	printf(_("  -t             turn on autocommit of transactions\n"));
 	printf(_("  --help         show this help, then exit\n"));
@@ -229,6 +230,8 @@ main(int argc, char *const argv[])
 					auto_prepare = true;
 				else if (strcmp(optarg, "questionmarks") == 0)
 					questionmarks = true;
+				else if (strcmp(optarg, "fetch_readahead") == 0)
+					fetch_readahead = true;
 				else
 				{
 					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]);
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 1ea6ce4..1a0b23b 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -34,7 +34,11 @@
  */
 int struct_level = 0;
 int braces_open; /* brace level counter */
+bool use_fetch_readahead = false;
 char *current_function;
+char *current_cursor = NULL;
+enum ECPG_cursor_direction current_cursor_direction;
+char *current_cursor_amount = NULL;
 int ecpg_internal_var = 0;
 char	*connection = NULL;
 char	*input_filename = NULL;
@@ -111,6 +115,26 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
 }
 
 /*
+ * set use_fetch_readahead based on the current cursor
+ * doesn't return if the cursor is not declared
+ */
+static void
+set_cursor_readahead(const char *curname)
+{
+	struct cursor *ptr;
+
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp(ptr->name, curname) == 0)
+			break;
+	}
+	if (!ptr)
+		mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", curname);
+
+	use_fetch_readahead = ptr->fetch_readahead;
+}
+
+/*
  * string concatenation
  */
 
diff --git a/src/interfaces/ecpg/preproc/ecpg.tokens b/src/interfaces/ecpg/preproc/ecpg.tokens
index b55138a..3995b59 100644
--- a/src/interfaces/ecpg/preproc/ecpg.tokens
+++ b/src/interfaces/ecpg/preproc/ecpg.tokens
@@ -10,7 +10,7 @@
                 SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
                 SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
                 SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
-                SQL_OPEN SQL_OUTPUT SQL_REFERENCE
+                SQL_OPEN SQL_OUTPUT SQL_READAHEAD SQL_REFERENCE
                 SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
                 SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
                 SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index a362aff..2bf960f 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -287,7 +287,7 @@ prepared_name: name
  * Declare a prepared cursor. The syntax is different from the standard
  * declare statement, so we create a new rule.
  */
-ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_name
+ECPGCursorStmt:  DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR prepared_name
 		{
 			struct cursor *ptr, *this;
 			char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
@@ -315,15 +315,22 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			this->name = $2;
 			this->function = (current_function ? mm_strdup(current_function) : NULL);
 			this->connection = connection;
-			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
+			this->opened = false;
+			if (!strcmp($4, "1"))
+				this->fetch_readahead = true;
+			else if (!strcmp($4, "0"))
+				this->fetch_readahead = false;
+			else
+				this->fetch_readahead = fetch_readahead;
+			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $6, mm_strdup("for $1"));
 			this->argsresult = NULL;
 			this->argsresult_oos = NULL;
 
 			thisquery->type = &ecpg_query;
 			thisquery->brace_level = 0;
 			thisquery->next = NULL;
-			thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
-			sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
+			thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($8));
+			sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $8);
 
 			this->argsinsert = NULL;
 			this->argsinsert_oos = NULL;
@@ -348,6 +355,11 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 		}
 		;
 
+opt_readahead:	SQL_READAHEAD				{ $$ = mm_strdup("1"); }
+		| NO SQL_READAHEAD			{ $$ = mm_strdup("0"); }
+		| /* EMPTY */			{ $$ = mm_strdup("default"); }
+		;
+
 ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
 			{
 			  /* execute immediate means prepare the statement and
@@ -988,6 +1000,7 @@ ECPGOpen: SQL_OPEN cursor_name opt_ecpg_using
 		{
 			if ($2[0] == ':')
 				remove_variable_from_list(&argsinsert, find_variable($2 + 1));
+			set_cursor_readahead($2);
 			$$ = $2;
 		}
 		;
@@ -1656,6 +1669,10 @@ char_civar: char_variable
 		{
 			char *ptr = strstr($1, ".arr");
 
+			if (current_cursor)
+				free(current_cursor);
+			current_cursor = mm_strdup($1);
+
 			if (ptr) /* varchar, we need the struct name here, not the struct element */
 				*ptr = '\0';
 			add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type
index ac6aa00..2662372 100644
--- a/src/interfaces/ecpg/preproc/ecpg.type
+++ b/src/interfaces/ecpg/preproc/ecpg.type
@@ -85,6 +85,7 @@
 %type <str> opt_output
 %type <str> opt_pointer
 %type <str> opt_port
+%type <str> opt_readahead
 %type <str> opt_reference
 %type <str> opt_scale
 %type <str> opt_server
diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c
index 8032c30..cbd37c6 100644
--- a/src/interfaces/ecpg/preproc/ecpg_keywords.c
+++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c
@@ -56,6 +56,7 @@ static const ScanKeyword ScanECPGKeywords[] = {
 	{"octet_length", SQL_OCTET_LENGTH, 0},
 	{"open", SQL_OPEN, 0},
 	{"output", SQL_OUTPUT, 0},
+	{"readahead", SQL_READAHEAD, 0},
 	{"reference", SQL_REFERENCE, 0},
 	{"returned_length", SQL_RETURNED_LENGTH, 0},
 	{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index ccf5548..3d22d3a 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -24,12 +24,17 @@ extern bool autocommit,
 			force_indicator,
 			questionmarks,
 			regression_mode,
-			auto_prepare;
+			auto_prepare,
+			fetch_readahead;
+extern bool	use_fetch_readahead;
 extern int	braces_open,
 			ret_value,
 			struct_level,
 			ecpg_internal_var;
 extern char *current_function;
+extern char *current_cursor;  
+extern enum ECPG_cursor_direction current_cursor_direction;
+extern char *current_cursor_amount;
 extern char *descriptor_index;
 extern char *descriptor_name;
 extern char *connection;
@@ -67,6 +72,9 @@ extern void output_statement(char *, int, enum ECPG_statement_type);
 extern void output_prepare_statement(char *, char *);
 extern void output_deallocate_prepare_statement(char *);
 extern void output_simple_statement(char *);
+extern void output_open_statement(char *, int, enum ECPG_statement_type);
+extern void output_fetch_statement(char *, int, enum ECPG_statement_type);
+extern void output_close_statement(char *, int, enum ECPG_statement_type);
 extern char *hashline_number(void);
 extern int	base_yyparse(void);
 extern int	base_yylex(void);
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 9958a0a..6e60392 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -112,10 +112,16 @@ static char *ecpg_statement_type_name[] = {
 	"ECPGst_prepnormal"
 };
 
-void
-output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+static char *ecpg_cursor_direction_name[] = {
+	"ECPGc_absolute",
+	"ECPGc_relative",
+	"ECPGc_forward", 
+	"ECPGc_backward" 
+};
+
+static void
+output_statement_epilogue(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 {
-	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
 	if (st == ECPGst_execute || st == ECPGst_exec_immediate)
 	{
 		fprintf(yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
@@ -145,6 +151,13 @@ output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 }
 
 void
+output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
 output_prepare_statement(char *name, char *stmt)
 {
 	fprintf(yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
@@ -178,6 +191,51 @@ output_deallocate_prepare_statement(char *name)
 		free(connection);
 }
 
+void
+output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
+output_fetch_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	char	*amount = mm_alloc(strlen(current_cursor_amount) + 3);
+
+	if (!amount)
+		return;
+
+	sprintf(amount, "\"%s\"", current_cursor_amount);
+	fprintf(yyout, "{ ECPGfetch(__LINE__, %d, %d, %s, %d, %s, %s, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor,
+			ecpg_cursor_direction_name[current_cursor_direction],
+			amount);
+	output_statement_epilogue(stmt, whenever_mode, st);
+	free(amount);
+}
+
+void
+output_close_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGclose(__LINE__, %d, %d, %s, %d, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
 static void
 output_escaped_str(char *str, bool quoted)
 {
diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl
index 515470e..aebcaf4 100644
--- a/src/interfaces/ecpg/preproc/parse.pl
+++ b/src/interfaces/ecpg/preproc/parse.pl
@@ -90,6 +90,8 @@ my %replace_line = (
 	'fetch_argsFORWARDopt_from_incursor_name'      => 'ignore',
 	'fetch_argsBACKWARDopt_from_incursor_name'     => 'ignore',
 	"opt_array_boundsopt_array_bounds'['Iconst']'" => 'ignore',
+	'DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt' =>
+			'DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR SelectStmt',
 	'VariableShowStmtSHOWvar_name'                 => 'SHOW var_name ecpg_into',
 	'VariableShowStmtSHOWTIMEZONE' => 'SHOW TIME ZONE ecpg_into',
 	'VariableShowStmtSHOWTRANSACTIONISOLATIONLEVEL' => 'SHOW TRANSACTION ISOLATION LEVEL ecpg_into',
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 68e0d1a..89c920f 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -130,6 +130,7 @@ struct cursor
 	char	   *command;
 	char	   *connection;
 	bool		opened;
+	bool		fetch_readahead;
 	struct arguments *argsinsert;
 	struct arguments *argsinsert_oos;
 	struct arguments *argsresult;
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index c07ea93..a15b7d9 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -20,6 +20,7 @@ test: preproc/array_of_struct
 test: preproc/autoprep
 test: preproc/comment
 test: preproc/cursor
+test: preproc/cursor-readahead
 test: preproc/define
 test: preproc/init
 test: preproc/strings
diff --git a/src/interfaces/ecpg/test/ecpg_schedule_tcp b/src/interfaces/ecpg/test/ecpg_schedule_tcp
index 77481b5..60994e0 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule_tcp
+++ b/src/interfaces/ecpg/test/ecpg_schedule_tcp
@@ -20,6 +20,7 @@ test: preproc/array_of_struct
 test: preproc/autoprep
 test: preproc/comment
 test: preproc/cursor
+test: preproc/cursor-readahead
 test: preproc/define
 test: preproc/init
 test: preproc/strings
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c
new file mode 100644
index 0000000..ef39815
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c
@@ -0,0 +1,663 @@
+/* Processed by ecpg (regression mode) */
+/* These include files are added by the preprocessor */
+#include <ecpglib.h>
+#include <ecpgerrno.h>
+#include <sqlca.h>
+/* End of automatic include section */
+#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+#line 1 "cursor-readahead.pgc"
+#include <stdio.h>
+#include <malloc.h>
+
+/* test automatic prepare for all statements */
+
+#line 1 "regression.h"
+
+
+
+
+
+
+#line 5 "cursor-readahead.pgc"
+
+
+
+#line 1 "sqlda.h"
+#ifndef ECPG_SQLDA_H
+#define ECPG_SQLDA_H
+
+#ifdef _ECPG_INFORMIX_H
+
+#include "sqlda-compat.h"
+typedef struct sqlvar_compat	sqlvar_t;
+typedef struct sqlda_compat	sqlda_t;
+
+#else
+
+#include "sqlda-native.h"
+typedef struct sqlvar_struct	sqlvar_t;
+typedef struct sqlda_struct	sqlda_t;
+
+#endif
+
+#endif /* ECPG_SQLDA_H */
+
+#line 7 "cursor-readahead.pgc"
+
+
+/* exec sql whenever sqlerror  sqlprint ; */
+#line 9 "cursor-readahead.pgc"
+
+/* exec sql whenever sql_warning  sqlprint ; */
+#line 10 "cursor-readahead.pgc"
+
+
+#define MAXID	(513)
+
+int main(void)
+{
+	int	counts[2] = { 1, 5 };
+	/* exec sql begin declare section */
+		
+		
+		   
+		  
+	
+#line 18 "cursor-readahead.pgc"
+ char * curname ;
+ 
+#line 19 "cursor-readahead.pgc"
+ int maxid ;
+ 
+#line 20 "cursor-readahead.pgc"
+ int i , j , count , rows ;
+ 
+#line 21 "cursor-readahead.pgc"
+ int id , id1 [ 5 ] , id2 [ 5 ] ;
+/* exec sql end declare section */
+#line 22 "cursor-readahead.pgc"
+
+	sqlda_t	*sqlda;
+
+	/*
+	 * Intentionally don't create a 2MB stderr file for this test.
+	 * Enable it manually if you're interested in it.
+	 */
+#if 0
+	ECPGdebug(1, stderr);
+#endif
+
+	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); 
+#line 33 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 33 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 33 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 35 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 35 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 35 "cursor-readahead.pgc"
+
+
+	maxid = MAXID;
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table ra_test ( id integer primary key )", ECPGt_EOIT, ECPGt_EORT);
+#line 39 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 39 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 39 "cursor-readahead.pgc"
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ra_test select i . i from generate_series ( 1 , $1  ) as i", 
+	ECPGt_int,&(maxid),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 40 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 40 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 40 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 42 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 42 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 42 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 44 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 44 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 44 "cursor-readahead.pgc"
+
+
+	curname = "xx";
+	ECPGset_var( 0, &( curname ), __LINE__);\
+ /* declare $0 scroll cursor for select * from ra_test */
+#line 47 "cursor-readahead.pgc"
+
+	/* declare xcur scroll cursor for select * from ra_test */
+#line 48 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 50 "cursor-readahead.pgc"
+
+
+	for (i = 0; i < 2; i++)
+	{
+		count = counts[i];
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare $0 scroll cursor for select * from ra_test", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 56 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 56 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 56 "cursor-readahead.pgc"
+
+		{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 57 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 57 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 57 "cursor-readahead.pgc"
+
+
+		id = 0;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 from $0", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 68 "cursor-readahead.pgc"
+
+			{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "$0", ECPGst_normal, "fetch $0 from xcur", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 69 "cursor-readahead.pgc"
+
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				id++;
+
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors forward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (sqlca.sqlwarn[0] == 'W') sqlprint();
+		if (sqlca.sqlcode < 0) sqlprint();
+
+		if (id == maxid)
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 95 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 95 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 95 "cursor-readahead.pgc"
+
+		{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 96 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 96 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 96 "cursor-readahead.pgc"
+
+
+		/* exec sql whenever not found  continue ; */
+#line 98 "cursor-readahead.pgc"
+
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare $0 scroll cursor for select * from ra_test", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 100 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 100 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 100 "cursor-readahead.pgc"
+
+		{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 101 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 101 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 101 "cursor-readahead.pgc"
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch last from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 102 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 102 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 102 "cursor-readahead.pgc"
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 103 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 103 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 103 "cursor-readahead.pgc"
+
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor '%s' (value %d), fetching backwards.\n", curname, id1[0]);
+		else
+			goto err;
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_absolute, "-1", ECPGst_normal, "fetch last from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 108 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 108 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 108 "cursor-readahead.pgc"
+
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "1", ECPGst_normal, "fetch from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 109 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 109 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 109 "cursor-readahead.pgc"
+
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id2[0]);
+		else
+			goto err;
+
+		/* exec sql whenever not found  break ; */
+#line 115 "cursor-readahead.pgc"
+
+
+		id = maxid;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch backward $0 from $0", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 126 "cursor-readahead.pgc"
+
+			{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_backward, "$0", ECPGst_normal, "fetch backward $0 from xcur", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 127 "cursor-readahead.pgc"
+
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors backward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+				id--;
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (id == 0)
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 149 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 149 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 149 "cursor-readahead.pgc"
+
+		{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 150 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 150 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 150 "cursor-readahead.pgc"
+
+
+		/* exec sql whenever not found  continue ; */
+#line 152 "cursor-readahead.pgc"
+
+
+	}
+
+	sqlda = NULL;
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 157 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 157 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 157 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "all", ECPGst_normal, "fetch all xcur", ECPGt_EOIT, 
+	ECPGt_sqlda, &sqlda, 0L, 0L, 0L, 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 158 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 158 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 158 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 160 "cursor-readahead.pgc"
+
+
+	id = 0;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t *tmp;
+
+		id++;
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors forward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+	}
+
+	if (id == maxid)
+		printf("Reading all records from a readahead cursor forward into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from a readahead cursor forward into sqlda chain: FAILED. id %d, id1 %d\n", id, id1[0]);
+
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 186 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 186 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 186 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  continue ; */
+#line 188 "cursor-readahead.pgc"
+
+
+	sqlda = NULL;
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 191 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 191 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 191 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_absolute, "-1", ECPGst_normal, "fetch last from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 192 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 192 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 192 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "1", ECPGst_normal, "fetch from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 193 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 193 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 193 "cursor-readahead.pgc"
+
+	if (sqlca.sqlcode == ECPG_NOT_FOUND)
+		printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id1[0]);
+	else
+		goto err;
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_backward, "all", ECPGst_normal, "fetch backward all xcur", ECPGt_EOIT, 
+	ECPGt_sqlda, &sqlda, 0L, 0L, 0L, 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 199 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 199 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 199 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 201 "cursor-readahead.pgc"
+
+
+	id = maxid;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t	*tmp;
+
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors backward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+
+		id--;
+	}
+
+	if (id == 0)
+		printf("Reading all records from readahead cursor backwards into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from readahead cursors backwards into sqlda chain: FAILED, id %d, id1 %d\n", id, id1[0]);
+
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 229 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 229 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 229 "cursor-readahead.pgc"
+
+
+err:
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 233 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 233 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 233 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 235 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 235 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 235 "cursor-readahead.pgc"
+
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 237 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 237 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 237 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 239 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 239 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 239 "cursor-readahead.pgc"
+
+
+	{ ECPGdisconnect(__LINE__, "ALL");
+#line 241 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 241 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 241 "cursor-readahead.pgc"
+
+
+	return 0;
+}
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stderr b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stderr
new file mode 100644
index 0000000..e69de29
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout
new file mode 100644
index 0000000..5e70dd7
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout
@@ -0,0 +1,11 @@
+Reading readahead and non-readahead cursors simultaneously forward by 1 record: SUCCESS
+After last record in cursor 'xx' (value 513), fetching backwards.
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading readahead and non-readahead cursors simultaneously backwards by 1 record(s): SUCCESS
+Reading readahead and non-readahead cursors simultaneously forward by 5 record: SUCCESS
+After last record in cursor 'xx' (value 513), fetching backwards.
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading readahead and non-readahead cursors simultaneously backwards by 5 record(s): SUCCESS
+Reading all records from a readahead cursor forward into sqlda chain: SUCCESS
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading all records from readahead cursor backwards into sqlda chain: SUCCESS
diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile
index 3bcb63a..dfe4166 100644
--- a/src/interfaces/ecpg/test/preproc/Makefile
+++ b/src/interfaces/ecpg/test/preproc/Makefile
@@ -8,6 +8,7 @@ TESTS = array_of_struct array_of_struct.c \
 	autoprep autoprep.c \
 	comment comment.c \
 	cursor cursor.c \
+	cursor-readahead cursor-readahead.c \
 	define define.c \
 	init init.c \
 	strings strings.c \
diff --git a/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
new file mode 100644
index 0000000..076f9b3
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <malloc.h>
+
+/* test automatic prepare for all statements */
+EXEC SQL INCLUDE ../regression;
+
+EXEC SQL INCLUDE sqlda.h;
+
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+
+#define MAXID	(513)
+
+int main(void)
+{
+	int	counts[2] = { 1, 5 };
+	EXEC SQL BEGIN DECLARE SECTION;
+	char	*curname;
+	int	maxid;
+	int	i, j, count, rows;
+	int	id, id1[5], id2[5];
+	EXEC SQL END DECLARE SECTION;
+	sqlda_t	*sqlda;
+
+	/*
+	 * Intentionally don't create a 2MB stderr file for this test.
+	 * Enable it manually if you're interested in it.
+	 */
+#if 0
+	ECPGdebug(1, stderr);
+#endif
+
+	EXEC SQL CONNECT TO REGRESSDB1;
+
+	EXEC SQL BEGIN;
+
+	maxid = MAXID;
+
+	EXEC SQL CREATE TABLE ra_test (id INTEGER PRIMARY KEY);
+	EXEC SQL INSERT INTO ra_test SELECT i.i FROM generate_series(1, :maxid) as i;
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL BEGIN;
+
+	curname = "xx";
+	EXEC SQL DECLARE :curname SCROLL CURSOR FOR SELECT * FROM ra_test;
+	EXEC SQL DECLARE xcur SCROLL READAHEAD CURSOR FOR SELECT * FROM ra_test;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	for (i = 0; i < 2; i++)
+	{
+		count = counts[i];
+
+		EXEC SQL OPEN :curname;
+		EXEC SQL OPEN xcur;
+
+		id = 0;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			EXEC SQL FETCH :count FROM :curname INTO :id1;
+			EXEC SQL FETCH :count FROM xcur INTO :id2;
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				id++;
+
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors forward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (sqlca.sqlwarn[0] == 'W') sqlprint();
+		if (sqlca.sqlcode < 0) sqlprint();
+
+		if (id == maxid)
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		EXEC SQL CLOSE :curname;
+		EXEC SQL CLOSE xcur;
+
+		EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+		EXEC SQL OPEN :curname;
+		EXEC SQL OPEN xcur;
+		EXEC SQL FETCH LAST FROM :curname INTO :id1;
+		EXEC SQL FETCH FROM :curname INTO :id1;
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor '%s' (value %d), fetching backwards.\n", curname, id1[0]);
+		else
+			goto err;
+		EXEC SQL FETCH LAST FROM xcur INTO :id2;
+		EXEC SQL FETCH FROM xcur INTO :id2;
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id2[0]);
+		else
+			goto err;
+
+		EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+		id = maxid;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			EXEC SQL FETCH BACKWARD :count FROM :curname INTO :id1;
+			EXEC SQL FETCH BACKWARD :count FROM xcur INTO :id2;
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors backward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+				id--;
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (id == 0)
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		EXEC SQL CLOSE :curname;
+		EXEC SQL CLOSE xcur;
+
+		EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+	}
+
+	sqlda = NULL;
+	EXEC SQL OPEN xcur;
+	EXEC SQL FETCH ALL xcur INTO DESCRIPTOR sqlda;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	id = 0;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t *tmp;
+
+		id++;
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors forward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+	}
+
+	if (id == maxid)
+		printf("Reading all records from a readahead cursor forward into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from a readahead cursor forward into sqlda chain: FAILED. id %d, id1 %d\n", id, id1[0]);
+
+	EXEC SQL CLOSE xcur;
+
+	EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+	sqlda = NULL;
+	EXEC SQL OPEN xcur;
+	EXEC SQL FETCH LAST FROM xcur INTO :id1;
+	EXEC SQL FETCH FROM xcur INTO :id1;
+	if (sqlca.sqlcode == ECPG_NOT_FOUND)
+		printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id1[0]);
+	else
+		goto err;
+
+	EXEC SQL FETCH BACKWARD ALL xcur INTO DESCRIPTOR sqlda;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	id = maxid;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t	*tmp;
+
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors backward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+
+		id--;
+	}
+
+	if (id == 0)
+		printf("Reading all records from readahead cursor backwards into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from readahead cursors backwards into sqlda chain: FAILED, id %d, id1 %d\n", id, id1[0]);
+
+	EXEC SQL CLOSE xcur;
+
+err:
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL BEGIN;
+
+	EXEC SQL DROP TABLE ra_test;
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL DISCONNECT ALL;
+
+	return 0;
+}
#14Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#13)
1 attachment(s)
Re: ECPG FETCH readahead

Hi,

2011-11-16 20:51 keltezéssel, Boszormenyi Zoltan írta:

2010-10-14 11:56 keltezéssel, Boszormenyi Zoltan írta:

Hi,

Robert Haas írta:

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

So, who has the next action on this patch? Does Zoltan need to revise
it, or does Michael need to review it, or where are we?

Michael reviewed it shortly in private and I need to send
a new revision anyway, regardless of his comments.
I will refresh it ASAP.

The ASAP took a little long. The attached patch is in git diff format,
because (1) the regression test intentionally doesn't do ECPGdebug()
so the patch isn't dominated by a 2MB stderr file, so this file is empty
and (2) regular diff cannot cope with empty new files.

Anyway, here is the new version with a new feature.
Implementation details:

- New ecpglib/cursor.c handles the client-side accounting of cursors.
- Functions in ecpglib/execute.c are split into smaller functions
so useful operations can be used by the new cursor.c
- ecpg -r fetch_readahead enables readahead by default for all cursors.
- Default readahead size is 256 rows, it can be modified by an environment
variable, ECPGFETCHSZ.
- *NEW FEATURE* Readahead can be individually enabled or disabled
by ECPG-side grammar:
DECLARE curname [ [ NO ] READAHEAD ] CURSOR FOR ...
Without [ NO ] READAHEAD, the default behaviour is used for cursors.
- Since the server and the client may disagree on the cursor position
if readahead is used, ECPG preprocessor throws an error if
WHERE CURRENT OF is used on such cursors.
- The default assumed behaviour of cursors with readahead is NO SCROLL.
If you want readahead and backward scrolling, SCROLL keyword is mandatory.

The regression test creates a table with 513 rows, so it spans 2 full and
1 incomplete readahead window. It reads the table with two cursors, one
with readahead and one without by 1 records forward and backward.
This is repeated with reading 5 records at a time. Then the whole table is
read into a chain of sqlda structures forward and backward. All other
regression tests pass as well.

The original regression tests also pass with these changes, the split of
execute.c was risky in this regard. Now the split is done more cleanly
than in the previous version, the file is not as rearranged as before.

New patch attached against yesterday's GIT tree. Changes:
- documented the new ECPG_INVALID_CURSOR error code
- consistently free everything in error paths in cursor.c

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.2-git-v5.patchtext/x-patch; name=ecpg-cursor-readahead-9.2-git-v5.patchDownload
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 68833ca..55feac2 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -454,6 +454,32 @@ EXEC SQL COMMIT;
    details.
   </para>
 
+  <para>
+   ECPG may use cursor readahead to improve performance of programs
+   that use single-row FETCH statements. Option <literal>-r fetch_readahead</literal>
+   option for ECPG modifies the default for all cursors from <literal>NO READAHEAD</literal>
+   to <literal>READAHEAD</literal>. Explicit <literal>READAHEAD</literal> or
+   <literal>NO READAHEAD</literal> turns cursor readahead on or off for the specified cursor,
+   respectively. The default readahead size is 256 rows, this may be modified by setting
+   the <literal>ECPGFETCHSZ</literal> environment variable to a different value.
+  </para>
+
+  <para>
+   Scrolling behaviour differs from the documented one at <xref linkend="sql-declare">
+   when readahead is used for a cursor. ECPG treats cursors as <literal>NO SCROLL</literal>
+   when neither <literal>SCROLL</literal> nor <literal>NO SCROLL</literal> are specified.
+   When backward fetching or positioning is attempted on a <literal>NO SCROLL READAHEAD</literal>
+   cursor, error code 55000 (Object not in prerequisite state) is returned to the application.
+  </para>
+
+  <para>
+   For cursors used in <command>UPDATE</command> or <command>DELETE</command>
+   with the <literal>WHERE CURRENT OF</literal> clause, cursor readahead must be
+   turned off, otherwise <command>ecpg</command> throws an error. This restriction
+   is because when the client side uses readahead, the idea about the cursor position
+   in the dataset may differ between the server and the client.
+  </para>
+
    <note>
     <para>
      The ECPG <command>DECLARE</command> command does not actually
@@ -5289,6 +5315,17 @@ while (1)
     </varlistentry>
 
     <varlistentry>
+     <term>-231 (<symbol>ECPG_INVALID_CURSOR</symbol>)</term>
+     <listitem>
+      <para>
+       The cursor you are trying to use with readahead has not been opened yet (SQLSTATE 34000),
+       invalid values were passed to libecpg (SQLSTATE 42P11) hor not in prerequisite state, i.e.
+       FETCH or MOVE BACKWARD was attempted on a non-SCROLL cursor (SQLSTATE 55000).
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term>-239 (<symbol>ECPG_INFORMIX_DUPLICATE_KEY</symbol>)</term>
      <listitem>
       <para>
@@ -6583,8 +6620,8 @@ EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
 
    <refsynopsisdiv>
 <synopsis>
-DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">prepared_name</replaceable>
-DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">query</replaceable>
+DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] [ [ NO ] READAHEAD ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">prepared_name</replaceable>
+DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] [ [ NO ] READAHEAD ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="PARAMETER">query</replaceable>
 </synopsis>
    </refsynopsisdiv>
 
@@ -6639,11 +6676,36 @@ DECLARE <replaceable class="PARAMETER">cursor_name</replaceable> [ BINARY ] [ IN
       </listitem>
      </varlistentry>
     </variablelist>
+   </refsect1>
+
+   <refsect1>
+    <title>Cursor options</title>
 
     <para>
-     For the meaning of the cursor options,
-     see <xref linkend="sql-declare">.
+     For the meaning of other cursor options, see <xref linkend="sql-declare">.
     </para>
+
+    <variablelist>
+     <varlistentry>
+      <term><literal>READAHEAD</literal></term>   
+      <term><literal>NO READAHEAD</literal></term>   
+       <listitem>
+        <para>
+         <literal>READAHEAD</literal> makes the ECPG preprocessor and runtime library
+         use a client-side cursor accounting and data readahead during
+         <command>FETCH</command>. This improves performance for programs that use
+         single-row <command>FETCH</command> statements.
+        </para>
+
+        <para>
+         <literal>NO READAHEAD</literal> disables data readahead in case
+         <parameter>-r fetch_readahead</parameter> is used for compiling the file.
+        </para>
+       </listitem>
+      </varlistentry>
+
+    </variablelist>
+
    </refsect1>
 
    <refsect1>
diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml
index 9c13e93..22dfe44 100644
--- a/doc/src/sgml/ref/ecpg-ref.sgml
+++ b/doc/src/sgml/ref/ecpg-ref.sgml
@@ -166,6 +166,14 @@ PostgreSQL documentation
          </para>
          </listitem>
         </varlistentry>
+        <varlistentry>
+         <term><option>fetch_readahead</option></term>
+         <listitem>
+         <para>
+         Turn on cursor readahead by default.
+         </para>
+         </listitem>
+        </varlistentry>
        </variablelist></para>
      </listitem>
     </varlistentry>
diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile
index 2b2ffb6..1f46ff6 100644
--- a/src/interfaces/ecpg/ecpglib/Makefile
+++ b/src/interfaces/ecpg/ecpglib/Makefile
@@ -25,7 +25,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 LIBS := $(filter-out -lpgport, $(LIBS))
 
 OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
-	connect.o misc.o path.o pgstrcasecmp.o \
+	connect.o misc.o path.o pgstrcasecmp.o cursor.o \
 	$(filter snprintf.o strlcpy.o win32setlocale.o, $(LIBOBJS))
 
 # thread.c is needed only for non-WIN32 implementation of path.c
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 997046b..7eda052 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -456,6 +456,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 
 	this->cache_head = NULL;
 	this->prep_stmts = NULL;
+	this->cursor_desc = NULL;
 
 	if (all_connections == NULL)
 		this->next = NULL;
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
new file mode 100644
index 0000000..bcaf913
--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,730 @@
+/*
+ * FETCH readahead support routines
+ */
+
+#define POSTGRES_ECPG_INTERNAL
+#include "postgres_fe.h"
+
+#include <limits.h>
+
+#include "ecpgtype.h"
+#include "ecpglib.h"
+#include "ecpgerrno.h"
+#include "extern.h"
+
+static struct cursor_descriptor *add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing);
+static struct cursor_descriptor *find_cursor(struct connection *con, const char *name);
+static void del_cursor(struct connection *con, const char *name);
+
+/* default fetch size, set on the first call to ECPGopen()  */
+#define DEFAULTFETCHSIZE	(256)
+static int	fetch_size = 0;
+
+/*
+ * Add a new cursor descriptor, maintain alphabetic order
+ */
+static struct cursor_descriptor *
+add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing)
+{
+	struct cursor_descriptor *desc,
+				*ptr, *prev = NULL;
+	bool	found = false;
+
+	if (!name || name[0] == '\0')
+	{
+		if (existing)
+			*existing = false;
+		return NULL;
+	}
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}
+
+	if (found)
+	{
+		if (existing)
+			*existing = true;
+		return ptr;
+	}
+
+	desc = (struct cursor_descriptor *)ecpg_alloc(sizeof(struct cursor_descriptor), lineno);
+	if (!desc)
+		return NULL;
+	desc->name = ecpg_strdup(name, lineno);
+	if (!desc->name)
+	desc->res = NULL;
+	desc->scrollable = scrollable;
+	desc->n_tuples = n_tuples;
+	desc->start_pos = 0;
+	desc->cache_pos = 0;
+	desc->next = ptr;
+
+	if (prev)
+		prev->next = desc;
+	else
+		con->cursor_desc = desc;
+
+	if (existing)
+		*existing = false;
+	return desc;
+}
+
+static struct cursor_descriptor *
+find_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *desc = con->cursor_desc;
+	bool	found = false;
+
+	if (!name)
+		return NULL;
+
+	while (desc)
+	{
+		int ret = strcasecmp(desc->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+		desc = desc->next;
+	}
+
+	return (found ? desc : NULL);
+}
+
+static void
+del_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *ptr, *prev = NULL;
+	bool	found = false;
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}
+
+	if (found)
+	{
+		if (prev)
+			prev->next = ptr->next;
+		else
+			con->cursor_desc = ptr->next;
+
+		ecpg_free(ptr->name);
+		if (ptr->res)
+			PQclear(ptr->res);
+		ecpg_free(ptr);
+	}
+}
+
+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");
+	scrollable = (noscroll == NULL) && (scroll != NULL) && (scroll < ptr);
+
+	new_query = ecpg_alloc(strlen(curname) + strlen(ptr) + (whold ? 10 : 0) + 32, lineno);
+	if (!new_query)
+		return false;
+	sprintf(new_query, "declare %s %s cursor %s%s",
+					(dollar0 && (dollar0 < ptr) ? "$0" : curname),
+					(scrollable ? "scroll" : "no scroll"),
+					(whold ? "with hold " : ""),
+					ptr);
+
+	/* Set the fetch size the first time we are called. */
+	if (fetch_size == 0)
+	{
+		char	   *fsize_str = getenv("ECPGFETCHSZ");
+		char	   *endptr = NULL;
+		int		fsize;
+
+		if (fsize_str)
+		{
+			fsize = strtoul(fsize_str, &endptr, 10);
+			if (endptr || (fsize < 4))
+				fetch_size = DEFAULTFETCHSIZE;
+			else
+				fetch_size = fsize;
+		}
+		else
+			fetch_size = DEFAULTFETCHSIZE;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, new_query, args);
+	va_end(args);
+
+	ecpg_free(new_query);
+
+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)
+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}
+
+		/* Add the cursor */
+		cur = add_cursor(lineno, con, curname, scrollable, n_tuples, &existing);
+
+		/*
+		 * Report the number of tuples for the [scrollable] cursor.
+		 * The server didn't do it for us.
+		 */
+		sqlca->sqlerrd[2] = (cur->n_tuples < LONG_MAX ? cur->n_tuples : LONG_MAX);
+	}
+
+	return ret;
+}
+
+static bool
+ecpg_cursor_execute(struct statement * stmt, struct cursor_descriptor *cur)
+{
+	char		tmp[64];
+	char	   *query;
+	int64		start_pos;
+
+	if ((cur->cache_pos >= cur->start_pos) && cur->res && (cur->cache_pos < cur->start_pos + PQntuples(cur->res)))
+	{
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}
+	else if (!cur->scrollable && cur->res && (PQntuples(cur->res) < fetch_size) && (cur->cache_pos >= cur->start_pos + PQntuples(cur->res)))
+	{
+		cur->endoftuples = true;
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}
+
+	if ((PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE) && !stmt->connection->autocommit)
+	{
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		{
+			ecpg_free_params(stmt, false, stmt->lineno);
+			return false;
+		}
+		PQclear(stmt->results);
+	}
+
+	/*
+	 * Compute the tuple position before the resultset. E.g.:
+	 * MOVE ABSOLUTE 0 + FETCH NEXT <fetch_size> will result
+	 * in a recordset having tuples 1 ... fetch_size
+	 */
+	start_pos = (cur->cache_pos - 1) / fetch_size;
+	start_pos *= fetch_size;
+
+	if (cur->scrollable)
+	{
+		sprintf(tmp, "%lld", (long long)start_pos);
+		query = ecpg_alloc(strlen(tmp) + strlen(cur->name) + 20, stmt->lineno);
+		sprintf(query, "move absolute %s in %s", tmp, cur->name);
+
+		ecpg_log("ecpg_cursor_execute on line %d: query: %s; on connection %s\n", stmt->lineno, query, stmt->connection->name);
+
+		stmt->results = PQexec(stmt->connection->connection, query);
+
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		{
+			ecpg_free_params(stmt, false, stmt->lineno);
+			return false;
+		}
+
+		PQclear(stmt->results);
+		ecpg_free(query);
+	}
+
+	sprintf(tmp, "%lld", (long long)fetch_size);
+	query = ecpg_alloc(strlen(tmp) + strlen(cur->name) + 24, stmt->lineno);
+	sprintf(query, "fetch forward %s from %s", tmp, cur->name);
+
+	if (cur->res)
+		PQclear(cur->res);
+
+	ecpg_log("ecpg_cursor_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, query, stmt->nparams, stmt->connection->name);
+
+	if (stmt->nparams == 0)
+	{
+		cur->res = PQexec(stmt->connection->connection, query);
+		ecpg_log("ecpg_cursor_execute on line %d: using PQexec\n", stmt->lineno);
+	}
+	else
+	{
+		/* shouldn't happen */
+		cur->res = PQexecParams(stmt->connection->connection, query, stmt->nparams, NULL, stmt->param_values, NULL, NULL, 0);
+		ecpg_log("ecpg_cursor_execute on line %d: using PQexecParams\n", stmt->lineno);
+	}
+
+	stmt->results = cur->res;
+
+	ecpg_free_params(stmt, true, stmt->lineno);
+
+	if (!ecpg_check_PQresult(cur->res, stmt->lineno, stmt->connection->connection, stmt->compat))
+	{
+		stmt->results = cur->res = NULL;
+		cur->start_pos = 0;
+		return false;
+	}
+
+	/* The tuple position in the cursor is 1 based. */
+	cur->start_pos = start_pos + 1;
+
+	if (!cur->scrollable && PQntuples(cur->res) == 0)
+		cur->endoftuples = true;
+
+	ecpg_free(query);
+
+	return true;
+}
+
+bool
+ECPGfetch(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, enum ECPG_cursor_direction direction, const char *amount,
+		const int st, const char *query, ...)
+{
+	struct cursor_descriptor *cur;
+	struct statement *stmt;
+	va_list			args;
+	bool			move, fetchall = false, negate = false;
+	const char	   *amount1 = amount;
+	int			step;
+	int64			n_amount, count, start_idx;
+	struct sqlca_t		   *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+
+	move = (strncmp(query, "move ", 5) == 0);
+
+	cur = find_cursor(ecpg_get_connection(connection_name), curname);
+	if (!cur)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_NAME, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+		return false;
+	}
+
+	va_start(args, query);
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name, questionmarks, (enum ECPG_statement_type) st, query, args, &stmt))
+	{
+		va_end(args);
+		return false;
+	}
+
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		va_end(args);
+		return false;
+	}
+
+	if (amount[0] == '$')
+		amount1 = stmt->dollarzero[0];
+	else if (amount[0] == '-' || amount[0] == '+')
+	{
+		/*
+		 * Handle negative and explicitely positive constants in
+		 * FETCH/MOVE ABSOLUTE/RELATIVE const.
+		 * E.g. '-2' arrives as '- 2', '+2' arrives as '+ 2'.
+		 * strtoll() under Linux stops processing at the space.
+		 */
+		if (amount[0] == '-')
+			negate = true;
+		amount1 = amount + 1;
+		while (*amount1 == ' ')
+			amount1++;
+	}
+
+	if (strcmp(amount, "all") == 0)
+	{
+		fetchall = true;
+		if (cur->scrollable)
+		{
+			switch (direction)
+			{
+				case ECPGc_forward:
+					n_amount = cur->n_tuples - cur->cache_pos;
+					break;
+				case ECPGc_backward:
+					n_amount = cur->cache_pos;
+					break;
+				default:
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+					return false;
+			}
+		}
+		else
+			n_amount = LONG_MAX;
+	}
+	else
+	{
+		char	   *endptr;
+
+		n_amount = strtoll(amount1, &endptr, 10);
+		if (negate)
+			n_amount = -n_amount;
+	}
+
+	switch (direction)
+	{
+		case ECPGc_absolute:
+			if (cur->scrollable)
+			{
+				if (n_amount < 0)
+					n_amount = 1 + cur->n_tuples + n_amount;
+				else if (n_amount > cur->n_tuples)
+					n_amount = cur->n_tuples + 1;
+			}
+			else
+			{
+				if (n_amount < 0)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					return false;
+				}
+				if (n_amount < cur->cache_pos)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					return false;
+				}
+			}
+			cur->cache_pos = n_amount;
+
+			if (!move)
+			{
+				if (cur->cache_pos > 0 && ((cur->scrollable && cur->cache_pos <= cur->n_tuples) || (!cur->scrollable && !cur->endoftuples)))
+				{
+					if (!ecpg_cursor_execute(stmt, cur))
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+
+					if (!cur->scrollable && cur->endoftuples)
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+						return false;
+					}
+
+					start_idx = cur->cache_pos - cur->start_pos;
+
+					if (!ecpg_process_output(stmt, start_idx, start_idx + 1, 0, true, false))
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+				}
+				else
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+					return false;
+				}
+			}
+
+			sqlca->sqlerrd[2] = (cur->cache_pos && cur->cache_pos <= cur->n_tuples ? 1 : 0);
+			break;
+
+		case ECPGc_relative:
+relative:
+			if (!cur->scrollable)
+			{
+				if (n_amount < 0)
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+					return false;
+				}
+			}
+
+			cur->cache_pos += n_amount;
+			if (cur->cache_pos < 0)
+				cur->cache_pos = 0;
+			else if (cur->cache_pos > cur->n_tuples)
+				cur->cache_pos = cur->n_tuples + 1;
+
+			if (!move)
+			{
+				if (cur->cache_pos > 0 && ((cur->scrollable && cur->cache_pos <= cur->n_tuples) || (!cur->scrollable && !cur->endoftuples)))
+				{
+					if (!ecpg_cursor_execute(stmt, cur))
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+
+					if (!cur->scrollable && cur->endoftuples)
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+						return false;
+					}
+
+					start_idx = cur->cache_pos - cur->start_pos;
+
+					if (!ecpg_process_output(stmt, start_idx, start_idx + 1, 0, true, false))
+					{
+						ecpg_free_params(stmt, true, stmt->lineno);
+						ecpg_do_epilogue(stmt);
+						va_end(args);
+						return false;
+					}
+				}
+				else
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+					return false;
+				}
+			}
+
+			sqlca->sqlerrd[2] = (cur->cache_pos && cur->cache_pos <= cur->n_tuples ? 1 : 0);
+			break;
+
+		case ECPGc_forward:
+		case ECPGc_backward:
+			if (n_amount == 0)
+				goto relative;
+
+			step = (n_amount > 0 ? 1 : -1);
+			if (direction == ECPGc_backward)
+				step = -step;
+			if (n_amount < 0)
+				n_amount = -n_amount;
+
+			if (!cur->scrollable && step < 0)
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+				ecpg_do_epilogue(stmt);
+				va_end(args);
+				ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE, NULL);
+				return false;
+			}
+
+			if (move)
+			{
+				int64 new_pos = cur->cache_pos + step * n_amount;
+				int64 diff;
+
+				if (new_pos < 1)
+					new_pos = 0;
+				if (new_pos > cur->n_tuples)
+					new_pos = cur->n_tuples + 1;
+
+				diff = new_pos - cur->cache_pos;
+				sqlca->sqlerrd[2] = (diff >= 0 ? diff : -diff);
+				cur->cache_pos = new_pos;
+
+				break;
+			}
+
+			for (count = 0; (cur->scrollable && count < n_amount) ||
+					(!cur->scrollable && ((fetchall && !cur->endoftuples) || (!fetchall && count < n_amount))); count++)
+			{
+				cur->cache_pos += step;
+				if (cur->cache_pos < 1)
+				{
+					cur->cache_pos = 0;
+					break;
+				}
+				else
+				{
+					if (cur->scrollable && cur->cache_pos > cur->n_tuples)
+					{
+						cur->cache_pos = cur->n_tuples + 1;
+						break;
+					}
+					else if (!cur->scrollable && cur->endoftuples)
+					{
+						break;
+					}
+				}
+
+				if (!ecpg_cursor_execute(stmt, cur))
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					return false;
+				}
+
+				if (!cur->scrollable && cur->endoftuples)
+					break;
+
+				start_idx = cur->cache_pos - cur->start_pos;
+
+				if (!ecpg_process_output(stmt, start_idx, start_idx + 1, count, true, (count > 0)))
+				{
+					ecpg_free_params(stmt, true, stmt->lineno);
+					ecpg_do_epilogue(stmt);
+					va_end(args);
+					return false;
+				}
+			}
+
+			if (count == 0)
+			{
+				ecpg_free_params(stmt, true, stmt->lineno);
+				ecpg_do_epilogue(stmt);
+				va_end(args);
+				ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
+				return false;
+			}
+
+			sqlca->sqlerrd[2] = count;
+
+			break;
+
+		default:
+			ecpg_free_params(stmt, true, stmt->lineno);
+			ecpg_do_epilogue(stmt);
+			va_end(args);
+			ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_DEFINITION, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+			return false;
+	}
+
+	ecpg_free_params(stmt, true, stmt->lineno);
+	ecpg_do_epilogue(stmt);
+	va_end(args);
+	return true;
+}
+
+bool
+ECPGclose(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	struct connection  *con;
+	va_list			args;
+	bool			ret;
+
+	con = ecpg_get_connection(connection_name);
+
+	if (!find_cursor(con, curname))
+	{
+		ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_INVALID_CURSOR_NAME, (connection_name) ? connection_name : ecpg_gettext("<empty>"));
+		return false;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, query, args);
+	va_end(args);
+
+	del_cursor(con, curname);
+
+	return ret;
+}
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index db97503..467be57 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -120,7 +120,7 @@ check_special_value(char *ptr, double *retval, char **endptr)
 }
 
 bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int var_index, int act_tuple, int act_field, int lineno,
 			  enum ECPGttype type, enum ECPGttype ind_type,
 			  char *var, char *ind, long varcharsize, long offset,
 			  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
@@ -167,20 +167,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	{
 		case ECPGt_short:
 		case ECPGt_unsigned_short:
-			*((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((short *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_int:
 		case ECPGt_unsigned_int:
-			*((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_long:
 		case ECPGt_unsigned_long:
-			*((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #ifdef HAVE_LONG_LONG_INT
 		case ECPGt_long_long:
 		case ECPGt_unsigned_long_long:
-			*((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long long int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #endif   /* HAVE_LONG_LONG_INT */
 		case ECPGt_NO_INDICATOR:
@@ -192,7 +192,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					 * Informix has an additional way to specify NULLs note
 					 * that this uses special values to denote NULL
 					 */
-					ECPGset_noind_null(type, var + offset * act_tuple);
+					ECPGset_noind_null(type, var + offset * var_index);
 				}
 				else
 				{
@@ -243,10 +243,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		if (binary)
 		{
 			if (varcharsize == 0 || varcharsize * offset >= size)
-				memcpy(var + offset * act_tuple, pval, size);
+				memcpy(var + offset * var_index, pval, size);
 			else
 			{
-				memcpy(var + offset * act_tuple, pval, varcharsize * offset);
+				memcpy(var + offset * var_index, pval, varcharsize * offset);
 
 				if (varcharsize * offset < size)
 				{
@@ -255,20 +255,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					{
 						case ECPGt_short:
 						case ECPGt_unsigned_short:
-							*((short *) (ind + ind_offset * act_tuple)) = size;
+							*((short *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_int:
 						case ECPGt_unsigned_int:
-							*((int *) (ind + ind_offset * act_tuple)) = size;
+							*((int *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_long:
 						case ECPGt_unsigned_long:
-							*((long *) (ind + ind_offset * act_tuple)) = size;
+							*((long *) (ind + ind_offset * var_index)) = size;
 							break;
 #ifdef HAVE_LONG_LONG_INT
 						case ECPGt_long_long:
 						case ECPGt_unsigned_long_long:
-							*((long long int *) (ind + ind_offset * act_tuple)) = size;
+							*((long long int *) (ind + ind_offset * var_index)) = size;
 							break;
 #endif   /* HAVE_LONG_LONG_INT */
 						default:
@@ -307,13 +307,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_short:
-							*((short *) (var + offset * act_tuple)) = (short) res;
+							*((short *) (var + offset * var_index)) = (short) res;
 							break;
 						case ECPGt_int:
-							*((int *) (var + offset * act_tuple)) = (int) res;
+							*((int *) (var + offset * var_index)) = (int) res;
 							break;
 						case ECPGt_long:
-							*((long *) (var + offset * act_tuple)) = (long) res;
+							*((long *) (var + offset * var_index)) = (long) res;
 							break;
 						default:
 							/* Cannot happen */
@@ -336,13 +336,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_unsigned_short:
-							*((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
+							*((unsigned short *) (var + offset * var_index)) = (unsigned short) ures;
 							break;
 						case ECPGt_unsigned_int:
-							*((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
+							*((unsigned int *) (var + offset * var_index)) = (unsigned int) ures;
 							break;
 						case ECPGt_unsigned_long:
-							*((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
+							*((unsigned long *) (var + offset * var_index)) = (unsigned long) ures;
 							break;
 						default:
 							/* Cannot happen */
@@ -353,7 +353,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #ifdef HAVE_LONG_LONG_INT
 #ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
-					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
+					*((long long int *) (var + offset * var_index)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, scan_length, compat))
 					{
 						ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -365,7 +365,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #endif   /* HAVE_STRTOLL */
 #ifdef HAVE_STRTOULL
 				case ECPGt_unsigned_long_long:
-					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
+					*((unsigned long long int *) (var + offset * var_index)) = strtoull(pval, &scan_length, 10);
 					if ((isarray && *scan_length != ',' && *scan_length != '}')
 						|| (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))		/* Garbage left */
 					{
@@ -400,10 +400,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_float:
-							*((float *) (var + offset * act_tuple)) = dres;
+							*((float *) (var + offset * var_index)) = dres;
 							break;
 						case ECPGt_double:
-							*((double *) (var + offset * act_tuple)) = dres;
+							*((double *) (var + offset * var_index)) = dres;
 							break;
 						default:
 							/* Cannot happen */
@@ -415,9 +415,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					if (pval[0] == 'f' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = false;
+							*((char *) (var + offset * var_index)) = false;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = false;
+							*((int *) (var + offset * var_index)) = false;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -427,16 +427,16 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					else if (pval[0] == 't' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = true;
+							*((char *) (var + offset * var_index)) = true;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = true;
+							*((int *) (var + offset * var_index)) = true;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
 									   NULL);
 						break;
 					}
-					else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
+					else if (pval[0] == '\0' && PQgetisnull(results, var_index, act_field))
 					{
 						/* NULL is valid */
 						break;
@@ -451,7 +451,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_unsigned_char:
 				case ECPGt_string:
 					{
-						char	   *str = (char *) (var + offset * act_tuple);
+						char	   *str = (char *) (var + offset * var_index);
 
 						if (varcharsize == 0 || varcharsize > size)
 						{
@@ -479,20 +479,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = size;
+										*((short *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = size;
+										*((int *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = size;
+										*((long *) (ind + ind_offset * var_index)) = size;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = size;
+										*((long long int *) (ind + ind_offset * var_index)) = size;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -508,7 +508,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_varchar:
 					{
 						struct ECPGgeneric_varchar *variable =
-						(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
+						(struct ECPGgeneric_varchar *) (var + offset * var_index);
 
 						variable->len = size;
 						if (varcharsize == 0)
@@ -524,20 +524,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + offset * act_tuple)) = variable->len;
+										*((short *) (ind + offset * var_index)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + offset * act_tuple)) = variable->len;
+										*((int *) (ind + offset * var_index)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + offset * act_tuple)) = variable->len;
+										*((long *) (ind + offset * var_index)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long long int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -604,9 +604,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					if (type == ECPGt_numeric)
-						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
+						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * var_index));
 					else
-						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
+						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * var_index));
 
 					PGTYPESnumeric_free(nres);
 					break;
@@ -657,7 +657,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					pval = scan_length;
 
-					PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
+					PGTYPESinterval_copy(ires, (interval *) (var + offset * var_index));
 					free(ires);
 					break;
 
@@ -701,7 +701,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((date *) (var + offset * act_tuple)) = ddres;
+					*((date *) (var + offset * var_index)) = ddres;
 					pval = scan_length;
 					break;
 
@@ -745,7 +745,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((timestamp *) (var + offset * act_tuple)) = tres;
+					*((timestamp *) (var + offset * var_index)) = tres;
 					pval = scan_length;
 					break;
 
@@ -762,6 +762,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
 				/* set array to next entry */
 				++act_tuple;
+				++var_index;
 
 				/* set pval to the next entry */
 
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 1dde52c..a2a4a9c 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -438,7 +438,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desparate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index ee553fd..7148f50 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -268,6 +268,20 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
 					 ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
 			break;
 
+		case ECPG_INVALID_CURSOR:
+			if (strcmp(sqlstate, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE) == 0)
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+
+			/*
+			 * translator: this string will be truncated at 149 characters
+			 * expanded.
+			 */
+				ecpg_gettext("cursor can only scan forward"));
+			else
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), str);
+
+			break;
+
 		default:
 			snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
 
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index f468147..cfe5a5e 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -109,6 +109,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -311,12 +312,12 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results, int start, int end, int act_field,
+				  const struct statement * stmt, struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
 	int			act_tuple,
-				ntuples = PQntuples(results);
+				ntuples = end - start;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -367,7 +368,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (act_tuple = start; act_tuple < end; act_tuple++)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -376,7 +377,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (act_tuple = start; act_tuple < end; act_tuple++)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -397,7 +398,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (act_tuple = start; act_tuple < end; act_tuple++)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -433,11 +434,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (act_tuple = start; act_tuple < end && status; act_tuple++, var_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, var_index, act_tuple, act_field, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -454,9 +455,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (act_tuple = start; act_tuple < end && status; act_tuple++, var_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, var_index, act_tuple, act_field, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1082,18 +1083,26 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 	return true;
 }
 
-static void
-free_params(const char **paramValues, int nParams, bool print, int lineno)
+void
+ecpg_free_params(struct statement *stmt, bool print, int lineno)
 {
 	int			n;
 
-	for (n = 0; n < nParams; n++)
+	for (n = 0; n < stmt->nparams; n++)
 	{
 		if (print)
-			ecpg_log("free_params on line %d: parameter %d = %s\n", lineno, n + 1, paramValues[n] ? paramValues[n] : "null");
-		ecpg_free((void *) (paramValues[n]));
+			ecpg_log("free_params on line %d: parameter %d = %s\n", lineno, n + 1, stmt->param_values[n] ? stmt->param_values[n] : "null");
+		ecpg_free((void *) (stmt->param_values[n]));
 	}
-	ecpg_free(paramValues);
+	ecpg_free(stmt->param_values);
+	stmt->nparams = 0;
+	stmt->param_values = NULL;
+
+	for (n = 0; n < stmt->ndollarzero; n++)
+		ecpg_free((void *) (stmt->dollarzero[n]));
+	ecpg_free(stmt->dollarzero);
+	stmt->ndollarzero = 0;
+	stmt->dollarzero = NULL;
 }
 
 
@@ -1129,20 +1138,12 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGresult   *results;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
-	const char **paramValues = NULL;
-	int			nParams = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1342,7 +1343,7 @@ ecpg_execute(struct statement * stmt)
 			ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS,
 					   ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS,
 					   NULL);
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false, stmt->lineno);
 			return false;
 		}
 
@@ -1357,7 +1358,7 @@ ecpg_execute(struct statement * stmt)
 
 			if (!insert_tobeinserted(position, ph_len, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false, stmt->lineno);
 				return false;
 			}
 			tobeinserted = NULL;
@@ -1370,23 +1371,38 @@ ecpg_execute(struct statement * stmt)
 		 */
 		else if (stmt->command[position] == '0')
 		{
+			const char **dollarzero;
+
+			if (!(dollarzero = (const char **) ecpg_realloc(stmt->dollarzero, sizeof(const char *) * (stmt->ndollarzero + 1), stmt->lineno)))
+			{
+				ecpg_free_params(stmt, false, stmt->lineno);
+				return false;
+			}
+			stmt->ndollarzero++;
+			stmt->dollarzero = dollarzero;
+			stmt->dollarzero[stmt->ndollarzero - 1] = strdup(tobeinserted);
+
 			if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false, stmt->lineno);
 				return false;
 			}
 			tobeinserted = NULL;
 		}
 		else
 		{
-			nParams++;
-			if (!(paramValues = (const char **) ecpg_realloc(paramValues, sizeof(const char *) * nParams, stmt->lineno)))
+			const char **paramValues;
+		
+			if (!(paramValues = (const char **) ecpg_realloc(stmt->param_values, sizeof(const char *) * (stmt->nparams + 1), stmt->lineno)))
 			{
 				ecpg_free(paramValues);
 				return false;
 			}
 
-			paramValues[nParams - 1] = tobeinserted;
+			stmt->nparams++;
+			stmt->param_values = paramValues;
+
+			stmt->param_values[stmt->nparams - 1] = tobeinserted;
 
 			/* let's see if this was an old style placeholder */
 			if (stmt->command[position] == '?')
@@ -1397,7 +1413,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false, stmt->lineno);
 					return false;
 				}
 
@@ -1405,7 +1421,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false, stmt->lineno);
 					return false;
 				}
 				tobeinserted = NULL;
@@ -1421,58 +1437,76 @@ ecpg_execute(struct statement * stmt)
 	{
 		ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
 				 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
-		free_params(paramValues, nParams, false, stmt->lineno);
+		ecpg_free_params(stmt, false, stmt->lineno);
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
+
 
+static bool
+ecpg_execute(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false, stmt->lineno);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
-	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, nParams, stmt->connection->name);
+	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, nParams, paramValues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, stmt->param_values, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
-		if (nParams == 0)
+		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, nParams, NULL, paramValues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, stmt->param_values, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
-	free_params(paramValues, nParams, true, stmt->lineno);
+	ecpg_free_params(stmt, true, stmt->lineno);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return (true);
+}
+
+bool
+ecpg_process_output(struct statement * stmt, int start, int end, int var_index, bool keep_result, bool append_result)
+{
+	char		*cmdstat;
+	PGnotify	*notify;
+	bool		status = false;
+	struct variable *var;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] += ntuples = (end - start);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1494,12 +1528,34 @@ ecpg_execute(struct statement * stmt)
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = results;
-					clear_result = false;
+					int	row, srcrow, col;
+
+					if (append_result)
+						row = PQntuples(desc->result);
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = PQcopyResult(stmt->results, PG_COPYRES_ATTRS | PG_COPYRES_EVENTS | PG_COPYRES_NOTICEHOOKS);
+						row = 0;
+					}
+
+					for (srcrow = start; srcrow < end; srcrow++, row++)
+						for (col = 0; col < nfields; col++)
+						{
+							bool	isnull = PQgetisnull(stmt->results, srcrow, col);
+							if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, srcrow, col),
+										isnull ? -1 : PQgetlength(stmt->results, srcrow, col)))
+							{
+								ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+								status = false;
+								break;
+							}
+						}
+
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1509,36 +1565,52 @@ ecpg_execute(struct statement * stmt)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
-					struct sqlda_compat *sqlda_new;
+					struct sqlda_compat *sqlda_last, *sqlda_new = NULL;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_last = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_last;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
+					}
+					for (i = end - 1; i >= start; i--)
 					{
+						struct sqlda_compat *tmp;
+
 						/*
-						 * Build a new sqlda structure. Note that only
-						 * fetching 1 record is supported
+						 * Build a new sqlda structure. 
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						tmp = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
-						if (!sqlda_new)
+						if (!tmp)
 						{
 							/* cleanup all SQLDAs we created up */
+							while (sqlda_new)
+							{
+								tmp = sqlda_new->desc_next;
+								free(sqlda_new);
+								sqlda_new = tmp;
+							}
 							while (sqlda)
 							{
-								sqlda_new = sqlda->desc_next;
+								tmp = sqlda->desc_next;
 								free(sqlda);
-								sqlda = sqlda_new;
+								sqlda = tmp;
 							}
 							*_sqlda = NULL;
 
@@ -1550,51 +1622,74 @@ ecpg_execute(struct statement * stmt)
 						{
 							ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_new == NULL)
+								sqlda_new = tmp;
+							else
+							{
+								tmp->desc_next = sqlda_new;
+								sqlda_new = tmp;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &tmp, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
+									 stmt->lineno, PQnfields(stmt->results));
 						}
 					}
+					if (sqlda_last)
+						sqlda_last->desc_next = sqlda_new;
+					else
+						*_sqlda = sqlda_new;
 				}
 				else
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
-					struct sqlda_struct *sqlda_new;
+					struct sqlda_struct *sqlda_last, *sqlda_new = NULL;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					else
 					{
 						/*
-						 * Build a new sqlda structure. Note that only
-						 * fetching 1 record is supported
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						while (sqlda)
+						{
+							sqlda_last = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_last;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
+					}
+					for (i = end - 1; i >= start; i--)
+					{
+						struct sqlda_struct *tmp;
+
+						/*
+						 * Build a new sqlda structure. 
+						 */
+						tmp = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
-						if (!sqlda_new)
+						if (!tmp)
 						{
 							/* cleanup all SQLDAs we created up */
+							while (sqlda_new)
+							{
+								tmp = sqlda_new->desc_next;
+								free(sqlda_new);
+								sqlda_new = tmp;
+							}
 							while (sqlda)
 							{
-								sqlda_new = sqlda->desc_next;
+								tmp = sqlda->desc_next;
 								free(sqlda);
-								sqlda = sqlda_new;
+								sqlda = tmp;
 							}
 							*_sqlda = NULL;
 
@@ -1606,16 +1701,23 @@ ecpg_execute(struct statement * stmt)
 						{
 							ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_new == NULL)
+								sqlda_new = tmp;
+							else
+							{
+								tmp->desc_next = sqlda_new;
+								sqlda_new = tmp;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &tmp, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
+									 stmt->lineno, PQnfields(stmt->results));
 						}
 					}
+					if (sqlda_last)
+						sqlda_last->desc_next = sqlda_new;
+					else
+						*_sqlda = sqlda_new;
 				}
 
 				var = var->next;
@@ -1625,7 +1727,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, end, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1644,9 +1746,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1670,12 +1772,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1687,12 +1789,12 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
-	if (clear_result)
-		PQclear(results);
+	if (!keep_result)
+		PQclear(stmt->results);
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
@@ -1707,46 +1809,20 @@ ecpg_execute(struct statement * stmt)
 }
 
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		enum ECPG_statement_type statement_type, const char *query,
+		va_list args, struct statement **stmt_out)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
-	char	   *prepname;
-
-	if (!query)
-	{
-		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
-		return (false);
-	}
-
-	/* Make sure we do NOT honor the locale for numeric input/output */
-	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
-	setlocale(LC_NUMERIC, "C");
-
-#ifdef ENABLE_THREAD_SAFETY
-	ecpg_pthreads_init();
-#endif
-
-	con = ecpg_get_connection(connection_name);
-
-	if (!ecpg_init(con, connection_name, lineno))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		return (false);
-	}
+	char	*prepname;
 
-	/* construct statement in our own structure */
-	va_start(args, query);
+	*stmt_out = NULL;
 
-	/*
+    	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
 	 * an end marker. per variable we list: type - as defined in ecpgtype.h
@@ -1759,11 +1835,24 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
 	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
 		return false;
+
+	/* Make sure we do NOT honor the locale for numeric input/output */
+	/* since the database wants the standard decimal point */
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	setlocale(LC_NUMERIC, "C");
+
+#ifdef ENABLE_THREAD_SAFETY
+	ecpg_pthreads_init();
+#endif
+
+	con = ecpg_get_connection(connection_name);
+
+	if (!ecpg_init(con, connection_name, lineno))
+	{
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
+		return (false);
 	}
 
 	/*
@@ -1774,9 +1863,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
-			va_end(args);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
+			free_statement(stmt);
 			return (false);
 		}
 
@@ -1805,9 +1893,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
-			va_end(args);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
+			free_statement(stmt);
 			return (false);
 		}
 	}
@@ -1834,10 +1921,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1892,10 +1977,8 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1910,29 +1993,80 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
+
+	return (true);
+}
+
+
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	/* reset locale value so our application is not affected */
+	setlocale(LC_NUMERIC, stmt->oldlocale);
 	free_statement(stmt);
+}
+
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement *stmt;
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name, questionmarks, (enum ECPG_statement_type) st, query, args, &stmt))
+		return false;
+
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), 0, false, false))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;  
+	}
+
+	ecpg_do_epilogue(stmt);
+
+	return true;
+}
+
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, query, args);
+	va_end(args);
 
-	return (status);
+	return ret;
 }
 
 /* old descriptor interface */
diff --git a/src/interfaces/ecpg/ecpglib/exports.txt b/src/interfaces/ecpg/ecpglib/exports.txt
index 69e9617..f05e4f1 100644
--- a/src/interfaces/ecpg/ecpglib/exports.txt
+++ b/src/interfaces/ecpg/ecpglib/exports.txt
@@ -29,3 +29,6 @@ ECPGget_PGconn			 26
 ECPGtransactionStatus		 27
 ECPGset_var			 28
 ECPGget_var			 29
+ECPGopen			 30
+ECPGfetch			 31
+ECPGclose			 32
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 96d49a4..2920a3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
 };
 
 /* structure to store prepared statements for a connection */
@@ -71,6 +77,17 @@ struct prepared_statement
 	struct prepared_statement *next;
 };
 
+struct cursor_descriptor {
+	char	   *name;
+	PGresult   *res;
+	bool		scrollable;
+	bool		endoftuples;	/* valid if ->scrollable == false and there is no more tuples */
+	int64		n_tuples;	/* valid if ->scrollable == true */
+	int64		start_pos;
+	int64		cache_pos;
+	struct cursor_descriptor *next;
+};
+
 /* structure to store connections */
 struct connection
 {
@@ -79,6 +96,7 @@ struct connection
 	bool		autocommit;
 	struct ECPGtype_information_cache *cache_head;
 	struct prepared_statement *prep_stmts;
+	struct cursor_descriptor *cursor_desc;
 	struct connection *next;
 };
 
@@ -126,7 +144,7 @@ struct variable
 /* Returns a pointer to a string containing a simple type name. */
 void		ecpg_add_mem(void *ptr, int lineno);
 
-bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
+bool ecpg_get_data(const PGresult *, int, int, int, int, enum ECPGttype type,
 			  enum ECPGttype, char *, char *, long, long, long,
 			  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
@@ -152,9 +170,16 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results, int start, int end, int act_field,
+				  const struct statement * stmt, struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list, struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_process_output(struct statement *, int, int, int, bool, bool);
+void		ecpg_free_params(struct statement *, bool, int);
+void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
@@ -191,6 +216,8 @@ void		ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int,
 #define ECPG_SQLSTATE_SYNTAX_ERROR			"42601"
 #define ECPG_SQLSTATE_DATATYPE_MISMATCH		"42804"
 #define ECPG_SQLSTATE_DUPLICATE_CURSOR		"42P03"
+#define ECPG_SQLSTATE_INVALID_CURSOR_DEFINITION	"42P11"
+#define ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE	"55000"
 
 /* implementation-defined internal errors of ecpg */
 #define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR	"YE000"
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index 343a793..9577ee7 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -393,7 +393,7 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, 0, row, i, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
@@ -578,7 +578,7 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, 0, row, i, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index 36b15b7..f21dad2 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -37,6 +37,7 @@
 #define ECPG_NOT_CONN			-221
 
 #define ECPG_INVALID_STMT		-230
+#define ECPG_INVALID_CURSOR		-231
 
 /* dynamic SQL related */
 #define ECPG_UNKNOWN_DESCRIPTOR		-240
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 3b8ed4c..236f797 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -63,6 +63,13 @@ PGTransactionStatusType ECPGtransactionStatus(const char *);
 
 char	   *ECPGerrmsg(void);
 
+/* Readahead cursor functions */
+bool		ECPGopen(const int, const int, const int, const char *, const bool, const char *, const int, const char *, ...);
+bool		ECPGfetch(const int, const int, const int, const char *, const bool,
+				const char *, enum ECPG_cursor_direction, const char *,
+				const int,const char *, ...);
+bool		ECPGclose(const int, const int, const int, const char *, const bool, const char *, const int, const char *, ...);
+
  /* print an error message */
 void		sqlprint(void);
 
diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h
index 7cc47e9..dc82457 100644
--- a/src/interfaces/ecpg/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -99,6 +99,14 @@ enum ECPG_statement_type
 	ECPGst_prepnormal
 };
 
+enum ECPG_cursor_direction
+{
+	ECPGc_absolute,
+	ECPGc_relative,
+	ECPGc_forward, 
+	ECPGc_backward 
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl
index 991c40c..8560eb0 100644
--- a/src/interfaces/ecpg/preproc/check_rules.pl
+++ b/src/interfaces/ecpg/preproc/check_rules.pl
@@ -43,7 +43,10 @@ my %replace_line = (
 		'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
 
 	'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
-		'PREPARE prepared_name prep_type_clause AS PreparableStmt'
+		'PREPARE prepared_name prep_type_clause AS PreparableStmt',
+
+	'DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt' =>
+		'DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR SelectStmt'
 );
 
 my $block        = '';
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index 5c5adf7..e80044e 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -15,7 +15,10 @@ ECPG: stmtClosePortalStmt block
 			}
 		}
 
-		output_statement($1, 0, ECPGst_normal);
+		if (use_fetch_readahead)
+			output_close_statement($1, 0, ECPGst_normal);
+		else
+			output_statement($1, 0, ECPGst_normal);
 	}
 ECPG: stmtDeallocateStmt block
 	{
@@ -24,8 +27,14 @@ ECPG: stmtDeallocateStmt block
 ECPG: stmtDeclareCursorStmt block
 	{ output_simple_statement($1); }
 ECPG: stmtDiscardStmt block
-ECPG: stmtFetchStmt block
 	{ output_statement($1, 1, ECPGst_normal); }
+ECPG: stmtFetchStmt block
+	{
+		if (use_fetch_readahead)
+			output_fetch_statement($1, 1, ECPGst_normal);
+		else
+			output_statement($1, 1, ECPGst_normal);
+	}
 ECPG: stmtDeleteStmt block
 ECPG: stmtInsertStmt block
 ECPG: stmtSelectStmt block
@@ -132,7 +141,10 @@ ECPG: stmtViewStmt rule
 		if ((ptr = add_additional_variables($1, true)) != NULL)
 		{
 			connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
-			output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			if (use_fetch_readahead)
+				output_open_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			else
+				output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
 			ptr->opened = true;
 		}
 	}
@@ -190,6 +202,21 @@ ECPG: stmtViewStmt rule
 ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
+		struct cursor *ptr;
+
+		for (ptr = cur; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp(ptr->name, $4) == 0)
+				break;
+		}
+		if (!ptr)
+			mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", $4);
+
+		if (ptr->fetch_readahead)
+		{
+			mmerror(PARSE_ERROR, ET_ERROR,
+				"\"WHERE CURRENT OF\" is incompatible with a READAHEAD cursor\n");
+		}
 		$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
 	}
 ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromcopy_file_namecopy_delimiteropt_withcopy_options addon
@@ -210,31 +237,77 @@ ECPG: var_valueNumericOnly addon
 		}
 ECPG: fetch_argscursor_name addon
 		add_additional_variables($1, false);
+		set_cursor_readahead($1);
 		if ($1[0] == ':')
 		{
 			free($1);
 			$1 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsfrom_incursor_name addon
 		add_additional_variables($2, false);
+		set_cursor_readahead($2);
 		if ($2[0] == ':')
 		{
 			free($2);
 			$2 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsNEXTopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsPRIORopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1"); 
 ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsLAST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		set_cursor_readahead($3);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("-1");
 ECPG: fetch_argsALLopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		set_cursor_readahead($3);
 		if ($3[0] == ':')
 		{
 			free($3);
 			$3 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		set_cursor_readahead($3);
 		if ($3[0] == ':')
 		{
 			free($3);
@@ -245,19 +318,76 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 			free($1);
 			$1 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup($1);
 ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		set_cursor_readahead($4);
 		if ($4[0] == ':')
 		{
 			free($4);
 			$4 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_relative;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		set_cursor_readahead($4);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup($2);
 ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		set_cursor_readahead($4);
 		if ($4[0] == ':')
 		{
 			free($4);
@@ -268,7 +398,15 @@ ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 			free($2);
 			$2 = mm_strdup("$0");
 		}
-ECPG: cursor_namename rule
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup($2);
+ECPG: cursor_namename block
+		{
+			if (current_cursor)
+				free(current_cursor);
+			current_cursor = make3_str(mm_strdup("\""), mm_strdup($1), mm_strdup("\""));
+			$$ = $1;
+		}
 	| char_civar
 		{
 			char *curname = mm_alloc(strlen($1) + 2);
@@ -291,7 +429,7 @@ ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
 	}
 ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
 	{ $$ = $2; }
-ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block
+ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsopt_readaheadCURSORopt_holdFORSelectStmt block
 	{
 		struct cursor *ptr, *this;
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
@@ -316,7 +454,13 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		this->function = (current_function ? mm_strdup(current_function) : NULL);
 		this->connection = connection;
 		this->opened = false;
-		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7);
+		if (!strcmp($4, "1"))
+			this->fetch_readahead = true;
+		else if (!strcmp($4, "0"))
+			this->fetch_readahead = false;
+		else
+			this->fetch_readahead = fetch_readahead;
+		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $6, mm_strdup("for"), $8);
 		this->argsinsert = argsinsert;
 		this->argsinsert_oos = NULL;
 		this->argsresult = argsresult;
@@ -343,6 +487,8 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 ECPG: ClosePortalStmtCLOSEcursor_name block
 	{
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
+		if (!INFORMIX_MODE || pg_strcasecmp($2, "database") != 0)
+			set_cursor_readahead($2);
 		$$ = cat2_str(mm_strdup("close"), cursor_marker);
 	}
 ECPG: opt_hold block
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 6f73148..afb898b 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -18,7 +18,8 @@ bool		autocommit = false,
 			force_indicator = true,
 			questionmarks = false,
 			regression_mode = false,
-			auto_prepare = false;
+			auto_prepare = false,
+			fetch_readahead = false;
 
 char	   *output_filename;
 
@@ -51,7 +52,7 @@ help(const char *progname)
 	printf(_("  -I DIRECTORY   search DIRECTORY for include files\n"));
 	printf(_("  -o OUTFILE     write result to OUTFILE\n"));
 	printf(_("  -r OPTION      specify run-time behavior; OPTION can be:\n"
-	 "                 \"no_indicator\", \"prepare\", \"questionmarks\"\n"));
+	 "                 \"no_indicator\", \"prepare\", \"questionmarks\", \"fetch_readahead\"\n"));
 	printf(_("  --regression   run in regression testing mode\n"));
 	printf(_("  -t             turn on autocommit of transactions\n"));
 	printf(_("  --help         show this help, then exit\n"));
@@ -229,6 +230,8 @@ main(int argc, char *const argv[])
 					auto_prepare = true;
 				else if (strcmp(optarg, "questionmarks") == 0)
 					questionmarks = true;
+				else if (strcmp(optarg, "fetch_readahead") == 0)
+					fetch_readahead = true;
 				else
 				{
 					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]);
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 94c45c8..6ca3d3e 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -34,7 +34,11 @@
  */
 int struct_level = 0;
 int braces_open; /* brace level counter */
+bool use_fetch_readahead = false;
 char *current_function;
+char *current_cursor = NULL;
+enum ECPG_cursor_direction current_cursor_direction;
+char *current_cursor_amount = NULL;
 int ecpg_internal_var = 0;
 char	*connection = NULL;
 char	*input_filename = NULL;
@@ -111,6 +115,26 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
 }
 
 /*
+ * set use_fetch_readahead based on the current cursor
+ * doesn't return if the cursor is not declared
+ */
+static void
+set_cursor_readahead(const char *curname)
+{
+	struct cursor *ptr;
+
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp(ptr->name, curname) == 0)
+			break;
+	}
+	if (!ptr)
+		mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", curname);
+
+	use_fetch_readahead = ptr->fetch_readahead;
+}
+
+/*
  * string concatenation
  */
 
diff --git a/src/interfaces/ecpg/preproc/ecpg.tokens b/src/interfaces/ecpg/preproc/ecpg.tokens
index b55138a..3995b59 100644
--- a/src/interfaces/ecpg/preproc/ecpg.tokens
+++ b/src/interfaces/ecpg/preproc/ecpg.tokens
@@ -10,7 +10,7 @@
                 SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
                 SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
                 SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
-                SQL_OPEN SQL_OUTPUT SQL_REFERENCE
+                SQL_OPEN SQL_OUTPUT SQL_READAHEAD SQL_REFERENCE
                 SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
                 SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
                 SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index a362aff..2bf960f 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -287,7 +287,7 @@ prepared_name: name
  * Declare a prepared cursor. The syntax is different from the standard
  * declare statement, so we create a new rule.
  */
-ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_name
+ECPGCursorStmt:  DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR prepared_name
 		{
 			struct cursor *ptr, *this;
 			char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
@@ -315,15 +315,22 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			this->name = $2;
 			this->function = (current_function ? mm_strdup(current_function) : NULL);
 			this->connection = connection;
-			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
+			this->opened = false;
+			if (!strcmp($4, "1"))
+				this->fetch_readahead = true;
+			else if (!strcmp($4, "0"))
+				this->fetch_readahead = false;
+			else
+				this->fetch_readahead = fetch_readahead;
+			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $6, mm_strdup("for $1"));
 			this->argsresult = NULL;
 			this->argsresult_oos = NULL;
 
 			thisquery->type = &ecpg_query;
 			thisquery->brace_level = 0;
 			thisquery->next = NULL;
-			thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
-			sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
+			thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($8));
+			sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $8);
 
 			this->argsinsert = NULL;
 			this->argsinsert_oos = NULL;
@@ -348,6 +355,11 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 		}
 		;
 
+opt_readahead:	SQL_READAHEAD				{ $$ = mm_strdup("1"); }
+		| NO SQL_READAHEAD			{ $$ = mm_strdup("0"); }
+		| /* EMPTY */			{ $$ = mm_strdup("default"); }
+		;
+
 ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
 			{
 			  /* execute immediate means prepare the statement and
@@ -988,6 +1000,7 @@ ECPGOpen: SQL_OPEN cursor_name opt_ecpg_using
 		{
 			if ($2[0] == ':')
 				remove_variable_from_list(&argsinsert, find_variable($2 + 1));
+			set_cursor_readahead($2);
 			$$ = $2;
 		}
 		;
@@ -1656,6 +1669,10 @@ char_civar: char_variable
 		{
 			char *ptr = strstr($1, ".arr");
 
+			if (current_cursor)
+				free(current_cursor);
+			current_cursor = mm_strdup($1);
+
 			if (ptr) /* varchar, we need the struct name here, not the struct element */
 				*ptr = '\0';
 			add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type
index ac6aa00..2662372 100644
--- a/src/interfaces/ecpg/preproc/ecpg.type
+++ b/src/interfaces/ecpg/preproc/ecpg.type
@@ -85,6 +85,7 @@
 %type <str> opt_output
 %type <str> opt_pointer
 %type <str> opt_port
+%type <str> opt_readahead
 %type <str> opt_reference
 %type <str> opt_scale
 %type <str> opt_server
diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c
index 8032c30..cbd37c6 100644
--- a/src/interfaces/ecpg/preproc/ecpg_keywords.c
+++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c
@@ -56,6 +56,7 @@ static const ScanKeyword ScanECPGKeywords[] = {
 	{"octet_length", SQL_OCTET_LENGTH, 0},
 	{"open", SQL_OPEN, 0},
 	{"output", SQL_OUTPUT, 0},
+	{"readahead", SQL_READAHEAD, 0},
 	{"reference", SQL_REFERENCE, 0},
 	{"returned_length", SQL_RETURNED_LENGTH, 0},
 	{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index ccf5548..3d22d3a 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -24,12 +24,17 @@ extern bool autocommit,
 			force_indicator,
 			questionmarks,
 			regression_mode,
-			auto_prepare;
+			auto_prepare,
+			fetch_readahead;
+extern bool	use_fetch_readahead;
 extern int	braces_open,
 			ret_value,
 			struct_level,
 			ecpg_internal_var;
 extern char *current_function;
+extern char *current_cursor;  
+extern enum ECPG_cursor_direction current_cursor_direction;
+extern char *current_cursor_amount;
 extern char *descriptor_index;
 extern char *descriptor_name;
 extern char *connection;
@@ -67,6 +72,9 @@ extern void output_statement(char *, int, enum ECPG_statement_type);
 extern void output_prepare_statement(char *, char *);
 extern void output_deallocate_prepare_statement(char *);
 extern void output_simple_statement(char *);
+extern void output_open_statement(char *, int, enum ECPG_statement_type);
+extern void output_fetch_statement(char *, int, enum ECPG_statement_type);
+extern void output_close_statement(char *, int, enum ECPG_statement_type);
 extern char *hashline_number(void);
 extern int	base_yyparse(void);
 extern int	base_yylex(void);
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 389a527..68ad718 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -112,10 +112,16 @@ static char *ecpg_statement_type_name[] = {
 	"ECPGst_prepnormal"
 };
 
-void
-output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+static char *ecpg_cursor_direction_name[] = {
+	"ECPGc_absolute",
+	"ECPGc_relative",
+	"ECPGc_forward", 
+	"ECPGc_backward" 
+};
+
+static void
+output_statement_epilogue(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 {
-	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
 	if (st == ECPGst_execute || st == ECPGst_exec_immediate)
 	{
 		fprintf(yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
@@ -145,6 +151,13 @@ output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 }
 
 void
+output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
 output_prepare_statement(char *name, char *stmt)
 {
 	fprintf(yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
@@ -178,6 +191,51 @@ output_deallocate_prepare_statement(char *name)
 		free(connection);
 }
 
+void
+output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
+output_fetch_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	char	*amount = mm_alloc(strlen(current_cursor_amount) + 3);
+
+	if (!amount)
+		return;
+
+	sprintf(amount, "\"%s\"", current_cursor_amount);
+	fprintf(yyout, "{ ECPGfetch(__LINE__, %d, %d, %s, %d, %s, %s, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor,
+			ecpg_cursor_direction_name[current_cursor_direction],
+			amount);
+	output_statement_epilogue(stmt, whenever_mode, st);
+	free(amount);
+}
+
+void
+output_close_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGclose(__LINE__, %d, %d, %s, %d, %s, ",
+			compat,
+			force_indicator,
+			connection ? connection : "NULL",
+			questionmarks,
+			current_cursor);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
 static void
 output_escaped_str(char *str, bool quoted)
 {
diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl
index 515470e..aebcaf4 100644
--- a/src/interfaces/ecpg/preproc/parse.pl
+++ b/src/interfaces/ecpg/preproc/parse.pl
@@ -90,6 +90,8 @@ my %replace_line = (
 	'fetch_argsFORWARDopt_from_incursor_name'      => 'ignore',
 	'fetch_argsBACKWARDopt_from_incursor_name'     => 'ignore',
 	"opt_array_boundsopt_array_bounds'['Iconst']'" => 'ignore',
+	'DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt' =>
+			'DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold FOR SelectStmt',
 	'VariableShowStmtSHOWvar_name'                 => 'SHOW var_name ecpg_into',
 	'VariableShowStmtSHOWTIMEZONE' => 'SHOW TIME ZONE ecpg_into',
 	'VariableShowStmtSHOWTRANSACTIONISOLATIONLEVEL' => 'SHOW TRANSACTION ISOLATION LEVEL ecpg_into',
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 68e0d1a..89c920f 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -130,6 +130,7 @@ struct cursor
 	char	   *command;
 	char	   *connection;
 	bool		opened;
+	bool		fetch_readahead;
 	struct arguments *argsinsert;
 	struct arguments *argsinsert_oos;
 	struct arguments *argsresult;
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index c07ea93..a15b7d9 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -20,6 +20,7 @@ test: preproc/array_of_struct
 test: preproc/autoprep
 test: preproc/comment
 test: preproc/cursor
+test: preproc/cursor-readahead
 test: preproc/define
 test: preproc/init
 test: preproc/strings
diff --git a/src/interfaces/ecpg/test/ecpg_schedule_tcp b/src/interfaces/ecpg/test/ecpg_schedule_tcp
index 77481b5..60994e0 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule_tcp
+++ b/src/interfaces/ecpg/test/ecpg_schedule_tcp
@@ -20,6 +20,7 @@ test: preproc/array_of_struct
 test: preproc/autoprep
 test: preproc/comment
 test: preproc/cursor
+test: preproc/cursor-readahead
 test: preproc/define
 test: preproc/init
 test: preproc/strings
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c
new file mode 100644
index 0000000..ef39815
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.c
@@ -0,0 +1,663 @@
+/* Processed by ecpg (regression mode) */
+/* These include files are added by the preprocessor */
+#include <ecpglib.h>
+#include <ecpgerrno.h>
+#include <sqlca.h>
+/* End of automatic include section */
+#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+#line 1 "cursor-readahead.pgc"
+#include <stdio.h>
+#include <malloc.h>
+
+/* test automatic prepare for all statements */
+
+#line 1 "regression.h"
+
+
+
+
+
+
+#line 5 "cursor-readahead.pgc"
+
+
+
+#line 1 "sqlda.h"
+#ifndef ECPG_SQLDA_H
+#define ECPG_SQLDA_H
+
+#ifdef _ECPG_INFORMIX_H
+
+#include "sqlda-compat.h"
+typedef struct sqlvar_compat	sqlvar_t;
+typedef struct sqlda_compat	sqlda_t;
+
+#else
+
+#include "sqlda-native.h"
+typedef struct sqlvar_struct	sqlvar_t;
+typedef struct sqlda_struct	sqlda_t;
+
+#endif
+
+#endif /* ECPG_SQLDA_H */
+
+#line 7 "cursor-readahead.pgc"
+
+
+/* exec sql whenever sqlerror  sqlprint ; */
+#line 9 "cursor-readahead.pgc"
+
+/* exec sql whenever sql_warning  sqlprint ; */
+#line 10 "cursor-readahead.pgc"
+
+
+#define MAXID	(513)
+
+int main(void)
+{
+	int	counts[2] = { 1, 5 };
+	/* exec sql begin declare section */
+		
+		
+		   
+		  
+	
+#line 18 "cursor-readahead.pgc"
+ char * curname ;
+ 
+#line 19 "cursor-readahead.pgc"
+ int maxid ;
+ 
+#line 20 "cursor-readahead.pgc"
+ int i , j , count , rows ;
+ 
+#line 21 "cursor-readahead.pgc"
+ int id , id1 [ 5 ] , id2 [ 5 ] ;
+/* exec sql end declare section */
+#line 22 "cursor-readahead.pgc"
+
+	sqlda_t	*sqlda;
+
+	/*
+	 * Intentionally don't create a 2MB stderr file for this test.
+	 * Enable it manually if you're interested in it.
+	 */
+#if 0
+	ECPGdebug(1, stderr);
+#endif
+
+	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); 
+#line 33 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 33 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 33 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 35 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 35 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 35 "cursor-readahead.pgc"
+
+
+	maxid = MAXID;
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table ra_test ( id integer primary key )", ECPGt_EOIT, ECPGt_EORT);
+#line 39 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 39 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 39 "cursor-readahead.pgc"
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into ra_test select i . i from generate_series ( 1 , $1  ) as i", 
+	ECPGt_int,&(maxid),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 40 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 40 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 40 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 42 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 42 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 42 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 44 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 44 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 44 "cursor-readahead.pgc"
+
+
+	curname = "xx";
+	ECPGset_var( 0, &( curname ), __LINE__);\
+ /* declare $0 scroll cursor for select * from ra_test */
+#line 47 "cursor-readahead.pgc"
+
+	/* declare xcur scroll cursor for select * from ra_test */
+#line 48 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 50 "cursor-readahead.pgc"
+
+
+	for (i = 0; i < 2; i++)
+	{
+		count = counts[i];
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare $0 scroll cursor for select * from ra_test", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 56 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 56 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 56 "cursor-readahead.pgc"
+
+		{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 57 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 57 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 57 "cursor-readahead.pgc"
+
+
+		id = 0;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 from $0", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 68 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 68 "cursor-readahead.pgc"
+
+			{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "$0", ECPGst_normal, "fetch $0 from xcur", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 69 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 69 "cursor-readahead.pgc"
+
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				id++;
+
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors forward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (sqlca.sqlwarn[0] == 'W') sqlprint();
+		if (sqlca.sqlcode < 0) sqlprint();
+
+		if (id == maxid)
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 95 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 95 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 95 "cursor-readahead.pgc"
+
+		{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 96 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 96 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 96 "cursor-readahead.pgc"
+
+
+		/* exec sql whenever not found  continue ; */
+#line 98 "cursor-readahead.pgc"
+
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare $0 scroll cursor for select * from ra_test", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 100 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 100 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 100 "cursor-readahead.pgc"
+
+		{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 101 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 101 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 101 "cursor-readahead.pgc"
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch last from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 102 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 102 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 102 "cursor-readahead.pgc"
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 103 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 103 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 103 "cursor-readahead.pgc"
+
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor '%s' (value %d), fetching backwards.\n", curname, id1[0]);
+		else
+			goto err;
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_absolute, "-1", ECPGst_normal, "fetch last from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 108 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 108 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 108 "cursor-readahead.pgc"
+
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "1", ECPGst_normal, "fetch from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 109 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 109 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 109 "cursor-readahead.pgc"
+
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id2[0]);
+		else
+			goto err;
+
+		/* exec sql whenever not found  break ; */
+#line 115 "cursor-readahead.pgc"
+
+
+		id = maxid;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch backward $0 from $0", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 126 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 126 "cursor-readahead.pgc"
+
+			{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_backward, "$0", ECPGst_normal, "fetch backward $0 from xcur", 
+	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,(id2),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 127 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 127 "cursor-readahead.pgc"
+
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors backward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+				id--;
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (id == 0)
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 149 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 149 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 149 "cursor-readahead.pgc"
+
+		{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 150 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 150 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 150 "cursor-readahead.pgc"
+
+
+		/* exec sql whenever not found  continue ; */
+#line 152 "cursor-readahead.pgc"
+
+
+	}
+
+	sqlda = NULL;
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 157 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 157 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 157 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "all", ECPGst_normal, "fetch all xcur", ECPGt_EOIT, 
+	ECPGt_sqlda, &sqlda, 0L, 0L, 0L, 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 158 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 158 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 158 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 160 "cursor-readahead.pgc"
+
+
+	id = 0;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t *tmp;
+
+		id++;
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors forward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+	}
+
+	if (id == maxid)
+		printf("Reading all records from a readahead cursor forward into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from a readahead cursor forward into sqlda chain: FAILED. id %d, id1 %d\n", id, id1[0]);
+
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 186 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 186 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 186 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  continue ; */
+#line 188 "cursor-readahead.pgc"
+
+
+	sqlda = NULL;
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "declare xcur scroll cursor for select * from ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 191 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 191 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 191 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_absolute, "-1", ECPGst_normal, "fetch last from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 192 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 192 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 192 "cursor-readahead.pgc"
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_forward, "1", ECPGst_normal, "fetch from xcur", ECPGt_EOIT, 
+	ECPGt_int,(id1),(long)1,(long)5,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 193 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 193 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 193 "cursor-readahead.pgc"
+
+	if (sqlca.sqlcode == ECPG_NOT_FOUND)
+		printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id1[0]);
+	else
+		goto err;
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "xcur", ECPGc_backward, "all", ECPGst_normal, "fetch backward all xcur", ECPGt_EOIT, 
+	ECPGt_sqlda, &sqlda, 0L, 0L, 0L, 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 199 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 199 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 199 "cursor-readahead.pgc"
+
+
+	/* exec sql whenever not found  break ; */
+#line 201 "cursor-readahead.pgc"
+
+
+	id = maxid;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t	*tmp;
+
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors backward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+
+		id--;
+	}
+
+	if (id == 0)
+		printf("Reading all records from readahead cursor backwards into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from readahead cursors backwards into sqlda chain: FAILED, id %d, id1 %d\n", id, id1[0]);
+
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "xcur", ECPGst_normal, "close xcur", ECPGt_EOIT, ECPGt_EORT);
+#line 229 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 229 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 229 "cursor-readahead.pgc"
+
+
+err:
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 233 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 233 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 233 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "begin");
+#line 235 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 235 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 235 "cursor-readahead.pgc"
+
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table ra_test", ECPGt_EOIT, ECPGt_EORT);
+#line 237 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 237 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 237 "cursor-readahead.pgc"
+
+
+	{ ECPGtrans(__LINE__, NULL, "commit");
+#line 239 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 239 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 239 "cursor-readahead.pgc"
+
+
+	{ ECPGdisconnect(__LINE__, "ALL");
+#line 241 "cursor-readahead.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 241 "cursor-readahead.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 241 "cursor-readahead.pgc"
+
+
+	return 0;
+}
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stderr b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stderr
new file mode 100644
index 0000000..e69de29
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout
new file mode 100644
index 0000000..5e70dd7
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor-readahead.stdout
@@ -0,0 +1,11 @@
+Reading readahead and non-readahead cursors simultaneously forward by 1 record: SUCCESS
+After last record in cursor 'xx' (value 513), fetching backwards.
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading readahead and non-readahead cursors simultaneously backwards by 1 record(s): SUCCESS
+Reading readahead and non-readahead cursors simultaneously forward by 5 record: SUCCESS
+After last record in cursor 'xx' (value 513), fetching backwards.
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading readahead and non-readahead cursors simultaneously backwards by 5 record(s): SUCCESS
+Reading all records from a readahead cursor forward into sqlda chain: SUCCESS
+After last record in cursor 'xcur' (value 513), fetching backwards.
+Reading all records from readahead cursor backwards into sqlda chain: SUCCESS
diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile
index 3bcb63a..dfe4166 100644
--- a/src/interfaces/ecpg/test/preproc/Makefile
+++ b/src/interfaces/ecpg/test/preproc/Makefile
@@ -8,6 +8,7 @@ TESTS = array_of_struct array_of_struct.c \
 	autoprep autoprep.c \
 	comment comment.c \
 	cursor cursor.c \
+	cursor-readahead cursor-readahead.c \
 	define define.c \
 	init init.c \
 	strings strings.c \
diff --git a/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
new file mode 100644
index 0000000..076f9b3
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <malloc.h>
+
+/* test automatic prepare for all statements */
+EXEC SQL INCLUDE ../regression;
+
+EXEC SQL INCLUDE sqlda.h;
+
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+
+#define MAXID	(513)
+
+int main(void)
+{
+	int	counts[2] = { 1, 5 };
+	EXEC SQL BEGIN DECLARE SECTION;
+	char	*curname;
+	int	maxid;
+	int	i, j, count, rows;
+	int	id, id1[5], id2[5];
+	EXEC SQL END DECLARE SECTION;
+	sqlda_t	*sqlda;
+
+	/*
+	 * Intentionally don't create a 2MB stderr file for this test.
+	 * Enable it manually if you're interested in it.
+	 */
+#if 0
+	ECPGdebug(1, stderr);
+#endif
+
+	EXEC SQL CONNECT TO REGRESSDB1;
+
+	EXEC SQL BEGIN;
+
+	maxid = MAXID;
+
+	EXEC SQL CREATE TABLE ra_test (id INTEGER PRIMARY KEY);
+	EXEC SQL INSERT INTO ra_test SELECT i.i FROM generate_series(1, :maxid) as i;
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL BEGIN;
+
+	curname = "xx";
+	EXEC SQL DECLARE :curname SCROLL CURSOR FOR SELECT * FROM ra_test;
+	EXEC SQL DECLARE xcur SCROLL READAHEAD CURSOR FOR SELECT * FROM ra_test;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	for (i = 0; i < 2; i++)
+	{
+		count = counts[i];
+
+		EXEC SQL OPEN :curname;
+		EXEC SQL OPEN xcur;
+
+		id = 0;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			EXEC SQL FETCH :count FROM :curname INTO :id1;
+			EXEC SQL FETCH :count FROM xcur INTO :id2;
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				id++;
+
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors forward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (sqlca.sqlwarn[0] == 'W') sqlprint();
+		if (sqlca.sqlcode < 0) sqlprint();
+
+		if (id == maxid)
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously forward by %d record: FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		EXEC SQL CLOSE :curname;
+		EXEC SQL CLOSE xcur;
+
+		EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+		EXEC SQL OPEN :curname;
+		EXEC SQL OPEN xcur;
+		EXEC SQL FETCH LAST FROM :curname INTO :id1;
+		EXEC SQL FETCH FROM :curname INTO :id1;
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor '%s' (value %d), fetching backwards.\n", curname, id1[0]);
+		else
+			goto err;
+		EXEC SQL FETCH LAST FROM xcur INTO :id2;
+		EXEC SQL FETCH FROM xcur INTO :id2;
+		if (sqlca.sqlcode == ECPG_NOT_FOUND)
+			printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id2[0]);
+		else
+			goto err;
+
+		EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+		id = maxid;
+		while (1)
+		{
+			for (j = 0; j < count; j++)
+			{
+				id1[j] = -1;
+				id2[j] = -1;
+			}
+
+			EXEC SQL FETCH BACKWARD :count FROM :curname INTO :id1;
+			EXEC SQL FETCH BACKWARD :count FROM xcur INTO :id2;
+
+			rows = sqlca.sqlerrd[2];
+
+			for (j = 0; j < rows; j++)
+			{
+				if (id != id1[j] || id != id2[j] || id1[j] != id2[j])
+				{
+					printf("Reading two cursors backward: ERROR. id = %d id1 = %d id2 = %d\n", id, id1[j], id2[j]);
+					break;
+				}
+				id--;
+			}
+			if (j != rows)
+				break;
+		}
+
+		if (id == 0)
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): SUCCESS\n", count);
+		else
+			printf("Reading readahead and non-readahead cursors simultaneously backwards by %d record(s): FAILED at %d, id1 %d id2 %d\n", count, id, id1[j], id2[j]);
+
+		EXEC SQL CLOSE :curname;
+		EXEC SQL CLOSE xcur;
+
+		EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+	}
+
+	sqlda = NULL;
+	EXEC SQL OPEN xcur;
+	EXEC SQL FETCH ALL xcur INTO DESCRIPTOR sqlda;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	id = 0;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t *tmp;
+
+		id++;
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors forward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+	}
+
+	if (id == maxid)
+		printf("Reading all records from a readahead cursor forward into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from a readahead cursor forward into sqlda chain: FAILED. id %d, id1 %d\n", id, id1[0]);
+
+	EXEC SQL CLOSE xcur;
+
+	EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+	sqlda = NULL;
+	EXEC SQL OPEN xcur;
+	EXEC SQL FETCH LAST FROM xcur INTO :id1;
+	EXEC SQL FETCH FROM xcur INTO :id1;
+	if (sqlca.sqlcode == ECPG_NOT_FOUND)
+		printf("After last record in cursor 'xcur' (value %d), fetching backwards.\n", id1[0]);
+	else
+		goto err;
+
+	EXEC SQL FETCH BACKWARD ALL xcur INTO DESCRIPTOR sqlda;
+
+	EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+	id = maxid;
+	id1[0] = -1;
+	while (sqlda)
+	{
+		sqlda_t	*tmp;
+
+		id1[0] = *(int *)sqlda->sqlvar[0].sqldata;
+
+		if (id != id1[0])
+		{
+			printf("Reading readahead cursors backward into sqlda chain: ERROR. id = %d id1 = %d\n", id, id1[0]);
+			break;
+		}
+
+		tmp = sqlda->desc_next;
+		free(sqlda);
+		sqlda = tmp;
+
+		id--;
+	}
+
+	if (id == 0)
+		printf("Reading all records from readahead cursor backwards into sqlda chain: SUCCESS\n");
+	else
+		printf("Reading all records from readahead cursors backwards into sqlda chain: FAILED, id %d, id1 %d\n", id, id1[0]);
+
+	EXEC SQL CLOSE xcur;
+
+err:
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL BEGIN;
+
+	EXEC SQL DROP TABLE ra_test;
+
+	EXEC SQL COMMIT;
+
+	EXEC SQL DISCONNECT ALL;
+
+	return 0;
+}
#15Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#14)
Re: ECPG FETCH readahead

On Thu, Dec 29, 2011 at 10:46:23AM +0100, Boszormenyi Zoltan wrote:

2011-11-16 20:51 keltez?ssel, Boszormenyi Zoltan ?rta:

2010-10-14 11:56 keltez?ssel, Boszormenyi Zoltan ?rta:

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

We yet lack a consensus on whether native ECPG apps should have access to the
feature. My 2c is to make it available, because it's useful syntactic sugar.
If your program independently processes each row of an arbitrary-length result
set, current facilities force you to add an extra outer loop to batch the
FETCHes for every such code site. Applications could define macros to
abstract that pattern, but this seems common-enough to justify bespoke
handling. Besides, minimalists already use libpq directly.

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5. That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document. I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

The ASAP took a little long. The attached patch is in git diff format,
because (1) the regression test intentionally doesn't do ECPGdebug()
so the patch isn't dominated by a 2MB stderr file, so this file is empty
and (2) regular diff cannot cope with empty new files.

Avoid the empty file with fprintf(STDERR, "Dummy non-empty error output\n");

- *NEW FEATURE* Readahead can be individually enabled or disabled
by ECPG-side grammar:
DECLARE curname [ [ NO ] READAHEAD ] CURSOR FOR ...
Without [ NO ] READAHEAD, the default behaviour is used for cursors.

Likewise, this may as well take a chunk size rather than a yes/no.

The patch adds warnings:
error.c: In function `ecpg_raise':
error.c:281: warning: format not a string literal and no format arguments
error.c:281: warning: format not a string literal and no format arguments

The patch adds few comments and no larger comments explaining its higher-level
ideas. That makes it much harder to review. In this regard it follows the
tradition of the ECPG code, but let's depart from that tradition for new work.
I mention a few cases below where the need for commentary is acute.

I tested full reads of various "SELECT * FROM generate_series(1, $1)" commands
over a 50ms link, and the patch gives a sound performance improvement. With
no readahead, a mere N=100 takes 5s to drain. With readahead enabled, N=10000
takes only 3s. Performance was quite similar to that of implementing my own
batching with "FETCH 256 FROM cur". When I kicked up ECPGFETCHSZ (after
fixing its implementation -- see below) past the result set size, performance
was comparable to that of simply passing the query through psql.

--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml

@@ -5289,6 +5315,17 @@ while (1)
</varlistentry>

<varlistentry>
+     <term>-231 (<symbol>ECPG_INVALID_CURSOR</symbol>)</term>
+     <listitem>
+      <para>
+       The cursor you are trying to use with readahead has not been opened yet (SQLSTATE 34000),
+       invalid values were passed to libecpg (SQLSTATE 42P11) hor not in prerequisite state, i.e.

Typo.

--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,730 @@

cursor.c contains various >78-col lines. pgindent has limited ability to
improve those, so please split them.

+static struct cursor_descriptor *
+add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing)
+{
+	struct cursor_descriptor *desc,
+				*ptr, *prev = NULL;
+	bool	found = false;
+
+	if (!name || name[0] == '\0')
+	{
+		if (existing)
+			*existing = false;
+		return NULL;
+	}
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}

Any reason not to use find_cursor() here?

+static void
+del_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *ptr, *prev = NULL;
+	bool	found = false;
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}

Any reason not to use find_cursor() here?

+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");

A query like 'SELECT 1 AS "with hold "' fools these lexical tests. Capture
that information in the parser rather than attempting to reconstruct it here.

+	scrollable = (noscroll == NULL) && (scroll != NULL) && (scroll < ptr);
+
+	new_query = ecpg_alloc(strlen(curname) + strlen(ptr) + (whold ? 10 : 0) + 32, lineno);
+	if (!new_query)
+		return false;
+	sprintf(new_query, "declare %s %s cursor %s%s",
+					(dollar0 && (dollar0 < ptr) ? "$0" : curname),
+					(scrollable ? "scroll" : "no scroll"),
+					(whold ? "with hold " : ""),
+					ptr);
+
+	/* Set the fetch size the first time we are called. */
+	if (fetch_size == 0)
+	{
+		char	   *fsize_str = getenv("ECPGFETCHSZ");
+		char	   *endptr = NULL;
+		int		fsize;
+
+		if (fsize_str)
+		{
+			fsize = strtoul(fsize_str, &endptr, 10);
+			if (endptr || (fsize < 4))
+				fetch_size = DEFAULTFETCHSIZE;

"endptr" will never be NULL; use "*endptr". As it stands, the code always
ignores ECPGFETCHSZ. An unusable ECPGFETCHSZ should procedure an error, not
silently give no effect. Why a minimum of 4?

+			else
+				fetch_size = fsize;
+		}
+		else
+			fetch_size = DEFAULTFETCHSIZE;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, new_query, args);
+	va_end(args);
+
+	ecpg_free(new_query);
+
+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)

Why is the commented code there?

+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}

You give this rationale for the above code:

On Thu, Jun 17, 2010 at 02:09:47PM +0200, Boszormenyi Zoltan wrote:

ECPGopen() also discovers the total number of records in the recordset,
so the previous ECPG "deficiency" (backend limitation) that sqlca.sqlerrd[2]
didn't report the (possibly estimated) number of rows in the resultset
is now
overcome. This slows down OPEN for cursors serving larger datasets
but it makes possible to position the readahead window using MOVE
ABSOLUTE no matter what FORWARD/BACKWARD/ABSOLUTE/RELATIVE
variants are used by the application. And the caching is more than
overweighs
the slowdown in OPEN it seems.

From the documentation for Informix and Oracle, those databases do not
populate sqlerrd[2] this way:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqlt.doc/sqltmst189.htm
http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PC_22/ch10.htm#toc139

The performance impact will vary widely depending on the query cost per row
and the fraction of rows the application will actually retrieve. Consider a
complex aggregate returning only a handful of rows. Consider SELECT * on a
1B-row table with the application ceasing reads after 1000 rows. Performance
aside, this will yield double execution of any volatile functions involved.
So, I think we ought to diligently avoid this step. (Failing that, the
documentation must warn about the extra full cursor scan and this feature must
stay disabled by default.)

+
+		/* Add the cursor */
+		cur = add_cursor(lineno, con, curname, scrollable, n_tuples, &existing);
+
+		/*
+		 * Report the number of tuples for the [scrollable] cursor.
+		 * The server didn't do it for us.
+		 */
+		sqlca->sqlerrd[2] = (cur->n_tuples < LONG_MAX ? cur->n_tuples : LONG_MAX);
+	}
+
+	return ret;
+}
+
+static bool
+ecpg_cursor_execute(struct statement * stmt, struct cursor_descriptor *cur)
+{
+	char		tmp[64];
+	char	   *query;
+	int64		start_pos;
+
+	if ((cur->cache_pos >= cur->start_pos) && cur->res && (cur->cache_pos < cur->start_pos + PQntuples(cur->res)))
+	{
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}

Why does ecpg_cursor_execute() also call ecpg_free_params()? Offhand, it
seems that ECPGfetch() always takes care of that and is the more appropriate
place, seeing it's the one calling ecpg_build_params().

--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -120,7 +120,7 @@ check_special_value(char *ptr, double *retval, char **endptr)
}
bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int var_index, int act_tuple, int act_field, int lineno,
enum ECPGttype type, enum ECPGttype ind_type,
char *var, char *ind, long varcharsize, long offset,
long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)

This function could sure use a block comment such as would be customary in
src/backend. Compare the one at heap_update(), for example.

--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -268,6 +268,20 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
break;
+		case ECPG_INVALID_CURSOR:
+			if (strcmp(sqlstate, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE) == 0)
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+
+			/*
+			 * translator: this string will be truncated at 149 characters
+			 * expanded.
+			 */
+				ecpg_gettext("cursor can only scan forward"));

Every other message works in the line number somehow; this should do the same.

--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c

@@ -1707,46 +1809,20 @@ ecpg_execute(struct statement * stmt)
}

bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		enum ECPG_statement_type statement_type, const char *query,
+		va_list args, struct statement **stmt_out)

A block comment would especially help this function, considering the name
tells one so little.

--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
bool		questionmarks;
struct variable *inlist;
struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
};

Please comment the members of this struct like we do in most of src/include.
dollarzero has something to do with dynamic cursor names, right? Does it have
other roles?

--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header

@@ -111,6 +115,26 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
}

/*
+ * set use_fetch_readahead based on the current cursor
+ * doesn't return if the cursor is not declared
+ */
+static void
+set_cursor_readahead(const char *curname)
+{
+	struct cursor *ptr;
+
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp(ptr->name, curname) == 0)
+			break;
+	}
+	if (!ptr)
+		mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", curname);
+
+	use_fetch_readahead = ptr->fetch_readahead;
+}

Following add_additional_variables(), use strcasecmp() for literal cursor
names and strcmp() for cursor name host variables.

--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -24,12 +24,17 @@ extern bool autocommit,
force_indicator,
questionmarks,
regression_mode,
-			auto_prepare;
+			auto_prepare,
+			fetch_readahead;
+extern bool	use_fetch_readahead;

The names of the last two variables don't make clear the difference between
them. I suggest default_fetch_readahead and current_fetch_readahead.

--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <malloc.h>

Why <malloc.h>? I only see this calling free(); use <stdlib.h> instead.

Thanks,
nm

#16Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#15)
Re: ECPG FETCH readahead

Hi,

first, thank you for answering and for the review.

2012-03-02 17:41 keltezéssel, Noah Misch írta:

On Thu, Dec 29, 2011 at 10:46:23AM +0100, Boszormenyi Zoltan wrote:

2011-11-16 20:51 keltez?ssel, Boszormenyi Zoltan ?rta:

2010-10-14 11:56 keltez?ssel, Boszormenyi Zoltan ?rta:

On Thu, Jun 24, 2010 at 8:19 AM, Michael Meskes <meskes@postgresql.org> wrote:

On Thu, Jun 24, 2010 at 12:04:30PM +0300, Heikki Linnakangas wrote:

Is there a reason not to enable it by default? I'm a bit worried
that it will receive no testing if it's not always on.

Yes, there is a reason, namely that you don't need it in native mode at all.
ECPG can read as many records as you want in one go, something ESQL/C
apparently cannot do. This patch is a workaround for that restriction. I still
do not really see that this feature gives us an advantage in native mode
though.

We yet lack a consensus on whether native ECPG apps should have access to the
feature.

I don't even remember about any opinion on this matter.
So, at this point don't know whether it's lack of interest.
We also have a saying "silence means agreement". :-)

My 2c is to make it available, because it's useful syntactic sugar.

Thanks, we thought the same.

If your program independently processes each row of an arbitrary-length result
set, current facilities force you to add an extra outer loop to batch the
FETCHes for every such code site. Applications could define macros to
abstract that pattern, but this seems common-enough to justify bespoke
handling.

We have similar opinions.

Besides, minimalists already use libpq directly.

Indeed. On the other hand, ECPG provides a safety net with syntax checking
so it's useful for not minimalist types. :-)

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5.

That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document.

I see. How about 8? Nice "round" power of 2 value, still small and avoids
87.5% of overhead.

BTW, the default disabled behaviour was to avoid "make check" breakage,
see below.

I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

This means all code previously going through ECPGdo() would go through
ECPGopen()/ECPGfetch()/ECPGclose(). This is more intrusive and all
regression tests that were only testing certain features would also
test the readahead feature, too.

Also, the test for WHERE CURRENT OF at ecpg time would have to be done
at runtime, possibly making previously working code fail if ECPGFETCHSZ is enabled.

How about still allowing "NO READAHEAD" cursors that compile into plain ECPGdo()?
This way, ECPGFETCHSZ don't interfere with WHERE CURRENT OF. But this would
mean code changes everywhere where WHERE CURRENT OF is used.

Or how about a new feature in the backend, so ECPG can do
UPDATE/DELETE ... WHERE OFFSET N OF cursor
and the offset of computed from the actual cursor position and the position known
by the application? This way an app can do readahead and do work on rows collected
by the cursor with WHERE CURRENT OF which gets converted to WHERE OFFSET OF
behind the scenes.

The ASAP took a little long. The attached patch is in git diff format,
because (1) the regression test intentionally doesn't do ECPGdebug()
so the patch isn't dominated by a 2MB stderr file, so this file is empty
and (2) regular diff cannot cope with empty new files.

Avoid the empty file with fprintf(STDERR, "Dummy non-empty error output\n");

Fixed.

- *NEW FEATURE* Readahead can be individually enabled or disabled
by ECPG-side grammar:
DECLARE curname [ [ NO ] READAHEAD ] CURSOR FOR ...
Without [ NO ] READAHEAD, the default behaviour is used for cursors.

Likewise, this may as well take a chunk size rather than a yes/no.

Done.

The patch adds warnings:
error.c: In function `ecpg_raise':
error.c:281: warning: format not a string literal and no format arguments
error.c:281: warning: format not a string literal and no format arguments

Fixed.

The patch adds few comments and no larger comments explaining its higher-level
ideas. That makes it much harder to review. In this regard it follows the
tradition of the ECPG code, but let's depart from that tradition for new work.
I mention a few cases below where the need for commentary is acute.

Understood. Adding comments as I go over that code again.

I tested full reads of various "SELECT * FROM generate_series(1, $1)" commands
over a 50ms link, and the patch gives a sound performance improvement. With
no readahead, a mere N=100 takes 5s to drain. With readahead enabled, N=10000
takes only 3s. Performance was quite similar to that of implementing my own
batching with "FETCH 256 FROM cur". When I kicked up ECPGFETCHSZ (after
fixing its implementation -- see below) past the result set size, performance
was comparable to that of simply passing the query through psql.

--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -5289,6 +5315,17 @@ while (1)
</varlistentry>
<varlistentry>
+     <term>-231 (<symbol>ECPG_INVALID_CURSOR</symbol>)</term>
+     <listitem>
+      <para>
+       The cursor you are trying to use with readahead has not been opened yet (SQLSTATE 34000),
+       invalid values were passed to libecpg (SQLSTATE 42P11) hor not in prerequisite state, i.e.

Typo.

Fixed.

--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,730 @@

cursor.c contains various >78-col lines. pgindent has limited ability to
improve those, so please split them.

+static struct cursor_descriptor *
+add_cursor(int lineno, struct connection *con, const char *name, bool scrollable, int64 n_tuples, bool *existing)
+{
+	struct cursor_descriptor *desc,
+				*ptr, *prev = NULL;
+	bool	found = false;
+
+	if (!name || name[0] == '\0')
+	{
+		if (existing)
+			*existing = false;
+		return NULL;
+	}
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}

Any reason not to use find_cursor() here?

Because both add_cursor() and del_cursor() needs the "prev" pointer.
I now modified find_cursor() and they use it.

+static void
+del_cursor(struct connection *con, const char *name)
+{
+	struct cursor_descriptor *ptr, *prev = NULL;
+	bool	found = false;
+
+	ptr = con->cursor_desc;
+	while (ptr)
+	{
+		int ret = strcasecmp(ptr->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		if (ret > 0)
+			break;
+
+		prev = ptr;
+		ptr = ptr->next;
+	}

Any reason not to use find_cursor() here?

+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");

A query like 'SELECT 1 AS "with hold "' fools these lexical tests.

But SELECT 1 AS "with hold" doesn't go through ECPGopen(), it's run by ECPGdo()
so no breakage there. ecpglib functions are not intended to be called from manually
constructed C code.

Capture
that information in the parser rather than attempting to reconstruct it here.

Okay, this makes sense anyway.

+	scrollable = (noscroll == NULL) && (scroll != NULL) && (scroll < ptr);
+
+	new_query = ecpg_alloc(strlen(curname) + strlen(ptr) + (whold ? 10 : 0) + 32, lineno);
+	if (!new_query)
+		return false;
+	sprintf(new_query, "declare %s %s cursor %s%s",
+					(dollar0 && (dollar0 < ptr) ? "$0" : curname),
+					(scrollable ? "scroll" : "no scroll"),
+					(whold ? "with hold " : ""),
+					ptr);
+
+	/* Set the fetch size the first time we are called. */
+	if (fetch_size == 0)
+	{
+		char	   *fsize_str = getenv("ECPGFETCHSZ");
+		char	   *endptr = NULL;
+		int		fsize;
+
+		if (fsize_str)
+		{
+			fsize = strtoul(fsize_str, &endptr, 10);
+			if (endptr || (fsize < 4))
+				fetch_size = DEFAULTFETCHSIZE;

"endptr" will never be NULL; use "*endptr". As it stands, the code always
ignores ECPGFETCHSZ.

You're right.

An unusable ECPGFETCHSZ should procedure an error, not
silently give no effect.

Point taken. Which error handling do imagine? abort() or simply returning false
and raise and error in SQLCA?

Why a minimum of 4?

I forgot.

+			else
+				fetch_size = fsize;
+		}
+		else
+			fetch_size = DEFAULTFETCHSIZE;
+	}
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks, st, new_query, args);
+	va_end(args);
+
+	ecpg_free(new_query);
+
+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)

Why is the commented code there?

Some leftover from testing, it shouldn't be there.

+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}

You give this rationale for the above code:

On Thu, Jun 17, 2010 at 02:09:47PM +0200, Boszormenyi Zoltan wrote:

ECPGopen() also discovers the total number of records in the recordset,
so the previous ECPG "deficiency" (backend limitation) that sqlca.sqlerrd[2]
didn't report the (possibly estimated) number of rows in the resultset
is now
overcome. This slows down OPEN for cursors serving larger datasets
but it makes possible to position the readahead window using MOVE
ABSOLUTE no matter what FORWARD/BACKWARD/ABSOLUTE/RELATIVE
variants are used by the application. And the caching is more than
overweighs
the slowdown in OPEN it seems.

From the documentation for Informix and Oracle, those databases do not
populate sqlerrd[2] this way:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqlt.doc/sqltmst189.htm
http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PC_22/ch10.htm#toc139

The problem here is that Informix in the field in fact returns the number of rows
in the cursor and the customer we developed this readahead code for relied on this.
Maybe this was eliminated in newer versions of Informix to make it faster.

The performance impact will vary widely depending on the query cost per row
and the fraction of rows the application will actually retrieve. Consider a
complex aggregate returning only a handful of rows.

Indeed.

Consider SELECT * on a
1B-row table with the application ceasing reads after 1000 rows. Performance
aside, this will yield double execution of any volatile functions involved.
So, I think we ought to diligently avoid this step. (Failing that, the
documentation must warn about the extra full cursor scan and this feature must
stay disabled by default.)

OK, how about enabling it for Informix-compat mode only, or only via an
environment variable? I agree it should be documented.

+
+		/* Add the cursor */
+		cur = add_cursor(lineno, con, curname, scrollable, n_tuples, &existing);
+
+		/*
+		 * Report the number of tuples for the [scrollable] cursor.
+		 * The server didn't do it for us.
+		 */
+		sqlca->sqlerrd[2] = (cur->n_tuples < LONG_MAX ? cur->n_tuples : LONG_MAX);
+	}
+
+	return ret;
+}
+
+static bool
+ecpg_cursor_execute(struct statement * stmt, struct cursor_descriptor *cur)
+{
+	char		tmp[64];
+	char	   *query;
+	int64		start_pos;
+
+	if ((cur->cache_pos >= cur->start_pos) && cur->res && (cur->cache_pos < cur->start_pos + PQntuples(cur->res)))
+	{
+		stmt->results = cur->res;
+		ecpg_free_params(stmt, true, stmt->lineno);
+		return true;
+	}

Why does ecpg_cursor_execute() also call ecpg_free_params()? Offhand, it
seems that ECPGfetch() always takes care of that and is the more appropriate
place, seeing it's the one calling ecpg_build_params().

I will look at it.

--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -120,7 +120,7 @@ check_special_value(char *ptr, double *retval, char **endptr)
}
bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int var_index, int act_tuple, int act_field, int lineno,
enum ECPGttype type, enum ECPGttype ind_type,
char *var, char *ind, long varcharsize, long offset,
long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)

This function could sure use a block comment such as would be customary in
src/backend. Compare the one at heap_update(), for example.

OK.

--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -268,6 +268,20 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
break;
+		case ECPG_INVALID_CURSOR:
+			if (strcmp(sqlstate, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE) == 0)
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+
+			/*
+			 * translator: this string will be truncated at 149 characters
+			 * expanded.
+			 */
+				ecpg_gettext("cursor can only scan forward"));

Every other message works in the line number somehow; this should do the same.

Fixed.

--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1707,46 +1809,20 @@ ecpg_execute(struct statement * stmt)
}
bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		enum ECPG_statement_type statement_type, const char *query,
+		va_list args, struct statement **stmt_out)

A block comment would especially help this function, considering the name
tells one so little.

OK.

--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
bool		questionmarks;
struct variable *inlist;
struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
};

Please comment the members of this struct like we do in most of src/include.

OK.

dollarzero has something to do with dynamic cursor names, right? Does it have
other roles?

Yes, it had other roles. ECPG supports user variables in cases where the
PostgreSQL grammar doesn't. There's this rule:

ECPG: var_valueNumericOnly addon
if ($1[0] == '$')
{
free($1);
$1 = mm_strdup("$0");
}

The "var_value: NumericOnly" case in gram.y can show up in a lot of cases.
This feature was there before the dynamic cursor. You can even use them together
which means more than one $0 placeholders in the statement. E.g.:
FETCH :amount FROM :curname;
gets translated to
FETCH $0 FROM $0;
by ecpg, and both the amount and the cursor name is passed in in user variables.
The value is needed by cursor.c, this is why this "dollarzero" pointer is needed.

--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -111,6 +115,26 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
}
/*
+ * set use_fetch_readahead based on the current cursor
+ * doesn't return if the cursor is not declared
+ */
+static void
+set_cursor_readahead(const char *curname)
+{
+	struct cursor *ptr;
+
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp(ptr->name, curname) == 0)
+			break;
+	}
+	if (!ptr)
+		mmerror(PARSE_ERROR, ET_FATAL, "cursor \"%s\" does not exist", curname);
+
+	use_fetch_readahead = ptr->fetch_readahead;
+}

Following add_additional_variables(), use strcasecmp() for literal cursor
names and strcmp() for cursor name host variables.

After modifying the grammar to use numeric values for readahead window size,
this function and the "use_fetch_readahead" variable are not needed anymore.

--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -24,12 +24,17 @@ extern bool autocommit,
force_indicator,
questionmarks,
regression_mode,
-			auto_prepare;
+			auto_prepare,
+			fetch_readahead;
+extern bool	use_fetch_readahead;

The names of the last two variables don't make clear the difference between
them. I suggest default_fetch_readahead and current_fetch_readahead.

Now fetch_readahead is int, the other one is no more.

--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/cursor-readahead.pgc
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <malloc.h>

Why <malloc.h>? I only see this calling free(); use <stdlib.h> instead.

Fixed.

I had to update the code, the previous patch didn't apply cleanly to current GIT.
I will send the new patch some time next week after fixing the "make check"
breakage.

Thanks,
nm

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#17Michael Meskes
meskes@postgresql.org
In reply to: Noah Misch (#15)
Re: ECPG FETCH readahead

On Fri, Mar 02, 2012 at 11:41:05AM -0500, Noah Misch wrote:

We yet lack a consensus on whether native ECPG apps should have access to the
feature. My 2c is to make it available, because it's useful syntactic sugar.
If your program independently processes each row of an arbitrary-length result
set, current facilities force you to add an extra outer loop to batch the
FETCHes for every such code site. Applications could define macros to
abstract that pattern, but this seems common-enough to justify bespoke
handling. Besides, minimalists already use libpq directly.

Sorry, I don't really understand what you're saying here. The program logic
won't change at all when using this feature or what do I misunderstand?

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5. That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document. I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

Using 1 to effectively disable the feature is fine with me, but I strongly
object any default enabling this feature. It's farily easy to create cases with
pathological behaviour and this features is not standard by any means. I figure
a normal programmer would expect only one row being transfered when fetching
one.

Other than that, thanks for the great review.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#18Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#17)
Re: ECPG FETCH readahead

2012-03-04 17:16 keltezéssel, Michael Meskes írta:

On Fri, Mar 02, 2012 at 11:41:05AM -0500, Noah Misch wrote:

We yet lack a consensus on whether native ECPG apps should have access to the
feature. My 2c is to make it available, because it's useful syntactic sugar.
If your program independently processes each row of an arbitrary-length result
set, current facilities force you to add an extra outer loop to batch the
FETCHes for every such code site. Applications could define macros to
abstract that pattern, but this seems common-enough to justify bespoke
handling. Besides, minimalists already use libpq directly.

Sorry, I don't really understand what you're saying here. The program logic
won't change at all when using this feature or what do I misunderstand?

The program logic shouldn't change at all. He meant that extra coding effort
is needed if you want manual caching. It requires 2 loops instead of 1 if you use
FETCH N (N>1).

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5. That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document. I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

Using 1 to effectively disable the feature is fine with me,

Something else would be needed. For DML with WHERE CURRENT OF cursor,
the feature should stay disabled even with the environment variable is set
without adding any decoration to the DECLARE statement. The safe thing
would be to distinguish between uncached (but cachable) and uncachable
cases. A single value cannot work.

but I strongly
object any default enabling this feature. It's farily easy to create cases with
pathological behaviour and this features is not standard by any means. I figure
a normal programmer would expect only one row being transfered when fetching
one.

Other than that, thanks for the great review.

Michael

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#19Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#18)
Re: ECPG FETCH readahead

On Sun, Mar 04, 2012 at 05:34:50PM +0100, Boszormenyi Zoltan wrote:

The program logic shouldn't change at all. He meant that extra coding effort
is needed if you want manual caching. It requires 2 loops instead of 1 if you use
FETCH N (N>1).

Ah, thanks for the explanation.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#20Noah Misch
noah@leadboat.com
In reply to: Michael Meskes (#17)
Re: ECPG FETCH readahead

On Sun, Mar 04, 2012 at 05:16:06PM +0100, Michael Meskes wrote:

On Fri, Mar 02, 2012 at 11:41:05AM -0500, Noah Misch wrote:

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5. That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document. I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

Using 1 to effectively disable the feature is fine with me, but I strongly
object any default enabling this feature. It's farily easy to create cases with
pathological behaviour and this features is not standard by any means. I figure
a normal programmer would expect only one row being transfered when fetching
one.

On further reflection, I agree with you here. The prospect for queries that
call volatile functions changed my mind; they would exhibit different
functional behavior under readahead. We mustn't silently give affected
programs different semantics.

Thanks,
nm

#21Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#16)
Re: ECPG FETCH readahead

On Sun, Mar 04, 2012 at 04:33:32PM +0100, Boszormenyi Zoltan wrote:

2012-03-02 17:41 keltez?ssel, Noah Misch ?rta:

On Thu, Dec 29, 2011 at 10:46:23AM +0100, Boszormenyi Zoltan wrote:

I suggest enabling the feature by default but drastically reducing the default
readahead chunk size from 256 to, say, 5.

That still reduces the FETCH round
trip overhead by 80%, but it's small enough not to attract pathological
behavior on a workload where each row is a 10 MiB document.

I see. How about 8? Nice "round" power of 2 value, still small and avoids
87.5% of overhead.

Having pondered the matter further, I now agree with Michael that the feature
should stay disabled by default. See my response to him for rationale.
Assuming that conclusion holds, we can recommended a higher value to users who
enable the feature at all. Your former proposal of 256 seems fine.

BTW, the default disabled behaviour was to avoid "make check" breakage,
see below.

I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

This means all code previously going through ECPGdo() would go through
ECPGopen()/ECPGfetch()/ECPGclose(). This is more intrusive and all
regression tests that were only testing certain features would also
test the readahead feature, too.

It's a good sort of intrusiveness, reducing the likelihood of introducing bugs
basically unrelated to readahead that happen to afflict only ECPGdo() or only
the cursor.c interfaces. Let's indeed not have any preexisting test cases use
readahead per se, but having them use the cursor.c interfaces anyway will
build confidence in the new code. The churn in expected debug output isn't
ideal, but I don't prefer the alternative of segmenting the implementation for
the sake of the test cases.

Also, the test for WHERE CURRENT OF at ecpg time would have to be done
at runtime, possibly making previously working code fail if ECPGFETCHSZ is enabled.

Good point.

How about still allowing "NO READAHEAD" cursors that compile into plain ECPGdo()?
This way, ECPGFETCHSZ don't interfere with WHERE CURRENT OF. But this would
mean code changes everywhere where WHERE CURRENT OF is used.

ECPGFETCHSZ should only affect cursors that make no explicit mention of
READAHEAD. I'm not sure whether that should mean actually routing READHEAD 1
cursors through ECPGdo() or simply making sure that cursor.c achieves the same
outcome; see later for a possible reason to still do the latter.

Or how about a new feature in the backend, so ECPG can do
UPDATE/DELETE ... WHERE OFFSET N OF cursor
and the offset of computed from the actual cursor position and the position known
by the application? This way an app can do readahead and do work on rows collected
by the cursor with WHERE CURRENT OF which gets converted to WHERE OFFSET OF
behind the scenes.

That's a neat idea, but I would expect obstacles threatening our ability to
use it automatically for readahead. You would have to make the cursor a
SCROLL cursor. We'll often pass a negative offset, making the operation fail
if the cursor query used FOR UPDATE. Volatile functions in the query will get
more calls. That's assuming the operation will map internally to something
like MOVE N; UPDATE ... WHERE CURRENT OF; MOVE -N. You might come up with
innovations to mitigate those obstacles, but those innovations would probably
also apply to MOVE/FETCH. In any event, this would constitute a substantive
patch in its own right.

One way out of trouble here is to make WHERE CURRENT OF imply READHEAD
1/READHEAD 0 (incidentally, perhaps those two should be synonyms) on the
affected cursor. If the cursor has some other readahead quantity declared
explicitly, throw an error during preprocessing.

Failing a reasonable resolution, I'm prepared to withdraw my suggestion of
making ECPGFETCHSZ always-usable. It's nice to have, not critical.

+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");

A query like 'SELECT 1 AS "with hold "' fools these lexical tests.

But SELECT 1 AS "with hold" doesn't go through ECPGopen(), it's run by ECPGdo()
so no breakage there. ecpglib functions are not intended to be called from manually
constructed C code.

I tried something like
EXEC SQL DECLARE cur CURSOR FOR SELECT * FROM generate_series(1 , $1) AS t("with hold ");
It wrongly generated this backend command:
declare cur no scroll cursor with hold for select * from generate_series ( 1 , $1 ) as t ( "with hold " )

An unusable ECPGFETCHSZ should procedure an error, not
silently give no effect.

Point taken. Which error handling do imagine? abort() or simply returning false
and raise and error in SQLCA?

The latter.

+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)

Why is the commented code there?

Some leftover from testing, it shouldn't be there.

+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}

You give this rationale for the above code:

On Thu, Jun 17, 2010 at 02:09:47PM +0200, Boszormenyi Zoltan wrote:

ECPGopen() also discovers the total number of records in the recordset,
so the previous ECPG "deficiency" (backend limitation) that sqlca.sqlerrd[2]
didn't report the (possibly estimated) number of rows in the resultset
is now
overcome. This slows down OPEN for cursors serving larger datasets
but it makes possible to position the readahead window using MOVE
ABSOLUTE no matter what FORWARD/BACKWARD/ABSOLUTE/RELATIVE
variants are used by the application. And the caching is more than
overweighs
the slowdown in OPEN it seems.

From the documentation for Informix and Oracle, those databases do not
populate sqlerrd[2] this way:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqlt.doc/sqltmst189.htm
http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PC_22/ch10.htm#toc139

The problem here is that Informix in the field in fact returns the number of rows
in the cursor and the customer we developed this readahead code for relied on this.
Maybe this was eliminated in newer versions of Informix to make it faster.

The performance impact will vary widely depending on the query cost per row
and the fraction of rows the application will actually retrieve. Consider a
complex aggregate returning only a handful of rows.

Indeed.

Consider SELECT * on a
1B-row table with the application ceasing reads after 1000 rows. Performance
aside, this will yield double execution of any volatile functions involved.
So, I think we ought to diligently avoid this step. (Failing that, the
documentation must warn about the extra full cursor scan and this feature must
stay disabled by default.)

OK, how about enabling it for Informix-compat mode only, or only via an
environment variable? I agree it should be documented.

For a query where backend execution cost dominates the cost of transferring
rows to the client, does Informix take roughly twice the normal time to
execute the query via an ESQL/C cursor? Is that acceptable overhead for every
"ecpg -C" user? (FWIW, I've never used Informix-compat mode.) If not, the
feature deserves its own option.

Whatever the trigger condition, shouldn't this apply independent of whether
readahead is in use for a given cursor? (This could constitute a reason to
use the cursor.c interfaces for every cursor.)

Does some vendor-neutral standard define semantics for sqlerrd, or has it
propagated by imitation?

This reminds me to mention: your documentation should note that the use of
readahead or the option that enables sqlerrd[2] calculation may change the
outcome of queries calling volatile functions. See how the DECLARE
documentation page discusses this hazard for SCROLL/WITH HOLD cursors.

--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
bool		questionmarks;
struct variable *inlist;
struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
};

Please comment the members of this struct like we do in most of src/include.

OK.

dollarzero has something to do with dynamic cursor names, right? Does it have
other roles?

Yes, it had other roles. ECPG supports user variables in cases where the
PostgreSQL grammar doesn't. There's this rule:

ECPG: var_valueNumericOnly addon
if ($1[0] == '$')
{
free($1);
$1 = mm_strdup("$0");
}

The "var_value: NumericOnly" case in gram.y can show up in a lot of cases.
This feature was there before the dynamic cursor. You can even use them together
which means more than one $0 placeholders in the statement. E.g.:
FETCH :amount FROM :curname;
gets translated to
FETCH $0 FROM $0;
by ecpg, and both the amount and the cursor name is passed in in user variables.
The value is needed by cursor.c, this is why this "dollarzero" pointer is needed.

Thanks for that explanation; the situation is clearer to me now.

nm

#22Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#21)
Re: ECPG FETCH readahead

2012-03-05 19:56 keltezéssel, Noah Misch írta:

Having pondered the matter further, I now agree with Michael that the feature
should stay disabled by default. See my response to him for rationale.
Assuming that conclusion holds, we can recommended a higher value to users who
enable the feature at all. Your former proposal of 256 seems fine.

OK.

BTW, the default disabled behaviour was to avoid "make check" breakage,
see below.

I would not offer
an ecpg-time option to disable the feature per se. Instead, let the user set
the default chunk size at ecpg time. A setting of 1 effectively disables the
feature, though one could later re-enable it with ECPGFETCHSZ.

This means all code previously going through ECPGdo() would go through
ECPGopen()/ECPGfetch()/ECPGclose(). This is more intrusive and all
regression tests that were only testing certain features would also
test the readahead feature, too.

It's a good sort of intrusiveness, reducing the likelihood of introducing bugs
basically unrelated to readahead that happen to afflict only ECPGdo() or only
the cursor.c interfaces. Let's indeed not have any preexisting test cases use
readahead per se, but having them use the cursor.c interfaces anyway will
build confidence in the new code. The churn in expected debug output isn't
ideal, but I don't prefer the alternative of segmenting the implementation for
the sake of the test cases.

I see.

Also, the test for WHERE CURRENT OF at ecpg time would have to be done
at runtime, possibly making previously working code fail if ECPGFETCHSZ is enabled.

Good point.

How about still allowing "NO READAHEAD" cursors that compile into plain ECPGdo()?
This way, ECPGFETCHSZ don't interfere with WHERE CURRENT OF. But this would
mean code changes everywhere where WHERE CURRENT OF is used.

ECPGFETCHSZ should only affect cursors that make no explicit mention of
READAHEAD. I'm not sure whether that should mean actually routing READHEAD 1
cursors through ECPGdo() or simply making sure that cursor.c achieves the same
outcome; see later for a possible reason to still do the latter.

Or how about a new feature in the backend, so ECPG can do
UPDATE/DELETE ... WHERE OFFSET N OF cursor
and the offset of computed from the actual cursor position and the position known
by the application? This way an app can do readahead and do work on rows collected
by the cursor with WHERE CURRENT OF which gets converted to WHERE OFFSET OF
behind the scenes.

That's a neat idea, but I would expect obstacles threatening our ability to
use it automatically for readahead. You would have to make the cursor a
SCROLL cursor. We'll often pass a negative offset, making the operation fail
if the cursor query used FOR UPDATE. Volatile functions in the query will get
more calls. That's assuming the operation will map internally to something
like MOVE N; UPDATE ... WHERE CURRENT OF; MOVE -N. You might come up with
innovations to mitigate those obstacles, but those innovations would probably
also apply to MOVE/FETCH. In any event, this would constitute a substantive
patch in its own right.

I was thinking along the lines of a Portal keeping the ItemPointerData
for each tuple in the last FETCH statement. The WHERE OFFSET N OF cursor
would treat the offset value relative to the tuple order returned by FETCH.
So, OFFSET 0 OF == CURRENT OF and other values of N are negative.
This way, it doesn't matter if the cursor is SCROLL, NO SCROLL or have
the default behaviour with "SCROLL in some cases". Then ECPGopen()
doesn't have to play games with the DECLARE statement. Only ECPGfetch()
needs to play with MOVE statements, passing different offsets to the backend,
not what the application passed.

One way out of trouble here is to make WHERE CURRENT OF imply READHEAD
1/READHEAD 0 (incidentally, perhaps those two should be synonyms) on the
affected cursor. If the cursor has some other readahead quantity declared
explicitly, throw an error during preprocessing.

I played with this idea a while ago, from a different point of view.
If the ECPG code had the DECLARE mycur, DML ... WHERE CURRENT OF mycur
and OPEN mycur in exactly this order, i.e. WHERE CURRENT OF appears in
a standalone function between DECLARE and the first OPEN for the cursor,
then ECPG disabled readahead automatically for that cursor and for that
cursor only. But this requires effort on the user of ECPG and can be very
fragile. Code cleanup with reordering functions can break previously
working code.

Failing a reasonable resolution, I'm prepared to withdraw my suggestion of
making ECPGFETCHSZ always-usable. It's nice to have, not critical.

+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+		const char *connection_name, const bool questionmarks,
+		const char *curname, const int st, const char *query, ...)
+{
+	va_list		args;
+	bool		ret, scrollable;
+	char	   *new_query, *ptr, *whold, *noscroll, *scroll, *dollar0;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	if (!query)
+	{
+		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	ptr = strstr(query, "for ");
+	if (!ptr)
+	{
+		ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
+		return false;
+	}
+	whold = strstr(query, "with hold ");
+	dollar0 = strstr(query, "$0");
+
+	noscroll = strstr(query, "no scroll ");
+	scroll = strstr(query, "scroll ");

A query like 'SELECT 1 AS "with hold "' fools these lexical tests.

But SELECT 1 AS "with hold" doesn't go through ECPGopen(), it's run by ECPGdo()
so no breakage there. ecpglib functions are not intended to be called from manually
constructed C code.

I tried something like
EXEC SQL DECLARE cur CURSOR FOR SELECT * FROM generate_series(1 , $1) AS t("with hold ");
It wrongly generated this backend command:
declare cur no scroll cursor with hold for select * from generate_series ( 1 , $1 ) as t ( "with hold " )

Ah, ok. The grammar test in ecpg is better.

An unusable ECPGFETCHSZ should procedure an error, not
silently give no effect.

Point taken. Which error handling do imagine? abort() or simply returning false
and raise and error in SQLCA?

The latter.

+	/*
+	 * If statement went OK, add the cursor and discover the
+	 * number of rows in the recordset. This will slow down OPEN
+	 * but we gain a lot with caching.
+	 */
+	if (ret /* && sqlca->sqlerrd[2] == 0 */)

Why is the commented code there?

Some leftover from testing, it shouldn't be there.

Actually, now I remember. It was a wishful thinking on my part
that whenever PG supports returning a number of rows at opening
the cursor, correct or estimated, this code shouldn't be executed,
just accept what the backend has given us.

+	{
+		struct connection *con = ecpg_get_connection(connection_name);
+		struct cursor_descriptor *cur;
+		bool	existing;
+		int64	n_tuples;
+
+		if (scrollable)
+		{
+			PGresult   *res;
+			char	   *query;
+			char	   *endptr = NULL;
+
+			query = ecpg_alloc(strlen(curname) + strlen("move all in ") + 2, lineno);
+			sprintf(query, "move all in %s", curname);
+			res = PQexec(con->connection, query);
+			n_tuples = strtoull(PQcmdTuples(res), &endptr, 10);
+			PQclear(res);
+			ecpg_free(query);
+
+			/* Go back to the beginning of the resultset. */
+			query = ecpg_alloc(strlen(curname) + strlen("move absolute 0 in ") + 2, lineno);
+			sprintf(query, "move absolute 0 in %s", curname);
+			res = PQexec(con->connection, query);
+			PQclear(res);
+			ecpg_free(query);
+		}
+		else
+		{
+			n_tuples = 0;
+		}

You give this rationale for the above code:

On Thu, Jun 17, 2010 at 02:09:47PM +0200, Boszormenyi Zoltan wrote:

ECPGopen() also discovers the total number of records in the recordset,
so the previous ECPG "deficiency" (backend limitation) that sqlca.sqlerrd[2]
didn't report the (possibly estimated) number of rows in the resultset
is now
overcome. This slows down OPEN for cursors serving larger datasets
but it makes possible to position the readahead window using MOVE
ABSOLUTE no matter what FORWARD/BACKWARD/ABSOLUTE/RELATIVE
variants are used by the application. And the caching is more than
overweighs
the slowdown in OPEN it seems.

From the documentation for Informix and Oracle, those databases do not
populate sqlerrd[2] this way:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqlt.doc/sqltmst189.htm
http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PC_22/ch10.htm#toc139

The problem here is that Informix in the field in fact returns the number of rows
in the cursor and the customer we developed this readahead code for relied on this.
Maybe this was eliminated in newer versions of Informix to make it faster.

The performance impact will vary widely depending on the query cost per row
and the fraction of rows the application will actually retrieve. Consider a
complex aggregate returning only a handful of rows.

Indeed.

Consider SELECT * on a
1B-row table with the application ceasing reads after 1000 rows. Performance
aside, this will yield double execution of any volatile functions involved.
So, I think we ought to diligently avoid this step. (Failing that, the
documentation must warn about the extra full cursor scan and this feature must
stay disabled by default.)

OK, how about enabling it for Informix-compat mode only, or only via an
environment variable? I agree it should be documented.

For a query where backend execution cost dominates the cost of transferring
rows to the client, does Informix take roughly twice the normal time to
execute the query via an ESQL/C cursor? Is that acceptable overhead for every
"ecpg -C" user? (FWIW, I've never used Informix-compat mode.) If not, the
feature deserves its own option.

Whatever the trigger condition, shouldn't this apply independent of whether
readahead is in use for a given cursor?

I guess so.

(This could constitute a reason to
use the cursor.c interfaces for every cursor.)

Indeed.

Does some vendor-neutral standard define semantics for sqlerrd, or has it
propagated by imitation?

No idea.

This reminds me to mention: your documentation should note that the use of
readahead or the option that enables sqlerrd[2] calculation may change the
outcome of queries calling volatile functions. See how the DECLARE
documentation page discusses this hazard for SCROLL/WITH HOLD cursors.

OK.

--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,12 @@ struct statement
bool		questionmarks;
struct variable *inlist;
struct variable *outlist;
+	char		*oldlocale;
+	const char	**dollarzero;
+	int		ndollarzero;
+	const char	**param_values;
+	int		nparams;
+	PGresult	*results;
};

Please comment the members of this struct like we do in most of src/include.

OK.

dollarzero has something to do with dynamic cursor names, right? Does it have
other roles?

Yes, it had other roles. ECPG supports user variables in cases where the
PostgreSQL grammar doesn't. There's this rule:

ECPG: var_valueNumericOnly addon
if ($1[0] == '$')
{
free($1);
$1 = mm_strdup("$0");
}

The "var_value: NumericOnly" case in gram.y can show up in a lot of cases.
This feature was there before the dynamic cursor. You can even use them together
which means more than one $0 placeholders in the statement. E.g.:
FETCH :amount FROM :curname;
gets translated to
FETCH $0 FROM $0;
by ecpg, and both the amount and the cursor name is passed in in user variables.
The value is needed by cursor.c, this is why this "dollarzero" pointer is needed.

Thanks for that explanation; the situation is clearer to me now.

nm

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#23Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#22)
Re: ECPG FETCH readahead

On Tue, Mar 06, 2012 at 07:07:41AM +0100, Boszormenyi Zoltan wrote:

2012-03-05 19:56 keltez?ssel, Noah Misch ?rta:

Or how about a new feature in the backend, so ECPG can do
UPDATE/DELETE ... WHERE OFFSET N OF cursor
and the offset of computed from the actual cursor position and the position known
by the application? This way an app can do readahead and do work on rows collected
by the cursor with WHERE CURRENT OF which gets converted to WHERE OFFSET OF
behind the scenes.

That's a neat idea, but I would expect obstacles threatening our ability to
use it automatically for readahead. You would have to make the cursor a
SCROLL cursor. We'll often pass a negative offset, making the operation fail
if the cursor query used FOR UPDATE. Volatile functions in the query will get
more calls. That's assuming the operation will map internally to something
like MOVE N; UPDATE ... WHERE CURRENT OF; MOVE -N. You might come up with
innovations to mitigate those obstacles, but those innovations would probably
also apply to MOVE/FETCH. In any event, this would constitute a substantive
patch in its own right.

I was thinking along the lines of a Portal keeping the ItemPointerData
for each tuple in the last FETCH statement. The WHERE OFFSET N OF cursor
would treat the offset value relative to the tuple order returned by FETCH.
So, OFFSET 0 OF == CURRENT OF and other values of N are negative.
This way, it doesn't matter if the cursor is SCROLL, NO SCROLL or have
the default behaviour with "SCROLL in some cases". Then ECPGopen()
doesn't have to play games with the DECLARE statement. Only ECPGfetch()
needs to play with MOVE statements, passing different offsets to the backend,
not what the application passed.

That broad approach sounds promising. The main other consideration that comes
to mind is a plan to limit resource usage for a cursor that reads, say, 1B
rows. However, I think attempting to implement this now will significantly
decrease the chance of getting the core patch features committed now.

One way out of trouble here is to make WHERE CURRENT OF imply READHEAD
1/READHEAD 0 (incidentally, perhaps those two should be synonyms) on the
affected cursor. If the cursor has some other readahead quantity declared
explicitly, throw an error during preprocessing.

I played with this idea a while ago, from a different point of view.
If the ECPG code had the DECLARE mycur, DML ... WHERE CURRENT OF mycur
and OPEN mycur in exactly this order, i.e. WHERE CURRENT OF appears in
a standalone function between DECLARE and the first OPEN for the cursor,
then ECPG disabled readahead automatically for that cursor and for that
cursor only. But this requires effort on the user of ECPG and can be very
fragile. Code cleanup with reordering functions can break previously
working code.

Don't the same challenges apply to accurately reporting an error when the user
specifies WHERE CURRENT OF for a readahead cursor?

#24Robert Haas
robertmhaas@gmail.com
In reply to: Noah Misch (#23)
Re: ECPG FETCH readahead

On Tue, Mar 6, 2012 at 6:06 AM, Noah Misch <noah@leadboat.com> wrote:

On Tue, Mar 06, 2012 at 07:07:41AM +0100, Boszormenyi Zoltan wrote:

2012-03-05 19:56 keltez?ssel, Noah Misch ?rta:

Or how about a new feature in the backend, so ECPG can do
    UPDATE/DELETE ... WHERE OFFSET N OF cursor
and the offset of computed from the actual cursor position and the position known
by the application? This way an app can do readahead and do work on rows collected
by the cursor with WHERE CURRENT OF which gets converted to WHERE OFFSET OF
behind the scenes.

That's a neat idea, but I would expect obstacles threatening our ability to
use it automatically for readahead.  You would have to make the cursor a
SCROLL cursor.  We'll often pass a negative offset, making the operation fail
if the cursor query used FOR UPDATE.  Volatile functions in the query will get
more calls.  That's assuming the operation will map internally to something
like MOVE N; UPDATE ... WHERE CURRENT OF; MOVE -N.  You might come up with
innovations to mitigate those obstacles, but those innovations would probably
also apply to MOVE/FETCH.  In any event, this would constitute a substantive
patch in its own right.

I was thinking along the lines of a Portal keeping the ItemPointerData
for each tuple in the last FETCH statement. The WHERE OFFSET N OF cursor
would treat the offset value relative to the tuple order returned by FETCH.
So, OFFSET 0 OF == CURRENT OF and other values of N are negative.
This way, it doesn't matter if the cursor is SCROLL, NO SCROLL or have
 the default behaviour with "SCROLL in some cases". Then ECPGopen()
doesn't have to play games with the DECLARE statement. Only ECPGfetch()
needs to play with MOVE statements, passing different offsets to the backend,
not what the application passed.

That broad approach sounds promising.  The main other consideration that comes
to mind is a plan to limit resource usage for a cursor that reads, say, 1B
rows.  However, I think attempting to implement this now will significantly
decrease the chance of getting the core patch features committed now.

One way out of trouble here is to make WHERE CURRENT OF imply READHEAD
1/READHEAD 0 (incidentally, perhaps those two should be synonyms) on the
affected cursor.  If the cursor has some other readahead quantity declared
explicitly, throw an error during preprocessing.

I played with this idea a while ago, from a different point of view.
If the ECPG code had the DECLARE mycur, DML ... WHERE CURRENT OF mycur
and OPEN mycur in exactly this order, i.e. WHERE CURRENT OF appears in
a standalone function between DECLARE and the first OPEN for the cursor,
then ECPG disabled readahead automatically for that cursor and for that
cursor only. But this requires effort on the user of ECPG and can be very
fragile. Code cleanup with reordering functions can break previously
working code.

Don't the same challenges apply to accurately reporting an error when the user
specifies WHERE CURRENT OF for a readahead cursor?

I think we need either an updated version of this patch that's ready
for commit real soon now, or we need to postpone it to 9.3.

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

#25Boszormenyi Zoltan
zb@cybertec.at
In reply to: Robert Haas (#24)
2 attachment(s)
Re: ECPG FETCH readahead

2012-03-15 21:59 keltezéssel, Robert Haas írta:

I think we need either an updated version of this patch that's ready for commit real
soon now, or we need to postpone it to 9.3.

Sorry for the delay, I had been busy with other tasks and I rewrote this code
to better cope with unknown result size, scrollable cursors and negative
cursor positions.

I think all points raised by Noah is addressed: per-cursor readahead window size,
extensive comments, documentation and not enabling result set size discovery.

Also, I noticed this in passing:

static void
free_variable(struct variable * var)
{
struct variable *var_next;

if (var == NULL)
return;
var_next = var->next;
ecpg_free(var);

while (var_next)
{
var = var_next;
var_next = var->next;
ecpg_free(var);
}
}

I rewrote this as below to eliminate manual unrolling of the loop,
they are equivalent:

static void
free_variable(struct variable * var)
{
struct variable *var_next;

while (var)
{
var_next = var->next;
ecpg_free(var);
var = var_next;
}
}

The problem with WHERE CURRENT OF is solved by a little more grammar
and ecpglib code, which effectively does a MOVE ABSOLUTE N before
executing the DML with WHERE CURRENT OF clause. No patching of the
backend. This way, the new ECPG caching code is compatible with older
servers but obviously reduces the efficiency of caching.

Attached are two patches, the first one is the feature patch.

The second patch makes all cursor statements go through the new
caching functions with 1 tuple readahead window size. It only changes
the preprocessed code and stderr logs of the regression tests affected,
not their results.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.2-git-v12.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-9.2-git-v12.patch.gzDownload
ecpg-cursor-readahead-all-cursors.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-all-cursors.patch.gzDownload
�z�lOecpg-cursor-readahead-all-cursors.patch�]s�6�����6M$�	�?���d�=O];�����v4E;|�D���f3��)��H�������,��������%8���Aw��k0���!p����a��z��
�m�
O]g�p:	�I�;��{0��a��T��o���+�u���
�b��CjO!'&�����)HQ��v��lZ)�=d���a*��iI���_������@�����o� ��������w~��D�*`�������?���g��w��4�q����~�\{`��:��#M��SVE?�������
�6�Q�#{�9�����]:w�Y�&f��Ao\{H�@OK����#��}��lT9�K���o\gh�9�p��Ue��S�����J 2�f6X��{7r>��z��-������������
��n-5~��;w�:QId��J��x�uH��'{D����|����x��t���%
�h�@���(��\}��E�?����v����n�k������g���OWW~��x�:�xLA������K��w0�������Y�xa1�0{FO��S���0��A���/�~�{�2Sgx�.����n��������f�;�81<��n�(�7�������w��|��)O1�����t��s3~<s�L����_���@;x�����������Mi�P&t��KJ����9�E��z^�^.u�}�����
aH�S!������%��$����e���8��.z��Z���
����e��E��ip�Fp��hO������c�R�T!]_����� Q
+R+���l�������Vym���(V����^���,��A-V^#b�t
�^,���������o���jRJ�bx�5#���xB�u���hi�.�V^+b�L��Y�n\������N����a���+�be���^0f���{������0�#j�Fy�C-�-5U1���2�%2gm���������h�LM�nL�fR�ot�y-�C0\
�|�����5��MU
z�����aZ����������V�(����tl�y�����U-'_��Z��������xT��E�^�b�4J>����/quG�h�,�C^�b��XS����f�����T��abm���������5�j��sW����n�]������h�p�0���\6A��v^��i=WZl6�9�Qa�~����]�����?���/^$�\�v�c��3��+�������
Z-]�t�C7_�?NMr���R�D->���@�d���=��8H���@Su�i�|�����/$[L��uM�w#�d��L��[C/�O���9�{?�d���7\-��w���1$����+y��\}����<u�z��nD^����
�R����������%��v�u�y��o;�I�Vt.����n�j��7t���qR�o&��Q��Q�l���a��I~�g�t�:}�P�����Th(��d�l�7�^�!W�-�
��[���R�����i�5v���@��$�|�7S�0x���*���&St��n�'�,_�j:��S����f"�WN'�,�F'�F���$�N'��
����C��;�}�����s=�{�����8=���Y�p���)=xNa�����S�l���c��$�����89��e�����0�>O���)���K��8������?\= t8�-:@5��a>��|�b�^v����"M��������6�wn���j~�a��dt������p�2��:��Oe8{!��s���S���jx��{�W�c�lN|a�$�����8%
Er<�;z7+���'����.�FZ��h��Y���f��?a�K25�te7��7,���J����u���'�J�i4�W���c���	AD��N���7�>p����^������9d��G_���qLnZ���A-�V�
u=���y{q�.���0;����l2�V`�('��(pY$��x�p��Q��O��������wufe'�����]FuN�A��|(�s�������#���'��T�������i�!���5��q(>���T�q�QS�����$���!g��&���#�YF��b����v���A��D�JS��Y.$ViFn��P������&T~ycz�1�����������)B�B�����z�<�T��3$��KW��M�>Qf_y��: z�c�����J�v��6���$D�U�j�H���L>�G�-6Zq���������.�/�}��K��JZ�es�qD���Rh�i��s���2>��Ys���M6��H�k���h
���?����m6N:h�?���]������+���_^��<}ws��W�����������;��2��.����=��g�&X&����do����n���.����&�?}�z�}���]�"���>�@�xj�+D��e��. �m���M���F��+Z�$M���hW������2Q��P��,�����3,�Mm�KM�+�T~v6V����7�,n���p�$m�������)��4�Z��n�����X�����\sB3,eFJ�-R~�Wd���{������U}��	��$.'��VE�i�rQW�%W��n��U�������YNlO
|
F7(0eY�,QW�qi�[�*V#�N{��S��kl,��~Qg���x�(���1������_{�wh���1�HE_���������L#�M��.�z���H���O��nn���l{
V�>u��I
���?���P��������;9u�g�2�C$�*>����}(S������g��G���t2t������� ,^'w8
���p���y�[���K�����c�9�p6��&����-�L��7B-�b���i/�)y7��L��K��ty����N@�
i�>��o��S�W�W:r��;�E������T�<�?�9s0���Q@�TC��|��~�Cv����M��$��,�[V��r�\r���u�*w����wgU��������_���o���#KK��x-Am�L���E�72Y[?���V�|�X�)5��^�a��0!R�x��o�4����e)@`��D�X�%��%��%BX��e��CKmdI#K6���.Q]�����K�t]"K�d������K*��)�r����F��P&��^���#m�������"EY���?uU�� �Q~}��E�x��t"Ki��W��D�Yw-�J�B��V�"�zZ�"�
U��������m���Ol�A*�H�jDL�(��:,u�R7�&Y�.�l��.XQ!��p�!��3�C��H�F�}bED�JQ�)��J����>a��>I9����G	��+3$D9�)��=H��+T���S�G�L%a�-�j}
�S�!DnhbC.7�N�F�<)M"?�dY�Hy�'�&��&�O����I,bEo4I�I6h�=���$�&y��D�B��&��z���4����DV��W�I����_qi4�MR��%���sU�l�	QHt��"7*��*H��uWA2N�U�,��%��QA5VA�N8���p",��x�}:�k�MdW���L�}9���|S�R#W�v��e>�s���`���L�p~����N��%^����Z_���=��������c[:p������'��*�
�c4{E���m1���a��]��Ub-��s/�C�F����5���]}�F'��`����q�c�|����<��W�9�u��������7d�&�hm��Bq��u�0K�e����8Fs��bh������S��
��P'f���2E�����W�J�#[�������W=~p?�0_����lW��l�0
O8T:�=ici��d5#G�;��aIZbEo��#�V�h����Y���~���6�1��H��u�M���L<�D��d��z�&��|QFN���	�\���o���R��?�!�fE�������PYJ4��R��_>C�n�������z���_��}�F=�Eg��3��i�EM���� B���b�dh4�����^�5��P����h�Zh����>q�a�2�j�_��[�����*��j�^����� "�H9���&�\�HH�X9�TT~m#rj(r$��r��=aDT����6y`Z����������D2)�J�Y������^�Y��X�714�������4�X������j'3��l��T	����'[e��+W�K�R��[D��1��[+����q�=�n����+��������z�Y���-�|����2n8�������S�t�����Cf�K1U2�����y�K<��Q�T�g�(��'aZ�y�����Y����\2s����mK!us�������^2:
���c �GJ�����c���a@�DjB	M��<t��s�����^HYO+��s���o\���������)*���=�#f/�EG�z���3a,��{p�;5�:;0Fc#��w�8}!ah.��Sq#;����k09����Y������ab�I���zb?Ab<��������
�Y�Q��:DPHE�b�#�k�Q��"�����k��cG:�|.V{�o��0�^���xq{y��~}
�Z4�@�#?b���)bs�y�,��GX
��,��!�s�����/��Z�U����\c�y�x +P�c[�*�V��8�8��-y��DJ�$�vU��"�}}���LH�"�6	�N0�D������Ad��A����0�C�����O\I(��(?e@&������H��!K&h����b{c�xqy�����v����H�]n�4�%������O@H�ebY���Y�L4��.�`/�M|���TY�h���������F T��n7X����
�PO� ����W �h��?<����>���$�~R��H��d
�j#IK��\�H�B{Y�H�<�h7����D���� wA��
�R��WU����O�z�f�������;,|ICd�g��O�+�m���`p�r��'�����+:t���W��DXs���jE���nP�#D�TPM���g-�7�!��v�=8��yj�����XOo����H�' %�o*�$%���CgH4RB:�����������A.�����>7z����zBS!6v^��;Q��D��M�D�$�R���FTH���������a����G�*L��KUR����''+$dF,�
I��&����N�',+L����h�=�� H����OD���H	��]�-%$i�L)�6R��R�"�����t����-)���1!�wN�l�D#%$�w]����U2���H�K��T{�R+&�Hn2f���h���Cb���l�:Q!���E�$��)*�FT�XTT��l���7�nD��!*,��I�lDE�E�)[THR-���hDE�EEE�=aQA0�j����
�*T���6i�������d�
I�%SV�������H�',+TbMn.E#+$���N�}���j��GM#��e���j
T
������)cZXs�$mz��1��R���ScS�kE*�����"F��!�
	��C����a�Ht ���4��?�aj����E��z�cP�V	��g���	�u����	����&�w!$���7��|�O'�{�5�P�GJ�P�P�I�"u�{�C|���H����`�����F?��45C��D&4z�I�	�;p.�	�1<{�FO�EO�e��XO`"��FO<:=a*PW��e4z��"]��M����$��q��FO�SOH�~�+���&>�����D�����j�^Y3����bB���M��/��/M��~��s��~�$�6�����z�I�|r��=CT�x���;p��5)b<�}x��7�\��7<e=|�at��1��q����������^�8��OP��j���#� ��X]�"=M�)��2���f�����&�UH���{*Y�	��B���6���Y��(�K*��v��O�""b���_x�
���O���}?|��~��������~2n!�������a����B���������f��2yH�.#w����V|j�����[�����-,32-[j-��_�_��W���^.�9~�j��D�m�?q���N��[�F�2YT���J�lc*�%/|��|
Z�Q�7�	�h{������z�u��6���>�:���7����nn����j������0���e�l���+�9e�"���2hTk|*�J�!��	y�~�}���W��������"����k�e6L��L���&����,��5�r�
D���9T]F�aZ4�c��a��:�&
�����]�fo�����>W,�����
�Q�N��YRm�9N�+�����/3�%h.���h��`�
A�+��2�-bE����+:��3���oH�:�����n9�S������(���s���oo��V����<�8��&@�1��n9�Omj��s���:��Tc�8�]Y��'�����>��A	.��%
��hv��~]/�}D)����)��,r�&�c^���n��zQ��%�O�� W��/��d�q��T�L��8�%�U�J���c^��\�]�w�],���'��1���A�N�{r}��r�	���"��/�	rqGX�b�0�H��/�"<#Z�|�g��217�yo�2e��6����1�qG���+:���C��"S��
[X7���(���0��m���~Af�'�S/���DQ��1+B����*���}�}��o7�6��FR��n#�FZ��n�}(qp�>l������&�4<6�)Epv�<��q��Ap7b��h�����zX/����/4L�u��
�<9e�B�x���t\s���{�����������;{��l��#_8{o�=BuN��#9[�����W6g���w��D(���{$�bK��������=n����{@�,7���G�'Js������k*[�#LY
��2���O�D�i%��4���\*>g.����T|���R�i�|:s��.a������t)�n#�F���n�=�\�0f>K!p��.v�r�].����.
�5g����w����OK���w�����\|��?1{�r���w�����\��a�].��1�{o�].>��w�����\�!��c2����+>�?x�xByI�itN�'�����Tt�N�[�����&��G�Ofai���`�]_�~8}����N�X���/?94�D,@L����|(F����m3��mN��?;����Vd7�$04v'N�����F���S��KK9��,���b�wV��Z:K|�����!�Z�iR��#����P���)@�\�LTT�ET��FeiU�������ROQ)�>%�n�Q1R���{��&�qqm��z�}���		;�������4Pt��<!�j*2�f$(r~"��dr�C�s.@}uV	G��'aM�f�O���[�~~)�O
������#CU��7���UK*p3q�m�T�\\{(�/�!�+�5u�jjl�4�����,Z
:�)�EG���E�8�B�2�*��W�Bd��T�;9�jjo�7"���J����Z���A�A���2��Og���G���{(�������Q���b���0�0��9z9Gx�	����f��g/�����RR�mnW���LS)2���Vy���P&:���"���0�Cf.Xp���.�J=�E�$���U'&CM���F�&$d����Lzi��d���17�d�v�<ka�	p�`@/m���5�:�X-����n)U8��`�Bq-t���� �Y0 	��}�[�N;&0���LH���L��h`Ch�.qJe�����&$=Me�q���
!�

�����QS;Y��H��e"4�i������@!&���]�$d������������Y�s��|����Z�����:�����e-���t�����B�_�����i3��h����c<��4������?n�*����o{C"��}Cr��o����!��EnS���(�����g�NN���p3-����B0��}]O}�D��1
�$���4�#�y�f6~�j5��x�~4#��,�%]Me��`d*:�D.:�H�^*==	k*uD�(J�w���FJ��e4@�P\�t����q�G	�@��>����XWv���vJ�_��:��=H�
�8���T�\8X���~B��T��� �����>��@\oo���3&��Ibo ��J��W/�d:��kLBf��8�ci"��":����E����BZ�#��u@5�W����j���������e�@����8w�/�^��b4xI��a�������|�v[�!������/����=~+��X�VRo���Td������gCbe��kS�T�\|���zk�De���I�	�8f6�/�9R����O[��
O���{O��R�s����(�u������0�fg�m;�<�S���+dg8�VQ�a�7�%�����I4Rn*�O*o.(������455f~���x�f*^���%VM�M9�K�������T�r������9ON�@�������7����G�'�����QH���QHm��"q�x�S�������~~&WI�>�;�H�F
}���*}j6�vzPb�?l7!B����6����+E��G��o=�R�n����{�����������M6���L��#�C������_��{�]le#����������k��?����Q���>;����J���r.���v�����R�M���4���|I��t�*���j���[ ��\�������A��7�� �7�f����v~��y������_b���K�N�{��7�^z�-���CD|�o/�K$)�'�o�M���@��3��=b<y����z�5�w`J[����wq��4,����>9���&����u.b��K]���R����Y�v�G�dW�zoE���m�Bc������Gt��zoI�CT������)�r��S?���zJ��|�*o�6 k���Q�pw���	bH5�Ur�6���g�>����O�\&7�a����������,N|�`k9n*�����;��#�m���9�����t�m�+�h�����M��B�C��=�!�	}��0	�CvOH�0��1�
�������u���'�����_�����&���\h�,���'~U~P0x��sy)r�n�=��qr�}������^|���+�������uw;F 	���z�\8��C���y����K����7/�n�k��\���������\���AN`��o�M������T<��nh����z����}{��d������j��NR��S?�%����;�R��%��eF�r�-��r~u��"MM�y�w2e�x��:�pz@k>
 Y<�����;����W����
���I�i�m��[������my���s3�����d�1���B"�y��+���3�g�U��$%X�4�y�@�}����uRY"LN��D�,%
�99E�B��j9_�E���h�^�x����yf��P!����������b1��+��~�����p����}�Yn��!����s���7�����A�!�HS�:C���d��L0,0�#��8�)�{P1��y�2�����G�8��N��#�Vsr����q�0T8"��G���x��#�����^�2�#RA�I���,=Px�G�;�F���tT�v0�!��J�(��-(�Gu+i����)Z��Q��P���I�#����D�ih�!��h���F`�A�
�����8b���,�(��$��!	���<�w_��I @��y�"��4�hJ��D�nNN���6�$�]�
I��C	�C	�}�B�P"��P$�����E������+O��)<�Q�x���e��P2LH�d68�����@IO@V�c����%�AY��&(d��"�c����	g�1D7m�&D1�l����H�A3����5�A
�f�n���)Z��14��Wbh����c�����Yd����_��f�O)|b�
(\`{"�K8@����q��]�|��=9�am�uk99E�B�8vwJ� B8,��I"A�\�D����$?H�A>4�0�i@W$��}��Ia�e���$o�����:��xh!���$a����A��Aa�BMc9=m�D�4h@�J�q�
F
���d���!ud="|��r��F�1����f�J�r�}o�	H�p�!F�p��l�I���l�F�sh�F� ��[Tm�D�<�0s���Q��E"dfY��
I�P�D��!BY3�.������$���I��1q�l��$Ix�Y�T6R#W%5��u��n>��m������C�+�+\13Y�Dh�	�����5K����!a~�P���
�H�6L1[�$���DI29"��]zY )I��*����L�i2m�
:=m�D�8��wJh�rh1c���2��J���(�D�=T�=�X���@��I��,��d��,��dp��7J�-�v��T���zt��[�^���5X�$���r%����J��u8VQ��F��F��n�������u"nP��{%���>
uh6�(�mB�1"
�QP`B��jO
T1��|I�fq���oL,��O$������D
i�����i['�����Pa	JS������G��)J�$!ShV���x6<v`4���u�./����L�q������c���0An�W�0��C��}�����2&`1h&`j['��a�P�����+E�_�5��W�e��1b�)F�=1�#���	
�[\[_����
b��A��� F�RZv��0����N��#
x��D�#�Q�f�q������$:F)�f	�F$MT^�$��)���/d��-���*����c{
���:\a�@S�:7�+�H����W�-�nLEW4����4p�+f�!�w���WL�v�7\���w�G(dJFm���5�I�U<xI�z����n�L��E��NO�:7-���Z�Z�Z$������c25��?��)��]�LaM�P�4��2?��'a��Q*l����t!S���|�B���,dJ3�@���"�B�d���d���=�(��*�Z����LV��u"nP��*J�Og�:1L�E(P0����P`�Q��R��
�(Dci!�`��B&���XB��q?A7�W2Lc��6�6,������N��c	x���!I�p�4�:�4���h�h�9j�O�� ���D�~�Od�������4Y�fu��p<��m�7�0�
D� �|���v�������u"n5 x
%j�5/n=%��n (	m��$Y�����!�~���)��
��W-���4Z27"��[6���$�z�P�G#_<4M�m�a0��m�����B	!B!J�%���)i���|A��Y���D��q
�p��*��}1A�"��&������m,	�f������M{i�0���m����F�#B�qB��d�\�1�����q�����F�)��~"�.(�"���F#MZ�Qs%�=a"�$������J���4��A�����u"nZ��%����0��������Di[���$SH�L��(�L���#��Jf�JJB?a�)�xo�
[���o��I28�B&���B&��62I��-d���	��J#��iD%�2vQ��Y���aj['����4���!Bg���4��9=}<�
N��F@���I��H��
�N�!��t@,�:.=��1�����t�X2Lc�5l�mX�a7��m����Nc�z��{��\��C�k��z���f}�tu�����r�y*�y*�����[N|�xz�^��o.������\��.�\����h>C����<�����1
=������O"�DQ�}��ap\�E�s�3�$(~��j�������~�����W������������o�)��U���AR�;���K��������p-����/u��k����X��^\|��?^]\�b���������l/�o���W�w�X^^�������_�o�����e�eNN��n/^}����)>���e�vz����W�=:;��W{�gg����zus�����Y�����S����G���x,��X����X������1;{�?X<H<Y�R�M9���M���U�}"w���������[�T��'�On8�����-�\m�Sr�������OC�~-'�N���_�R=����W/�
��wd+�x�w����p5�:Q��n�0�36�i����������')�����?�}����$�R��n�<�����/Jjl�(��^��nG�g���r�],�k��=_f��/x�S���<
����(����4�zY���1�����y���z)����dxav��8�k=�1�xU�=o^_1���H�`��2������D6R�a�Y�����`23���E�k?Lu�B����wP!�(�:z�*Q��/�(�C�CB}�Ih��������A�*��u�]C�O��'�D�.��N$
P��C�*�@$`>���X*���=B�{U��Oz6p�����{����4�g��]�w]�T�`�j�p=_I���#	�
e��r��r��(}�������0�I_G��|�@�g9�A�pPE0H�g�`�@0H-��-���r�o�~�^L���Y.�s�6s5 sz�����3�����:�Lw�#��'�]������v}y�����W�;��'g_K�V��^s3������5�k����;��W�����VW���:31o��VW��b��w�^�L�B 9��$�	����'!%��� �)��\>x�|�m��J�e�Q���]��_���$����[��x�V7B��|'�3�%�r��Y����MlC�������������I����|��^E��������w4�T|7���j�����������3����%�cY�}s����h�=����jZ|T�%���m��|�����l��-S�d��K�=����,8p3,����c&yWAN+u7�~<8�V?Y�!r�nR�7��W��k39�+M/r�~��]�o^�$}k�h��I��i���Q�h&����I�I��&B�n��DS&��bj����L
�89U�B�t��+(l?��%�f!zd��}���>!�a*4p�������*h�����\�
F�r�.hy5��<h�
h 4�	\�P�C
��!����`I{F�C
���l���H �����e��`��
!aC�|����`)�C
�5 d�VQ,i��u��R���{�Q�N#��H�P�TPC����W��	j��Q,Q��P���AS��1j`�'�C
���N���WPVp%�o�/������C)((�9�QJ��R�`��D�X�R4U�m���P�A�����7����C����g����?�U�R���������|��D|��������W��h/�_^nD��F��y�������%��jq�������x���������P���+���w�(�?�D������G�N���_�x��w�3�9����mub���I'��/Z�e�c��rm"���������K������������V���,
L���H
�����������
v_�*����5�a�6S���L��*��6�K��:!����i�n�|+SO��5��=,�W,����c���^�x��|�G\���_Y�}�._���_��B�0�.���m�X/7s��w�/������������$
U�y������	���E&$�:�ef��a3�����<�k�kb#Z�VSE�����pm&��3{~����;����r_V��Q��r�?3����R�c�:��c,'�z7�sq���e���A����u���z�������f�=u���x1RLY0���&}(� ��D��������f�R*���)�����3��x]�[#t�t7��tJ6G�M���pn������l!
{��\L5�B�t��7P���{p4�����\����C=4��lp����M�������t�]����=�]�l��J���}�`�@���R�:�i����4��#��oNezd���S��2E`<��M��vz�,x��Q:��	;�x �!����Q�����@����@?k��>�T�.�M�x0(�Xn.���O�E^��b�\��6��rE���g�D>��nH)6~I���OI%6�i��>�;d�S��I=X{Q�t�O�������T!��N3'oon(�t��Y3�=(���Q����v{��TW���'�����d�-��o��P������[�>�w����&��y���n��'������}~En�oo�o;��]/H��dI|���������'��U���P���se� ����H����-bm��g>M������T��=�A,��{�8���n�������'������|O|�����_�2�C�
��*�7����S��5��$����(��!I�5��h"�V�Y���3�v��@1t`�-Lji.^f�o�@a�;)r�� b?$5� �p0�wh=��
�U��A��
T+�!�j+3I�������s�=�p�^��������\���:��K�p8"�o���q����u��"����W]~����Z���������������J�H��V#��|����T+���~6�y3������U��L�
�.)v�I��.����F��X-������*�0K}�H�	L����X�/EV1"zw�c���M�-+����.]��tSg�e�%w���t��Z�mK���'�]�|�_���)>�yiS|���L�va�&�,����w������q����W������_�WCE^�}�1�r<Z����f3y6s��Gd+���������'��������
���Zz��O�^�M�t�����E�`L%����^���E=�����Gohf��}�������*+���R>����g�.����'@=L�R.Et*Q��:Q,���,�X���&�[
��<a�0jP�/�`+�x<(����Y����Hc�^0����^/&���/v �]�`p;;}�d�Vg�"T��b#��v���)���PK�2��u4�$
��A�
����p��P�09�q bh�I"I��D�� yBfi�>��!��H����lp_�14�a�{�1�S�4Cd�1�W�b�0��D��/�������(A���Qf3�1�}hh
�:�MPV|�Y;5�4P�>w�C��`�rLbc$���4�a�1���u�m~T(����7[/f�a������0I�itN�'�Dq���4VJ"CSa6��A��OX\��	�����b��D�_�U �����ld�o.�j�)�U���C�*��h��:�I�;u�X+���S��}�{m��������)H�(�>� a}G�Z
t����r]��A�;)��j������V[�SnZ���~��q�����g�'���m�F�����+������z�{������J�y>jkx����u�Q�2�]K�!9;�B8���������G4�|JH�����p�p�F�4������{���w��[�>Y���/�����?����
W[�	�Jt|}�@}}��������2���p�e����k�2-�j�2K|�6��N-M��H}__H�_���_  W$�)��'�,�O�mR�J��� ��B�s|��v#[��\����� �����t�8��FJ�,�P�7���k�9x�QuT'F�xw|���h�Yr��������A�+4��o���[������F[]#�!��v'���_&r�>
C����g�f��q�|��=_�83A��5]+�����a�l--z�X��/:��L-�A�n��
���	���=�gC=����������b]hw�9�O~;~A2t��;��#
�WM I$+�^�����FD�&m$�I1�HT�
�w����������I�C�=���Hb�1�H�0W1�Z�T18#�/\m#�Or��D��z����K(pf�V�+�d����VRS�����J�aI$+i����$�VZI����VRS�����J��/�0c�I$;�4��3��IMsf�3y��d�m&����L��LZh&5U��Ik����L��$�V����I����93i�������U�8����cj�����TT��P�(X��NA��e���O
>�p�sU#�f�BW Yo�)��I�:�6i&mTM�F!p0��1�VZL>�]w�����y��J����y���aP�	�wz-8������?�5� �1e����)}�$qL�0����,�@k�9��;Md�Bh�7���B���1j������mz?\� zEu�b��b���J�Kx�S�������~^Y���|���YG���s���YH@WI	}BfU-	�&'����PS�VVY�}k�%����U�gX��V�0��i�]���
���dw�\B��%��
�zu�����u2�|�vM�<��#O�*��\������5?o���nlW���������=j��z�N���*�+��0h�
9���!������'��U�I[�lT�V��DSc�����B���T�y�C��)o&���;,��i�j��!,m��c�$��p��c�����0�'��.��Y��g�~��}���A�c.��>W,�����V���$MkJ�@��P���L�(:�PU/�H���|�
NBz�:I�����?�`�h��pq�=��8+_J����Y��.M��]�0dW,+W���:�VTe�L-��G��h��C�~�=>���>�T�_��9@QDH�$@{�����u	HS�([Hk7���v��{��@�x���T�h����� 7�*��
�e��l�-�(�&�/�&�m� ���d+� U������-�G���q�0��S�.�M�����
�����Ff��}����s���P�3b��8q��D���o�z�9a�Q�� "~��������'��#P=p�^!����D9�x�!�����_�~�� B� �U�,�2�	�!�"8q� ��H�@WJ!���jv!D"����9���^������J�]��	�(S��.7:�����������jxky�c�i���I���w��j�,���gV�3<d=CA���d�9j����rda#k$�~���C��!kM5�B��m�����]�_�����x$=�.-Y��3oIw�����p��_	��=�]n���3��}��n3����
�oB]I�Fu�����f�WR3[����g��195�B����!Ku%E����n�����Tu�~9�Y[p�t���?k����N�������=Y����d�
 ��r�F��t7��7%#���yi 4�a
 ���(��L5�B�4@��J� ����A+������:=z�������ai��	Q���|8U�h���:��^�S-�XAQ��@���H��T5��(1�7���B��^?�������>^n�B�s���I�f�Q�k��$���s��}����N���+���5�"���������������w�EG3�T|�v��Vc���:#��iF��-�hA���N��4�=v7�hM6Y�C&�J'�cR<�"�������P���*Z}�N}��g��]>�����g1����6E�:�]s�XH;�����'��k�
��h����	/�e0��5G*:^�6��v���h�u9��%����lba?=\���a�$���������y{�a�r������v-���?�����������ti��*c�EY��L�N"�P?;�j�
�C[�f3����'���SpG����*51c��c?Ov�wT��zM�!$���I��3wN�e1�Lv����:���Wg�i�V[��)Klv��-P:�4��)X��U���@@�H��V�0��d�\6x�S���<
���r�A���lc+�?{���(r>Mc�mq@a\dc�-�����t�P��!c^UG��P=��*|V�Ar�����6L������������f_x��nunuv����xw��P;�q�S��:�����2"������gg&H��fh��2�08����E�X�������"U��rb9
��s��c�1�h�n�z�s�o	�T�.��%��'�� :5������3��$�>������$��M�H��b$��>�>�|��a���iw7������-F���F������0���I}�jI}�C�$������_B��0���Hf�@�g%����*���5V�
K"YI��d�m%����F��J�e%5U�YIk�dk����1��D��J393i���T1g&�1��M&�f�+�d����fRS�����L����L"�a��L����Lj��3������I��^U���	J���'!r�c�jF,���Q���1\<6�/+�N}�P��n�=o�'Q@5��u�5����@=������;7B�pAwSJ�F!p0�;T:L>�]w���~�ML%�B�t�px�0������.�Zp���)�����|����$N�=�X��d�+��<�H���@��r�������{���O��p��h��I�V&,jrWY.�
~��=�>���+��h�k�4�:�����z��C��,���������%��y���Zz�������_Rn�z�(�%�!/Z{,�H����������z���M���L�Ci��B�F�&�G�0r=� �C]�����%�$`����??���7���m����o<����8�_s�z���=?����~�Y�9��RI��!����������bF���������~�f�s��[QL�N�`C<S��m������N�r�F8i��'���Q���
�h?��w6L����m�gmxo06����
�8��1�?��}����8��'4���Z�Ih�>C�
-p=�����6@#3���f�O�-�3���O"����va�d���	������}�BS��8�-H��A^��=^D�O�^8��F_����9�������9�q`�H^������E�GWu'�;�<4�^PV����9�>�=C@��w�%f� k���� ��=����h�Y���m3,#�mo<��;��p�rm���^!E�Q�����B�(�I8��BAbh!�����;%����i����E��f����p�n�����
���/?9>��@��\s	��mNa� �3��1���I�=��A�������e���L�j4���55<�����y����_���I����v)H��*[��v�k���n�oo���:�*@B�J����!�c� �Uw��S^�
���,:dRe#m���1P�J�,T�uh�vi-R[��0i���~��Z������a������Q�x�6�P!KLOI�y�;,cM
����^���Q�3��=����w,Dp@1�"����rI�zD[���ZQ���.���#�W�KK�0��5�b��Cu\M'��2[��p
��x-~�y���N���<{!?o!�L���!�.�*�}����
)�C>�P�.�����1��V��o^�KQ@E=*z�!l��'Pn��s�xH��#T�J��e�e��{-����C�^�#v�I����u"n:��w��D�1<�����"J\��_	��q�����S�O""o��\�W����v)����"r�8�k��%���W��`	2P��:Xb,1R@{�aI��u������-���p��%S�%�*5\��|��m.�� ��e\B�	e�L�t{�����j�5�Y�V'@�o������Nc���$���v,�P�R�BXh��4�a!��R�p�y�kk�|���O�����>�)v
���L��CD8��pB@�#i�y��Z\\�����Ya���3/������9��c�����oi��7pg}y#����{����{7�\�Y.��Bf�U��G�,o1��(��:����0C����=�S�E?��S�I����M*:�6�}y��D6.�d���
��b�I����n�8�m�AXD�=@����E����	�t���E�)�X4�����F����c����S9���� ��|�����f���c7'����kP.����{vb��o��XE�H������4�������������a��M;��u"�-�@_�.W�f��SD����N����)Bwy�.W'u��]�;Eh�"�pX���/t���I�����v���L�a���H��u�0I_��0�3M��b���`#1�2\1Bj�1x;�{o,|p���yo�����9�=!�mw�tpR�����d.Tj���2K`C�IX@�H���I�$M��D�h��>Z�\b���!��A�
#26Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#25)
Re: ECPG FETCH readahead

On Sat, Mar 24, 2012 at 10:49:07AM +0100, Boszormenyi Zoltan wrote:

Sorry for the delay, I had been busy with other tasks and I rewrote this code
to better cope with unknown result size, scrollable cursors and negative
cursor positions.

I think all points raised by Noah is addressed: per-cursor readahead window size,
extensive comments, documentation and not enabling result set size discovery.

The new comments are a nice improvement; thanks.

The problem with WHERE CURRENT OF is solved by a little more grammar
and ecpglib code, which effectively does a MOVE ABSOLUTE N before
executing the DML with WHERE CURRENT OF clause. No patching of the
backend. This way, the new ECPG caching code is compatible with older
servers but obviously reduces the efficiency of caching.

Good plan.

diff -dcrpN postgresql.orig/doc/src/sgml/ecpg.sgml postgresql/doc/src/sgml/ecpg.sgml
*** postgresql.orig/doc/src/sgml/ecpg.sgml	2012-03-12 09:24:31.699560098 +0100
--- postgresql/doc/src/sgml/ecpg.sgml	2012-03-24 10:15:00.538924601 +0100
*************** EXEC SQL COMMIT;
*** 454,459 ****
--- 454,479 ----
details.
</para>
+   <para>
+    ECPG may use cursor readahead to improve performance of programs
+    that use single-row FETCH statements. Option <literal>-R number</literal>
+    option for ECPG modifies the default for all cursors from <literal>NO READAHEAD</literal>

This sentence duplicates the word "option".

+    to <literal>READAHEAD number</literal>. Explicit <literal>READAHEAD number</literal> or
+    <literal>NO READAHEAD</literal> turns cursor readahead on (with <literal>number</literal>
+    as the size of the readahead window) or off for the specified cursor,
+    respectively. For cursors using a non-0 readahead window size is 256 rows,

The number 256 is no longer present in your implementation.

+    the window size may be modified by setting the <literal>ECPGFETCHSZ</literal>
+    environment variable to a different value.

I had in mind that DECLARE statements adorned with READAHEAD syntax would
always behave precisely as written, independent of ECPGFETCHSZ or "ecpg -R".
Unadorned DECLARE statements would use ECPGFETCHSZ if set, then the value
passed to "ecpg -R" if provided, and finally a value of 1 (no readahead) in
the absence of both ECPGFETCHSZ and "ecpg -R". Did you do it differently for
a particular reason? I don't particularly object to what you've implemented,
but I'd be curious to hear your thinking.

+   </para>
+ 
+   <para>
+    <command>UPDATE</command> or <command>DELETE</command> with the
+    <literal>WHERE CURRENT OF</literal> clause, cursor readahead may or may not
+    actually improve performance, as <command>MOVE</command> statement has to be
+    sent to the backend before the DML statement to ensure correct cursor position
+    in the backend.
+   </para>

This sentence seems to be missing a word near its beginning.

*************** DECLARE <replaceable class="PARAMETER">c
*** 6639,6649 ****
</listitem>
</varlistentry>
</variablelist>

<para>
! For the meaning of the cursor options,
! see <xref linkend="sql-declare">.
</para>
</refsect1>

<refsect1>
--- 6669,6728 ----
</listitem>
</varlistentry>
</variablelist>
+    </refsect1>
+ 
+    <refsect1>
+     <title>Cursor options</title>
<para>
!      For the meaning of other cursor options, see <xref linkend="sql-declare">.
</para>
+ 
+     <variablelist>
+      <varlistentry>
+       <term><literal>READAHEAD number</literal></term>   
+       <term><literal>NO READAHEAD</literal></term>   
+        <listitem>
+         <para>
+          <literal>READAHEAD number</literal> makes the ECPG preprocessor and
+          runtime library use a client-side cursor accounting and data readahead
+          during <command>FETCH</command>. This improves performance for programs
+          that use single-row <command>FETCH</command> statements.
+         </para>
+ 
+         <para>
+          <literal>NO READAHEAD</literal> disables data readahead in case
+          <parameter>-R number</parameter> is used for compiling the file.
+         </para>
+        </listitem>
+      </varlistentry>

One of the new sections about readahead should somehow reference the hazard
around volatile functions.

+ 
+      <varlistentry>
+       <term><literal>OPEN RETURNS LAST ROW POSITION</literal></term>
+       <term><literal>OPEN RETURNS 0 FOR LAST ROW POSITION</literal></term>
+        <listitem>
+         <para>
+          When the cursor is opened, it's possible to discover the size of the result set
+          using <command>MOVE ALL</command> which traverses the result set and move
+          the cursor back to the beginning using <command>MOVE ABSOLUTE 0</command>.
+          The size of the result set is returned in sqlca.sqlerrd[2].
+         </para>
+ 
+         <para>
+          This slows down opening the cursor from the application point of view
+          but may also have side effects. If the cursor query contains volatile function
+          calls with side effects, they will be evaluated twice because of traversing
+          the result set this way during <command>OPEN</command>.
+         </para>
+ 
+         <para>
+          The default is not to discover.
+         </para>

I mildly oppose having syntax to enable this per-cursor. Readahead is a
generally handy feature that I might use in new programs, but this feature is
more of a hack for compatibility with some old Informix version. For new
code, authors should do their own MOVEs instead of using this option.

The patch also adds an undocumented ECPGOPENRETURNSRESULTSETSIZE environment
variable to control this. I see no use for such a thing, because a program's
dependency on sqlerrd[2] is fixed at build time. If a program does not
reference sqlerrd[2] for a cursor, there's no benefit from choosing at runtime
to populate that value anyway. If a program does reference it, any option
needed to have it set correctly had better be set at build time and apply to
every run of the final program.

IOW, I suggest having only the "ecpg"-time option to enable this behavior.
Thoughts?

+        </listitem>  
+      </varlistentry>
+ 
+     </variablelist>
+ 
</refsect1>
<refsect1>
diff -dcrpN postgresql.orig/doc/src/sgml/ref/ecpg-ref.sgml postgresql/doc/src/sgml/ref/ecpg-ref.sgml
*** postgresql.orig/doc/src/sgml/ref/ecpg-ref.sgml	2011-08-07 11:29:16.003256959 +0200
--- postgresql/doc/src/sgml/ref/ecpg-ref.sgml	2012-03-24 10:13:08.679284063 +0100
*************** PostgreSQL documentation
*** 171,176 ****
--- 171,196 ----
</varlistentry>
<varlistentry>
+      <term><option>-R <replaceable>number</replaceable></option></term>
+      <listitem>
+       <para>
+        Turn on cursor readahead by default using <replaceable>number</replaceable>
+        as readahead window size.
+       </para>
+      </listitem>
+     </varlistentry>
+ 
+     <varlistentry>
+      <term><option>--detect-cursor-resultset-size</option></term>
+      <listitem>
+       <para>
+        Detect the cursor result set size during <command>OPEN</command> and
+        return it in sqlca.sqlerrd[2].

Make reference to this option in the ecpg-sqlca section, where sqlerrd[2] has
its primary documentation.

+       </para>
+      </listitem>
+     </varlistentry>
+ 
+     <varlistentry>
<term><option>-t</option></term>
<listitem>
<para>

I did not re-review the code changes in the same detail as before, but nothing
caught my attention when scanning through them. If some particular section
has changed in a tricky way and deserves a close look, let me know.

The documentation-cosmetic and policy questions I raise above shouldn't entail
large-scale patch churn, so I've marked the patch Ready for Committer.

Thanks,
nm

#27Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#26)
2 attachment(s)
Re: ECPG FETCH readahead

2012-03-29 02:43 keltezéssel, Noah Misch írta:

On Sat, Mar 24, 2012 at 10:49:07AM +0100, Boszormenyi Zoltan wrote:

Sorry for the delay, I had been busy with other tasks and I rewrote this code
to better cope with unknown result size, scrollable cursors and negative
cursor positions.

I think all points raised by Noah is addressed: per-cursor readahead window size,
extensive comments, documentation and not enabling result set size discovery.

The new comments are a nice improvement; thanks.

The problem with WHERE CURRENT OF is solved by a little more grammar
and ecpglib code, which effectively does a MOVE ABSOLUTE N before
executing the DML with WHERE CURRENT OF clause. No patching of the
backend. This way, the new ECPG caching code is compatible with older
servers but obviously reduces the efficiency of caching.

Good plan.

diff -dcrpN postgresql.orig/doc/src/sgml/ecpg.sgml postgresql/doc/src/sgml/ecpg.sgml
*** postgresql.orig/doc/src/sgml/ecpg.sgml	2012-03-12 09:24:31.699560098 +0100
--- postgresql/doc/src/sgml/ecpg.sgml	2012-03-24 10:15:00.538924601 +0100
*************** EXEC SQL COMMIT;
*** 454,459 ****
--- 454,479 ----
details.
</para>
+<para>
+    ECPG may use cursor readahead to improve performance of programs
+    that use single-row FETCH statements. Option<literal>-R number</literal>
+    option for ECPG modifies the default for all cursors from<literal>NO READAHEAD</literal>

This sentence duplicates the word "option".

Fixed.

+    to<literal>READAHEAD number</literal>. Explicit<literal>READAHEAD number</literal>  or
+<literal>NO READAHEAD</literal>  turns cursor readahead on (with<literal>number</literal>
+    as the size of the readahead window) or off for the specified cursor,
+    respectively. For cursors using a non-0 readahead window size is 256 rows,

The number 256 is no longer present in your implementation.

Indeed. Oversight, that part of the sentence is deleted.

+    the window size may be modified by setting the<literal>ECPGFETCHSZ</literal>
+    environment variable to a different value.

I had in mind that DECLARE statements adorned with READAHEAD syntax would
always behave precisely as written, independent of ECPGFETCHSZ or "ecpg -R".
Unadorned DECLARE statements would use ECPGFETCHSZ if set, then the value
passed to "ecpg -R" if provided, and finally a value of 1 (no readahead) in
the absence of both ECPGFETCHSZ and "ecpg -R". Did you do it differently for
a particular reason? I don't particularly object to what you've implemented,
but I'd be curious to hear your thinking.

What I had in mind was:

NO READAHEAD == READAHEAD 0. This will translate into 1 tuple sized
readahead window that cannot be modified by ECPGFETCHSZ.

READAHEAD 1 also means uncached by default but ECPGFETCHSZ may
modify the readahead window size.

Values greater than 1 means cached by default with the specified window size
but it can also be overridden (even disabled) just in case. This part can be debated,
I agree. This is in add_cursor():

-----8<-----8<-----8<-----8<-----8<-----8<-----
desc->cachable = (ra_size > 0);
/*
* If this cursor is allowed to be cached, the readahead
* windows is also allowed to be overridden (possibly
* even disabled) by default_fetch_size if it's set.
*/
if (desc->cachable)
desc->ra_size = (default_fetch_size > 0 ?
default_fetch_size :
ra_size);
else
desc->ra_size = 1;
-----8<-----8<-----8<-----8<-----8<-----8<-----

The check (default_fetch_size > 0) can be modified so it reads
(default_fetch_size > ra_size) so the override can only happen upwards.

This part is policy that can be debated and modified accordingly,
it doesn't affect the internals of the caching code.

+</para>
+
+<para>
+<command>UPDATE</command>  or<command>DELETE</command>  with the
+<literal>WHERE CURRENT OF</literal>  clause, cursor readahead may or may not
+    actually improve performance, as<command>MOVE</command>  statement has to be
+    sent to the backend before the DML statement to ensure correct cursor position
+    in the backend.
+</para>

This sentence seems to be missing a word near its beginning.

Sounds like a corner case to me, but I am not a native english speaker.
Which one sounds better:

UPDATE or DELETE with the WHERE CURRENT OF clause...

or

UPDATE or DELETE statements with the WHERE CURRENT OF clause...
?

I went with the second. The committer can change the wording in any way
he wants.

*************** DECLARE<replaceable class="PARAMETER">c
*** 6639,6649 ****
</listitem>
</varlistentry>
</variablelist>

<para>
! For the meaning of the cursor options,
! see<xref linkend="sql-declare">.
</para>
</refsect1>

<refsect1>
--- 6669,6728 ----
</listitem>
</varlistentry>
</variablelist>
+</refsect1>
+
+<refsect1>
+<title>Cursor options</title>
<para>
!      For the meaning of other cursor options, see<xref linkend="sql-declare">.
</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>READAHEAD number</literal></term>
+<term><literal>NO READAHEAD</literal></term>
+<listitem>
+<para>
+<literal>READAHEAD number</literal>  makes the ECPG preprocessor and
+          runtime library use a client-side cursor accounting and data readahead
+          during<command>FETCH</command>. This improves performance for programs
+          that use single-row<command>FETCH</command>  statements.
+</para>
+
+<para>
+<literal>NO READAHEAD</literal>  disables data readahead in case
+<parameter>-R number</parameter>  is used for compiling the file.
+</para>
+</listitem>
+</varlistentry>

One of the new sections about readahead should somehow reference the hazard
around volatile functions.

Done.

+
+<varlistentry>
+<term><literal>OPEN RETURNS LAST ROW POSITION</literal></term>
+<term><literal>OPEN RETURNS 0 FOR LAST ROW POSITION</literal></term>
+<listitem>
+<para>
+          When the cursor is opened, it's possible to discover the size of the result set
+          using<command>MOVE ALL</command>  which traverses the result set and move
+          the cursor back to the beginning using<command>MOVE ABSOLUTE 0</command>.
+          The size of the result set is returned in sqlca.sqlerrd[2].
+</para>
+
+<para>
+          This slows down opening the cursor from the application point of view
+          but may also have side effects. If the cursor query contains volatile function
+          calls with side effects, they will be evaluated twice because of traversing
+          the result set this way during<command>OPEN</command>.
+</para>
+
+<para>
+          The default is not to discover.
+</para>

I mildly oppose having syntax to enable this per-cursor. Readahead is a
generally handy feature that I might use in new programs, but this feature is
more of a hack for compatibility with some old Informix version. For new
code, authors should do their own MOVEs instead of using this option.

The patch also adds an undocumented ECPGOPENRETURNSRESULTSETSIZE environment
variable to control this. I see no use for such a thing, because a program's
dependency on sqlerrd[2] is fixed at build time. If a program does not
reference sqlerrd[2] for a cursor, there's no benefit from choosing at runtime
to populate that value anyway. If a program does reference it, any option
needed to have it set correctly had better be set at build time and apply to
every run of the final program.

IOW, I suggest having only the "ecpg"-time option to enable this behavior.
Thoughts?

I wanted to make it available for non-Informix mode and a way to
disable it if the command line option enables it.

But the extra environment variable seems to be silly indeed.
I deleted that part of the code.

+</listitem>
+</varlistentry>
+
+</variablelist>
+
</refsect1>
<refsect1>
diff -dcrpN postgresql.orig/doc/src/sgml/ref/ecpg-ref.sgml postgresql/doc/src/sgml/ref/ecpg-ref.sgml
*** postgresql.orig/doc/src/sgml/ref/ecpg-ref.sgml	2011-08-07 11:29:16.003256959 +0200
--- postgresql/doc/src/sgml/ref/ecpg-ref.sgml	2012-03-24 10:13:08.679284063 +0100
*************** PostgreSQL documentation
*** 171,176 ****
--- 171,196 ----
</varlistentry>
<varlistentry>
+<term><option>-R<replaceable>number</replaceable></option></term>
+<listitem>
+<para>
+        Turn on cursor readahead by default using<replaceable>number</replaceable>
+        as readahead window size.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--detect-cursor-resultset-size</option></term>
+<listitem>
+<para>
+        Detect the cursor result set size during<command>OPEN</command>  and
+        return it in sqlca.sqlerrd[2].

Make reference to this option in the ecpg-sqlca section, where sqlerrd[2] has
its primary documentation.

Done.

+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
<term><option>-t</option></term>
<listitem>
<para>

I did not re-review the code changes in the same detail as before, but nothing
caught my attention when scanning through them. If some particular section
has changed in a tricky way and deserves a close look, let me know.

Well, the extra comments should explain everything. The rewrite did not change
the execute.c function split, only comments were added. The changes in cursor.c
were mainly about being able to properly deal with negative cursor positions,
i.e. traversing the cursor backwards, e.g. with FETCH LAST or FETCH ABSOLUTE -N.

The documentation-cosmetic and policy questions I raise above shouldn't entail
large-scale patch churn, so I've marked the patch Ready for Committer.

Thanks. The patch with the above changes is attached.
Also attached the second patch from the previous mail,
in case the committer wants to consider it.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.2-git-v13.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-9.2-git-v13.patch.gzDownload
�@tOecpg-cursor-readahead-9.2-git-v13.patch�\{s���[�m�n @Y�-"�XY(H��������)3xf&����GwO�Yqv���u%6�t��>����z�x���O�hq%a��G2��7�������~���s_���~��m��lww������V��<�����;n��^��m6{/�^��l>���_��Pj�D�}�>:�t�N�s�98��6P����_g���Kq6|����%���sX;������������g�Ld�x~��o'�'rN���=������]�(��Z,c)�e����3qf��HB��Q� �BF�0�;�+E8�x9���$3'!
�����+�������'�s$qC����9�i}$���NF'�����Dja���z2�	$li�,���:��V�i�S�WC1������<]���g:�����s��)�E1���@$�(��,�TV^2K����a&������Yy�$\Ua-�lJ���"�&j��%��� �uC�BG��Q��f�D��E,�K4�2Q@$�����U^(v��D�s�Kd�#��TF��/���]�H�j��f�X������N��`��:\��7���NN�^��o'��;r�<<\2SE$�kN��^Fq�v4\����l]��������'%I7Y�����V
�l�f�K���!11���;���q?��&�����7��X�'�x	��0�@���<<�L�lr������)�2�/�Ut�-��]�G�~�1	��)��
�I�t��G�u/�l�{�;�����\���F5�M��@mB].�l-Dn�i��2�&��l���i�'��'���D$y<�<i��UKHm�Y��2L^�J%���S���������<i;�T���\�Qg��3} _G�%�G�����f\������|�vtu#.�7�b4|'��7���<^/��Ji�#�c���( �\����H��i�����92�5����tn$��9�S�{������e��B�I<X�z����?5����Uw5�@��V����~��u���T{;�N�sp����dp���6��I�I�}O�7����AKTN���.d|_\����8j�G'��Y�d�F��HD��d U���u�bK�&V�d�	5S�C��3}'e�&�P�SN��
�57������lV���3s��dW�����hz�;�w~��\�:>{}yqK�4���%M']������|���"e�xs6�����|=����\���������F�@	�u.b/�x8���~���P��-|��0`�����u��m�}������T��_\�G������fp�g��}�����//��4�!�]���?�����x=�<�.���-f�Ao&%��'���������z��R�Z�&��n���u���>����>���)��0�y�aT�C��[����j����;����r���{�'�����hLS�S+��6������*B�K'@�"*e��/�k�w\t��g	vI�X.��
� �����&>�G�Z���m���������0��Ml!���g����������Gy��e~e�w~?�|e���+3.��4�<d/W�)}%�������2(!dq(��
�O,r�2H��v�EN����,����D��n�}A:Y9���d6��2�N���H>u��R�5�d0��M����$�&�v^�fd^!���
�������cd�:���B�s�z";�6bh���w
�_@���)8���7
e���>Q��W���G�l�%��=������U`%';1&bO� 24-*Ir� �&��3������`w�3��sf��x:�0aV��R1�a2*���Jg��fx����uzl��7�1	��|��(�km�:��2��lw��p��l��aAq!�E��,�i����q�������+�����5|����2����1���AH�/�JXCC6���mR��+��4s������{�Af���'�B���|-��(M�9��q���'y(��^`U9����0��_/��`�Uo��7�D�u�����f�����:���XA���)�����9h�����N���P��f���%�2�����u�����i��z����9am��N����v��:C���aP�g���!U`��U�D��P� `L5�,�S�����o��9��!8���{[�4o��SY^��2����$3�J
���6&��<|^���1?�Z`C��}b�4�=�4��f������Q��;8�vzG����_#���6bI�����MQ��d�4�����)������?2�*����V~C��u���q{%��^^�L�a�1��9x���~/�>;n2�$e����d��`j+�l��V0��K�+�������4l$��3��_W5p��;j��`yZ��:n6�?0;��7h������w^4:�n��ku��6���K
lU�`O���A�U�r��bF���%��b��}��T�6t]n
n�*?~;]�/�����m���T6f�j�~z'�]cv�i������4�}����R����	����3p90����s�]�[2x������������.��v��L-�5������B��s|@�	sL��n)s�H��������^������Z78�	U������/,���mU�)o u�z��/�X�2�B?��j3�P#�_r��+.���n�&�6���y8�����*�FT��+�1��2L �cjtg�z,�?Pq��b�����{t?���q-���:��E�.���9f��>q��E� c$vy;Zb�t"��	���@."Dq���N;�;�������V�������,���ciw^���`��|�
�Oq��^��d�b_��y�*c����_R�O�N���taa8]�J&c~T�
��]���.���ts3�]��1.�as_eT`�����l�"�$�	��� =��Z��s\aF�z ���,N@}hm[hs�3�"�j�
ln�R�dh&�J4y2�d���eA�@�G����&���kXQt�-�&���/f������I�$J�H��Y����>������P,��$6(!�
�R����DA(�+����w�y��&��(9�	���T+jb�x���s�=�z�b�H��:��H�(��"m��:f�[0UN ��D��g����f{|����M���V�m�|��y�'�e�1���WO<�5����9_��?i�:������)����P���w�S/5us05%�����5+MG�a�&t+��p�qH�0��@��</����>����&��^��TZ�=Y.*���9��H4nI�yY�s:�BF`����i?���|����g�-7bTA%<��� �����
r}��/�`%'|oMPlf1s�Q�e�'�Aq������L�0VTy�J��*�6�Z�
�;NS�Y]�� �5.�`��!p���]��$l_��(OI�c�P��������2#O�F��(c�,iHP+'Q\M������2(#g�Pz
�	]V������6C<N9g���~T���,C��~����!%T�>����)Z�H��,���e"m��$�����BD\p�B�v"���9}�~��a���l�`���&��s(UA��Z`�$�v}�U*[T{�})

""��e��\�QW�����k�I�����,*h��"^~��K���-�8	�I����� �&<���b��x�����Of�
.������2�B]���g^D���w���]�
0m�'����M[M'n�6}�:|fgf�aA��G�|�LUw�gW�R���Y.xI�u�9�)��I��c��^��Q���%@�*��$I�S����u4���:=g������J���9N�%����	9�F�y�9L�����u6q�"T�G�?I��9�Z����,g>o�!�-��&"�JO��h@�!��X-�0HU�}F�D��H���z��%���0���L�_`�iY
���cm(���W����"�@
%x�^����
��	�`2��C�~ZS�$�,�����^`�C	�d�(�[�T�����(��1Yl�i��/=29�"Ju�~%'��Z\+���o������Q/6��:go�d�`�"kGU�2����-�R��H��zb�_����V�G���s�|(������;T&r-�	]G��D��
>���ee��������N�f�o
�������q���!���xGA�m���P�2�[�\9G�s��_��F��������|Z�����cl�C����3#�MGq���������9�g���5Q~ �:�tO��x^0�Y�U��Vm���>k��@u�q"v�@�x�^���;t��a
����V0N���zK?��*���ulk���c+`��Kt��+���IR�gB���0��2�e��U�w'�/vA�I��%���Fyc a��4�hm�*G�����-0+��l`�
V�e"�(����iO/K�l}��-/6q0��t	"��HI�}�T!�Xj2k��Tr��;`]��������62�����mk��
���)�+��sI��~�����&ZM��HCI#���F���O�.f��u���j���dk]��h4�\
�+�������r#�`�t�r��v�ze�m���4��_A����J]&��s������K%������I�2I�N��Mbh�Y�Kp���|c����V)8�����Q�q��N3kt������.
�]��������n��T5��+���VW-eK�#V�����E�.}���U����4�"
�������:oz�H�s�1?x��6/|%����Y�Q����N%P�E�v����Y����k]"D+Nq�7�Cgk8ScAR���W�����GMW�����J��6`+�`q�VQe\�
+���E��T�}�|�0�Fa�������`G����e�k�c�����\���v�����vS`V*���a�_���i��p}7���LG-3����N�j��V,�h5�)}!W1$���^�T/"��Sk�5,�P)���o�{����i���%@K��U���DJ���s�'`�b|�3o�d\�=�,�j�j�>a���^������^��c>��f\E�����D$J>��p�m��t�����.}D�����,{�
3���iz���F^'�rx���M�W+�����<��,_&�n��y\��a�
1���������n���E6dn���
�o'Y�y�V�s���u3�8����`�J5�Z�%R�:�\e�
[�]Q��l��\�)�j'��NXG��\�9���Z���6/��n�t�������0��t"?}��i@��s��r/�1���;�a����.�s�&+vm��R 1i���p���o���������t���C�b���j�����O�t>�TXX]��\r�c�^/6�g��W�`���yR?����~�Q=���4-����#W��X�YWi�=$p��������K�)�������p�W.�����S�3�u���}z���7��q�;������w��9��E{�&v�2�;4o\/�9~�����^���w���i	z�K����J��&���y}�s����\-(?D9F��{+���"��d�Jk��@IhJ�qo�X�+��K�������#|m����y��7tE�ep���i��wl�Zfg����iI2��sa��R4k(�o\)�V�9^��ov���Rg6�����-u?�y/�F��#r1�s8�[8�kjU�p+)�����U���l���������=6gn0�dF�������
 ��~��������e�Q���%A?K��Z��\TU��r2.ia.Td_	S"(���_��z�<��I`�����Ar��E6��;Bt�B�x�.K�N����J��=�J]�4���������b��L���},�G6bF��6Lc6�H�a�/U��A9������t�V�$h`���O������M�Q�\�2����D�H�����tK��'�46I@.�r��V(9��*��n����zd^K��������=�d�?��������J���j U}]$�|X\8�I��p�_�bRFB�%<[e��|�������'�8�;�5���&�\��9�~M�&��R��h����Y iX�������ci��|�67���b�	��@g�%9:�4�!q���I�����^g�hf$�>	�fz������EZ�Hsi��P�R.X)���yw'x��l��<bm�S������q�{�A�������=��s�������~a��@�Cd*�"@��n�B��"�[1�4"y��u)��|��%v�����?D2�%'V7�"I���mSh6����C��9GV�m~M�d\���GBvZ��T���o<��6���
kb{"_#�w��f���e��:|sW�z�e6�l/\OZ��*��TE��h��r!/jW�86��+������:�,,����2��-�W�b@�#lk �H�M-��qaPH�UZ|^5�;x�\���h6���#���.^����S��.)���T��[�EU��6��)�GsH��^���7K����9kSj.����A2��+��5�"X�^AjW��6L\Q�tqEF����3c�)�s���,���,m��>�Ej������d�Pg0_���88c����>S$��Kd�W@�S�.�����h�P�eE����T���7Na��>p���z]1R3����K�	�4�1��cE�Q�~0�������I�����*���qI���@L�����+]q��n�������@��C�Y�z.�.���m4[#�mR�Q3H���:���)�Q���-�0T�X�K���7�	�{������v@�6T�;��I�g$������e�$F�]��}|��J�-J��4z���k
C;E���9���)����v��Z!���/"K����z�%��T���IH�HDk����q�[��EE6�l�����"��}q{%�bu{�)0� �M
����a���D���X����x�F�
�ao:Q>Yf��
n{�0dB��cN���,R+���]~���MC�!0$U<"��@0�!u�z�������-q���=Ei���=S�V����{!�K��Z�L\eE���E������f:H��\d��Z��"�L#�&|r���E;��
���MKN��"=��:"���V�X����{j�$j��Z��vW��W���;S��[{��8}�
_�����<|��`�o�����p3���?\�*�>WZe�%#�B�R"/�H�/'�u�S�����	��#:�k�1-������f��}?N%��ON*�8�����`m���`�K�JV�:]�<
�E�Zn������<��o9H��7t�u��+u6��'=����b��=��Xtf^"#��a\��x`F"�rqD9� 4��`_n�BR4!*���x�>��s����V.������|p3v'"~�i�	!`��6��z�h5;����l�cS�	�c-x��s��5M/v�4����y��<����Nnh;��P5��������X7Rc'���uS�
-�{ha����O�����J�G6�k���*\,a����U<��7�gA����`26�&�a�4>��X�'����T�����0-d���hk��"������Cjz�e�I����drO�5�OKv��[�gt�/���NH)��@/uecHD���+�|��LK]��6���j��4�+��V[��%�i
�.����HR/1K��7kH��`@�S�����P
�u�%9��[�g�"(�ZL����rJ!�g��e���:���K�|���FdO��i]5��|Z��,��-�Px�f����E���a������?�,:�a���m��
�y!�������V�<2����X���|�&�-���2���C��w�0%�:�w�+���C@���\B�r�\^�F��3�i�E��\b�<�`�8<�8��X���)�?���$]!S���6TQ�t<�l�o��\��k����a�d��5e^ }�0�����y5$��rl�Q�������:��k:F��M0I���O�ta+-S�(�����&x�F����9�r^����dr�i50N�8St�3x88+����;�
�����w�1�6 d�����G@ "<����LAD�@H��������(GgY_8R����V
���Mo��`<WhJ{#�@i
���g�&cH*�ih��|����,���F���k��7c.b������� "����@�0{!�[�F��d�/�@�7J�n��r�W�BE�.��;�h�"���[S�����{�A�v��h
%������s�nAn����`i"7���
�N�?O1�T�6v������pI�v���'g4�?�J�_�7������@�G4�cS����k����R�������}�m��?��r�9��������W��qK/���H�go2�]]L���S
z�'�LO��
�(�s�����{��gcZ�������"���� +��dgAe�#6��S�;�4�Z��$�D� �kDf8�,�X)����t��/���~�����"���+��������L�
��ta��0��W%�F��;4��@ 6I�AA�<-K�r_R���{���������k��,`"k��aW����hG�X�'=�I����Kub����|��Z��eX��z`q���	��y{�*.���������]RM�2���y.�%�!Z�:tZ��Q<��~�(�n��5n����&��p��@&��#�%�Pb���������5�7�q�h�K��z��@�u�����5Fo��@x�&>0�)H��HO�g��2���������8���lu�������lE��c����Z�\.i>� �q��������K�k1�gvk@�|Om�oxf����)�y��[8��z�=:��hJ�P��e�}z��m�}�����I��q�/4�c~%��������~��������gpfp�,,.=��2����sqzF���
�yptH���=��)����r?U����>���N6b���`���hk��R�t3���S(��%*>j_��3�����v?~�>kC.����;y-TVpJ�"B��[�
�,*�(\8:(��z����Ta��TP���h_l�Q�����R�-k��rvx��Q���k*��W��o+������Nw�Yu�L�:T(O�cDS<0���u8G+}=�����If\c
qa��R�.���WsdX(e�g[���f����Qy��P�'�	�p��n\P�cX�Q{����<���-D��e�p��
�C,;�2�Pi�O'����D�+��+�bj�nRxx��O��"���S���&���$Y����f���V������R��DFF*%�~�Y1�qM�4�Tz�$�T
R%�;���5�[��T����Z�Zi����|
f�jD��:d�nz1�io����AwH�s%Z���?�����g��-�������=>��Fv�D�>�`I*������1U�}�����<3o�C��g �2���:����}h� H���!�hwB���d|y�1�E]|-������������O�l0�N&�;�����������Wm�`�G��j6)�5�����G�4�B#�J�hk*��a%v�=/I8U�6@���I
�=Q�q�6M2����J����r�����Q��Z�!������J�������� Sp�d�"���������D����n|�[����X$f��O�(��%
��[\�k`�g���wC
��������1>8���Hz`���$�=U,0m�8�-���GG�������������)JR5"p��Y%r|�B�B������:F�s����l�l3q�i��U��FX�~!�`��Y������(�~���p!����;0.��tO�C,����B��$���q;�=����X������o(V����K!f��j��O3������#����;��8\u�7�L����^��|4\���|���U*�O��	|}~���_5���M.�!�����>�Jh�]r�_�A�W2@a������Q�kp��/�w?�;��_D�0�0��*��8���K���0p�
����5�����������=�-Z���Z�X%u*f�p��oEQ���x�����Qg>����m5���!@n�wd�~ �@���1���X<g�Q]H��,1e�HD�@���5������L'|��h�A2�9h9�#����'���K��'._�m8�WQ��o5OMQ���E^��x5O(q�
F]�[c�?�~��!`P����2�`�C��'6��o����])�\���s�p�����\����`�\�y�1-�lQO��x����{�!WfN�������j5���{��_b������umi���e����O��q������`�1�]+n�����7���5b�)�7��d��Q��Z��2����,;^�e��E����0��qESf�a<6�L9��)3���N�mY�V���C:�&�X��O�6Z����(2M�e0Z��*L�����Q�R�aR�6�����T*�S�V-&����*�zYF���|��R��lf\\I[�|��.7��&��EA�F��L���Y���j1�2��/���:�F%������?��FpX�AqX��j�RS;l�Xb�;�8�8Q��hQE�)RI\
2��������]��E:8�]u'��W>9+���2�
��	��V.:o���������	�Z��T�js| `D��#0��t��9��H:(�
p�����(D$��!�$��S�F��������v���|�iC�i
|��m<)Z�;��@l�H���~��Z���mlnRFg"(e�H?Ui��J��V�#�S����S��X-��j9���r8�v{|�x]����d�d�!
��u�^>�z5�Z�z�ZH6Q�H�tr�M����*	�*��,�_���'.=��%��9����T$�K4�����C�
��G�wQ=��-�����+"��p���_���>��|srr���1h��M�\�K��)Mj~(x��X<���bx�[^�#������������_��7�b\�����|h��Or:��[9v�x��l��*�e�:
�������c��\��j�a��%{�N"���'��q���D�����Tk
��D��@	{��\ �!*�*�[^#�,d6��q����e�<�Tu�����r���m-r�'b-�0��(k-�B �e��q-�UyhA:��%c�d�"�r]�/�}�3��nr-���Rw����s��s]��e��\\���U�0�Z{zN��]D?+��\�Y
=������3�D��{��tjn5f�;����ON(v�����'�#y2<W�*%�O����w^�Q�Q�"�b�*�Vi�l�5���=�$����ya��{{���{g��0��c\��5f�J�=��rj��C���������T�t���-�g����u.�][y�����Y�n�.�"x��3�����53���B�\<����w��J)�g�z
>���iv6������;����)����)#
�"JZ���r�[��@�2h�xX_V���p�u[2���O�bd��`9����i	g7������9�����x�QHOg.D4���(7l��9U�>����/Z�K�h E�����F��7�eG��\~$��Y�9�������?�uon��~dh��4�tMMP�~�@�{N�.(��l8������ �8�Sd�1���G����Q��\e���m5��Pc89�n,s��e�Z�T.����@����8���W��T�j��r��({M��!�MT�v4�F�i�D����v�������_���M��6�BdqT���r�N�Ws��=��3��q9��\����k����;%nt`��k��!�`���a�~�+��5h���i	�x�������o�g�/6���`�:z��/+��M���������d~%����6���(����(hT���%�rk�V����n�Qq�J�"���h6b�5a���1������������p���Z�,���D�E0�A�I�v.H	�9�!� �u����u#���&�����R��;����@�5C�uN �V
��FDm�4�������?iE����=G^M��������M�n�u�i�{�n
)�;X����������2;�A���j��x���k2+A�#������[�$�R�P��X���VO���
���]�i��2���'���e��b;�p3���5vk�J�^k5j����-~�p9?�x_��#�Km�T�+�=���<g\Xt�J��*�PiA���7����ya/�0o�/�����yAu��YLi���}�� d%Y����b������_�i���t�R�')�������n�zhbT��`;zjT�XS1�K����;���[�+��06N����&$";�� �(G�Ve����#����=�& ����Y�\��`���:�t�'�|)�m��N�������T�e���f	b�3R$0q�c��H�;,f	:���������M�(�B��,eD�����0���0��&M���1�<����td��I�6�V�C����tyX)��JE[�@�n4�n�o�C!E�(� >����$�S�^jy�'�S��&�*`�%c��p�~t8E�{�/D �"!�q1��/��A�n��O|����u*�`�_����!)B1B'���O55�'vD��,C�qp2P�}|/����_b����]�X|��V�C�~�#���>1�z=X3C��5�nb�q��>�c���,�F��6B��k���@/�����x��l<��Q
��@J���	�!Y��u��y����S�d�������V��J��}��5�����:��|�~~s���Gt_���[�����lK�/rf[1>0���-hs��{C:�b(2��yO@�&F0��b����/����r�S�>%+Z�6�5��rc���l�K`��G*��S-|�����]�����x���Lm_
�4�\d���I9�%��g���_�T��i-,���2F�.u1�$�v���������(J3��|2�l?��S���*���d	���b����mbJ��'�!����!�'R����I�Ob��+.1Ja�TL��*1���Y��8�
!Xs�hI�����4�1��W0���F%�	w1����j�X��P��]��&C5g�$�cQ��S�ka��d��+
^�,CB�'�%(18�����^��BC2i����n��m���t#�-�DI�����[�`.y�������}��LJ�x���wI0��S����J=@Lt$Y!����&5�" ������0&�Ic�fclV��[���:���S+/������e��w��[G�u�"��v9���t�F�$���������g[��T�3��k�!�����Ow�=#��F%5��aBo|�J��s����;�����>	����^a8���������,���N=5K3�`�%1���������X@�n	P�fKT^�ao�G
Y���m��!k����h�C��;���}�����J����/��s4��%S�S��\���T�rk3r��n��*��)��x>� F9N��"����'��t0��?!��~-^������A>�A	D���=��v`9��\Y�������M�V@��1!�E&��2�\Mc�T��Y��)<A��Y���N������/�E�*���2���J,�x��(s�}�6���>�Og�)�S(-&���������8�/�TQ�U���B��O8|����7�@�Y'�V��HQc�z��\��C��i����''�7�?w��}��}|q�d�P������v^�=ow^���1a;$����i_�����5���Zb�aD�Ms��8'����
��z��� ��3��{J)�<�<DPkp�hwq�q>jw�;��u��"+�QH��2�@.dFLY��}j��Xn���������N*
��{46�|�-C{/7*��eZ���3��AU�L
)��a>^�+z���7�%{K���Ma��S�lk��uG���5�XR	�7fIu�3��28}���m�l�
}��7�}���[�J�2�m���`��n������%o����7DR�
���Vj��f$54]`7$ge�g��1�	
�F���Ja�.��:6!�� ���m���lG�����
�xc��TD�_���9H~[��2,l���1�/���C��������^�:��#��H4A���T��8�P�XO�<�F�%��lO�L����RR��x}��j�}"�w��K_�#����o[���!�B�C���Z�<R�b�ps �Z��I�n�r����h-Q��V�|V�j�
�U>��>"=�O��u�$A.>S�n�>Re;O���<x�M�\��.��{�c�y������r�"�
/;F�n����@=��Q����t\2��Y���g����WGm4�
���gc��i�M����B�U�WbO[�_�ZAPj���
%m?�^\��K����W'��5Q��zh��{���F�wZ�mR���F��=�t�O�O�ZgU�nBY�M�RD��5'x.0�$����{��:�s�t&G��������yI�@���J��"~�;����Ne0��O��� ����g�4��1�kE�(���\=.=��D6�D��4O9Lw��l\��g�d�j[��A���tfY)���KxLn!�W���P�r��K.c\��k�����ha���;o%O�����g|o�x{z�?N�#�����/��,�Dy�e���b{�;������'�����#�V%���D�d9g&�,i.�>\,i����X%)���Z���&U���b���	��7`oG;���5����%��9����q-������
��q����9������
'�m��N�8^�����-�P��;V?E�<Y���dc
L�"�)A��Eu��7wb��Z[��_�+E#?��l���	����/K��,��Ib��A�q@&?�7^X{�����P_u��0�JqY�zz�)��C
�.n���q��X�l��E-�e�����%1"������v2���i�K��s����3f�
�
�Q���;8Z��Y��v8v���6��P�^�G��z�8���W _�>��|�l��AA�J��*,�-��������p
�}Z#������� v�>\z�����?���u �T�����?�@�V���C;^�E�\2P��+#0f�j��	R8�C�5�L�Q0TU&�����P��lww
���F����(8w����+zx��S�D���<����5�����`�����������?s9P*F����Z^�k��hc����)����rT����I3B��G}�U������HH3��J���m���.	P�q����v��p:��|A.x�(���.R,G�ew0�T-���/N�P7zq���$Y�D�J���$I���,lM�mk��5ir�,%��m;��h{	#��,�W[�|�#l�,�� [2\�Wr�56���5��F�z����G����q�fg��=6���K
,y�#���8��}��|��Q��u�V�NZ�[|9�g�h����I���ROH�a�G@S�If��c�/�.N���b�oQ5Q/��nr_�|��m�K%�~��C}5K�	�9M�}L�N4����:�K<� =�u^z|{w)�a�����\\�����G�@'c?;>�8|�����?�F�4��z���^�����-<5�8����*���&�m���\���,�AG<����V���P�Qj��d�����	��(�kXLEv�oJ�����Nc��qe�K5�	3�����������7�7'g?c�E�0�#W�~#b[�*C���2{3+����j��V�Ri�����,���x���M6��=����dS�Q�������A�I"�@{`b<6����.��;BcW��|��?r��I�@�:b0�4Z@Sj8�r!wW?WN�"�V7�N(�9d`=�}���Z�f�y�����j��=kT�
�'�p��!#��i�
��l�����j0d��e�8u��g��x��@���hxgV���T	v�2��)����1�����$�{"�r����8���I�VU��� 8=���D3�s���)�Po�i~����G�����$��DA�MR�Z]!|T+\�hY)}���r�X��I_����bV"��`j(�X�"���~3��p����kfn�[g9yV�iE-1�n#D���"9W��D���z7�c_�W�}
12:�I&&�:dd!Y6��f7�wX��5Hy{��U@�
s�'��������E����?�W1U�B�.�q�M������V�>-�<��dc����#f1�V�l�\����J!mjR�X��Y��\O3������9���%Fz�`M?������FJ}"�g����*
�2Y���0�O�O����u,�������S�O�w����N��g��U6ug���g�x)��Q�L���S]9��;m=q3s*�ivn&H
n�|�`���OKo_�RH2�j�\fD�~yti��)����6�}Y-f�6����2�Oh�Oh�<�Ij[�	-a��|B����F�p��hOh	�����tB��!�:4��g/V�K ��2^�2^��aj^
L���;��������%�P��:��������W��U��'���O����ys��]�HH8q4���������2����4"P�`�y^�r�����Fzk������7����*��a&���H��pW�6�BG������f��$���l<,a����|���b�)+d���� ���s�'�{5G$�q�7����<�}[��m�B�����yV
�7�7-�#���C��n������!��>6�}�������YN1.M�.9DEz	��S�����O`�l�Q�n���g0����_!)�$����nBT#���jo���{��8������vuM�si���"�#�T��F������y����<���[f�B��N��2�c4�0b����/�N�a~dh
�y����%�85��)Ab��T�
3@���-�E�� @��t9����w=��z"��	p"j*��������S���u��f��=��P�9�
�<1�l�Y����c]5@��0dR�%����	wP������"q/�P�Oq���z&
XA/���77��S����n�J���][�=?���������G�6_��0��`�b;6�J��M`�5��J�������RN���<I��A�T���.��D[jT���(�7H�$R:p���ao���E�A���E�������Y�A��'L�ps�al�����{7;>�`���E .	>C2�1���L8��>iL�����`��]�,��F�����~op�2�<������E���y���"wd����RC���e��d���o��������:���?#���iv
>VS�
���g^�K�^l������������Z���4�g7W�n�m7	�d`�
Fl<�0���'�p���i���!�p��S��I����KPG��8M���@�ON?HJ�]������Ddvkp�����^W��������F�����#,��'���������G��w�%�S�^5`�����L�����j0w���R�c�����\��<�$0�!_v���r����f��W��JT�D�;��94w'%,��\���<��)f�������eU�R���������=�`@���2���i@��u�B���]�BJ���v3�/�1F$���������ls��/�r���V��y��������ai�%!��Z`���aX�n�iqQ�^�:�
�~I���()�$���:��a���������^�&|�f���P��H�@��qu����8�z�2�����8�� .�� ���c[�!���h����!z��
@����=��
e�6����D&��?�e��.:NY���75*�75�2��cb��Q=Qa�:bl%����J{�Wr���!���Rr�D1��Tp)�Wa���S���d(~S������D�S�!�bj����������#k,�S$C��1��p�o������z�Dxx����!_6o.�C����>�0l���7�p��G�,�T�1PuKj�r������e��������Dw���l��-�B�}X-���M�nx����v��yY����5��'�ca��7���8Z9��V��x�r��@����X�,M�B5�������+�p���5���V/�-���p�D`��>p�bBwgG�O�$���������p����/(c�H���k4�X�r�F�<9>N��m��@`�b{J���g��������Ls�W�������@�p��b�<K)^1�%���M3�^YB,�BP� Cdf!�a`�A-d������u//�R\L��������c�Pj��A#���n5T�4�5�s������`�} ]-��:RV<�'"�A4�'����q���.c[��:��I]����x;F�����%&S�
�)M(l�A��q+~I�UI�3"T���N1+���h�@���+)iF�����aqO�����n�P��^��v2��C���>=S�3:Ji�{)q����[t;�L]���xu]��i������S�<��ZU
dm��t-�=�Z��(#�H�+$� X�uz3K?�@��B���\h'��\\��|B�G���ZY�w�X�A�:����f�:����,�%�8�w�;U�
�d���*��|�l
o�w
��?�����1wx�)4�9/�!
���(~A�]�?�	��}x�G�V��./�N�7�=���+N����'��g�I��*<}S�?���g�G����>��zi��*cwk^�-��[;����^��Wk���?�]��i�i�4���+;^����W��Uv[
�m�<�*��:6����[@-�C�:��k9��El�S�D:k�6�K�zx�8���xve<kq���o}��R�a���	I���{��p<��I%����������O���r����ru���r�x�j�
r�E��n���W��|P��Y��N]k ����}�|e��[����!Ui��`�c���@��5�+����UP`��5�����T���g����3[����������~*L��LP�����e#"N�a��)?�M���e�J!h4����P]�w>\�%T����#�>wGB`�+��1����Sy�mB����+f���{�5\�Q����p\O���e[�I�������Gp����$�����n�#�����!�JEVi� �����n��jVH��
����Q��7/�������C*�����@fh���~<���}wr�
�������/�����-gv�h�������!b_����-�"\��s/�Z��\�������	?��.��Lo����ib��3|���g����J�OU�8��Zz��������E�
�g���x7��4��O��+��*�H�����z��
�up��8����������Q�\�{����+���[�
�$ z>();�6%��	F�?�|.�!jd N�d���o�����F>�L`e� �:���)�:������~<8{e5g��I_6w*I������dr�4��0w.����*��'������LO9ed���.�B3��QP4�#j@��K�{3GeW���kv=�B@�n��5���$�K�>����UsPae��B���j�B��r�U�R]���J5����F�
�|7�2l���X=�X0�X3<���w���������xg+fo	A`���� A����{��n��y`��L'�2y%3�0�		�+6��@�8���	ZZ�O����X�Gx��gl�m�c�2��qW�m��"������w�������xpvv�s������E����)�$��1��5�������#a��6�"��<F�D�u��$�&�N�F��/Z'Y��G0��N����\��8�����v��&�@q�5X�t�������Vp��(��F�&1�e��j;�(Dl�b��A
��*'��$lG���\~:F(��&�6�s]���������D"��+���m������L������VD�08S�t��/�����.B�����%mT^�(�0�N�����f��
7U'��5��0��Fq|!��G������x(���I���1dX��t�j-����^q�����X�P�c���xr��:�)�d�I�S�
$����
���!����M}���R�t���	*�hB���P�2���1�2�~�h<H�����x�O��iz=��f��:<�q�����2m�$�Y��`~	��R*�e�������N{���W����n��t�J���v:��r�iut�����s���}Y:�����c�����~s���(���j�Uv��W�>�?�h���;���;.����1��(u�yGvE�$x�i�����p���xr���*���V��`�����5|\qb�x&��[,�E	9N6�������M��[h��`T����XL�-��/F���=�B��>P�hxG����������8tW�$pT=�,B�W�F $��x`�u��${i��^z�S5��-Vn�y�=��[kU*�Z�Q[~�Z�WxVx��p�NX�3����p<Wy���������wziB9���1��e<O�o9�����<ybfqV��"8�|Dv�}s�F�`	*8����:$�Z7�$.�+�hl6���>����f>����� `N��WA3J�|R{iP,X�b%OW����IT��d>����A')*��h��:��V������yB
�A��=��_�5/����������t�}7���������`*��e�]������1wQ�B��ey�12�{�����}g�g�%d���SGmK��"(uA�4Z�u��{��k��(I�8���[4�_�~�%?��a*V�8���a����"����^(��~'N��P�H<e��*p���x�20��a����2�Q$�����QJ�i;����c~'tAd��>�p�� Z���N���6����O����=��
��/�a_6���)�
��eA��r]"��K/���Lo8�������
����D�p��q��2^�j0�FfO���G��c��,���n�3���C�:�r]��8R������y��aD��������G3\{Ys6a�t
+������:������s�?5Q����������EB�y��n-�L�C��D�[FI
�2c���3�G���.t��F)lM���������jm������iv���L6x�b��f�E��f������f;�[ 3���z�Xsx�-�`�%����:��q��/N�3v�>j�����x�1mq4Zb�&���#�3�\j& &j�9A��U���E�6�SKCn��t�mo�����t��>)P���4���mM��M��&��,�Pp�VT���Z����}d`����4f���S�:i<f@��6��]UT".�x
R��A�(B�D����������W�O���i+E����d1k�9�/)<�c��*=�/��0���9Y0&�O
�M�������.��9�S���9�!r6��B��1H����+gy�����+f(\�I��|?�j�H��Z]&�/�/�@����v����{�*�o�R�����fP��Fh��1��1�����u	����8�VK;x�������|[���
���B��|�d"u7������N~�����,Jk��N�_\�C����#����g�A���I�O���������!'o�y�'_��?�j�WyQTSk4���u�_�9��E�Y�Fx���d2/v�����+G�-��*��e�31��S��q~��e��xtv���s��Y��l��E*����g�'gXF4����>=t������Kt���?�'?w^��_��^P3�r.r���r��2���-Z`����{Uw����Z�Zid#�p4�����E8���e�7)+b�g8��j�F�z�q:��,V��>Q�4i~����Wc�~�����Q����6�ZSO(*C��o��}�D���
�rgA<F���k6���OA�q��E��uv���rd��So����l�%���T�q�������K�+8[�x��QOl���V1Lg�.<r�Zv�����F��F-�kS���6^}��<^��\���8S�{�`^.M4f�T'7����|�628�|B����t�����BV�-/-��YL�[-�-v������B�C���������������������G(������r<�:��G����d"�l���������1b�%��]M�C�{;\���Z�I&�zQ���I��S�bH���=���7w/�����Zq���i��YLoOng��-���������vf�	?,��s�����-/�|&P�+nd�8��v�S�z��S*{>���{M��>w��G���\�A�
����7D�@���0�@�wi;�!��;�������lc��=�����
Gn�xE�$O��W��G�I��=�u|���X�t]~}rv�9���%aF+�n�A���@f����3�N��QWL��xg��m1>�������a�)��Qei�a�U*k�	�M��Wm����J��6�s�@�a��t�e��B���+�K�3N��Yw�gn��������L��%_�)�K�\b3q�U�C��+%�R|Q0����`�h�C�rCS�&�~b`(@-�f&�[���AY�xU�R��7����
�#GKhk��,0V~ �������5H�q�[pqCp��a���~ ���h�Of1/5;����~���h�V�C8[�A��Z3x�;X�4��k�jZ5Js�-H*�\���G����Y|��>� ����D��I��--��W��]�Cg�A��y���5����9`dYV�`����n�����h���LJww|�[��0N�t�������Na����n���a��������������k&��N���hD K�#�a�����������������[���KM^Z@w�<vHxRS%��0�A\������0��2:���@�M�qYY��`&`�k�_��c�2?���R�m�U�����������W�Z;�� �o�U�C���M���d��Zr�K�@B�|���H��<%�
���7'g�S��M�f3��H���JQ�T)B����w
�2��v,b������_;7������1�w���/�.��������q���H��
xD�L�bZ
���W��Q8��NL�]��w���$����Cv��
7;8��V��Q3	���������	�2L�1��?n��28�9�1$�8���`|��"�W��$��0�n�]�N�P�%Z���mTu�����K�u���m���Mj�?��m�J��9n�i����/�����*�Q�8����<��S�4��o�D�����%���x���Q�n��;T�R�������({
b��;�9����������S�6$�P��P:�:>'��j���1�L���RT�*C�=3y�����z�A�UP�K��k��_�=;��_�'����<��yV��|�_V)�f�{~��,�R��+�b6�|r��<�����@6�����$p�]	�*��_�-Z>4��'��y�+�77x�^����-�/:�.��iW����?��"�
?Q�cw�/��/a`x>��<���������uN,������;� O���`����w�b\D<�����o�zg���x�Dc�/��O7L���7��?����[H4�A�3tL	UO ����<�I�0���zn�� ��Io��Ld>����u�F<�j���um����Kz
0#um�(]�����*��AD����������.�	/.����8�r��	�����N�O%
|*�-��b���9Yt��J|��>�g�t_���6:-�X�^����?H�^(/|��a'FGG�J����"����#�BN��aB�:\q����R�����C�����`	�r��6���
�s����A4�E�����i�Q5Wv5qeW�����K�2mA��P,P!��*j�����V��o�O��^�;���#�.[�2�-�"Z^�$�� ���G�?|��r���9�/��g���E�@^����U0�EF�H��7�i��_�4.m�( $��4x���C���J�^��DX�p��m35in"*8l}���4����Di��d_�Z�I#�i[���
��j������`��Km���(:E��O����E��B@�"�;�t��DQ�'����LV����^������r1lZ�L�0��VQ�����Z&�4}�4-�� ��k���������!&�Z�P������/v����T�47�����h��D'<F��&0��;��d"6�tiX����5�/��P�� ���XX1Z����m}>��F*k����8^�x� �Y	���b:�����(�mX�h�����e�����r`��_�[t4'o���^����h��"��V��S�Txs��N�@�Oi���3JGn`r�Q��m�;�Ky;�i�f]u�fu��S���|�9S��
��.��=!g�*Ho���5���x��F
B�-���_��.����4i�D@ej�~�R�;���i�S���f���G���U@g6��@�"C\T���;�����"�TD�Oj�f��R�2��������o�#GN�r�lDRd��(2��r�S5bH��S�
_qSo���<:97���v���>�x�tx�w�7�?a� nL����2�:���������!��X�1xH&ja�m�/i�d��������dm�Ru�N�n���-��)����"xV���X�=o���ZO5&ZN�
?�Q^^��bBaby�('������@Nc�S��q!��*r^?6:�t�������O%�{�s
b���������3�@@�T��c����s��LK�Ql�oG�+Y��t���?�<W�EJ2.��
-������)*�:��i7�
�p|y	���Br�Zeap�4���wRt&���������'G����
���H�x�{�N:
����h0��w�_p��O�#�x��*;�����W>^�AD?�~�D���|7B��� 'K��Oz�`�?���7$�0 ��w�O�����|7�a�S����2��KZ�a�F�$C_��Q\��S���k�7DG�~!w�F�&��������4���(����`�	���^����#����b�� c�d<���U��R���l!�$hn��~��3U����|�[����Lk�>px�?�2��X�;�������=�p*�C��W�)�S����.�~��AJ������_�W�`K��m��u��H�
vJ����������Gm��d0�������_G���C��vr
.�3���G;�(X�����x�/���#�p��M�u����h����.��~X$���6i���u������}F�
�	�����N.ZW����DY�����1c���3�{�P�;JA�����	���65C9X�����o��M~|	���i��;�u!��?���~�egh�?��uB�w>��8��� ����h�����~�g3@oxGL3k��^cl�r������F+A53����#.��6����\F ����d�1^�5E?hE�n�oa-��\����jd��o���;G'��v�k�r��&���}v�����T����Y��
V�P1��B����?{tq�������Z����{�`�f����}l�O���%h+E5������n@�����V��u�_�|���s��������z��	�W�����&��
h��P��'-���F�GReB_��0rH��
�G��G���5SLX��O�������������_Fm?��N��(y��n�0"������N�==���7���S�DfT9�
%��E������`�7~�0���[������H�T�$H�dY��@�[����f���/�&{���$�0q�Nh&���H#<�H���z�����q�S��S7��<S��F�k���^��x��I�A�T{�i��=7o���*��������$�������ap����P���q�o��{��������:�27c��z	^�0l��	��8���J�xxt�����C�|�I|�9����m�m��I����0��

_��w�[���xK&�B(
_��*��.H3���<$����/�|�p�N������U_k|'����r�0r���+����e���p�n��h��o&����&�W��P��(���riOh�ZJkAU��d�N+S��m�U+{���W)���r��Q�b5��x�Qi%e��9�[w����Li������}������Zx$����2�q���T�-� ����QP`��O�G�/���34(�3'I
���^@5�Ic�=����6B1d�o0~L���;��Ix��9��
V"
��-��E��W�Q���f�]v�:=.���11�.3���R}C	�"1"&#e[�%$�������
c�����K�Q�'{��J���	p���'[���*��;� =�6���M��G�����'u��b��������*�����S�'�����,	6-��.�F��<!������;��6$���W�R�,�SL�����S�;�]�}�.p� �
J���f�S�a�� ��]�f��kQ%�������m���:"'����\bU�
x�(r��,������T|���c����xb
9e��0���Ou:�I�&��a���;��$�i����x�&G}P�`�y��J����c�1�&��^-4�09�?�9�_Q�D�!�#���'l-Q1�l������BS5B	�<�:f����\�88�G�Ym4V/��h�L�c)�M���_��F��q������r�a��]��,B��ZR�$�%j��S�*����s��Kz������?���I����Q-��j�/*yOB��kD�F\N�(������?�~1O�����N��6��Z�����7�A�]��9�<���^^p{�>���;��9�$�ve�����#���������u}��g��W��?F��{�*��}�>~���3���`��o������U�#��j����d5��/����d;YQ]"Q�����+���=��m4�u����O���nzY�$�����e,�0�����/�XM�'�����j_�>l��iA���_�i��y��+�I��	Gx�\����"#*�Dn�jLg�'?|s���(���6;�����Q���������G���v�?:=;<��?~<8;>�X����)�Z��c��Q)8�?��������)�D��|�*n���U�6���^������z��f����r�*r���5k%!R�7N���\�D �����<1�8���f��p4�h`�%N��X���9��K���1����b�8�������AQ;��1�"�VT�,k��&E�������*�f�D�g N��sr'������|���2XbS�k��W��"l��������f)�,S;����g[�$���h<�������{k���x��A]��-B�<s�V���9�hp�K�A�������|�$�0��;d�H���J�]��]�.��,�������t�7��Y^��e2�6�T��2�y!\q��s9>������. �d�6_�JrK
.�u #�-t�m�9Lf �\����z�0���F8]��������F����O�X�re�x�+����S��k�!�m�4�K����(���n�K�Ugp���Y�Jr���@k�U��eV�N�V1/����]_[��n�����}��pd(��[�����O���Q��C����p�~sz�3]�(�M~����,J"�?��x:=h`��Xtv��U�E�U\�E��d{���8g������NO�/��5<3��Y����J�Q��
J�u�.`z���D��C.i�"S��J�}��M��!��3?���r%~���L���v�wA�+l�������G�����5��� tM�H��f�i�]�[�['�����gbz'�{U��Q��F�<RF���3��=L��QHBH�P�J�zN�`I)��8�r��K.!�m���H�\�4�u30�[oV��V�(��,82a�t
����d�`d0C�Y����.��>�������Z8xUk����lA��.-Z�`2`��Lq��n�Z��-L�t���!�tsp���3w�I�q����%�.��F��"�W���5c.A\�)�Yu����`
���+�����2��.��"t���E�Gd	���/�4��	0	�
�
]G����x!�y"�Lf�P,'�����x7�u�����{�f"�fb���	B�_�DEE $�~DB���Uj��f�Y�6�Yn��v#��*�h��2�i!������x�(��h��OG`-�o>�5��R5!��S�E��x��3�3��6s0/�cR�?h�`����1�s
�Y�+�}1��Y�<������QF�[��Y�d�G����k���E�j)(fu�%X89���;I(\o8
O�3���T
���QE4(������~W�$�m"��tps;�,�U<���������Ja��iy���lc�~n������uwz=��9w���� +�����8��~R���Q�N��)�[��?�k8���9�Y`�h\.�{���cMGfu
��u��/C���w��P�\��X��C^�'zO�ucV�����M�_Z��I�������Ju��������V��Af�K��l
���M��'��(N�����u�jB�&���|:�����8V	p51���F[�G�->R���a����������@	%�2s����J��C�����+ ,�'s�%#���nl�T.� ��B�;J[a�g!�~��0
��oq�%U�*���0���@7?q�]���Fd�1���C��a�C~9I�%���J���,�a�A�s����'�>6Y>����\1��|6�1�!B}+��uF@} ��R���[o��s��/s��i��u=���]���)���cY�Du�)��5��o������X�B	���,��^��������9n�a�VP��%J�/��S�1mG�����eo��K^]�x�V5�r&S�:2�J8<	�B����xpn��B�5������L'�
[$�_/���/�1�`N~�9�����x��I���zn�E�:;�R�v�r"�	�|�i���T
�����'Es1>���� qcB$J?B�Qd"�X@������W	��f1}Im>U���07`�qZ:��g�\��<E�{V��H���VM�k�xa8����Jp��W]�E��Og8�d��R���u��������
I�(���MT5�����7�D�^��`���-���.�h-�*�o��YB�O�S����K�6'�$��UB�����	Y~iu������Rk,�.	�T�4P]R�Q�������!�A0����3k����:~�#��F(�ct�
ry��m�����p�e�������P��K�w�w�I�����l�%��o�vuN�E��������X������q�~~=����;���M��P��"*��8����7��wr������g�8;8>?@����H�zr|���}d���0U�a)�����m��W*����j1~Cn����{�em�\�M��+���@����\��0�>��e�f�B�qO�Sa�k���*l������3��JD�}����Z�����[��	�	��:6�x���$���B2����:��{
�:����.��):\5��^+���Y<��[���Rv#����=&����e�@�����g�[�Si����1|��#��2J�����.@1�B��*�����Ig��]+P+�@����l�3�K6o9�����0��h{��;d]��_|����%Ikq�1y������w�e��_������xc c;�/�p���n��������kdh�I���t3�p�d@�N�tP�He�A���%�
�U���y�^�D���c���46}G�l<��B�1�l��V�N�V]��V%�������Z,�����a^�#)�������Rt�m ^@�RY����ib%�8�T!��U����_�aJ2Y~i��H���� [���y?��_<�g���&g���(l��V.��gCa��'�0�lr���9n��
���-��Z-
��3�0���Q�}6�Q�5�z�������-/
��3�0���Q�}6�J!�j��W
�$������ctV��=��xVV�BEo���i���r`�#vgg��N��T:DH~s���Kp�F_�;��3�eF�z$2<��r���i�c��S�)dCT���5-��6<.veD���,��-v+�����wO�V��l�~v��^#��nqA�L�i>�N����!��/G*�L�$fH���������� �,�&��d�����f����u����\AS�.��H�2U��)y
����TqT�[.�y�ry�r�����rqIm�U.V�L���F�:$�;��w�c�d~9'?�h���Fk�A7��[��gFO.9�����o�!�Vr�X���i�I��;��A�nA���d���m�R�-w\��#N�����/8��**V��T�S?�`L[���Q#pB����M(A�+`~y��A`�i�!���$�����.��������>+�����������Z0��E���� ��	B�N�`�CV.;w3s�J�8R	
~)DN)#�=��~3��l�K��rVdW��aj�D1��[���2���I���"������Vk��QM`9�[����/~���.�%�D��6= ���!,��8��2�k`���d�0�����Ir��nu�O��?���y5��,�+������4���,h��)e�rO)��0�!��
l����������=�G�����T��
g���H�z�8���R����f�V�N���j�\f��}�����:�iO�$���
5�����v	�j3�#����I:6y�����F�{z9Cy
�8f�p��3�����;���t��nk5���]�p�y������hr�����������z$.�#���;r5�LV.b���Q� �@�1��7��j����Z����X�GW�s�]���Z�Aubca��9Q�������V��d�'f ����A���5��K��jvD��eWM�v�h&�����[�fv1-���2A�����D���L5����4�F�2S�R�"	���c�Tkf�
���kX�Q����,aT� ��.�n�izy������l5+E���Edl�,W;E�c�f;��a��5��(c�qn\	/0d��0k���<`��	'm��s
�����S��?��}���-���� D�&%��e/����DHv9�S�9�}�	,��y�j�K����B�����c~<��/���!dx���������,7�l�7r���|���U�'��M�g���m�����&����
�#�[#���a��jV4T��1P��2Lu�C��eJc6����{�N��	?�@IW�N^�\.GD�����W��`3S(��7���O����_
 P;d�A=�5E4^��P�5�k�Y��5��3��_"qID�#����3�Z��.g�<�����$i@+���"���?����������g�]�L��j\����h0��k�-/�$�7?�Z+���X;�_Q�k��?]�A���/F����r�Ks�����H�X5�����6����J��?a;�d�\��>�*��q�T�@���a�3�{	a�6���2�{
�D�&0!j����.����7�������E���E�_X��_YX��h����h�Jc�Db��nm�������/��!�<G�&g�w�?m�t&^��7|-����	.��C��+Zh�0��;�c3|5����� ���o��+/#*�>v���S�%�#��f�;��n���\��77wl4��
�)cEx�_G����0B�aq1����]g�4
�����Fc%�
YB0	v��
��1S{1�)��P��  �X��-����y��S_��ESOn
�N<�91�}V�a�9��"�4�Ia�V�)~�E]
+B�R���t'w�����/�g����������H5�Ed�2�-���2Rd������s�]���
�!~�w�	�'�U\F.q�a_��m���
DPT*o������tJ�j�U�"s'/�i�9>������'gj������q�������-�]rS�B��VuP/x�K��h��M����!)���ho���������?����0�,S������6�t�������)�|YfMN��IA��-Z�r��'|��-g��SK���+;�����.A�=bv�&���k����m#OD����7���E
pD�V7k&���y��f��L������4��a��G��^��H��YA�vS�����%��R��S+X [��Eh[,���8V����t�����m�����~���2�_��I\������X����G^��'�o����@0H_�#\q���=�jp:���S��e���j�T�0k�4�1K/�e�[�D4%��]�td�TN�}n�����N1���u�O�lk�y
���T�'��N��5W��	��~�2�2�-"���VC�qE���L�v�by������
�����������6�l�}6�0b�T��D�B�Y���W2�$Mg�i������M�7�~�C�A������(T��D���\p2|��3�+������F=���M��q�����`
{�}vvr��P��e�������;�;Gv&�m�[&d��Q�{fy��H.=�	(��H!A#�E��������O$�����p����tx'�2)������o_�l��#�z:i���~e]�>8<j�b���$

�(5N3����#(�=�P��k��jp�]���A0UJ��F��r�
��-��BH-���E^���%��`�f6������X)�7S �I���PY�
aQ[��:7��6���",j+#���1�r�D��?�s�;���L��L���iA[���3NG���t�D��(�����a��q�y}���U�,pp9��2%��\Bl*O��\��P�T�e���.	�2=5����B���x6[�����2G&���w�Xm����`�`�
�+ZZ����N����'��-
(Z�Z�����V�,���i� 
�B�Q�FwFr��/����h���\����O�?��(�)��>�$�
j��.���U�����It����#��Wt}�e��c��^%��O���%3Y�.���=]�$����G:�}��L���������Y�`�L�!�������C���������:�U���L������|���p+���j�.�����g���Q�k��_���(In&�h��NXn�d��F��3���_@dF�Sr�c[��[C7A�3k��-���&��y1E/Y�j����%+����[w���<i�q��m0���,�H)^�����I�0|H`��gTc�LE� ^\Eq�H���`a�@1%��
�3a�Z���(���nH�Apj9'
�����f�}��T�V���������[p���F����cv�av���#�Z��!=/96E:X���t�����,�#�`k��\H5�/�
�W����	��J���I��RG?���U
6�X��E�����b�WY|��%.'��D�{�a,���8��4|(���CB�V>)��C6���t�F���x=���\���n��}&K1^�m��G�h!u�q�m�s���o���({��b��%|��`��x��Ow/�aZ���L�a�0R���"�O�<�(Q��\^f9�-�bk�By���c�����4������D����>�qh���9"t�pWr�h�^��E�Y����%L����
��g�[�(�������w�e\�����B�(��i���nK5��c�������Q��f��a�bA[��(��W���R
.�����>l����.�zi-�.��B@-�M������2
.�~����4s���h�Z���2
.��baNX������������$����N��stu�it��
�Xoz)C����IQ_W�^�Aq0�������G/tZz�"1��B�K�b���/>�+��y���
�b"����0�#��@X��a-����>�B������w��>��g��U�v�5�����q�fV�#-���XE������2�T�fkA�[�b��#DY)s��@#�F��wp��ymzX��=���s�����YP)�s�R�gF�|�e|<�2�%3��
��U� �V����Ywr���}����<�b6$.��/��6��d��sc2�����m�U+{���Wq[�Z���+�G���j�A���V��S��.>�:?�3YH?�prt������}��_�;���*�c8�<�����m1��}w2%kV>����2�����H|�zyyL��Up��E�fsUD^������.�v?�y�����W��
��Z�����3��"����]?'_�
���uw�*��{n}��v�Z�kV+��|��'���9_��|"yo+�7&�FX�*N+��Z
3���{����X�9�i���� �J8�x�)����V�+g�g� |��7>�,�`4�,�1�oRy0Zi:�&�^I���3KQ)
�����I��
g���\����:����dk���3�0���Y1��-v	�5��"�5#��+\"��Rc{3�OnA(��_�g/�{�JNW>�x���YJ�J���D��\�v�i@Y��_���>�<�����w
b2yi�X���eCc�������X\��p�k9��W�8^e��k�X�Y3j?��A�!��A1�d�Z����oJ�����Nw2��-{4*f<-���� ����s_=���[�bXM	����/Q�\ct!�P���}�s�M�����	b/flac��C�z~X�8-�W�L/��3�\��g���3S��Ey@�|��������J�^�����E�����lx��A��"�<��'������A�|������9�4���v5���}�	�����k���F�M����Kl�L����"P(m\~:��=��C�U@�������"��KAe�jN�iV=����Nh�3����p��y��
6�)Q��r?D%��o�	4��^����j.f6��h��k1Z2M���J��T�8	4v/��/_@p�����vv��ndu"��GX�p=�1*1�im1*�[�2	�z`)(���-����dj6�W�u�Z[���O�y9�{���<�8���;�{^&V�+��%��fR���R��b&v'������Mg�y���U�)��I�j����j���-��(�V�����I�k��g�|]�}b��D���2���j����X�+P������P5�N#�2��t�S1�C�~��^�E��`��c��;H��dE�����ouy8��NJ��l6��S�~�e`����b�7��!�]Uf�"����Z�F��0��,������V�J6�3p�*`y��V��	dX�y&� �e�O�-k0�z��x2��k��sl\f3�����Dl_��Z������&g
�j5K�����(Z���*�_��_��W���������1����
�f���Q�h>����C,�?7��{��,G���������&�I���Q�-P�G�o-���Vf@�otAn�SoJ+�r"�����uBIJ���-�e�O����1��E���A�(��8M���lv����]�4��{��{<����e�VUs�����m�V�u
w�=l�!�;l[���f��'6����t������a�~���*�W����l�:��=3>��3���_���i6�������4��b��J������`e��[m9n-`��j��e�@�NQc|�fR��$K^�}��cp	��y��������!�l���5?��r"L\>��p�
M-/B���� �8�"&�����)����kD��F����J��^����|��Ww �����(4g4��!���S �L���j��T�*��Z~sK	�J��*_�eg��������63bC�Y����9���m
�Us=����Z��eC���,�����g�t�>�e���Y|������D�z������u�
��E��g���`;4�t*6�>�\��g[����)�\]��ew0�tJ%E�F��`�'h]-Sd%6���7|�����+����g���(1��w����u�F�M�0�`�b�i�;�G�4�J�T/����l�������V	*�k�$xG������}|��tVH��O��i1I���4WN�	��I�j@��%������6�!�^zm4�6����ef@�C���{(�S��S��t����1
63����;����{���
��0�%�(p��O	3�R�`���R���t�~���We�}fi��i�3	��$N��@|����,qs	�2��	.��cU���jQcL�o�<������p��r��V�8@���I"�[��]s��!LG����=��B-n=��-Z��|���%�j<�2�6j�0������@����k���3�>�&�H
���G������&�bWt3~%d8��D�9�0��SKA��~|��j4��%�.�u�V������_R^o0����;�� �k�a��}�]� N.����#b�?�J�����r���
����Q�q���FLdt�����ky2!����p������������=��q�B��|6��EOZ�A�<$9.���4��m��O�����#vx�����6��}6�S�GD>�P!�O������q����@�_N��/����xpv|x��UfH������_�� -�HQ+%���A��	�f����x�g���{�gY5�i���~�i{x�^�_���y�����1���k[�����/[��~�����~w�������������)]��E���K�7�����dV�?�W�G��i��U�8����~����m�_��9����sL�w���I�]�����\���!Q��z0E��-�Gd�@���;������-'��p�VVz�y��8�
�w���u��	������bk�w��%%����P{����������cvq��������_}��K!��SD)'��P��g���6�8���-sr���	��-'XN�o�~f�i�A���1wx|�>��
'����s��Ih���^���aW��~�3�'
�����Qc���7����������=0IN{�����.p���/���Xi�[4@9���W|�����Z�	4ek�����W�/�6�G~i��P�g�My�c{{Sg�Z���X���dM=����1k?������5D��~���Qr�?�!
�w��|H�3�*������������y�G�d�z\��/����!�����x��<fb�k�
���#7*'�>gVi�y��NXl�����������}���������q.����M�+�N����%H�}v�����J�K<Y�E��S@r�A5���X�i������M��.����kT�P�J4�no���d�"�3��${�7�Q�$�d�j�2K�9k��Wev)�-�$oT~��z���w�}�����5o����Y�@�Y^�i)�KOq��!b�4� X�e���
��F��J���
�~}px�~��3�Q%Q((d�<�,����y����������y|r�w��\b�������v�
!����/Rp�@�����i���R� ��<�O�*�5��I�	;4$�M���������@[�`0X��4�f����Y�Ae�o^���^�����y}����j1A���	|����_Vf���\�������������'��w��vP��t�����<���W5�y��G���~V��+I�yu���'�����I�6W����A�_���P���������x��[��Plk�������j���B�����I��L@RU����z���(vIZ+Q���5����G��q";#���J\N|�$�0Txq��H;8)�r%��L�7��g�4�����Wl7���z�E��"��bYF��Lb�=C�X(�eSK{�{�<N��^�P�"Na����knq�<BB�h&��Op�M>�4�)Fh���H���~�c8Kr�lA�}s�C�|s~r���
��9�Gp����@I������6���6F������m1�z�[���w�b�V
-�Lp�����6p�|���D�|�P�������!����[	w�.�"�
p�*���@�������w����sy
s@�
�Gd�9o��t����j��YY)�
��]��kT��������9���_v����7���y7��A����������c��04�G`e���1�A�����a��a\����.�>���h0c�G>�C�l�R��������
ecpg-cursor-readahead-all-cursors.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-all-cursors.patch.gzDownload
�z�lOecpg-cursor-readahead-all-cursors.patch�]s�6�����6M$�	�?���d�=O];�����v4E;|�D���f3��)��H�������,��������%8���Aw��k0���!p����a��z��
�m�
O]g�p:	�I�;��{0��a��T��o���+�u���
�b��CjO!'&�����)HQ��v��lZ)�=d���a*��iI���_������@�����o� ��������w~��D�*`�������?���g��w��4�q����~�\{`��:��#M��SVE?�������
�6�Q�#{�9�����]:w�Y�&f��Ao\{H�@OK����#��}��lT9�K���o\gh�9�p��Ue��S�����J 2�f6X��{7r>��z��-������������
��n-5~��;w�:QId��J��x�uH��'{D����|����x��t���%
�h�@���(��\}��E�?����v����n�k������g���OWW~��x�:�xLA������K��w0�������Y�xa1�0{FO��S���0��A���/�~�{�2Sgx�.����n��������f�;�81<��n�(�7�������w��|��)O1�����t��s3~<s�L����_���@;x�����������Mi�P&t��KJ����9�E��z^�^.u�}�����
aH�S!������%��$����e���8��.z��Z���
����e��E��ip�Fp��hO������c�R�T!]_����� Q
+R+���l�������Vym���(V����^���,��A-V^#b�t
�^,���������o���jRJ�bx�5#���xB�u���hi�.�V^+b�L��Y�n\������N����a���+�be���^0f���{������0�#j�Fy�C-�-5U1���2�%2gm���������h�LM�nL�fR�ot�y-�C0\
�|�����5��MU
z�����aZ����������V�(����tl�y�����U-'_��Z��������xT��E�^�b�4J>����/quG�h�,�C^�b��XS����f�����T��abm���������5�j��sW����n�]������h�p�0���\6A��v^��i=WZl6�9�Qa�~����]�����?���/^$�\�v�c��3��+�������
Z-]�t�C7_�?NMr���R�D->���@�d���=��8H���@Su�i�|�����/$[L��uM�w#�d��L��[C/�O���9�{?�d���7\-��w���1$����+y��\}����<u�z��nD^����
�R����������%��v�u�y��o;�I�Vt.����n�j��7t���qR�o&��Q��Q�l���a��I~�g�t�:}�P�����Th(��d�l�7�^�!W�-�
��[���R�����i�5v���@��$�|�7S�0x���*���&St��n�'�,_�j:��S����f"�WN'�,�F'�F���$�N'��
����C��;�}�����s=�{�����8=���Y�p���)=xNa�����S�l���c��$�����89��e�����0�>O���)���K��8������?\= t8�-:@5��a>��|�b�^v����"M��������6�wn���j~�a��dt������p�2��:��Oe8{!��s���S���jx��{�W�c�lN|a�$�����8%
Er<�;z7+���'����.�FZ��h��Y���f��?a�K25�te7��7,���J����u���'�J�i4�W���c���	AD��N���7�>p����^������9d��G_���qLnZ���A-�V�
u=���y{q�.���0;����l2�V`�('��(pY$��x�p��Q��O��������wufe'�����]FuN�A��|(�s�������#���'��T�������i�!���5��q(>���T�q�QS�����$���!g��&���#�YF��b����v���A��D�JS��Y.$ViFn��P������&T~ycz�1�����������)B�B�����z�<�T��3$��KW��M�>Qf_y��: z�c�����J�v��6���$D�U�j�H���L>�G�-6Zq���������.�/�}��K��JZ�es�qD���Rh�i��s���2>��Ys���M6��H�k���h
���?����m6N:h�?���]������+���_^��<}ws��W�����������;��2��.����=��g�&X&����do����n���.����&�?}�z�}���]�"���>�@�xj�+D��e��. �m���M���F��+Z�$M���hW������2Q��P��,�����3,�Mm�KM�+�T~v6V����7�,n���p�$m�������)��4�Z��n�����X�����\sB3,eFJ�-R~�Wd���{������U}��	��$.'��VE�i�rQW�%W��n��U�������YNlO
|
F7(0eY�,QW�qi�[�*V#�N{��S��kl,��~Qg���x�(���1������_{�wh���1�HE_���������L#�M��.�z���H���O��nn���l{
V�>u��I
���?���P��������;9u�g�2�C$�*>����}(S������g��G���t2t������� ,^'w8
���p���y�[���K�����c�9�p6��&����-�L��7B-�b���i/�)y7��L��K��ty����N@�
i�>��o��S�W�W:r��;�E������T�<�?�9s0���Q@�TC��|��~�Cv����M��$��,�[V��r�\r���u�*w����wgU��������_���o���#KK��x-Am�L���E�72Y[?���V�|�X�)5��^�a��0!R�x��o�4����e)@`��D�X�%��%��%BX��e��CKmdI#K6���.Q]�����K�t]"K�d������K*��)�r����F��P&��^���#m�������"EY���?uU�� �Q~}��E�x��t"Ki��W��D�Yw-�J�B��V�"�zZ�"�
U��������m���Ol�A*�H�jDL�(��:,u�R7�&Y�.�l��.XQ!��p�!��3�C��H�F�}bED�JQ�)��J����>a��>I9����G	��+3$D9�)��=H��+T���S�G�L%a�-�j}
�S�!DnhbC.7�N�F�<)M"?�dY�Hy�'�&��&�O����I,bEo4I�I6h�=���$�&y��D�B��&��z���4����DV��W�I����_qi4�MR��%���sU�l�	QHt��"7*��*H��uWA2N�U�,��%��QA5VA�N8���p",��x�}:�k�MdW���L�}9���|S�R#W�v��e>�s���`���L�p~����N��%^����Z_���=��������c[:p������'��*�
�c4{E���m1���a��]��Ub-��s/�C�F����5���]}�F'��`����q�c�|����<��W�9�u��������7d�&�hm��Bq��u�0K�e����8Fs��bh������S��
��P'f���2E�����W�J�#[�������W=~p?�0_����lW��l�0
O8T:�=ici��d5#G�;��aIZbEo��#�V�h����Y���~���6�1��H��u�M���L<�D��d��z�&��|QFN���	�\���o���R��?�!�fE�������PYJ4��R��_>C�n�������z���_��}�F=�Eg��3��i�EM���� B���b�dh4�����^�5��P����h�Zh����>q�a�2�j�_��[�����*��j�^����� "�H9���&�\�HH�X9�TT~m#rj(r$��r��=aDT����6y`Z����������D2)�J�Y������^�Y��X�714�������4�X������j'3��l��T	����'[e��+W�K�R��[D��1��[+����q�=�n����+��������z�Y���-�|����2n8�������S�t�����Cf�K1U2�����y�K<��Q�T�g�(��'aZ�y�����Y����\2s����mK!us�������^2:
���c �GJ�����c���a@�DjB	M��<t��s�����^HYO+��s���o\���������)*���=�#f/�EG�z���3a,��{p�;5�:;0Fc#��w�8}!ah.��Sq#;����k09����Y������ab�I���zb?Ab<��������
�Y�Q��:DPHE�b�#�k�Q��"�����k��cG:�|.V{�o��0�^���xq{y��~}
�Z4�@�#?b���)bs�y�,��GX
��,��!�s�����/��Z�U����\c�y�x +P�c[�*�V��8�8��-y��DJ�$�vU��"�}}���LH�"�6	�N0�D������Ad��A����0�C�����O\I(��(?e@&������H��!K&h����b{c�xqy�����v����H�]n�4�%������O@H�ebY���Y�L4��.�`/�M|���TY�h���������F T��n7X����
�PO� ����W �h��?<����>���$�~R��H��d
�j#IK��\�H�B{Y�H�<�h7����D���� wA��
�R��WU����O�z�f�������;,|ICd�g��O�+�m���`p�r��'�����+:t���W��DXs���jE���nP�#D�TPM���g-�7�!��v�=8��yj�����XOo����H�' %�o*�$%���CgH4RB:�����������A.�����>7z����zBS!6v^��;Q��D��M�D�$�R���FTH���������a����G�*L��KUR����''+$dF,�
I��&����N�',+L����h�=�� H����OD���H	��]�-%$i�L)�6R��R�"�����t����-)���1!�wN�l�D#%$�w]����U2���H�K��T{�R+&�Hn2f���h���Cb���l�:Q!���E�$��)*�FT�XTT��l���7�nD��!*,��I�lDE�E�)[THR-���hDE�EEE�=aQA0�j����
�*T���6i�������d�
I�%SV�������H�',+TbMn.E#+$���N�}���j��GM#��e���j
T
������)cZXs�$mz��1��R���ScS�kE*�����"F��!�
	��C����a�Ht ���4��?�aj����E��z�cP�V	��g���	�u����	����&�w!$���7��|�O'�{�5�P�GJ�P�P�I�"u�{�C|���H����`�����F?��45C��D&4z�I�	�;p.�	�1<{�FO�EO�e��XO`"��FO<:=a*PW��e4z��"]��M����$��q��FO�SOH�~�+���&>�����D�����j�^Y3����bB���M��/��/M��~��s��~�$�6�����z�I�|r��=CT�x���;p��5)b<�}x��7�\��7<e=|�at��1��q����������^�8��OP��j���#� ��X]�"=M�)��2���f�����&�UH���{*Y�	��B���6���Y��(�K*��v��O�""b���_x�
���O���}?|��~��������~2n!�������a����B���������f��2yH�.#w����V|j�����[�����-,32-[j-��_�_��W���^.�9~�j��D�m�?q���N��[�F�2YT���J�lc*�%/|��|
Z�Q�7�	�h{������z�u��6���>�:���7����nn����j������0���e�l���+�9e�"���2hTk|*�J�!��	y�~�}���W��������"����k�e6L��L���&����,��5�r�
D���9T]F�aZ4�c��a��:�&
�����]�fo�����>W,�����
�Q�N��YRm�9N�+�����/3�%h.���h��`�
A�+��2�-bE����+:��3���oH�:�����n9�S������(���s���oo��V����<�8��&@�1��n9�Omj��s���:��Tc�8�]Y��'�����>��A	.��%
��hv��~]/�}D)����)��,r�&�c^���n��zQ��%�O�� W��/��d�q��T�L��8�%�U�J���c^��\�]�w�],���'��1���A�N�{r}��r�	���"��/�	rqGX�b�0�H��/�"<#Z�|�g��217�yo�2e��6����1�qG���+:���C��"S��
[X7���(���0��m���~Af�'�S/���DQ��1+B����*���}�}��o7�6��FR��n#�FZ��n�}(qp�>l������&�4<6�)Epv�<��q��Ap7b��h�����zX/����/4L�u��
�<9e�B�x���t\s���{�����������;{��l��#_8{o�=BuN��#9[�����W6g���w��D(���{$�bK��������=n����{@�,7���G�'Js������k*[�#LY
��2���O�D�i%��4���\*>g.����T|���R�i�|:s��.a������t)�n#�F���n�=�\�0f>K!p��.v�r�].����.
�5g����w����OK���w�����\|��?1{�r���w�����\��a�].��1�{o�].>��w�����\�!��c2����+>�?x�xByI�itN�'�����Tt�N�[�����&��G�Ofai���`�]_�~8}����N�X���/?94�D,@L����|(F����m3��mN��?;����Vd7�$04v'N�����F���S��KK9��,���b�wV��Z:K|�����!�Z�iR��#����P���)@�\�LTT�ET��FeiU�������ROQ)�>%�n�Q1R���{��&�qqm��z�}���		;�������4Pt��<!�j*2�f$(r~"��dr�C�s.@}uV	G��'aM�f�O���[�~~)�O
������#CU��7���UK*p3q�m�T�\\{(�/�!�+�5u�jjl�4�����,Z
:�)�EG���E�8�B�2�*��W�Bd��T�;9�jjo�7"���J����Z���A�A���2��Og���G���{(�������Q���b���0�0��9z9Gx�	����f��g/�����RR�mnW���LS)2���Vy���P&:���"���0�Cf.Xp���.�J=�E�$���U'&CM���F�&$d����Lzi��d���17�d�v�<ka�	p�`@/m���5�:�X-����n)U8��`�Bq-t���� �Y0 	��}�[�N;&0���LH���L��h`Ch�.qJe�����&$=Me�q���
!�

�����QS;Y��H��e"4�i������@!&���]�$d������������Y�s��|����Z�����:�����e-���t�����B�_�����i3��h����c<��4������?n�*����o{C"��}Cr��o����!��EnS���(�����g�NN���p3-����B0��}]O}�D��1
�$���4�#�y�f6~�j5��x�~4#��,�%]Me��`d*:�D.:�H�^*==	k*uD�(J�w���FJ��e4@�P\�t����q�G	�@��>����XWv���vJ�_��:��=H�
�8���T�\8X���~B��T��� �����>��@\oo���3&��Ibo ��J��W/�d:��kLBf��8�ci"��":����E����BZ�#��u@5�W����j���������e�@����8w�/�^��b4xI��a�������|�v[�!������/����=~+��X�VRo���Td������gCbe��kS�T�\|���zk�De���I�	�8f6�/�9R����O[��
O���{O��R�s����(�u������0�fg�m;�<�S���+dg8�VQ�a�7�%�����I4Rn*�O*o.(������455f~���x�f*^���%VM�M9�K�������T�r������9ON�@�������7����G�'�����QH���QHm��"q�x�S�������~~&WI�>�;�H�F
}���*}j6�vzPb�?l7!B����6����+E��G��o=�R�n����{�����������M6���L��#�C������_��{�]le#����������k��?����Q���>;����J���r.���v�����R�M���4���|I��t�*���j���[ ��\�������A��7�� �7�f����v~��y������_b���K�N�{��7�^z�-���CD|�o/�K$)�'�o�M���@��3��=b<y����z�5�w`J[����wq��4,����>9���&����u.b��K]���R����Y�v�G�dW�zoE���m�Bc������Gt��zoI�CT������)�r��S?���zJ��|�*o�6 k���Q�pw���	bH5�Ur�6���g�>����O�\&7�a����������,N|�`k9n*�����;��#�m���9�����t�m�+�h�����M��B�C��=�!�	}��0	�CvOH�0��1�
�������u���'�����_�����&���\h�,���'~U~P0x��sy)r�n�=��qr�}������^|���+�������uw;F 	���z�\8��C���y����K����7/�n�k��\���������\���AN`��o�M������T<��nh����z����}{��d������j��NR��S?�%����;�R��%��eF�r�-��r~u��"MM�y�w2e�x��:�pz@k>
 Y<�����;����W����
���I�i�m��[������my���s3�����d�1���B"�y��+���3�g�U��$%X�4�y�@�}����uRY"LN��D�,%
�99E�B��j9_�E���h�^�x����yf��P!����������b1��+��~�����p����}�Yn��!����s���7�����A�!�HS�:C���d��L0,0�#��8�)�{P1��y�2�����G�8��N��#�Vsr����q�0T8"��G���x��#�����^�2�#RA�I���,=Px�G�;�F���tT�v0�!��J�(��-(�Gu+i����)Z��Q��P���I�#����D�ih�!��h���F`�A�
�����8b���,�(��$��!	���<�w_��I @��y�"��4�hJ��D�nNN���6�$�]�
I��C	�C	�}�B�P"��P$�����E������+O��)<�Q�x���e��P2LH�d68�����@IO@V�c����%�AY��&(d��"�c����	g�1D7m�&D1�l����H�A3����5�A
�f�n���)Z��14��Wbh����c�����Yd����_��f�O)|b�
(\`{"�K8@����q��]�|��=9�am�uk99E�B�8vwJ� B8,��I"A�\�D����$?H�A>4�0�i@W$��}��Ia�e���$o�����:��xh!���$a����A��Aa�BMc9=m�D�4h@�J�q�
F
���d���!ud="|��r��F�1����f�J�r�}o�	H�p�!F�p��l�I���l�F�sh�F� ��[Tm�D�<�0s���Q��E"dfY��
I�P�D��!BY3�.������$���I��1q�l��$Ix�Y�T6R#W%5��u��n>��m������C�+�+\13Y�Dh�	�����5K����!a~�P���
�H�6L1[�$���DI29"��]zY )I��*����L�i2m�
:=m�D�8��wJh�rh1c���2��J���(�D�=T�=�X���@��I��,��d��,��dp��7J�-�v��T���zt��[�^���5X�$���r%����J��u8VQ��F��F��n�������u"nP��{%���>
uh6�(�mB�1"
�QP`B��jO
T1��|I�fq���oL,��O$������D
i�����i['�����Pa	JS������G��)J�$!ShV���x6<v`4���u�./����L�q������c���0An�W�0��C��}�����2&`1h&`j['��a�P�����+E�_�5��W�e��1b�)F�=1�#���	
�[\[_����
b��A��� F�RZv��0����N��#
x��D�#�Q�f�q������$:F)�f	�F$MT^�$��)���/d��-���*����c{
���:\a�@S�:7�+�H����W�-�nLEW4����4p�+f�!�w���WL�v�7\���w�G(dJFm���5�I�U<xI�z����n�L��E��NO�:7-���Z�Z�Z$������c25��?��)��]�LaM�P�4��2?��'a��Q*l����t!S���|�B���,dJ3�@���"�B�d���d���=�(��*�Z����LV��u"nP��*J�Og�:1L�E(P0����P`�Q��R��
�(Dci!�`��B&���XB��q?A7�W2Lc��6�6,������N��c	x���!I�p�4�:�4���h�h�9j�O�� ���D�~�Od�������4Y�fu��p<��m�7�0�
D� �|���v�������u"n5 x
%j�5/n=%��n (	m��$Y�����!�~���)��
��W-���4Z27"��[6���$�z�P�G#_<4M�m�a0��m�����B	!B!J�%���)i���|A��Y���D��q
�p��*��}1A�"��&������m,	�f������M{i�0���m����F�#B�qB��d�\�1�����q�����F�)��~"�.(�"���F#MZ�Qs%�=a"�$������J���4��A�����u"nZ��%����0��������Di[���$SH�L��(�L���#��Jf�JJB?a�)�xo�
[���o��I28�B&���B&��62I��-d���	��J#��iD%�2vQ��Y���aj['����4���!Bg���4��9=}<�
N��F@���I��H��
�N�!��t@,�:.=��1�����t�X2Lc�5l�mX�a7��m����Nc�z��{��\��C�k��z���f}�tu�����r�y*�y*�����[N|�xz�^��o.������\��.�\����h>C����<�����1
=������O"�DQ�}��ap\�E�s�3�$(~��j�������~�����W������������o�)��U���AR�;���K��������p-����/u��k����X��^\|��?^]\�b���������l/�o���W�w�X^^�������_�o�����e�eNN��n/^}����)>���e�vz����W�=:;��W{�gg����zus�����Y�����S����G���x,��X����X������1;{�?X<H<Y�R�M9���M���U�}"w���������[�T��'�On8�����-�\m�Sr�������OC�~-'�N���_�R=����W/�
��wd+�x�w����p5�:Q��n�0�36�i����������')�����?�}����$�R��n�<�����/Jjl�(��^��nG�g���r�],�k��=_f��/x�S���<
����(����4�zY���1�����y���z)����dxav��8�k=�1�xU�=o^_1���H�`��2������D6R�a�Y�����`23���E�k?Lu�B����wP!�(�:z�*Q��/�(�C�CB}�Ih��������A�*��u�]C�O��'�D�.��N$
P��C�*�@$`>���X*���=B�{U��Oz6p�����{����4�g��]�w]�T�`�j�p=_I���#	�
e��r��r��(}�������0�I_G��|�@�g9�A�pPE0H�g�`�@0H-��-���r�o�~�^L���Y.�s�6s5 sz�����3�����:�Lw�#��'�]������v}y�����W�;��'g_K�V��^s3������5�k����;��W�����VW���:31o��VW��b��w�^�L�B 9��$�	����'!%��� �)��\>x�|�m��J�e�Q���]��_���$����[��x�V7B��|'�3�%�r��Y����MlC�������������I����|��^E��������w4�T|7���j�����������3����%�cY�}s����h�=����jZ|T�%���m��|�����l��-S�d��K�=����,8p3,����c&yWAN+u7�~<8�V?Y�!r�nR�7��W��k39�+M/r�~��]�o^�$}k�h��I��i���Q�h&����I�I��&B�n��DS&��bj����L
�89U�B�t��+(l?��%�f!zd��}���>!�a*4p�������*h�����\�
F�r�.hy5��<h�
h 4�	\�P�C
��!����`I{F�C
���l���H �����e��`��
!aC�|����`)�C
�5 d�VQ,i��u��R���{�Q�N#��H�P�TPC����W��	j��Q,Q��P���AS��1j`�'�C
���N���WPVp%�o�/������C)((�9�QJ��R�`��D�X�R4U�m���P�A�����7����C����g����?�U�R���������|��D|��������W��h/�_^nD��F��y�������%��jq�������x���������P���+���w�(�?�D������G�N���_�x��w�3�9����mub���I'��/Z�e�c��rm"���������K������������V���,
L���H
�����������
v_�*����5�a�6S���L��*��6�K��:!����i�n�|+SO��5��=,�W,����c���^�x��|�G\���_Y�}�._���_��B�0�.���m�X/7s��w�/������������$
U�y������	���E&$�:�ef��a3�����<�k�kb#Z�VSE�����pm&��3{~����;����r_V��Q��r�?3����R�c�:��c,'�z7�sq���e���A����u���z�������f�=u���x1RLY0���&}(� ��D��������f�R*���)�����3��x]�[#t�t7��tJ6G�M���pn������l!
{��\L5�B�t��7P���{p4�����\����C=4��lp����M�������t�]����=�]�l��J���}�`�@���R�:�i����4��#��oNezd���S��2E`<��M��vz�,x��Q:��	;�x �!����Q�����@����@?k��>�T�.�M�x0(�Xn.���O�E^��b�\��6��rE���g�D>��nH)6~I���OI%6�i��>�;d�S��I=X{Q�t�O�������T!��N3'oon(�t��Y3�=(���Q����v{��TW���'�����d�-��o��P������[�>�w����&��y���n��'������}~En�oo�o;��]/H��dI|���������'��U���P���se� ����H����-bm��g>M������T��=�A,��{�8���n�������'������|O|�����_�2�C�
��*�7����S��5��$����(��!I�5��h"�V�Y���3�v��@1t`�-Lji.^f�o�@a�;)r�� b?$5� �p0�wh=��
�U��A��
T+�!�j+3I�������s�=�p�^��������\���:��K�p8"�o���q����u��"����W]~����Z���������������J�H��V#��|����T+���~6�y3������U��L�
�.)v�I��.����F��X-������*�0K}�H�	L����X�/EV1"zw�c���M�-+����.]��tSg�e�%w���t��Z�mK���'�]�|�_���)>�yiS|���L�va�&�,����w������q����W������_�WCE^�}�1�r<Z����f3y6s��Gd+���������'��������
���Zz��O�^�M�t�����E�`L%����^���E=�����Gohf��}�������*+���R>����g�.����'@=L�R.Et*Q��:Q,���,�X���&�[
��<a�0jP�/�`+�x<(����Y����Hc�^0����^/&���/v �]�`p;;}�d�Vg�"T��b#��v���)���PK�2��u4�$
��A�
����p��P�09�q bh�I"I��D�� yBfi�>��!��H����lp_�14�a�{�1�S�4Cd�1�W�b�0��D��/�������(A���Qf3�1�}hh
�:�MPV|�Y;5�4P�>w�C��`�rLbc$���4�a�1���u�m~T(����7[/f�a������0I�itN�'�Dq���4VJ"CSa6��A��OX\��	�����b��D�_�U �����ld�o.�j�)�U���C�*��h��:�I�;u�X+���S��}�{m��������)H�(�>� a}G�Z
t����r]��A�;)��j������V[�SnZ���~��q�����g�'���m�F�����+������z�{������J�y>jkx����u�Q�2�]K�!9;�B8���������G4�|JH�����p�p�F�4������{���w��[�>Y���/�����?����
W[�	�Jt|}�@}}��������2���p�e����k�2-�j�2K|�6��N-M��H}__H�_���_  W$�)��'�,�O�mR�J��� ��B�s|��v#[��\����� �����t�8��FJ�,�P�7���k�9x�QuT'F�xw|���h�Yr��������A�+4��o���[������F[]#�!��v'���_&r�>
C����g�f��q�|��=_�83A��5]+�����a�l--z�X��/:��L-�A�n��
���	���=�gC=����������b]hw�9�O~;~A2t��;��#
�WM I$+�^�����FD�&m$�I1�HT�
�w����������I�C�=���Hb�1�H�0W1�Z�T18#�/\m#�Or��D��z����K(pf�V�+�d����VRS�����J�aI$+i����$�VZI����VRS�����J��/�0c�I$;�4��3��IMsf�3y��d�m&����L��LZh&5U��Ik����L��$�V����I����93i�������U�8����cj�����TT��P�(X��NA��e���O
>�p�sU#�f�BW Yo�)��I�:�6i&mTM�F!p0��1�VZL>�]w�����y��J����y���aP�	�wz-8������?�5� �1e����)}�$qL�0����,�@k�9��;Md�Bh�7���B���1j������mz?\� zEu�b��b���J�Kx�S�������~^Y���|���YG���s���YH@WI	}BfU-	�&'����PS�VVY�}k�%����U�gX��V�0��i�]���
���dw�\B��%��
�zu�����u2�|�vM�<��#O�*��\������5?o���nlW���������=j��z�N���*�+��0h�
9���!������'��U�I[�lT�V��DSc�����B���T�y�C��)o&���;,��i�j��!,m��c�$��p��c�����0�'��.��Y��g�~��}���A�c.��>W,�����V���$MkJ�@��P���L�(:�PU/�H���|�
NBz�:I�����?�`�h��pq�=��8+_J����Y��.M��]�0dW,+W���:�VTe�L-��G��h��C�~�=>���>�T�_��9@QDH�$@{�����u	HS�([Hk7���v��{��@�x���T�h����� 7�*��
�e��l�-�(�&�/�&�m� ���d+� U������-�G���q�0��S�.�M�����
�����Ff��}����s���P�3b��8q��D���o�z�9a�Q�� "~��������'��#P=p�^!����D9�x�!�����_�~�� B� �U�,�2�	�!�"8q� ��H�@WJ!���jv!D"����9���^������J�]��	�(S��.7:�����������jxky�c�i���I���w��j�,���gV�3<d=CA���d�9j����rda#k$�~���C��!kM5�B��m�����]�_�����x$=�.-Y��3oIw�����p��_	��=�]n���3��}��n3����
�oB]I�Fu�����f�WR3[����g��195�B����!Ku%E����n�����Tu�~9�Y[p�t���?k����N�������=Y����d�
 ��r�F��t7��7%#���yi 4�a
 ���(��L5�B�4@��J� ����A+������:=z�������ai��	Q���|8U�h���:��^�S-�XAQ��@���H��T5��(1�7���B��^?�������>^n�B�s���I�f�Q�k��$���s��}����N���+���5�"���������������w�EG3�T|�v��Vc���:#��iF��-�hA���N��4�=v7�hM6Y�C&�J'�cR<�"�������P���*Z}�N}��g��]>�����g1����6E�:�]s�XH;�����'��k�
��h����	/�e0��5G*:^�6��v���h�u9��%����lba?=\���a�$���������y{�a�r������v-���?�����������ti��*c�EY��L�N"�P?;�j�
�C[�f3����'���SpG����*51c��c?Ov�wT��zM�!$���I��3wN�e1�Lv����:���Wg�i�V[��)Klv��-P:�4��)X��U���@@�H��V�0��d�\6x�S���<
���r�A���lc+�?{���(r>Mc�mq@a\dc�-�����t�P��!c^UG��P=��*|V�Ar�����6L������������f_x��nunuv����xw��P;�q�S��:�����2"������gg&H��fh��2�08����E�X�������"U��rb9
��s��c�1�h�n�z�s�o	�T�.��%��'�� :5������3��$�>������$��M�H��b$��>�>�|��a���iw7������-F���F������0���I}�jI}�C�$������_B��0���Hf�@�g%����*���5V�
K"YI��d�m%����F��J�e%5U�YIk�dk����1��D��J393i���T1g&�1��M&�f�+�d����fRS�����L����L"�a��L����Lj��3������I��^U���	J���'!r�c�jF,���Q���1\<6�/+�N}�P��n�=o�'Q@5��u�5����@=������;7B�pAwSJ�F!p0�;T:L>�]w���~�ML%�B�t�px�0������.�Zp���)�����|����$N�=�X��d�+��<�H���@��r�������{���O��p��h��I�V&,jrWY.�
~��=�>���+��h�k�4�:�����z��C��,���������%��y���Zz�������_Rn�z�(�%�!/Z{,�H����������z���M���L�Ci��B�F�&�G�0r=� �C]�����%�$`����??���7���m����o<����8�_s�z���=?����~�Y�9��RI��!����������bF���������~�f�s��[QL�N�`C<S��m������N�r�F8i��'���Q���
�h?��w6L����m�gmxo06����
�8��1�?��}����8��'4���Z�Ih�>C�
-p=�����6@#3���f�O�-�3���O"����va�d���	������}�BS��8�-H��A^��=^D�O�^8��F_����9�������9�q`�H^������E�GWu'�;�<4�^PV����9�>�=C@��w�%f� k���� ��=����h�Y���m3,#�mo<��;��p�rm���^!E�Q�����B�(�I8��BAbh!�����;%����i����E��f����p�n�����
���/?9>��@��\s	��mNa� �3��1���I�=��A�������e���L�j4���55<�����y����_���I����v)H��*[��v�k���n�oo���:�*@B�J����!�c� �Uw��S^�
���,:dRe#m���1P�J�,T�uh�vi-R[��0i���~��Z������a������Q�x�6�P!KLOI�y�;,cM
����^���Q�3��=����w,Dp@1�"����rI�zD[���ZQ���.���#�W�KK�0��5�b��Cu\M'��2[��p
��x-~�y���N���<{!?o!�L���!�.�*�}����
)�C>�P�.�����1��V��o^�KQ@E=*z�!l��'Pn��s�xH��#T�J��e�e��{-����C�^�#v�I����u"n:��w��D�1<�����"J\��_	��q�����S�O""o��\�W����v)����"r�8�k��%���W��`	2P��:Xb,1R@{�aI��u������-���p��%S�%�*5\��|��m.�� ��e\B�	e�L�t{�����j�5�Y�V'@�o������Nc���$���v,�P�R�BXh��4�a!��R�p�y�kk�|���O�����>�)v
���L��CD8��pB@�#i�y��Z\\�����Ya���3/������9��c�����oi��7pg}y#����{����{7�\�Y.��Bf�U��G�,o1��(��:����0C����=�S�E?��S�I����M*:�6�}y��D6.�d���
��b�I����n�8�m�AXD�=@����E����	�t���E�)�X4�����F����c����S9���� ��|�����f���c7'����kP.����{vb��o��XE�H������4�������������a��M;��u"�-�@_�.W�f��SD����N����)Bwy�.W'u��]�;Eh�"�pX���/t���I�����v���L�a���H��u�0I_��0�3M��b���`#1�2\1Bj�1x;�{o,|p���yo�����9�=!�mw�tpR�����d.Tj���2K`C�IX@�H���I�$M��D�h��>Z�\b���!��A�
#28Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#27)
Re: ECPG FETCH readahead

2012-03-29 12:59 keltezéssel, Boszormenyi Zoltan írta:

2012-03-29 02:43 keltezéssel, Noah Misch írta:

On Sat, Mar 24, 2012 at 10:49:07AM +0100, Boszormenyi Zoltan wrote:

+    the window size may be modified by setting the<literal>ECPGFETCHSZ</literal>
+    environment variable to a different value.

I had in mind that DECLARE statements adorned with READAHEAD syntax would
always behave precisely as written, independent of ECPGFETCHSZ or "ecpg -R".
Unadorned DECLARE statements would use ECPGFETCHSZ if set, then the value
passed to "ecpg -R" if provided, and finally a value of 1 (no readahead) in
the absence of both ECPGFETCHSZ and "ecpg -R". Did you do it differently for
a particular reason? I don't particularly object to what you've implemented,
but I'd be curious to hear your thinking.

What I had in mind was:

NO READAHEAD == READAHEAD 0. This will translate into 1 tuple sized
readahead window that cannot be modified by ECPGFETCHSZ.

After the core patch, this is not totally true yet. The "NO READAHEAD"
cursors don't go through the new cursor functions at all. But cursor.c
is prepared for the second patch that makes all cursors use the caching code.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#29Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#27)
Re: ECPG FETCH readahead

On Thu, Mar 29, 2012 at 12:59:40PM +0200, Boszormenyi Zoltan wrote:

2012-03-29 02:43 keltez?ssel, Noah Misch ?rta:

On Sat, Mar 24, 2012 at 10:49:07AM +0100, Boszormenyi Zoltan wrote:

+    to<literal>READAHEAD number</literal>. Explicit<literal>READAHEAD number</literal>  or
+<literal>NO READAHEAD</literal>  turns cursor readahead on (with<literal>number</literal>
+    as the size of the readahead window) or off for the specified cursor,
+    respectively. For cursors using a non-0 readahead window size is 256 rows,

The number 256 is no longer present in your implementation.

Indeed. Oversight, that part of the sentence is deleted.

+    the window size may be modified by setting the<literal>ECPGFETCHSZ</literal>
+    environment variable to a different value.

I had in mind that DECLARE statements adorned with READAHEAD syntax would
always behave precisely as written, independent of ECPGFETCHSZ or "ecpg -R".
Unadorned DECLARE statements would use ECPGFETCHSZ if set, then the value
passed to "ecpg -R" if provided, and finally a value of 1 (no readahead) in
the absence of both ECPGFETCHSZ and "ecpg -R". Did you do it differently for
a particular reason? I don't particularly object to what you've implemented,
but I'd be curious to hear your thinking.

What I had in mind was:

NO READAHEAD == READAHEAD 0. This will translate into 1 tuple sized
readahead window that cannot be modified by ECPGFETCHSZ.

READAHEAD 1 also means uncached by default but ECPGFETCHSZ may
modify the readahead window size.

To me, it feels too magical to make READAHEAD 1 and READAHEAD 0 differ only in
whether ECPGFETCHSZ can override. I'm willing to go with whatever consensus
arises on this topic, though.

This part is policy that can be debated and modified accordingly,
it doesn't affect the internals of the caching code.

Agreed.

+</para>
+
+<para>
+<command>UPDATE</command>  or<command>DELETE</command>  with the
+<literal>WHERE CURRENT OF</literal>  clause, cursor readahead may or may not
+    actually improve performance, as<command>MOVE</command>  statement has to be
+    sent to the backend before the DML statement to ensure correct cursor position
+    in the backend.
+</para>

This sentence seems to be missing a word near its beginning.

Sounds like a corner case to me, but I am not a native english speaker.
Which one sounds better:

UPDATE or DELETE with the WHERE CURRENT OF clause...

or

UPDATE or DELETE statements with the WHERE CURRENT OF clause...
?

Here is the simplest change to make the original grammatical:

Given an UPDATE or DELETE with the WHERE CURRENT OF clause, ...

I might write the whole thing this way:

To execute an UPDATE or DELETE statement bearing the WHERE CURRENT OF
clause, ECPG may first execute an implicit MOVE to synchronize the server
cursor position with the local cursor position. This can reduce or
eliminate the performance benefit of readahead for affected cursors.

one of the new sections about readahead should somehow reference the hazard
around volatile functions.

Done.

I don't see the mention in your latest patch. You do mention it for the
sqlerrd[2] compatibility stuff.

+<varlistentry>
+<term><literal>OPEN RETURNS LAST ROW POSITION</literal></term>
+<term><literal>OPEN RETURNS 0 FOR LAST ROW POSITION</literal></term>
+<listitem>
+<para>
+          When the cursor is opened, it's possible to discover the size of the result set
+          using<command>MOVE ALL</command>  which traverses the result set and move
+          the cursor back to the beginning using<command>MOVE ABSOLUTE 0</command>.
+          The size of the result set is returned in sqlca.sqlerrd[2].
+</para>
+
+<para>
+          This slows down opening the cursor from the application point of view
+          but may also have side effects. If the cursor query contains volatile function
+          calls with side effects, they will be evaluated twice because of traversing
+          the result set this way during<command>OPEN</command>.
+</para>
+
+<para>
+          The default is not to discover.
+</para>

I mildly oppose having syntax to enable this per-cursor. Readahead is a
generally handy feature that I might use in new programs, but this feature is
more of a hack for compatibility with some old Informix version. For new
code, authors should do their own MOVEs instead of using this option.

The patch also adds an undocumented ECPGOPENRETURNSRESULTSETSIZE environment
variable to control this. I see no use for such a thing, because a program's
dependency on sqlerrd[2] is fixed at build time. If a program does not
reference sqlerrd[2] for a cursor, there's no benefit from choosing at runtime
to populate that value anyway. If a program does reference it, any option
needed to have it set correctly had better be set at build time and apply to
every run of the final program.

IOW, I suggest having only the "ecpg"-time option to enable this behavior.
Thoughts?

I wanted to make it available for non-Informix mode and a way to
disable it if the command line option enables it.

I can understand the desire to have a way to disable it. Perhaps you have a
bunch of old Informix code, so you enable the global option and later discover
some expensive cursors that don't use sqlerrd[2]. It would be nice to locally
suppress the behavior for those cursors.

Still, we're looking at dedicated ECPG syntax, quite visible even to folks
with no interest in Informix. We have eschewed littering our syntax with
compatibility aids, and I like it that way. IMO, an option to the "ecpg"
preprocessor is an acceptable level of muddle to provide this aid. A DECLARE
CURSOR syntax extension goes too far.

Thanks,
nm

#30Michael Meskes
meskes@postgresql.org
In reply to: Noah Misch (#29)
Re: ECPG FETCH readahead

On Thu, Mar 29, 2012 at 01:03:41PM -0400, Noah Misch wrote:

Still, we're looking at dedicated ECPG syntax, quite visible even to folks
with no interest in Informix. We have eschewed littering our syntax with
compatibility aids, and I like it that way. IMO, an option to the "ecpg"
preprocessor is an acceptable level of muddle to provide this aid. A DECLARE
CURSOR syntax extension goes too far.

+1 from me.

Let's not add special ecpg sql syntax if we don't absolutely have to.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#31Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#30)
Re: ECPG FETCH readahead

2012-03-29 20:34 keltezéssel, Michael Meskes írta:

On Thu, Mar 29, 2012 at 01:03:41PM -0400, Noah Misch wrote:

Still, we're looking at dedicated ECPG syntax, quite visible even to folks
with no interest in Informix. We have eschewed littering our syntax with
compatibility aids, and I like it that way. IMO, an option to the "ecpg"
preprocessor is an acceptable level of muddle to provide this aid. A DECLARE
CURSOR syntax extension goes too far.

+1 from me.

Let's not add special ecpg sql syntax if we don't absolutely have to.

Michael

This is what I waited for, finally another opinion. I will delete this
from the grammar.

What about the other question about the 0 vs 1 distinction?

Without the second patch, 0 drives the cursor with the old
ECPGdo() code. All other values drive the cursor via the new
ECPGopen() et.al. Should we keep this behaviour? In this case
the 0 vs 1 distinction is not needed in add_cursor() as the 0
value doesn't even reach ECPGopen().

But if we consider including the second patch as well, should we
keep the "NO READAHEAD" option in the grammar and in cursor.c?
After solving the problem with WHERE CURRENT OF, this and
the 0-vs-1 distinction starts to feel pointless.

And what about the override via the environment variable?
Should it work only upwards?

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#32Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#29)
2 attachment(s)
Re: ECPG FETCH readahead

2012-03-29 19:03 keltezéssel, Noah Misch írta:

To me, it feels too magical to make READAHEAD 1 and READAHEAD 0 differ only in
whether ECPGFETCHSZ can override. I'm willing to go with whatever consensus
arises on this topic, though.

I now removed this distinction because the grammar does it so
the value 0 doesn't even reach ECPGopen().

This part is policy that can be debated and modified accordingly,
it doesn't affect the internals of the caching code.

Agreed.

+</para>
+
+<para>
+<command>UPDATE</command>   or<command>DELETE</command>   with the
+<literal>WHERE CURRENT OF</literal>   clause, cursor readahead may or may not
+    actually improve performance, as<command>MOVE</command>   statement has to be
+    sent to the backend before the DML statement to ensure correct cursor position
+    in the backend.
+</para>

This sentence seems to be missing a word near its beginning.

Sounds like a corner case to me, but I am not a native english speaker.
Which one sounds better:

UPDATE or DELETE with the WHERE CURRENT OF clause...

or

UPDATE or DELETE statements with the WHERE CURRENT OF clause...
?

Here is the simplest change to make the original grammatical:

Given an UPDATE or DELETE with the WHERE CURRENT OF clause, ...

I might write the whole thing this way:

To execute an UPDATE or DELETE statement bearing the WHERE CURRENT OF
clause, ECPG may first execute an implicit MOVE to synchronize the server
cursor position with the local cursor position. This can reduce or
eliminate the performance benefit of readahead for affected cursors.

OK, I used your text.

one of the new sections about readahead should somehow reference the hazard
around volatile functions.

Done.

I don't see the mention in your latest patch. You do mention it for the
sqlerrd[2] compatibility stuff.

sqlerrd[2] compatibility stuff? I mentioned it in section "ecpg-sqlca", this is the main
documentation section, not the compatibility one AFAIK. Anyway, I now reference the volatile
function hazard in the first paragraphs added to section "ecpg-cursors".

I can understand the desire to have a way to disable it. Perhaps you have a
bunch of old Informix code, so you enable the global option and later discover
some expensive cursors that don't use sqlerrd[2]. It would be nice to locally
suppress the behavior for those cursors.

Still, we're looking at dedicated ECPG syntax, quite visible even to folks
with no interest in Informix. We have eschewed littering our syntax with
compatibility aids, and I like it that way. IMO, an option to the "ecpg"
preprocessor is an acceptable level of muddle to provide this aid. A DECLARE
CURSOR syntax extension goes too far.

I have now deleted this grammar extension.

Attached is the new core feature patch. Summary of changes:
- documentation changes according to your query
- cursor.c doesn't distinguish between 0 and 1, this is the job of the grammar.
- I saved some MOVE statements in case the cursor position in the backend
is what we want at the moment. This means READAHEAD 1 is at the same level
of performance like without caching, there are no extra implicit MOVEs.
WHERE CURRENT OF also avoids MOVEs in this case. The caching code is now
clearly faster in case when there are a lot of MOVEs without actual FETCHes.
This is only an if () condition around the previously coded MOVE block in
ecpg_cursor_execute(). It doesn't change the semantics, only omits the
MOVE in case it's not needed.

I also refreshed the second patch that drives all cursors with the new
cursor functions. Because the runtime doesn't handle 0, 1 is the default
readahead window size. Now, NO READAHEAD would mean READAHEAD 1
but ECPGFETCHSZ can also override it. This means that NO READAHEAD
makes no sense, so it's removed from the grammar and the documentation
is changed accordingly.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.2-git-v14.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-9.2-git-v14.patch.gzDownload
��tOecpg-cursor-readahead-9.2-git-v14.patch�\}s�6��������lI�d[���VO������2��,N(R%(;n��~�� )%N{ws�\f�H �v�}���h~���Dew�T�E�$
�v���U)���G��_�����mM�g���O$��mw���^����Qw�h������v��B��;���f���I-���h������~ko���v���R(m�����Sq���8�ys~��V����?��AsS������g�2��H������K���l��7�(��W?���(�J
��$��o��,�|�&�R,d:M���R$S�w�7WL%�yQPa|�f�<���������L�e���-�0��qf2���������L�wM������ ��R��4��QFO�(��Ub�&����H\g���O�.l����*kh���E�a���"I��V �e�*��!��0���W��c&��w�?~��<�q�<�a-�lJ���#�=m�I����,���cK�BG��Q&��>�G�d��`��]&
�d|������>L��.��4�&�D�{hNe���R
����L<��Q���a��=�[i�
��h�m������b���lp;D��
/���*$l��w�����P����^����L��<P�F~H�a�2�<���7����E��3�;r�D �{�5D��"��@b�NQ�{Q�q�2Ac`�TK<w����y�>h�{2'2�SXhH�t`��~f5A}��$���J���I�~�}����g}%�\."8���U;��L6� ����_�����{�q�'s�Ap2�^��o-������
B ��\B�r�l����<U4����*}���� 5q�10v<��i�l�AQ��YJJ�S"�:��-e
���6@�B��'����^�t�87������1�S�����W��qS��n���*VJX�Tz�yXE�<h��c�d!c�����8��I&O��.�SO���?�^��9�-���
���gK��c�J�,]����h�]��ow��N��Oh@|�h	���[�YB�h��
��
�����V+��:V&"���	����(<�(o[+qj�z:`�*��	=�����5����p��'e��5��xP��$|Z+G��9���&��O=4e�/��S\�f����YV���$Q��I��/���n?����n�q����>@�N�$�>����b��n��O��������$a�6>��ypq~6�p3�>������4��G�������F�4n<&K�����4�9d�<>q)�����9�8�7�h�����v=�z�07jEque��u9.s���~�;������:>{{uq~
K�8�G�K�N���5B�>��ppq1B��������vt-���T>{���{��A��a�	�,q�P�
�{���|?y�\h��~���%��J���\���p�y��`!�w��'�����rp��>�_�/o�o�������y/`��������_�o_�?����[�I�]�A�������7�����Y��NP=sIi}�J��~��=h�z{]s��7
�]���S�C�J�����Q�2�<�G=��>h�~�@Oom�*`�V
���k�����u,7��|I�	eA5LoU5��b���H�������s�9)"n������v\3�76�S���c��������_0-��LK�{Zf�W��`+��Y�_h��dB��(\�Y(Z��T=��������/�7"��;�!%���tg���p�z)'�<8=!0�I>�f���	��Pt�e^����%�����lC!8D�U'�T!������?�U����+��eU�w����P�����1F�=%�l�����F������a�p��{>�y��mCEY���m-h���#xj��P���������_��V�`.��l�h�E�s��uz�v{�{���u.�sY��)��������V����8����^1u�u��u�Cd�u;��a/�u����#�5)W�xt�l��/�<C�YIyNm.wI��W��T%�I�u���e��j�=-����:#��m/g�pX�E�X�"�lU����W�^�WY����X�sx��/����B������������+��I#��o��4�;���{{��.
}�"�tKz�u�"0��B
f��N�4~��#S�a�q��t�e�:N$��)�����39���J\���x�?Cw`��y����L-'=?c�^}����C�5���Ec�t��+�R���@,?fv�_V��>]gt��W=p��?l7�`y:��9�*`����4��u��w�mu[{��a���Rahm��4:����w��6�m]��!W-�$�D�,����\m�2.��:���F7�?\o�:MA���;��-��4�Oek������*`w��I�����NJ�7���BS*��j3 a�T|.�v=�����$I�!�{<5N�L�H�������1Rb"#�G���"����V>�,�"@��9���l7�9nd�lLh�J4;/a�w����N1�
�:�l�/<�q7�����l M�f�"#�cJ����I)���#L��-���]�RY���q���9
�T'�������A��m�d2h05*<���T2���=e��pl���ChzL?���p-��������)�+�~���E���R��YdL�6o�AKl�^
`���"Bw|�~�����%��F��yk�������La�,�HI�����;^;�SQh����V�ZDw������ux,�4�:��}�,��F�
�L���0��=��p���c~T3-��mkx.wq]
���	o��q�V��j�����dc��&�N�b��h3kI��q�A����8���m��������a7�]�eH����h�+�����]l��M�����K*'{��3��02L�@������H I���x+��E"�%Q.x��[X��Y���RN�c���0 +5r��J�b�� ���k~���5q����0`�.��Z�s/�"������7�0���h�����(�f+�ca�S�	�����<��y�=j������_w�Hk���{�'xBP��Aa@���z��l�m#����I�7�����GN��4�*|��!�zi���i(u(���Yk:�c86�_��&��C��9���/�ye5��v��.����^��TZ�,5���9��H4n�J�y�j
�t2��&����/�~V-����</�[�*
U�P^��p�$]>;���������D��D���hA�I+�~�$��U����U���+���o�8Wt8��)xY`���?<xi���GV�!O��P�y�e���}�@���UI����%����� 0�f���#�X<�Q>sP}#����O�_��J�@3�rk��cL{���H��QY���qg�u����x7�I���@F_���5�kp�����
�����0��8�\�����A&y����P�]��B�OUAA�1��j)D�Q$Pc���#cL��g�B������ZN*b��n��b`��.���/c
����F�b�����"L�
[\1���h�����pp37���W#�i�����4Yxw^Fwm��`��R0�.-���N��\��������^��� �yC}Q�4)l�#SHK0�[F����2�)2��3S���U����w����db�m&��^H-d�{�HFi�6�B�>L#��*Fi������sJ���&��������N�sc&�|����9�/�F��i���:���Q���#h����s��I��t�5�Q�F�<|��B�����8W�w��VK�'-�(���CoG��xW��XW�N=)(,-�e��~�
W�*��]�Ha��G�2N�m��d����@��N��	�+ �t��al#>�>q�*��)s���� 
<���b{��)BE���{� ��Z-�\����r�����K��7E�eU�l�����*�\��_g�`0�"����@����[����J��������d�
	WOt�H;���l�H�`�<���G��q���{}���R�}iw�$���onU��/^,>�d��k �T��4�!���x�R�]���P22s[�|9-�����(F����������
�����r�F	l]�����S�~w��3�!6��v�K�zam@�Y��Y���+U
���	,��& �w�5���Y�5�E�3�M�����Z=O����~o���76��~��2����F5,����c^z�����o�h����
&>!,J��H=wS���FVa.�����_d)"���F'���u��\���
]���2]`�-�8�H���D�TS�[�Qy��H�l}��-��D���3��+�j��H,���-��=���`*#4��{�.��5;\�(fWA�������M
��o�T���y�,���Fl�������U���Q�HUSvU3����x�yp����b�j<��]7\-�k�������r�������,��8�����X
Z]-�����R��&�|�s:����
~
�\���I�����2S�|�P�U��f.b�;6E��fq��S���G����&ul�)Hj9�3��\T{L�?���WK��R7H���jX]}%[
q��������G�.#���%�v�`>��V���Y�\)!��G�D�`�����F�y��%y_@��B��l���	M�N�_���(�%���`��'~�	�8IL��&^���� )��q�2����Z���1��=��m�V�� :��8R�����W�4
]�S��^�q��*��w�9F�9bW?hF��O/��e;�~�0��������|�Xw��[i��[�z1oL�u������t�1c�pM��t=���U#e[n��$�!j������Z�`��2X���J��Mm6�����~�6k�����!rJ�s>����x`'U���tT������YV
���l�������q�U&��%& ��?$�R�	���c�
�u�[O��D%�s����e�}�
3�������+�K������������N� ��}\/Y�B*��_�"��y��b�{���Q��+��'��l��(^=h�@�d^�Te���s�����f|~v1�[����j:�IG�Vu�j���rA����T3�~#;�������lo���Q�5{Q�������fr������3�����m�g|	h���	����L�����]��Gp����r�����K���s�0�aS<����|�2L"_ ���&7qQ��1Y�Q0�[��V�T`Q`u)����������M��L��_u�W��po�5O����2M�g�h������W�9r�(���M�/���f����GNQUt�����3�����#&�8-������ft��v�{=���O��%�����jv���!����a�)�[
��Sx��y�z9��ju�'���G�o�P��fz�B����K��6�[�ys�s����RI�<D;V���(���"��d�Nko�@IJ�qg�Z(��t+�����a����2LF����Y8.������y����o��=j����c��+��%���g���]C�~�J�������{~�K�L(u�B ��R�d��;?Q�{��<-��J���~���E�U����������~f{Mp��*��cK�������~���"��=��=x�K���2���8���t�8��j���U-�������PQ�c���A�3JR���?0B�`X%#k��D��H��U6�|{��8J��^�,#z�!�Aj�c|��e���`u��]�����j��l���X1�l����m���bn���~6�HT�c��j�����L�V�$`���O������M�Q�\�2������J�S��^��b��y�l������_���
&�TBEC���	�{B3��������f��r���6`������VBqY�@��>J��p�p:�`�T��z�x��I	��T�v��r�b����d�8�{�
l��:�|'�����$�l*��_�1^?���;�@�rd���+����
^.^v����<j��e^�]����P-G�W���p���
G�+#����Ht�����,������]mK����S��qf�����!FNx/8�/��������6O���vU�:�F3# ��I�4�kUuuuu-r��I�%��;XYB4����F�!H�2T1���������bn>����n���"������p�$�l��)4���Lv�!���#��v�&2�i��#�;-N@����S�3il��f����=	������63�j��2J�f���a��'w�.��-oK�bl�"����v����M
��J������K�A��ypP����+	Z1���5J�e��N��0Z��*->����>���L4��y��oe�A�O	ls���D��Z}z
���-���*^n�����9�ln7j��������Y�����)��A	C�F�t`���Cb����W������W�m]\����/���NJ�\|�%K���,S^!9��i��D(�of4#Y3���W������i�)��%��+��)r�t��u�n�X����LBq*wl��0qK8�q�@���D:�\{���1$G�r�Pj���<�6R0ip��X�t{3.	���I<���5�a�+�51����1S��`h�x��B"�T��e��p�A;��fkdNj�0�ciP�.[�>�� 9�5R�E�*K v	�P�?��$Gc��;}��Jm��w���P�HPE����"^I����#00��.��[�8
Zi8�����v�Z��s�m*SLY�@�B��E_F�D�#=��K�e���^������QQ����M��l:��>c5�E�E���J����4xS`XAX�2	)D	�p�9������cv���rR�r�|���2�
`��&�������Y�V/����s��$��C`H�
x9"�8�C4������#�[�[�.+�{���ug��P�n����B��,��������X�1�~%KY�t����(�eD�FM
��"�O�v}/�	v������ez��u4D�>3���?��-�/w���I����l�������K������q����uk�	y�|2�@�(<0�'F�f>�K� �U�}��.�D�R n�
2(D^���_ N4�=��r;��g8eGtL/�LcZ�	d������~8DJ�M��T�qx��3���E^�kGa��(@_���:b7���'9�-`�q����>��N�{�\g���_�<������+c�Z��K^���F�	�}�F�����O�k�[^J��&DE4��sO������x�B��E�<Q}��n��DD1-2�����j��W�7�M�m+?>6��PQ6���h:��=�t���A���[|vOJ_�j�����
U��L?y�"T�F��d��K����Z�"=��u2�r@�b������Xx�qX��mB$>@H�M��K����[�����!`h�d��%wI���6mM�m��;�L����K��8�+C�h���a_��J@��=�lj,0
J�k��d��������m�l�"�?fP����3������9j���D�E�.�u���t'{:M����������l��*9\�4-X��([��kG��J�H�M�dNa��_��5(��8Hx9��M���
�^�&y��v�)����(�1Yd��,��Xk"!mz"��%���%��[�J.�#u^��	ljr$`��j������$eu�7@a�?�����x>��Np����G��9�S2
N�AB!����5�����G�L�6�6V���a�	F��`G�L�����J���U$0�-�J��d��T��k�������+�^j�v��7��yCu�{���p@��7�����JZ��0�����-k��q�MV����b[��8B�m5rx����]!�s��fkQ6�t"�lo{C����Qy���>��������^�^�������s)Tj�����W2�=h�(Y�e�0U�l�	#�T}��;riLv���-�6��ww�_OZ�)j!h0L^�>Cc��]W�������Z
�����6�O� ��{�J*j���=�D?�z���pD�
D���A57��0`��-���R���H!FgXt�d��������R�I0���s��(�4���e2��
�9#�����9ULwF���k��7c~�!]R����AD����a�(�>�2�7�����!Rg�g��9�+cAYz�BuX�O��v"��7���*�5m�������Gk()-��^��O�
�l�`�uK,��ZU��pR�y�)��n�u����u�P���i�O�I@�h������ongw/�7���\��`�#��:�r���-��E����U���s|5�z���V�z	����Z �B���bJ4��`���Z0@@���,G�`�>��,�����|6��h����[-�+.m	�b�M��TFPb#:��N����O~�J$��6@d���B'Q?�
��H7�R����|�Y�!�������P0N��- ��D�@�AFc�zU�tn����@�I�T&�;(��e�P�KJ_��sO������v��V��k@��a��l���H��<�PO�f������QN{��:���k�����a����m��'����A0B��I�`�b��]RM/pV�Y����o�����F�@+�X����g���d��I�+\�8�
����!����dc�`��c����D���H���z��@�u���;�5����@D��!0�Ky8I�����2����q��;��
���J���m;�W}�����Wc�8D��P��c�T�|�V�(���,�L���,d�b������0��������6�GS�s���p�-��GzB=��r[��{�zk�Z�B���1z���_jl�YK^[��+ju%GZK��k)��-���x�YX\z�eH��������O?����2��{�S�{�?�~���o_}X?%��%tW�HF�[���*��B���"�^bl���E�=goO �;���]��
��������PY�)����n�1*�����p���8>�]�f/"UE�[Sq�b��}��G����.J��TZ�R���F���t�_�W��P��2�f:��g��2����<��M!,���?�4�4�b$�PO&�y�\��=��KO1.2e (�0GK��Vs���e��h�'��h����Qz��L/����]������X�Q|���7���^��Ai��%��Pv��$L1��#/��H�:�t�bYQD)1���2ft�&E��j��/R�����l��^�����(oq5��[D�&�A'�Xe�#3Q�!kNl0�I��J/���A�jw����&s+���n��S+W+M��r����[�H�^���M/&y:�_�[�7��~�D�c5��s��y6���n�q�:��fA/������=���'X����LK�P��������p
�I���L��3���q�a�Y������_�e����;!�]|2������.>��s�l��l������m6�v'���x������E���A[-�d��M�>0�����0
x>I���@q��"afX��~�KN�
P+0oRCh��e�!�]����##�R����&��p~bFh�DY��|�o�,�0'�����t3#24�\(o��Ey*-�Ef�51�����/�����6y����Sy������M���60��L�s�;�!E�����WWt���,��xm$=���C���*��]���cZ�%5ARmI��kf�KYL�%�8o��9�Q�]"%d���+#�9}SOZ6j��8��m���]#,T�F���,Ft�|J\�o�`z8�H���bm�
���(���e�+�!�PW�����A�VML��d�����q,�
������+��f����p]�b���ppGL@��
�m��O��(�u����l7�t>��F~_�~s|V*�O�l���l��/8J�lnr�)���\�VB����0~�R���!
��@o� �E��_���������������"j�)�5VA����_\�,���[x����!�����/N�vI�hy��j�b������Qg�!E�K��1P����G���.'k��TL�Ab�9C�����������;�bA���Fu!������#���>�����s�3��9,;�1v9lhS�������k��'�8����|=��x^E-���<5E%�3!x����<M��y7u�~��������A1����:0�4�������oz�w�8,rI�C�a"gv�'��r�D��
�C��k1d�z�M�k44��p�2;pB��|$W�q�V-�������Dn�kK��A�onj����7���-)�����alZk���q�H�Y#��r�q�]N�u���)#\�����Z�nq_�i�C��P4e��c����^�2s1�J��T���l��ZM���h"���`�Tn��EPZ:�"��^�%�H���^��;��-U�9�R� a:�0�J�s*���dV��"W��@/+�H���0�oqU�����+i���X��fW�d��(��(T����Y<K�aZP-�\�V�ECXb��]���d\��� ��r���q#(���@��Tjj�MK�w�g'J=-�0EJ �KAf�c�W�^w�������(�����]����/g%u`UQFW!B������7�AW2�w������s���wt8�c���h:����Q���|$]�q��*����$����6
	"v�,I��������gFI0@�p6"�PxZ?�'FOJ���������$j���l��C�����e������A��OUZe�����������7��k!V�e�Z�zz�����-^W���:7�}H��|�����^��V����M�+�2���xSu9t��E��Ja%�,���8��KO�z�;&��y� ��M�67-��e�"�Q�]TO�����������5����W'�?��.:���9�8FZ�w5W���gJ��
�6)��������������`bbk� ����W�8���Wvq�j'�l���N$:�V����)��&[vF��sY�N����o�m�Xp-�<�ZoXk�AI�^p������	$b\��%�|���:�Z�d?Qb<P�n�=��e��
��s���h#��q��&��u�,�2�F��6=s���|l[������F��Ls,�Z���~�|\�yUZP���k��1����\����c_��(��\�w����]ex����0�\��k��-����r��L�����g��
�9�xVC����h�9�2�s.�^+7��[�����blar���]�#2����@�/�JI�So�����Ce��H�X�J��UZ1��CM2fw�2�|$�q^X�<��kEo���b��*�+���e���}����Z��{~�=����bU<�/?�GK��r��@��u�V�6!}�dnV��K�@9���7��i�����9�;���]i��TJ�����*kb���;}�7��e��g��e��&1���B�������z���=��*V����U>��5�z��L>-��k�Y�=Xh��aZ���
�f��CbhzN�i�,+g������4�
[D�dN���������V�1H�nxu�Q��M|��n3�I>`VkN����lp�Og���4���(;�F=@GT��/P����
�y5N��4<�;H���Y`L����lr�w��-W�ukKMn/�N�R���F{���� �K��1� P�v�"��5��w+��Zs�\o5�^��f�c������l�1�l�D=����p�+:a��8�j�u�M��YU�5�I�d����R�O�7��r\� ��/)�|�����N�X#���tD�87}u����J���D
���rZ�T`~��U�������+���}z*����f���
1o����� n��f,D(�a@���0�M�e'�/��D=
Unms�����Uw+���jT\������b3��XgMXg�j�:3n@�*sDp��o�6�+9�V4��-{+Q�C�z�z��RB�d�xH��~]:�u�K�����)���j���A��a-}M�P�d�H����Y���Q�6���2��t$BTZ��ov�g��W�1�1f!�%���6DRb@���[C�c��|�c��;cn����oP�d���?�v�Z���'2er��]�����a�-}�+U��,PDh���HhD�D�?����
�NB�\���
��2YS��r��W��;�V�R����E�p�?k���y��h~�Q���E����EVT�3.,�e��@�`�4�� ����P����R�7�eyR�l���O�d���?��>\C����W�~���F��P���4n��R�@)����T[JHH7S=41��F�=5�H��8��p�x�L�s�-���W�\��j
���gj���G���p��R�.�	�$�k|9W,7�b<�?��7_��A[�t����e��)2a��c�Y�����	L���.��YA��b"w!<(K�6e=
�c4KQg}g2,�d>5���I�,�E$O����5�G9bR0�M�����1r?]V�u�RQ��$��M����PH��
#���C��!���T���@�������	�
�o��y:��NQ�s��F�uD\G=�=b��)���hn�J+���9/#bH�P�������SMMDE��18�P�G�q�����0y����0|�G�B�E _1��o�����df)�O���@V��P2�`����w��.���-�6��Q<���b��s�!�4����x��l<�T
���J���	�!���u��y�4�!�S�d������V���4i{4�k<)qY�u��������?�����$i���	��o�3���9�m����&���)��
�|�A��\�!<���h�@�����8�7.��O	���h!�l��J���n���/E��O<��N�l�MR�+Svaf����qf��_0�=5�Dr���'���J�!��Rq����^��0�������{�����b����(��{��2�NB�����%H����~S��)1L���
R/���H��*'�>��/���(�!3P1	�_�0�,~fU�k�6�`�e�%~X���� ��_� ���&���g�s�5c<^B�^w1�bx�<��]����E��N���	�����Y �(x��	I@��������J�{��
-��z�u�����EF��� �TL%�Nlz�[n���P��ZD@��{?��/3�(q�g����K��f���h�x-`�W�b�#�
�fF�@G�0��C�^t�6�1N�=c��=��p���=�Z��G�r���/�����v�:8"�������I-���6�h�� 9\�u
�h4<��H�1S|���jim���t���@ 0"elT�Ryi&����D�<�XkY�P�jj�O��P��H���C(�,��pIj�
��S�4�yQ��x8�N���������h�D�uq��^��uk��q`����� _��>d������G���x:����������=G3_2��:�_�5
��vH�(�6#on�����<�������b����
)"����x�]OSc�������
��j�����@T����=k�3|a/�e�.m�iH`jE!mT���]d���(S��4�I�(�%����d)�u��+���j�H���"]T���(/���������'�<�2G�W@ac�(�`�tv��>�Rg�K�;�?��3��L�Y�J�+����#�7��I����	T��pbH`%��5�7\�~:t�0������Q�~qr�y��sg����o���J�
�!x{~x�m������v���}�I�1 A�t�l�M��}f�7����}�c�#n����9�4g�V����|��?�9G��SJ����!�Z�D��c4��Q���n�;x����BR,��r!3b��4��S3e�r��T�f���-tRi�������Q�3n�{��Q�<,��_��)����gjHy���J^�����qX-�[�<4m
D��i[���[8�4����J���0K�k�a�����7h��������{S���{��|�d.c����v;���k���X��i��{C$��@��j��YhFRC�5vCrV�x�(����kd�]����"��c�
R�!���x�V�M�����P�7l@E��%<IA1�����%k�*�����*c���:��Z<��<�E�sI8���D�YOL�����5a�E���#k$X"�������[\�1.%(���J��'Bx7�����0����I���(�*�9����U�#-�7������F!+Z9����j��gU�F���Y�CX��� �s��ZWM��3�����#U���y�����$��<����'>&���x�|~(G-����cd�v�=:t�C�5Y��I�%�;���~q�|�9<8j�T�Fw>�H�l��F����{r��;�
�
z�Rk��o(i�����O]��hL���:����
?�C������6�����l��-}6������=2P}��:��t��h��"��9�s�	'a�-������1���39���N|>V�K�`�6W2=�;�I,�P6v�+����|
�Q7G�>������)]+:G���Z��q���&��$��P�Yx�a�#�d���(�>'+W���
���v�3�J��` %�_�cr��2�>E�J���\r�
M^�u�T�G�@�y+y]O�=�{����#�q��E4G~	��`q$��.[�_<������o<�pH���xQ�*$�'b%�931dIs���bI�����*!H����
f�~0�"��+<Xw(O�%��{;�at���|/A��(��8�k9m�n�����wd�!<$��~G8)l�5�VB�����m�o1���^���)J����7%k`bA�(M	j�,�������������_)���gO��&}Y���`���NS�J�2Y��������7�����Q��o����e���w�R]1��������+����1�X�b�X�!j�Y#����o'��?�v��x;;�)=c���0��E�k������uoo�a7�� h�^�u��|D����Sl�|���C�������{
T����r�R�BL�n�{
�	�`}��1�%�1����`��\
b�����wMm�����!���P�Mu��Y���4l�*=���Z��%���2�c��n� ��9�Y��tCUQe2�@.�|%|�vvv���n�����s�hI;���'/>UN����#
Xc���!@�V��;M����N���1���b��������6fLn���8��-G*@��4#d?Hq��[5Z��x����19��y
����l:���U���h���c���w��<��"�r�_vCN%������u��_�M�eI��4P!�,-@��%����1��6:[�&g�R�
���l���0��rx��9�F���%��x%gXcS\X��o0�����yt�-8�kv����c#���D�����H0b
�c�������eq)^l��U)���3z��J
_��n
.�4���8�{4e�d�;����D���8!f@�U�r�q�v �e����F�T2��go<�W���������T�Dc��������|��X����wg�B�):������9��|��t2������W��NN�sntI-�����5�N;����S�~��
~��b]o2��/_���?��t��)�{a�>

���lH�=�~*��L�����Tdw��TI���aK�4��mW� �T�0�Y0X�z;y{�9y�y�~sr�s0�YT	��1r�7"��z�2T]<,��7�b�L�����jU+����II�����q����o�d�����KlL6%UH�/��T�$��&�c��`Z�Bo�S!4v�(��y�#0�$�#�M�4��#(rw�s��/�Lau#��rO�C���_�����El�7��=���f�Z��FE���}B]'2������D�6������!AF�]�Sw�x�����	�X��wf�K�K�a�/#._��r:���A����{`N���'2�)X���8���AlU5)�3��c~�O4C8w�O��z<H����>�6L&U%����xl����
��Z��G�J����7x�;�b�L���|���]]SC��"gV��@����/X3sc�:����L+j��t!��g��b��&ZhE���q��Z��S���	O21!�!#����6�������(�A��K���T�k=	p-�x~���-JG&�^������R�u)�{l�|e�^�z�i)�i$�Xw�0��Q�2g����@T
iS��
����z��$�]���1v,1���h�i�fW6R�!<�����U��h���Z��Y}�~j�0?�cy�v'~����}��SN�wZ�?�������;��?��K���2g��F ����6�i���q��P��K�s3ARp���{�4-Zz���7�B�yT[G�2#���{�K�@���HI����!��j1;����f��|B�|B[�	MR��Oh	���Z���'4����G{BK ��'��Z���x��Yv?�x�2^�}��
����4S�j`Z�F���L/O$��%.y���oF��@���4��"<<9<~}r��������v�"!������F^V��N�TZFO��@����Ax��^3C���
��W'o���aU���LX����M?��mh���������IfY��xX�.l#�%,��<�-��dSV���?) 8@N�/:
1��O"�$<j��H��oZ�[x�� �S�����'
��oToZ�F6���`��2.����C\5}l�
����?�,�b\�T]r���D��Ii�;��t1��������`^g��BR�I�Q���FN�
����i��q�[�E'���p���[�E.G��(��m��?���-�y8�������J_���e��h�a���?�_(�
8�����������Kqj�%\S���-�*f�M{[:�D�A�**G	�r���Q�z2���DX��D�T�1���O�8�5����{��"�shybx�	����%��j�f�a���+JD��B�� ��q�E�^�������9��L:��^�;`�on��?�f����z�:;;;*��{~Lgkk��e���m�2OaX{��vlb�~��k�:���i���L9m�*:�$y��S�#"��&m�Q�N�[���� �"x�H��e��Z���7���������#��fY����0e��i�
������������]s�H��$�����0b�s�F�<�1�z�Jb���?t!�p����>����Mw���DTVh�gK�����%������_�K
���}������9jw.�;k�t��_�/~F4�#��|��|f%��/���R�������i!+`�=�g��$c�i�/�n�$��<�*n���2��x>a���O ��=���|	�C��J�"'���u����&
q��/���2~��~��D#�_!=�������w�I��&��-\�������uGXOv���)��a�"=o�K���j����k��69�m��`��
x���������Yy�I`�B�2�*�����n�{�t)���<�%�shn3NJX������y>B/S��
@y�Y����/Z<�a�	�1z8����)Pe����R)�V�4�m������G�fX_lc�Hx�=�#�������m_���
�Z5 ���	������
KB����E�!�������T)��u>(��Q(QR,I��iu����')��J�=��2M���d;v3�4�����#������q���e4}��q<@\��A\��#8���C���[UmC�h!����{��*�m�-%5<�L�/����]t���	>'ojT8ojjd������
$z��Pu��JF��}�����#�C�?���@	,�b����R����)�+(����P���;e���
��C����?(Y;��u�=G�X0�*H�2�c>�5���t
r#�
��*��������C�l.�\����G|a�:��o��A�Y��5b����d�q�?�
�D����I��"K!�*a[�����Zi���$�F�7�%m�5��\%��k4)O����od;�Iq�r���V����j!�� 
-3���Y(���j��MW��WL�
@��k.u�^�[�R��N#��B�}��1������T�vId;����!m�>M'��_P���j#&E�h�����|ur|�J?�d������v�1�?�J�_�7������.�,�)9��V����Fy�$R.�b�JJc�fh���X(��A�&>��B�����Z��I�{%?�^^"~���Fcx'���������$F(dK��j�hi�k����K�s���@�Z3u��xb!NDh�h�OBq-���; ]��<�u/���9��v�v+:S��KL�NS�P���4�V�����g(D�j�bV:��#���R%NAWR��J[��M���A�{��B�������dt�)���O}
z�gt����R���Q���v���<E-�����7�
`1�%�w9��%x�5����H��Z�z���+.QF��8�WH�A����f�~^����x��N����fC!���)6*�$������@'�,��u �_��/t��'YKbq��Pw�f�l�f{!>U���������E"��9�%�c��Rh�s^�+B MGQ����D��W��`�:���\^��~or{	�gW���;�OW����sUx�����w����<��}���V�#T�����[�.��=����jk���)�l���(�.?,h��.W��s�]��[������ynU4ul�����ZP�xu���r��;����J/�2t0�<Tm������q�gM���x���
<���g�,��6>q��6:��!>����x���J*��G;��aM�3��*
���sk���n�����Z�f0�.�|�]��W�u��ew�Um��5���`>(���jM��5��GL���L�2���X�a����jm0��R��T U��o�W�*(�T���ZsYW�tn��mh����-Y��j�]���ru���N&(�m�X��'�0�������H[��l�4�Dw�Q�.�;.�����x�]��#!0��UT��^S��������
��ya���d�������kV�h8���a��e���
zK-�����t�wM+H2\�?#s#�q��l~K@|����x*9X���`����F����Y9 =x�64kB�GM�
���(
�s&0�@���7�U���.����;����
57��!"a_�!=��[��l/���+���{C��Gg�[E���^d�.��������~�c]�����=�#������
�=
	����E���
��q<������!�w��&�����n�ij%����W��U��������&�2
�"�B]q��=6�Y
��+.�r����G��������h�����0����W��q��@�F�������/�;����`��"yC�Cu��
w�}
�z|��;��;|C����SF6���BZ,sP������r^J��9*�"��]���#�t���a�f%9\9��8EEq���&����'�<�[j�(��C�Mh�,�R�$[N�����U�Rl�:U�i��*�����#��#�!���f�:p��.�����d^h<�����|X$2-�����=�Kx�S���R�{�St�����
h���?�����K�����t�}T�#�Ju�S���AW�h�5�8`+����"���������������v��s������Ex��3)e��Q��.�RHJ��@���0fu������n�
3P���E�rV�n#�����&D�#�vB'�������8����v��&;q	3XH�W������YA��L��cw�[��~f��j;��'Dl�4��A
��*'M�$lG(���Z~�E(��&���+7�Sv�kr�J�R�����b������z4���6�[���L��v����
�\�:Y{�/��1Py�[W���:!�NXR80���+�PT��{�0��T����.9
�fF��h~88�'mf)��a�J���n���!���i��@��h4��1����ubS���n��cG��"��C8b)�����!�J�r���T�I��z0�"e�7'c��b���xYOzs^��a>�+���x>+�K��x��c���Y�)��g�7�Q�%��J������7��Z����n����;�j�m4+�����@����
�4x�}3$���>{��h��s���}Y:����]����~s�v�(���j,P���W�>�?�h|��;���;!���1��(u��DvD�#x�i��>�;����xr���*n��V��`�����5|\qb�%��[,�E	9N6�������M��[h��`T��a��XL�-��/F��;=�+��>P�hxG�����������8tW�8pT=�,B�W�F $��x`�u��${i��^z�S5��-Vn�z�]��SkU*�Z�Q[~�Z�WxVx��p�NA�����eyW���=�������tziB���1��e|I��n9_�H��%yb�eV��b2�|D��=s�F
`	*8���:��Z7�.�s�hl6���>����f>���g ` ��WA�H� R�]PtWnb�CW����I.���|�e;��NRT����Uuzv��5�}�g����t�{���lk~W=��s3������n���s��5��T���(����8_c t��
�����cd�����#��&#�JK�(�:���&��*�DP��2
�p�0�?���v��Q�<�p��m�hF�:��K~*�(�����2a1u��P�;��%�������*����Y���R&CQ<L�|p^:��?|w0��m���~������;�'t�������\�������Y����S�������e#\����]D)�%B�`���9����s>�o��� hOJO���-7�a�(s��� l�av���|t<<Vj\���l�69���:�J��?
����z���M�0bzm�kwq�D���9���?��9�0@:����jTgc�Y���z�9Y������x���Q�b���M���-��CY��-����E&�F����#~�i��\����#}oT���C�6U6pco�4;�~IF�o1�3�"�l1���j�z���-���V=
U�9���l��tD@d����Z�'�9;k����qxX����5-�h���D���ON25�� a�*���"
��)��!�g�:���7c���b:fK�(���u����&x�&�ApG�?��D�(Qcv-,s���^/���K]�OL�Mi��>0�V����**I�)�W� ��P!H"JCk�E���j���'�����~�}	hWR��������W���LN����z���\��,��'{�������X@I�����t
[�9�Bt!��$�_�����CCR�3��$m[�Y�e�KL�.�����z��r�A�U�g��Z���S�{�V�u3(��f#4f
��U��Y��Q���ZiU�J��]�qiQJqK�C�-�DdJ�xe!L0>P2����p�6�?�w'�~��������	'���W�����"�H������uP�"s������}"�wpd���r^����F�����U^��M�&o���FN��j����3��?����c"����u����izY�LL��T=}���*��(��������y���2K��J�:=E�x�����������������������N��������A������5S-�"��-GX!)`M����]��[uw��[����F6BP
G�A� �Z�LQ�[�^�y��r!v�q�#�m��h�gg�[�b%m�eJ���h{5�;���'l����I`pl��5���2(Y�����GM_O��.w��`���p�f�q����d��^�\`��)G�Q�8���j����o�����P�ok7�+4��Wp�F��c��\(��
�b���]x
�Z��V#�#23�.�E�Z����m���y��a��A/3p������<�&h�<�Kn(
����7l,dp��B�.#
�`�;[���[^ZF�����Z�[6�N���n��~�=J��������}7�3���PF��S���x�y����3��DL�N�w;�O�q�/��.K*"��s�����t�v�3��R�Lt��,2['�i�V+����[s�z���E���cOyk���������V���m�xu�������s�. b�p��t��Yw��l���j�z�K*�	T��Y2N�������p�q�����nf�^*����Q��s*�gPt��x���
Q)�g�>�.��]�pH|��o�0���� q���f�������X6�e��	xu�~u��L�_��(i����@g��'g����	{\�f���f�0QN��*��2�.3^����~�t�}R��hTY�Gu�v�k��R��V�;�r��t����"�������N����F�%��.z����t<�u�}�����|��J��T2\rk1���tQ�%��ZE+�=(�����������{EC�%�{�",��CYi���03��
&��:P��:����Y>�|�n�9=[��c�����������A0�k������2<��/GS2�y��A�����p^4D#0z":��
fj�`�r�`��pj�hi�(��� ��q�����f�E�����2P�VQo%���4.�N�VKv�����n��F���_�����eY���"7�uK�b3Z��K�()����;l�O���9:<nw:{:u������iK6���.[��^V�C��X/v���'����,e������
�<��_���z��5���C���4v��I����RJ��=a*��(���a��O�����6e�ddQ�������{u^�5J�h,s�Ka�E�VA��#��7��^
��d������W5e��o�6+�K��n�ke�.a		(�Q��3#�Sj��+@O����]tNA.7m�Q���#MY�*E�R���^��) ���[�`�'����f|����>�*w8����3?��?�@���W�'�)�Z 36�U3
@�`i)\�����pDg��2�|5����}I���+�LBnvp��,��fX����}:�A�e��cw5~�B=ep�s�NHqD������E�1���I"��a��Tj=5����K��m���������W0�BM�$�?�����@�Z�s�J���+�D���+��i���p���JH"m���C�K���7�n�K�����w�"��S���a1��6�Q��D�/�R6C�<����mH�SJK���Qm����#��i��Y��[eH�gF�8�r�Vo�k"��
�x?��w�����gg������yk`�g�:�������/����}cw������u@��UbeVxF�NX��� ;�z�F�����!+�;C����E�]�p����?OxQ����K����eV��E�����?��!������T��'�u�N��~�%�l�g���� �Pwu|�����ePY�j|{G��� |��������C�`�(����p~3��
������8��e0��2	~����f0�'P��S{��>u���)�	��P��3)V�^��\��$&0�������G��"Q�a��N���/]M�����m�5 @�rIBOf�n���T��{Q��7�lhu�R�A��:���p����3��%��Sp�\��?��8>[�����OE�E�TL�<��#��}Y�������������q�N�������s�P��I��%���� �=l��h��(@��:5�X$�B���8u$�V���2"H@��+.��!��A*Z�Y<taPs���Z�:��!�<�T!zq��3����p�Wv5
:����&���Z��{�Bc	W&<���S�E*D�UEM��Z����Jc!��������v�4�b��e�_F���ZD�+�����Y�h������_��X:'�7������K�\���
F�H���	���5�|���������V����pX[��Z��.S�-�� �MD���>��F9�2�(-���KW�<i�a�l��z�m�a�WmV�Z��Rr��4�xE��H�I; ����Q[�cG����(��D��P��������A7�+wq��r[.FH���|�M�j �IA>��S������E��a����AZ����o�}@�����7]�Y��?����w�B*aF���m�r�Y������VU�S2[�4,{�����|T��Uw���V,��k�����>�B#� D�CF/|�O���l�tK1��R~X���C4ltkN���l|d�j��������7��;.�q�X43]�}d���T<���Sa��S�������?X��a���{��R�Do��Y����YD�����2�T}���`�1�K�6t'��Y�
�[(�e�zq)�6�Q��9@k|��W?��t��)3�Wu'�����T�NMH/��-�P.��#�j���3��K�Q.�����YZee���Y��0
��~��U������W>R�,�jz�5�N�0�x��::97w���6
I�hvP:<������0�D &#K:Aib�SA��u�ra��|�+-<$�0��V�4I&VIoN~h���6I��M�Z7LR�UH���DxV���W���*ohC� �z�1�rV�9�r�
�����Fq2\b/r����'���4�VY������q���t0�M/�*)��S3�f�5���v���V���#(�oG��gZ��b�;�\�RGh���6$�	��z�."P�q�JV����^LQ����h��l����K�6>�s��(�t��Q�^����$Y�b�����+;��[�V��JB�����������%�w�u9.�\���A��z>Lg�����v�S������N1�|������qvO�<Q�7#)��88H�R5����d��8a���������S�} ��n�M|��Tz���������VM�e�����7o���T*����
�Q�V����3�*���?�������4�b���]>?RL1�|���ysv$5�JL������W�����j����-D���s��#�ox~���2��bz���$�i]����
�AqP�4F�=�w0���1�n���b��)�$�kxk]��uyEA����
c���L�(A\�uJ��m�������Gm��d0��P����_G���6��vr
��&����G���T�����x�'���#�p��M�u����h�	���.(�~XT�y�6i���u������}F�
:	��A��=:�he7�o+r|eeV�Ln��a������M�o�\��l������]9lj�r�Pv�)%P�������"�'�y�w��Bt2��������J���D��|�q�{7�Af;1���,���1��f�&����&f�01�����S3�<��V�jfz��F\ �+m�;3Q;��@��9�)��Dk�~��r�*��ZzM�^�q+������/8�w�N���|�>:���M*�C���/��5/��Y����9�|�b���
��/�����}�9?����@
3���;������9:+�����7J�V�j)��;z��T�o�U#��������j�5�t�F��#���������UXUmM�)��D!\�\OZ�)[�D���P ���`�������j�qk�d�|��X�;.5q��bS�8�g�[|�� #T;�?��^L<[����E��/o�:��t�����fO��P��6���M�#FR�����!���l��R�K7"�Q	��d���:l�}o0�=����_�Nv���I�^����L�����w����5+��E1���,��m�n"gy���^�f�z\�����J/xxt��v��C���)!
��jp�6�6v��LXr�k`6�K|�|8����anYM�����P�7R��N��0�o=U�]�9g���iG���a��j>����^��-��u�en����\�1�'�'�C7�-'=� <����I3�2���F.���f�ZfJ=����U�V�$��.���&�ND(q��B�EO����:�S\��z�*s�����J�U���Iv�t �v�����VR���c����
�L������W���M`<#�Z��2�Q8]<j)��e5�`�QF�2p����}�����=CK�8;��P��J�T��1��3��49l#�$������%����h����_h%�p�ff�z�j0���B��0x���[����� &fB����k
C �6�p*�a�K~�I� ����<��X�;�����F*����K�(�	W���'6����3�;� �9�6���M�������+���bN�������*������S�'�����,	����F��#!i��'��;��6$��S1��
[R�*l�L��&o�hN���w�O�_���dF	�&z}3X���)�0b_��.T���UN�`#�K6b�-4"����N^sIL��
�Y�����R�[��	�g	��K��S��Z���Pz��$Q��h�	��J���s�K������?���`=�f6�7��X
|���P��$�j����T��!�����X�$d+"0g���D��A�-F�nX�+i� �yu|�����qp�����h81]��4N����R���7h���}7�`�E���m~�c+k�ncY������I��k��S������s��Kz������?���I����Q-��j�/*YLB��kD�F\��(������?�~1O�����N����Z=����7�A�]��9�<���^]p{�>���;�
9�$�ve���������������u�DD������w�����Gs�����n���_��2�L��=��������Ax��|�U��\s��f�?�%�NP�l'+�K$���^�y�]���y;�F��5x��r��M/K�$��W�-�^��������D|\�����������AL*+��O����6���O�hLM8���z��%H�p�Q�� r�Tc:h<����W�Gq-��1�&}�����??���D_�?��((������������������<�NN������J��������&]~P^N�$�d�sTYp#o����ew���iy�z��X&�{B�d`�����^s���[�j�U���-�]��H}�l8��2���ps��:���.�@7�u?��@{F�A�8��c}�o��R�a�����/RX��PF�;B'/9����X�tNQ	���

;�|��
r���Uzn��(�5�����N���o7�#�����e���l�:���3��#G@�����O:��0U�k�����6���G��w�+:��E���	.u���\���=���_"��Sh�u5/�9}Z��k�45�/� ����#���m�vC-�cq����L��^��)��]��g��iG����+�.��`��p�
���l/Tor�����T�|I�*��'����������0��fs}S������/��<v���������*�so��3���x��zN��-�����tn��J�<{S��.�����w��9���y5'���*Vs����o��6�J�b^�s�Po�A���p�[����f��)���f������n3��0�*�!���^�LW.��o��w�������H�O9"�AX�*����{���z�5rqP�T��,��*����7��C�NVUt�"e ���"0
�F��������2�
\	Gb����	���1��!��l5�N�e���)���?Z)��=��oW�WL�P>�DH�)\�c��L|p�QWI�
����D�Q�k�o�/@W�$IQ!�0V��]�@��:����A[�z������'�Q������w�����Na�p�	�}�]�e?�����D����A4��CB� je.�G2�Kt&m��P7~-o�Q:���`�9��S���;��$��|��4��	��Ow�]J?�+d�Z��1�yt�e7��J4lf����+;e�u+e�m$h��5�e�<�O����^L/q���N�a��f���jaGTQ�?����0��?y���L
�Fh�:5�E��	AT����*�����[��4��f���g�F4������M���*���v� _3HK]��5����������,���Z3��T���1�$��G!/��8k�@m0��?&�NQv���Z��c�
��w��b8�2�x oE�����'
�7[�������hw9+��as��RP��3�pzf��#9(\o8
Os�F��HDC��"����z}��>���������VT�@�-c�����*�a8�f)�Z\�1I?V�|-�h��u��^#�C��%�b3�
����;����T`����hs
��>�������z|��k���r���$O�h*82�3P!M�#G9�������|@!c")EsT�X�N�i[V�����I�_Z��I�������Ju��������V�v!f�������w��j�Z����%0�/6I#���7���<�~=���z�Q�	�K>�c���������7�d;bm���K�6��P����U:r�DE��m�71 EzKF��]���W@A������w�N�p�
�B*��SU"���tb�]%Uu�_��0���@7?����������������2�����*�	<�$��V�.C(MCWt��i*!�H��`l��O�s�����TG�F���
��!]���&H�`� � ^��y\f���,��z�.�toQ�8	�_�d�����S�k��������{�>���yiY1�j�qkeS�Ts�f�����B~�%J�/@���1mE��a��eo���.=���V5���R�:+�Jx���B��0�pn��B9\5������L�
[$�G
/���/�1�`N~�9�����x��I���zn����[m,�l('����'��7+M�p���xR�1'��a�x��D��#�\E ��t�,:q�V@�`�7��Sui�s�����U��|���G�#��
f���T��^E�]����K��7KT������C)���x���'3���P,���H�t�^+����8e�o��	�l�Fl�h'���+��to��~��.p�G+LVp�������$b�'��W1� Y5#�����UD��KkFd���-.�������@�J3R��4v*-�m�p����cOy;C4U�`L/X	g�*;-#�9��&��q�)�6�=��K�1��'u�	T��>����Ca~��u�q&��o��A��m���9�n�`h�7O�g�k^�e�����z��w�#��7�k���B	&������.�����q{C��G��k�l��|�H�O ����Q������.�T!���>��c����T���k�������z����W���q�^��4*�z��6�nS��V�i��a�6}��*[�u���8�JE�
\��v���y���
��C+!	E%�E��hFF�4�+�?��8��#���%�y<��Q�H��S�0.�	�HM���7�Zy�\��F�r�@�m�*�C����$��_v�8M��x��?��7P{>���a�~.#WD=�6-E�)�.�B�vnZ�tf�����r�T_���?�M�d���3V���N
�6��M����wi�Y��7c�V�{�Z��~?]��0���@~�C~���f�J#�a�UVr7�>��[��l�5�����w{W��^A�4xZ��
:�aX)��G!1����������<n�z"^���QxR����F�,�8�E5����S�UWx�U�y9���|���y&��p����F
�9��bw��Ep�*p�JL��8\��.b%�8zS���U����_�aJ2Y~i�CF������}�|x?��_<�g���&g���(l��V.��gCa��'�0�lr���9n��
���-��Z-
��3�0���Q�}6�Q�5�:�������-/
��3�0���Q�}6�J!�j��W
�$������ctV��=��xVn�BEo���i���r`�#vgg��N��T:�C~s���KpmF_����3�eF�z$2<��r��i�c��S�)dCT���5-��6<.veD���,��-v+�����wO�V��l�~v��^#��n1Q�-kg>�N����!.�/G*�E�$f�3���0��,� �'F_&��d���3�����������#�G�(K�/�Ze\�uS�l=M���J#�������r�
K;�%������\���
�5��u�hLw~����<��$�r*N~���3$��0[.n�	������:\r���?��CN����&#'�X�P�w�+��
��V�=����ky�Z[���G���e�Y_p�UT�����~>�����c)���O���P��W��� �Us������������~x|�>����bw��t�|�7��G�rx�O Vj��RHA�@�&p�;��%Y�����A*��8H%(�e�9��<$��4��0�=.�W�Y�]
J��!��nA�����&����c.�WZ�[���F5��(ny�>j�z�]���$k�x��H �����<��xn�<�I�X��pa�e=�5�"���3�����k����j�WYtW�;��3i���Y�J�S����R��a�C��X�O��w��Y�-{r�j!�q=���3z���%|���q0o����e���Z);���s�
nx���[�L{3�t�=��,�7��r�CLg0r�%8������g�&�'��P�q����Y����5���a�A+��[v��(���M�_x�����v�������W/�����?���G�2�u����������2Y��A�G1��_��\����^���jk���*b4q��[�V�:Naa�J�&�=�_��v�j�������r?3�_:�&�s��S�������	���`��8�z�z���.�E�\&�]"/�{��j�5gAi��60�5dZ��E�'#�����4:����&�c�Y���A0]6������]%����jV����7��:�"Y�v���|�v
a�f�kn�Q�X.���^
`�Va�\��y��1N���4B!	��)���BV�wwI��tdoqV6)5/{q�O}&������2L���S}H� ����cP�_����>�v�_����h|A��!��������M�d���IC���,�����J?9?o?K?mnq�8��77)J����Do�����?s�W���F����&�V�;�'S�9
���uz�Op���J��v���r9� ��B���w���xL�|��>9{s��~)�@]l�a�28��x�+B%����^d�~�(��D���t=�0�jR��kq�������7�;���*��#��@�*��{N&Z��tM2qb�qMv>t'���*�U��h��<���tx�V���v�-0��x�2,���d�_<���}
����(��W����i.��5�m�7���C3~�v��H�0c}$U������%�+
��~g�b�9l2�0eF���ZM`B�j���]��o���-y��1+����z5\����Y��)_������&���3�">9��9�69#�c��hc���zo��k���nO�p!Y2��B{���������n<�������|#�_yQ���KV��z/q�"��IEe�w\�:������x�
6�w��1�~�����!N�1����vw���4�U?��{��d6d	u�$d��7,;�L��XD�lJC!F���c]����O���O}��M=�)�:���p�,xXa�����8���}Z3��Iu)�l�
2�O7������$4�I�(�w���B?�0RM`Y�L{����iyGc�)�[��~��Fw�>_��w��y���K\s��.c��;e����[t�*!�7�D��t��H���l�u�O� vp�j���L�����1������[��E�Knj!_�=����}���=���<�� $e���-�zrS0u��`����=���jR��~URB���ct�W[����_������AR���b��������3MC��%�jB���}��rw� ��1?���r~�5�����0�'�B�|���W�"�|8�W����Z���sN���
��e�[@��Z����#Yk����_�,r�)�m��|&���Q��S+X [��Eh[,���8V���t�����������~���2�_���M������X����G^��'�o��h�@0H_�#\q���=�jp:���S��e���j�T�0k�4�1K/�e�[�D4%r�]�td�TN�}a�����N1���u�O�lk�����T�&��N��5W��	��~�2�2�-"���VC�qE���B�v�by������
�����������6�l�}6�0b�T��DzA��
��H:2�$Mg�i������M�7�~�C�A������(T��D���\p2|��3�+������F=���M��q�����`
��}vvr��P��e�������;�;Gv&�m�[�)��Q�{fy��H.=�	(��H!A#�E�������O$�����p����tx'�2)������o_�j��#�z:����}e]��?<j��b
{��&�Ey����V(w���xK5���.jK� ��$aw��x�R���jp!�k��"����_0H�2��~�r�]����)����l�,N�����i��tY�
s�i��yt�v9R�����9�n��{&zZ��E���������
��d�|:Z���t��V�	A������>y{|8�_����L�Dj0������#W8:���w��z�CB�L'
"v����5���V" r/�������m7V���k�8"��������ip!���2j��������ip!$�U8���cZ�H��PA�j�������������.��g�-�m�����"J�@
-��7I���Z�w�K5�h,h��e�]&���H.�]qY`{����WIt�S.��G�L��Ki�yO�>	����3E��,��"F������i-X-��BH�������A��)x�p�p���7�j-2,��"�.h+�*�;�
�����A�;�+�-�e��ZE���ip!J����/Zq��[+��A��*�L��_�������������� ��5��3���M,��r�^���>�uu]KV*�f�3����
y�����`+Y�R�E��5>?�Pa����3�?������A
*����d�0�I�� �bJ|��g�4��CcQrO�������rN,5����+�w���Em�Y��{���.���z<{���2
.��"��Gr���Cz^rl�t�D�� ���Y�G@���K5��jR_,~���%o��i���}��~H���lF�T��(gA[�~����K\N�_���,�+�*X��-�p�i�PN)���r�|,R���lT?$�;����"m}�z�'U�^#�_����L�b������z�B�2
.�0���4,����?�Q�B#����K���
�<?!�j��^���h�o��ta�4�lED��y`Q��M���r�[���R
.�����J�E+#�ip!L+#���G��}�'�"�L7,��sD�����(X�T�����-��K�:D�O�����BQXs+��E���4��v[��Px?��F���jp!D�t�g�]jY�8y����2
.���NQ '�����\8��Y|�&�[;�]���,Z6]����Z,��]%E��e\8��! ��i8������5����e\8�����������S�Q�	IN�X�Z�����������R�X�����������`�[zy���^���:nEb8�����
��-'_*|TW
�;�Naa��DR+EYa�F�����?�Z2�K)|����a����6�3}2���a��>k�Y;'����(GZD/������-=ZIe��8���|�V%&�&H/F��R���F���������<��8�{&Y��=�-7��R��F�r��:9���>�x�e�Kf�U�[�dA^��uW�����3 /�����y.�lH\v_�3�m�M�l!��d6%�
.�W����Vv+������r��W���)�A�`�jUs%&��5��;\|�u~�7f��~	����%�K�/=�`3�Vw*uoU��pZy�/�w?��3�b8���dJ��|F���etC1�O+�������P?��0n��"�������5�e)\��~(<�P���5�^Y�[���c��gj1|E��e�+�~N������n{U��w�����4����V*y���O_�s�RU�D��V�oLt��hU�V���fZQ9*�8�KC
��s�2���A��p��|S��M��:�W���VA���o>|�Yd�h�Y�c4���`��t �M2F��0�Yg�>�Rf��1+f����&��&��u.B���&�2`�g2a���b)0[�,0�kR)EFkF$�W�D����f����P
I�2�^
�4�(��|*�x�9�����S��<
���������;���}tyx��U��d�� �������
m��)�-���q'�,�4rpW�Rq��"	�8���f�~���C��b����9�c3����	y���d��[�0hT�x
4ZX��/�A������z�+U�����*��_�����Bb����H���JwCc�^�����y������qZ��d�^��g��$��H �g�"���(�Z�!!O�Y��.�Z�w7�.!o_t�����Ey�OY��?�����eGSUs�i����jV�Z�5����F3v��J��Cm-��" ���E��E�P���t��}:��������CE:����$?���(�zx��G��:�gX-�1������>l�S���~�J@C�6=h$P��g�\.�6lN����b�d��}����!ph�^`�_���&�����2��9$���D�����z cTb<5��bT*��VeP��RP�ci[1��1	�<�l��V�N��:K/����rp�d��y�p��Qw8��L�DW��Kt+1����I�^��L�N"�I�I#�&��/��e���S^����a�#�
�E�[�}Q��tGu1�t���$��(���/��5�e�{U��E��W�PE/��j��F�eb)� j�bv��l%�����%���w��s��<.|9mMo���p4�'����l~;��������;���H1n�)$C��� hE�u	
�����`6	�Y��eEo��:�lvg�dU��t��<���B�L A��>��[�`�����d�e�2k����fV�w{������Z�=7u�M���j�t?b�Q�5<��Ub�����c��7�����c������8C���|8���w�Xn&��1�.�pY���U����H_M��)��[����"Z�mG���0;�����)��*�V*�DZ��G�������[���z3_1b`��$��LQ �Aq��g1��<��'�@i=��;�x��!�������U����."v���z��C�w��rO����O>lf��?�����������U���i��,bu��{f|��gX�9���i?�l�oW����iFE�[�hau�����)��r�Z�j|��s�:n�&���.�����I��48�~?���%��53�[
�+�B0��.$%�k~6�C�D��|J5���Z^��=A
p�EL����5S
�����9x�hau��F���k�<��@#-S}Qh,�hKB��@���
��F��6Ud������h� ,}U�Z����y���.mf���d1�s��#��!��z��W�6<����9��Y�����!&�6},���3��@+�)#:�`��V�
�i���5�r��e��vhp�Tl|}��Za������Sv3������`��J�������3N��Z0��Jl6�uo��7>}SW}��;�X��Pb|����E	�N�*��a���-���Bw6�i����&^�%��Yg3��E�Tx��I��������Y��b]�������b���3i��4���R0���1K�#C�S/dm6C����h lZ	x�9��*��L���P����"K�._o#X#bl6f�%�]w�?���#^�"]a�?J�Q"����f6����!@�VE��*6�(��&�>�������g�'I�|�����1Y���e��\Zg��������`��y�:�����7��:7�q�0����D���#���cC���Y{�#�Z�zR+8[�b{�,�EKr�x�e:m�Ra ������+�����g�}�M:�D��&���M���f�J�pX��sX)`�I��������a�h>��K�]��&�������9����.`��0�%w��A�����W�b��A&�\��9�F��4� ���.I-��1�#���y���n��Si�3~�V�������1z-O&d��`��a�Y0��~|8����?NW�a����7\��I�;H��$������fS �-��������_�=h����@0�|D��������k�h���Z������b/����g����Za���������`�i�D�Z)A����OH4�����s>�_�����8���O{��]��M���cv�~u��f��W�'�X���=�uo�=��M����~
�����M����LF�|M��}.���_j����?u'�2��K�j>R?�H����D�wfk��������e��!'����;�.|� I���7�0�+�r0$��]�H1;��������96�y��x�1�Q�����.��J��"/��S��7�*qPw����N}(p)�6z�y[RRY��
�G�=��*(�:9>��a'����Y����w/X
�.�"J9� ]���:k�_����7Gm����xN��o9�r}��3�O�g������������T8Q-���`��NB�
����
��G ����?�S�.�����N��9�H�� `>������Ir����_��p���l�|����J�|F��?9;�3��g&�B�EH�)[�<����agw������_�)����oS����������9/���7YS����}����x�k,s|�Q���ai�\�OtHC����;����a�rk�������G^��'����������pf �%$�]�0'���Zj�p�������/�UZ�E^g��{i��$"���x*qE�p���b�o���w�K��+�d�
�Dx+�%@	R~�]�l�a���Oy������AP�/�)Vz�g���i{��`/{��Z$T�M�[[z.8��Ls �����o�3	8������k�Z��G��r�'��_<�B��b��]l�����m�'�?`��a�W`Z���S��"o��8� �|Y�9�i�b�����>���_��Xw�"�$
���G�%�::9o[<9�R2r��"�O.���KL\�8<~���!����E
����B��8�����S���D�����Te���#2�5a��D�)�"�c`18b�z(b+�w" �&����><��������#��?MX���g��qI
���\�������1�ee����m��Y�ki�yO�{B��-^a�!�.@'jQ�}?�s��yU���6?��^����\I��	���x�#�'I�\5O��|��B����nn�
���5��3��mb�����}w�_���Yw/@�b���6�x�	H���X��;�.Ik%��4�������5��!Ndg��Q��������
/.��)b'ZN�d>����uC�L��^x4�������S/�(XZ$^,����I��g��=�lji�paO���iP��JV�)��R�b-�-��GH��$r�	����F9%��c�Q�0�!�qgI���-��oN~h��o�O��^�!�>'�������Z�}�@��nz;k3a�N^[���3�U�tk���[l�����	�4��������H�������0�SwQs+�.���]����vC�R�hU>�uY��N��;8<��0����kqTA���f�M���������� ���Z�F5a����F\�����9���_v����7���y7��A����������c��04�G`e���1�A���[�a��a\����.�>���h0c�G>�C�l�R����*#6��
ecpg-cursor-readahead-all-cursors-v2.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-all-cursors-v2.patch.gzDownload
#33Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#32)
Re: ECPG FETCH readahead

On Fri, Mar 30, 2012 at 12:48:07AM +0200, Boszormenyi Zoltan wrote:

2012-03-29 19:03 keltez?ssel, Noah Misch ?rta:

one of the new sections about readahead should somehow reference the hazard
around volatile functions.

Done.

I don't see the mention in your latest patch. You do mention it for the
sqlerrd[2] compatibility stuff.

sqlerrd[2] compatibility stuff? I mentioned it in section "ecpg-sqlca", this is the main
documentation section, not the compatibility one AFAIK. Anyway, I now reference the volatile
function hazard in the first paragraphs added to section "ecpg-cursors".

This patch adds two features, and those features are independent from a user
perspective. The primary feature is cursor readahead, and the secondary
feature is "ecpg --detect-cursor-resultset-size" (the referent of my above
"sqlerrd[2] compatibility stuff" reference). Each feature has independent
semantic implications when the application uses cursors on queries that call
volatile functions. Under --detect-cursor-resultset-size, we will execute
functions for all rows at OPEN time and again for each row at FETCH time.
When you declare a cursor with "READAHEAD n" and do not FETCH it to the end,
up to "n" unFETCHed rows will nonetheless have their functions executed. If
the volatile function is something like clock_timestamp(), the application
will observe the executions to have happened in clusters of "n" rather than in
step with the application's FETCH calls.

Your latest patch revision hints at the semantic implications for "ecpg
--detect-cursor-resultset-size", but it does not mention them for readahead.
Then again, perhaps it's sufficiently obvious to not warrant mention. Without
knowing internals, I would not expect users to guess the consequence of "ecpg
--detect-cursor-resultset-size". With readahead, it may be guessable enough.

Thanks,
nm

#34Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#32)
Re: ECPG FETCH readahead

On Fri, Mar 30, 2012 at 12:48:07AM +0200, Boszormenyi Zoltan wrote:

Attached is the new core feature patch. Summary of changes:
...
I also refreshed the second patch that drives all cursors with the new
...

I'm slightly confused here. It seems Zoltan added a second patch *after* Noah
marked this patch as ready for committer. That second patch seems to apply
cleanly after the first one got applied. Now, which one was reviewed and is
considered ready for commit? The first one? Or both?

Michael

--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#35Noah Misch
noah@leadboat.com
In reply to: Michael Meskes (#34)
Re: ECPG FETCH readahead

On Sat, Apr 07, 2012 at 01:20:08PM +0200, Michael Meskes wrote:

On Fri, Mar 30, 2012 at 12:48:07AM +0200, Boszormenyi Zoltan wrote:

Attached is the new core feature patch. Summary of changes:
...
I also refreshed the second patch that drives all cursors with the new
...

I'm slightly confused here. It seems Zoltan added a second patch *after* Noah
marked this patch as ready for committer. That second patch seems to apply
cleanly after the first one got applied. Now, which one was reviewed and is
considered ready for commit? The first one? Or both?

Both. The second patch appeared after my first review, based on a comment in
that review. I looked at it during my re-review before marking the overall
project Ready for Committer.

I do call your attention to a question I raised in my second review: if a
program contains "DECLARE foo READAHEAD 5 CURSOR FOR ..." and the user runs
the program with ECPGFETCHSZ=10 in the environment, should that cursor use a
readahead window of 5 or of 10? Original commentary:
http://archives.postgresql.org/message-id/20120329004323.GA17329@tornado.leadboat.com

#36Michael Meskes
meskes@postgresql.org
In reply to: Noah Misch (#35)
Re: ECPG FETCH readahead

On Sat, Apr 07, 2012 at 11:50:42AM -0400, Noah Misch wrote:

Both. The second patch appeared after my first review, based on a comment in
that review. I looked at it during my re-review before marking the overall
project Ready for Committer.

Thanks.

I do call your attention to a question I raised in my second review: if a
program contains "DECLARE foo READAHEAD 5 CURSOR FOR ..." and the user runs
the program with ECPGFETCHSZ=10 in the environment, should that cursor use a
readahead window of 5 or of 10? Original commentary:
http://archives.postgresql.org/message-id/20120329004323.GA17329@tornado.leadboat.com

I'd say it should be 5. I don't like an environment variable overwriting a
hard-coded setting. I think this is what you, Noah, thought, too, right? I'd
say let's change this. Is it possible to allow just READAHEAD without a number?
In that case I would accept the environment variable.

And some comments mostly directed at Zoltan:

ecpg --help says ...default 0 (disabled)..., but options less than 1 are not
accepted and the default setting of 1 has a comment "Disabled by default". I
guess this needs to be adjusted.

Is there a reason why two new options for ecpg were invented? Normally ecpg
options define how the preprocessor works but not the resulting binary. Well,
different preprocessor behaviour might result in different binary behaviour of
course. The only option that only effects the resulting binary is "-r" for
"runtime". Again, this is not completely true as the option has to make its way
into the binary, but that's it. Now I wonder whether it would make more sense
to add the two options as runtime options instead. The
--detect-cursor-resultset-size option should work there without a problem. I
haven't delved into the source code enough to find out if -R changes something
in the compiler stage.

The test case cursor-readahead.pgc has a comment saying "test automatic prepare
for all statements". Copy/Paste error?

I cannot find a test that tests the environment variable giving the fetch size.
Could you please point me to that?

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#37Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#36)
Re: ECPG FETCH readahead

2012-04-08 16:25 keltezéssel, Michael Meskes írta:

On Sat, Apr 07, 2012 at 11:50:42AM -0400, Noah Misch wrote:

Both. The second patch appeared after my first review, based on a comment in
that review. I looked at it during my re-review before marking the overall
project Ready for Committer.

Thanks.

I do call your attention to a question I raised in my second review: if a
program contains "DECLARE foo READAHEAD 5 CURSOR FOR ..." and the user runs
the program with ECPGFETCHSZ=10 in the environment, should that cursor use a
readahead window of 5 or of 10? Original commentary:
http://archives.postgresql.org/message-id/20120329004323.GA17329@tornado.leadboat.com

I'd say it should be 5. I don't like an environment variable overwriting a
hard-coded setting. I think this is what you, Noah, thought, too, right? I'd
say let's change this.

Do you want me to change this or will you do it? I am on holiday
and will be back to work on wednesday.

The possibility to test different readahead window sizes
without modifying the source and recompiling was useful.

Is it possible to allow just READAHEAD without a number?
In that case I would accept the environment variable.

After the 2nd patch is applied, this is exactly the case.
The cursors are driven and accounted using the new functions
but with the readahead window being a single row as the default
value for fetch_readahead is 1.

And some comments mostly directed at Zoltan:

ecpg --help says ...default 0 (disabled)..., but options less than 1 are not
accepted and the default setting of 1 has a comment "Disabled by default". I
guess this needs to be adjusted.

Yes, the help text was not changed in the 2nd patch, I missed that.

Is there a reason why two new options for ecpg were invented? Normally ecpg
options define how the preprocessor works but not the resulting binary.

The -R option simply provides a default without ornamenting
the DECLARE statement.

Well,
different preprocessor behaviour might result in different binary behaviour of
course. The only option that only effects the resulting binary is "-r" for
"runtime". Again, this is not completely true as the option has to make its way
into the binary, but that's it. Now I wonder whether it would make more sense
to add the two options as runtime options instead. The
--detect-cursor-resultset-size option should work there without a problem.

You are right. This can be a suboption to "-r".

I
haven't delved into the source code enough to find out if -R changes something
in the compiler stage.

"-R" works just like "-r" in the sense that a value gets passed
to the runtime. "-R" simply changes the default value that gets
passed if no READAHEAD N clause is specified for a cursor.
This is true only if you intend to apply both paches.

Without the 2nd patch and fetch_readahead=0 (no -R option given)
or NO READAHEAD is specified for a cursor, the compiler makes
a distinction between uncachable cursors driven by ECPGdo() and
cachable cursors driven by the new runtime functions.

With the 2nd patch applied, this distinction is no more.

The test case cursor-readahead.pgc has a comment saying "test automatic prepare
for all statements". Copy/Paste error?

It must be, yes.

I cannot find a test that tests the environment variable giving the fetch size.
Could you please point me to that?

I didn't write such a test. The reason is that while variables are
exported by make from the Makefile to the binaries run by make
e.g. CFLAGS et.al. for $(CC), "make check" simply runs pg_regress
once which uses its own configuration file that doesn't have a
way to set or unset an environment variable. This could be a useful
extension to pg_regress though.

Best regards,
Zoltán Böszörményi

Michael

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#38Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#37)
Re: ECPG FETCH readahead

On Sun, Apr 08, 2012 at 06:35:33PM +0200, Boszormenyi Zoltan wrote:

Do you want me to change this or will you do it? I am on holiday
and will be back to work on wednesday.

I don't think waiting till later this week is a real problem.

The possibility to test different readahead window sizes
without modifying the source and recompiling was useful.

Sure, but you can still do that when not defining a fixed number in the
statement.

The -R option simply provides a default without ornamenting
the DECLARE statement.

Could you please incorporate these changes, too, when you're back from vacation?

I cannot find a test that tests the environment variable giving the fetch size.
Could you please point me to that?

I didn't write such a test. The reason is that while variables are
exported by make from the Makefile to the binaries run by make
e.g. CFLAGS et.al. for $(CC), "make check" simply runs pg_regress
once which uses its own configuration file that doesn't have a
way to set or unset an environment variable. This could be a useful
extension to pg_regress though.

How about calling setenv() from the test program itself?

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#39Noah Misch
noah@leadboat.com
In reply to: Michael Meskes (#36)
Re: ECPG FETCH readahead

On Sun, Apr 08, 2012 at 04:25:01PM +0200, Michael Meskes wrote:

On Sat, Apr 07, 2012 at 11:50:42AM -0400, Noah Misch wrote:

I do call your attention to a question I raised in my second review: if a
program contains "DECLARE foo READAHEAD 5 CURSOR FOR ..." and the user runs
the program with ECPGFETCHSZ=10 in the environment, should that cursor use a
readahead window of 5 or of 10? Original commentary:
http://archives.postgresql.org/message-id/20120329004323.GA17329@tornado.leadboat.com

I'd say it should be 5. I don't like an environment variable overwriting a
hard-coded setting. I think this is what you, Noah, thought, too, right?

Yes.

#40Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#38)
Re: ECPG FETCH readahead

2012-04-08 19:38 keltezéssel, Michael Meskes írta:

On Sun, Apr 08, 2012 at 06:35:33PM +0200, Boszormenyi Zoltan wrote:

Do you want me to change this or will you do it? I am on holiday
and will be back to work on wednesday.

I don't think waiting till later this week is a real problem.

OK.

The possibility to test different readahead window sizes
without modifying the source and recompiling was useful.

Sure, but you can still do that when not defining a fixed number in the
statement.

OK.

The -R option simply provides a default without ornamenting
the DECLARE statement.

Could you please incorporate these changes, too, when you're back from vacation?

Sure.

So, it's established that a specified READAHEAD N should not
be overridden. Even an explicit READAHEAD 1.

Only a non-decorated cursor can be overridden, even if
a different default readahead window size is specified with
e.g. "ecpg -R 8". If ECPGFETCHSZ is not present, 8 will be used,
if ECPGFETCHSZ is present, its value will be used. ECPGopen()
will need an extra bool argument to distinguish this.

Is this acceptable? Noah, Michael?

I cannot find a test that tests the environment variable giving the fetch size.
Could you please point me to that?

I didn't write such a test. The reason is that while variables are
exported by make from the Makefile to the binaries run by make
e.g. CFLAGS et.al. for $(CC), "make check" simply runs pg_regress
once which uses its own configuration file that doesn't have a
way to set or unset an environment variable. This could be a useful
extension to pg_regress though.

How about calling setenv() from the test program itself?

Sure, I didn't think about it. It should be done before the
first EXEC SQL OPEN cursor.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#41Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#40)
Re: ECPG FETCH readahead

On Tue, Apr 10, 2012 at 09:35:21AM +0200, Boszormenyi Zoltan wrote:

So, it's established that a specified READAHEAD N should not
be overridden. Even an explicit READAHEAD 1.

Only a non-decorated cursor can be overridden, even if
a different default readahead window size is specified with
e.g. "ecpg -R 8". If ECPGFETCHSZ is not present, 8 will be used,
if ECPGFETCHSZ is present, its value will be used. ECPGopen()
will need an extra bool argument to distinguish this.

Is this acceptable? Noah, Michael?

Sounds perfect.

#42Michael Meskes
meskes@postgresql.org
In reply to: Noah Misch (#41)
Re: ECPG FETCH readahead

On Tue, Apr 10, 2012 at 10:37:22AM -0400, Noah Misch wrote:

Only a non-decorated cursor can be overridden, even if
a different default readahead window size is specified with
e.g. "ecpg -R 8". If ECPGFETCHSZ is not present, 8 will be used,
if ECPGFETCHSZ is present, its value will be used. ECPGopen()
will need an extra bool argument to distinguish this.

Is this acceptable? Noah, Michael?

Sounds perfect.

Fine by me.

Michael

--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#43Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#42)
Re: ECPG FETCH readahead

2012-04-10 16:55 keltezéssel, Michael Meskes írta:

On Tue, Apr 10, 2012 at 10:37:22AM -0400, Noah Misch wrote:

Only a non-decorated cursor can be overridden, even if
a different default readahead window size is specified with
e.g. "ecpg -R 8". If ECPGFETCHSZ is not present, 8 will be used,
if ECPGFETCHSZ is present, its value will be used. ECPGopen()
will need an extra bool argument to distinguish this.

Is this acceptable? Noah, Michael?

Sounds perfect.

Fine by me.

Michael

OK. Next question: now that both patches are intended to be applied,
should I send a unified single patch that contains the previous functionality
and the required fixes or a new one that only contains the last required fixes?

Thanks in advance,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#44Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#43)
Re: ECPG FETCH readahead

On Tue, Apr 10, 2012 at 05:24:55PM +0200, Boszormenyi Zoltan wrote:

OK. Next question: now that both patches are intended to be applied,
should I send a unified single patch that contains the previous functionality
and the required fixes or a new one that only contains the last required fixes?

I'm fine with whatever is easier for you.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#45Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#44)
Re: ECPG FETCH readahead

2012-04-10 17:34 keltezéssel, Michael Meskes írta:

On Tue, Apr 10, 2012 at 05:24:55PM +0200, Boszormenyi Zoltan wrote:

OK. Next question: now that both patches are intended to be applied,
should I send a unified single patch that contains the previous functionality
and the required fixes or a new one that only contains the last required fixes?

I'm fine with whatever is easier for you.

Michael

I guess the second option is easier for all of us because
reviewing it doesn't invalidate the previous ones.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#46Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#42)
1 attachment(s)
Re: ECPG FETCH readahead

Hi,

2012-04-10 16:55 keltezéssel, Michael Meskes írta:

On Tue, Apr 10, 2012 at 10:37:22AM -0400, Noah Misch wrote:

Only a non-decorated cursor can be overridden, even if
a different default readahead window size is specified with
e.g. "ecpg -R 8". If ECPGFETCHSZ is not present, 8 will be used,
if ECPGFETCHSZ is present, its value will be used. ECPGopen()
will need an extra bool argument to distinguish this.

Is this acceptable? Noah, Michael?

Sounds perfect.

Fine by me.

Michael

you commented on "two new options were added and they should
be suboptions to -r". I looked at "man getopt_long" to see what I can do
about the "-R" option and there seems to be a getsubopt() call which is
an extension to getopt_long. My manpage under Fedora 16 says this:

NAME
getsubopt - parse suboption arguments from a string

SYNOPSIS
#include <stdlib.h>

int getsubopt(char **optionp, char * const *tokens, char **valuep);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

getsubopt():
_XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

I wonder whether the manual parsing of "-r" suboptions may be rewritten
using this function or PostgreSQL supports systems without the above
X/Open or POSIX support levels.

Anyway, to make it possible to rewrite using the above call, I modified "-R"
and it's now "-r readahead=number". Documentation is adjusted.

With the above, it would be possible to use a comma separated list of "-r"
suboptions, e.g. "-r prepare,questionmarks,readahead=16" in one option.

Summary of other changes:
- The result set size detection is a suboption of "-r", documentation is adjusted.
- Only undecorated cursors use ECPGFETCHSZ, documentation is adjusted
- "ecpg --help says ...default 0 (disabled)..." fixed.
- Comment in cursor-readahead.pgc is fixed.
- New regression test that exercises ECPGFETCHSZ=8 and a "non-readahead"
cursor. The stderr file shows the "fetch forward 8" executed by the runtime.
- Also added a note to the documentation about a possible performance trap
if a previously written ECPG application uses its own custom readahead via
multi-row FETCH statements.

This patch should be applied over the two patches I last sent.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-fixes-v3.patch.gzapplication/x-tar; name=ecpg-cursor-readahead-fixes-v3.patch.gzDownload
#47Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#46)
Re: ECPG FETCH readahead

On Tue, Apr 10, 2012 at 07:56:35PM +0200, Boszormenyi Zoltan wrote:

With the above, it would be possible to use a comma separated list of "-r"
suboptions, e.g. "-r prepare,questionmarks,readahead=16" in one option.

Yes, that sounds like a good plan. But of course it's outside the scope of this
patch, so we can add this later on.

- Also added a note to the documentation about a possible performance trap
if a previously written ECPG application uses its own custom readahead via
multi-row FETCH statements.

I didn't know that before you send this patch. Noah, did you?

Frankly, I don't like this at all. If I got it right that means a FETCH N is
essantially computed as N times FETCH 1 unless you either add a non-standard
option to the DECLARE statement or you add a command-line option to ecpg. Did I
get that right?

If so we would deliberately make ecpglib work incorrectly and remove
performance. Why is that? I'm interested in what others think, but to me that
sounds like a show-stopper.

Michael

--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#48Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#47)
Re: ECPG FETCH readahead

2012-04-16 04:46 keltezéssel, Michael Meskes írta:

On Tue, Apr 10, 2012 at 07:56:35PM +0200, Boszormenyi Zoltan wrote:

With the above, it would be possible to use a comma separated list of "-r"
suboptions, e.g. "-r prepare,questionmarks,readahead=16" in one option.

Yes, that sounds like a good plan. But of course it's outside the scope of this
patch, so we can add this later on.

- Also added a note to the documentation about a possible performance trap
if a previously written ECPG application uses its own custom readahead via
multi-row FETCH statements.

I didn't know that before you send this patch. Noah, did you?

Frankly, I don't like this at all. If I got it right that means a FETCH N is
essantially computed as N times FETCH 1 unless you either add a non-standard
option to the DECLARE statement or you add a command-line option to ecpg. Did I
get that right?

Yes, just like when the readahead window set to 256, FETCH 1024
will iterate through 4 windows or FETCH 64 iterates through the
same window 4 times. This is the idea behind the "readahead window".

If so we would deliberately make ecpglib work incorrectly and remove
performance. Why is that? I'm interested in what others think, but to me that
sounds like a show-stopper.

How about allowing the readahead window to be resized for the
non-decorated case if the runtime encounters FETCH N and N is
greater than the previous window?

Michael

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#49Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#48)
Re: ECPG FETCH readahead

On Mon, Apr 16, 2012 at 06:24:57AM +0200, Boszormenyi Zoltan wrote:

Yes, just like when the readahead window set to 256, FETCH 1024
will iterate through 4 windows or FETCH 64 iterates through the
same window 4 times. This is the idea behind the "readahead window".

Really? It's definitely not the idea behind FETCH 1024. Using the same window 4
times for FETCH 64 is the idea though, I agree.

How about allowing the readahead window to be resized for the
non-decorated case if the runtime encounters FETCH N and N is
greater than the previous window?

To be resized by what? IMO a FETCH N should always be a FETCH N, no matter
what, i.e. if the readahead window is larger, use it, but even if it's smaller
we should still fetch N at the same time.

Michael

--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#50Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#49)
Re: ECPG FETCH readahead

2012-04-16 18:04 keltezéssel, Michael Meskes írta:

On Mon, Apr 16, 2012 at 06:24:57AM +0200, Boszormenyi Zoltan wrote:

Yes, just like when the readahead window set to 256, FETCH 1024
will iterate through 4 windows or FETCH 64 iterates through the
same window 4 times. This is the idea behind the "readahead window".

Really? It's definitely not the idea behind FETCH 1024. Using the same window 4
times for FETCH 64 is the idea though, I agree.

OK. I would like to stretch your agreement a little. :-)

Can we state that caching means that if the cache should serve
the incoming request(s) until the request spills out of it?

If your answer to the above is "yes", then please consider this case:
- readahead window is 256 (via ECPGFETCHSZ)
- FETCH 64 was executed twice, so you are in the middle of the cache
- FETCH 1024 is requested

So, if I understand you correctly, you expect this scenario:
- set a "one-time" readahead window size ( N - # of rows that can be served
= 1024 - 128 = 768) so the next FETCH by the runtime will fullfill
this request fully
- serve the request's first 128 rows from the current cache
- for the 129th row, FETCH 768 will be executed
- all subsequent requests use the old readahead size

How about allowing the readahead window to be resized for the
non-decorated case if the runtime encounters FETCH N and N is
greater than the previous window?

To be resized by what?

By the new FETCH request. Instead of the above, I imagined this:
- the runtime notices that the new request is larger than the current
readahead window size, modifies the readahead window size upwards,
so the next FETCH will use it
- serve the request's first 128 rows from the current cache
- for the 129th row, FETCH 1024 will be executed and the remaining
768 rows will be served from the new cache
- all subsequent requests use the new readahead size, 1024

IMO a FETCH N should always be a FETCH N, no matter
what

This part of your statement contradicts with caching. :-)

, i.e. if the readahead window is larger, use it, but even if it's smaller
we should still fetch N at the same time.

So, there can be occasional one-time larger requests but
smaller ones should apply the set window size, right?

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#51Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#50)
Re: ECPG FETCH readahead

On Mon, Apr 16, 2012 at 07:18:07PM +0200, Boszormenyi Zoltan wrote:

OK. I would like to stretch your agreement a little. :-)
...

Yeah, you got a point here.

By the new FETCH request. Instead of the above, I imagined this:
- the runtime notices that the new request is larger than the current
readahead window size, modifies the readahead window size upwards,
so the next FETCH will use it
- serve the request's first 128 rows from the current cache
- for the 129th row, FETCH 1024 will be executed and the remaining
768 rows will be served from the new cache

That means window size goes up to 1024-128 for that one case?

- all subsequent requests use the new readahead size, 1024

Sounds reasonable to me.

So, there can be occasional one-time larger requests but
smaller ones should apply the set window size, right?

Yes. I do agree that FETCH N cannot fetch N all the time, but please make it
work like what you suggested to make sure people don't have to recompile.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#52Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#51)
Re: ECPG FETCH readahead

2012-04-17 05:52 keltezéssel, Michael Meskes írta:

On Mon, Apr 16, 2012 at 07:18:07PM +0200, Boszormenyi Zoltan wrote:

OK. I would like to stretch your agreement a little. :-)
...

Yeah, you got a point here.

By the new FETCH request. Instead of the above, I imagined this:
- the runtime notices that the new request is larger than the current
readahead window size, modifies the readahead window size upwards,
so the next FETCH will use it
- serve the request's first 128 rows from the current cache
- for the 129th row, FETCH 1024 will be executed and the remaining
768 rows will be served from the new cache

That means window size goes up to 1024-128 for that one case?

I listed two scenarios.
1. occasional bump of the readahead window for large requests,
for smaller requests it uses the originally set size
2. permanent bump of the readahead window for large requests
(larger than previously seen), all subsequent requests use
the new size

Both can be implemented easily, which one do you prefer?
If you always use very large requests, 1) behaves like 2)

- all subsequent requests use the new readahead size, 1024

Sounds reasonable to me.

So, there can be occasional one-time larger requests but
smaller ones should apply the set window size, right?

Yes. I do agree that FETCH N cannot fetch N all the time, but please make it
work like what you suggested to make sure people don't have to recompile.

Michael

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#53Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#52)
Re: ECPG FETCH readahead

On Tue, Apr 17, 2012 at 06:02:34AM +0200, Boszormenyi Zoltan wrote:

I listed two scenarios.
1. occasional bump of the readahead window for large requests,
for smaller requests it uses the originally set size
2. permanent bump of the readahead window for large requests
(larger than previously seen), all subsequent requests use
the new size

Both can be implemented easily, which one do you prefer?
If you always use very large requests, 1) behaves like 2)

I'd say let's go for #2. #1 is probably more efficient but not what the
programmer asked us to do. After all it's easy to increase the window size
accordingly if you want so as a programmer.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#54Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#53)
Re: ECPG FETCH readahead

Hi,

2012-04-17 06:48 keltezéssel, Michael Meskes írta:

On Tue, Apr 17, 2012 at 06:02:34AM +0200, Boszormenyi Zoltan wrote:

I listed two scenarios.
1. occasional bump of the readahead window for large requests,
for smaller requests it uses the originally set size
2. permanent bump of the readahead window for large requests
(larger than previously seen), all subsequent requests use
the new size

Both can be implemented easily, which one do you prefer?
If you always use very large requests, 1) behaves like 2)

I'd say let's go for #2. #1 is probably more efficient but not what the
programmer asked us to do. After all it's easy to increase the window size
accordingly if you want so as a programmer.

Michael

OK, I will implement #2. Another question popped up: what to do
with FETCH ALL? The current readahead window size or temporarily
bumping it to say some tens of thousands can be used. We may not
know how much is the "all records". This, although lowers performance,
saves memory.

Please, don't apply this patch yet. I discovered a rather big hole
that can confuse the cursor position tracking if you do this:

DECLARE mycur;
MOVE ABSOLUTE n IN mycur;
MOVE BACKWARD m IN mycur;

If (n+m) is greater, but (n-m) is smaller than the number
of rows in the cursor, the backend's and the caching code's
ideas about where the cursor is will differ. I need to fix this
before it can be applied.

That will also need a new round of review. Sorry for that.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig& Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#55Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#54)
Re: ECPG FETCH readahead

OK, I will implement #2. Another question popped up: what to do
with FETCH ALL? The current readahead window size or temporarily
bumping it to say some tens of thousands can be used. We may not
know how much is the "all records". This, although lowers performance,
saves memory.

I would say doing a large fetch in two or three batches won't cost too much in
terms of performance.

Please, don't apply this patch yet. I discovered a rather big hole
that can confuse the cursor position tracking if you do this:
...
That will also need a new round of review. Sorry for that.

No problem, better to find it now instead of after release.

Anyway, I moved the patch to 2012-next (I hope I did it correctly) so 2012-1
can be closed. Let's try to get this patch done in the next commit fest.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

#56Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#55)
1 attachment(s)
Re: ECPG FETCH readahead

Hi,

I am restarting this old thread... :-)

2012-04-24 10:17 keltezéssel, Michael Meskes írta:

OK, I will implement #2. Another question popped up: what to do
with FETCH ALL? The current readahead window size or temporarily
bumping it to say some tens of thousands can be used. We may not
know how much is the "all records". This, although lowers performance,
saves memory.

I would say doing a large fetch in two or three batches won't cost too much in
terms of performance.

Please, don't apply this patch yet. I discovered a rather big hole
that can confuse the cursor position tracking if you do this:
...
That will also need a new round of review. Sorry for that.

No problem, better to find it now instead of after release.

Anyway, I moved the patch to 2012-next (I hope I did it correctly) so 2012-1
can be closed. Let's try to get this patch done in the next commit fest.

Michael

I had time to look into this patch of mine again after about 1.5 years.
Frankly, this time was too long to remember every detail of the patch
and looking at parts of the patch as a big entity was confusing.

So I started fresh and to make review easier, I broke the patch up
into small pieces that all build on each other. I have also fixed quite
a few bugs, mostly in my code, but some in the ECPG parser and
the regression tests as well.

I have put the broken up patchset into a GIT tree of mine at GitHub:
https://github.com/zboszor/ecpg-readahead/
but the huge compressed patch is also attached for reference.
It was generated with

$ git diff 221e92f64c6e136e550ec2592aac3ae0d4623209..870922676e6ae0faa4ebbf94b92e0b97ec418e16

ECPG regression tests are now Valgrind-clean except two of them
but both are pre-existing bugs.

1. ecpg/test/compat_informix/rfmtlong.pgc points out a problem in
ecpg/compatlib/informix.c

==5036== 1 errors in context 1 of 4:
==5036== Invalid read of size 4
==5036== at 0x4E3453C: rfmtlong (informix.c:941)
==5036== by 0x4007DA: fmtlong.constprop.0 (rfmtlong.pgc:22)
==5036== by 0x4006BE: main (rfmtlong.pgc:45)
==5036== Address 0x60677d8 is 24 bytes inside a block of size 25 alloc'd
==5036== at 0x4C28409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5036== by 0x4E34268: rfmtlong (informix.c:783)
==5036== by 0x4007DA: fmtlong.constprop.0 (rfmtlong.pgc:22)
==5036== by 0x4006BE: main (rfmtlong.pgc:45)

The same error is reported 4 times.

2. ecpg_add_mem() seems to leak memory:

==5463== 256 bytes in 16 blocks are definitely lost in loss record 1 of 1
==5463== at 0x4C2A121: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5463== by 0x4E3E153: ecpg_alloc (memory.c:21)
==5463== by 0x4E3E212: ecpg_add_mem (memory.c:110)
==5463== by 0x4E3542B: ecpg_store_result (execute.c:409)
==5463== by 0x4E37E5A: ecpg_process_output (execute.c:1777)
==5463== by 0x4E38CCA: ecpg_do (execute.c:2137)
==5463== by 0x4E38D8A: ECPGdo (execute.c:2159)
==5463== by 0x400A82: fn (alloc.pgc:51)
==5463== by 0x5152C52: start_thread (pthread_create.c:308)
==5463== by 0x545C13C: clone (clone.S:113)

The last two issue we talked about in this thread are also implemented:
- permanently raise the readahead window if the application sends a
bigger FETCH command, and
- temporarily raise the readahead window for FETCH ALL commands

The cursor position tracking was completely rewritten, so the client side
properly follows the cursor position known by the backend and doesn't
skip MOVE statements where it shouldn't. The previously known
bug is completely eliminated this way.

Please, review that patch.

Thanks in advance and best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.4-v16.patch.bz2application/x-bzip2; name=ecpg-cursor-readahead-9.4-v16.patch.bz2Download
BZh91AY&SY��������������������aU�|�[e
����j�}z�f#��3b�wvM7��ik��^{����HMS���v����u/^��|���gY���knl�
�>���u���f���<R������m> ��t��0wer��=y`����6�5�C���v;f�z���]��sp|����P����^=�z/gx���(eE��q���}�x��N�����V�Y�����Vy=f�YU��+���k]������p���=]����7o%[�x�qT�����n}����M�������i�t��{�x;�t�	����u��Ox3`�/������^�2����'}�/��<_uv�gZ��o�]������n�w������>����v���������������6<���������l��>H����f�����>��p�QD�T����������sQy�[������N�3Z-�^������D&�����������+m������_ c���v�7h1j��J�M����]�wg6��^�C����;�-������&�����f=�=I�Y�;�s'c_&>�{���v��j����_n���w����C�w���4�}�3��)k�������c��o�����wlYS� r�[�Rr��������#Y*Q[�]����/a���������l���rc
���}/��%�v��A�T���������DHR<��/`�P��gM7�uv�"����NUR���o�s�:\;:��������m�B�����}��k]�{���W������=���jO�E���[�
c�����{B��OC�v���_���s����h24�dOE<�����j��?S&A)��$�&��z����OQ��M�����4�hI�H��M�SO��oB������G�z��y��OQ�4I���!4&i2i�����B� Bb2d�OS!�'�0���zS�hOT<P4�
� ��4C!< eOS�I��j�11=Mn��$#��E[`-H-�,P����IB!2�iAYD���
��$�l[ED���6M�(jP�� �4L+H	�\ C4�JZ��D-�L���5(���:��k�P�3#1�?N�D� �BR�eF������m35E]]v5���h��U�h�D�a�,0���L(���S���nR[�&���������M�2+t��u�W]V�;��R0e]un�_��f�RT��n�7vC20�eT�%c�L� f�(�������t�-�e�\6��Rt�kI.�u��$���,������b�����#����(������������n�I�*���!�9I,�l����4���U���J2L������	Y&V���Vb9��v���������#�CmDA��9�0���Ud�z�-���K��v\�5y��4�iwj1R2��:c�z���������2D�!�$P��wzj�U��\��?-�=���C��y�\d������`\�	����%`��z�$BSw9��{���rk�W�l�C�A:�������a�&%$�af+�����yK���$��uQ����&rt�|]�0��dH[���Z�t������+h�MC���(�I�����%'&wq�;�2st��D�+�����&��}�g��G1UC�3�t��]q��Y�8Y
59S/J�j������R������0�x�qA�N��'	f@�a�Y���J�1�������
t���[1�c�E	1.�^]{W�����E5��)�\{�;6$�@FHJ��b��Z�����$0���+Q�OU����j��^�$U��f s�"�-tSR����wk��"M2,HP��#����[P��F�2P��
���N#����l��@&�bJ���k,�4b��S-�,�a����P�dV�e
�[R�h��0(�C�7��r��h��j���1123�5�2��9�e�8�d#������)Je-��S|����m��,oCj���G��\���e�yF#J��`��+C�1��5��4�������y�@�����:5������������E��{ZRl�2���i��U��������y�\�R��D�1+�d�o
P-A�iPY�S�y[����,�t�1���>_S�0��NP�#�uH��In[Q��1�&�#5d�P���I*����b�m'9��M�����U��P�0�84���a�)������2�N07)
��	:u����Xf��P��J���%4�@
!�p����$����1�X	$��M��m���[^-:���$����
�2+$��TL1L`BV�����c��l������}=���t����L���J�$�FEm�����$s-��:�*��j@�1U)H �����"xA��D�vz0�1INS�� ��A�!�Z�P��2�`��E|�����j0�a�Y�}6�%������{,���u�P���S�J���������[���F�O|�n�z�P��!R}��@������_U�g�g��
�l�o��t��A�FM8�b
���\cK
l��Wc����M���-�4���#j*A���5j�c��d�|�J�j�`R��lL:f�������d�xc�Ir��������~U&��T���z��7j�����[����F^�������9��
+ ��?���2D�~�C��aK�������n�h�=����p"!z���$����Bl�����������!JF���I��F�r����������������uP�AC�|���;��<�|�GA�e��������;�{=;���2�5N��h����\a���7��y*��2)e��)m)0��00A�����������;8�0���	��L�����w`��J��g���"J�?����
�h��`L�n�L��
!HN�����p|[�����j")

��cf2oZ���P�Jg
���iM�#b�Z���������q���9����}����2bfbS�d2@�rh��2[cCe�����p�T�����'i�\����>����g/�=EzW�����������)a
E��q%C<�[r����Z����O���K�����X�����<�8�hV�1X
G��A�|����#'�0�|$"�WQB\k&�H�	��I*8���G��T.I���`�&�C��q[���E�2}����RTun�!T�����F�����B���U���E�32�~r���s�/)D�%'���Ws��e��M1�e����h�}�%)bG�Fy�#�
���L�x8�'�u����vO*(��k��\��e����RG�dw��'&��O=��tRz��O������A�	
�X�F�R}Z>�gpz��t+�����;�������tm��g{<������1�t����4����Y��|~�	K���1��,�k��4R%���"���` B�TB@�Tk���H��s+6i��cT���^a����F��@���0�N��\?!�G)�A���D�Jb&u�D�S&�0��d����^oR��ZQ
���������?���l��%�EM��i�f�|���Sdge63�'�hjSF����D\l�e�������>`��=k��RO���B�4#x/��p��Z(F��{!���Q���2�z��q����f�E�Yo�n I$!!�;CI]�j]�#1���c��^*s{��L��t'9�;s2\�e*fLE�_g[�EfN�����6���
�i$�Ns��_T�����y�t���r-��3��\�'����lm6�
��@���������7�^��0Gl�Ix�l���~ybU�v������z�O�W�l}�y��]����f��� .�n�����(�����0B �(p����^3bc�0��R��*�e��N��"TR��QMh�E�6��Lo��w�5���M��%�:�j�7'60���%�����-�����p7#F��I
k�f. ��
9�25		G�q0V$��9%7LL������|�ch����I���!�������sS{4�H`1����-�e��S����8�I��}�����m�{��"�l
�1T�
)I��5c�-a&��&��O|9T���j��>��`���5��@��8r�\&[����� m��U
���+%�ZL�����{WRb���R��G��e
I)���'��H%�'���u
3�S&`bBh0!_~�R�~��5M(VJ-�U����}m�jM���
���}��=�f�	��+}Uy[���'��^�7.]��^=��F�@������m)���$�Wb���I.�L����h��F��#a�@�zXbqgM�-T��%�y��=����[�I%�����_����d
����2 ��������E�����*��
�B
������D"��y;o�
������2t�]q��\���8���FZ=���N=v"��=u�T�%l�)1@�Y���2R�����]��\E�-�)G�l���>_<��`���
�nl�������2��y�f�>2����6gc
3�;��3�Dy�~�y���G��(�p��M����;��}�����mlj>�Y����1Cv��>|���y�^�(���1l/���9�����N
���bh0=�����`�q	������;_���:��������A���H���o�C��V�T�Qa?���[rB���H��s�k{�2�%U*�3��$�$�$	n;�������4��@1 �H3� �x��$-`�C���$T�B��E�R��7
P�J�y\|0i+��A���G�
PDE��L!5$I�3B�IXI.9w��#4������q�e���b�I�k4��D)U�����&�hU>�G2�a�I��A5
!AB�YPM�z�-	�]�m���@�n
a��!�!")�&yu��E���[qw�@PR��R���7e�'��{���nr��T���i��9�r�@d��X�����"���� �8�|5)t�{(zc?M��P�g')��I)4NVw�+��E��q�t�j��b~�qSI���mC*jL���K������9��P�������$��P��uBWrE��je)!*��v���W���h=|\{�I��I���J��
$�MJ�J�����/��+u�����`a�
 ����fL9���b-N!��/J�Y����&=&����_������*�;n�WN�[N�I�O)�y��p]��n6��m���Ut�Jf�NhZ��Jj���������2�#A|����FV9H�1�w��:������)�r� 2����r����k%R�
L��`Fa�EQE��9��,*!A�n�XU3$����~y��F�n��wwwpz34�i*�v*�r���#����z�����]
�T�[��(K2c�T�3134�.���e�8��Y�j�V�-��9q���9x��7#�6�����|@NI��U���3��%q1e��d�%�l�1�2��7(���n��>�
������:�	
P�r`���I������D�O�����&��I���2r7t�9���&����#GJP��c#h���E��"%Q3�����9�uu�:::;����4kX��U��Y��@�N8�����H��8��m<x�oU�.S��j���c������z�fr���t��z���76������Hj���c1�ys3�^39s�����f�c�����Y����nm�qnS%Q%ITH1�B�R-�}��&5mRJiML�����l�8
&w�3�4�c$��
J���f������X�gV���M4�L"
JM�n����a��1�(E�+cccGSrM�[��Un�����RJ2T������a�������G3�r�=����������j����%
D�����V�Z����(� /�����o^�|��[�=�39���b����2��I����%5*8R������f{]������������x����8������W�7�z�$�x���:
Z�[���~r�����(|��jE�����;W��
Pj�u�\�K����������M�JSf�4����+��o7]]�6�K����@��:��W��Q���7������_A��'�/���?�������z����&�lw��%+y���`�}��~wI%�3����P�}%�r��jP��
{KK��f=����h��W6253�������q��MM��\^t���Y�bl	��r���"Q8�.�G�W���87b�\m��}N�&P�\;:@_lF��&����c��\�r����������-�]�F�����N�����37t��V����{�#����L�lFD��(FZ����P��!���^�g�� A�@���^��@�cH@�M���w��#�-������UM�L���K��RU�������2&}99��D������w��;��?��O�O����M.����?W��{�v����_0�T����Y�4�3�'G�*E4��Ux���S�Z�v��V>�5�t���~���3�R�����O��,�+�}[����R}�O��0���� $��M���[hb>��������n���u�[�n4���F'��Jx�n�������wN<y�g?MW��UQ�*��,�#>���;���E����c���a��=�es��m�����W������$~h�Bz�P�P��C?�1bR�<=�h~�����a#u-*1E"�&����6Ap�"�Q��1���������J���
��Pq(>��~��i4�c�X�~�t�4��
���c}y���I�g��sx2
AXAl�O�d��>�5�qz)���)����U����k.�>7�kZ0��qsSc�u
)���6�m����MYoT^�A��?� ����}�������G����K�|R���<&5�s���YW�C�/�9�fF"c8G�xy�MG`���u��~�/���^�q�peUEx��?����DX���A#���L&*�3�K`?��e�(EAS��#ETU�0_�b�?%��<������~������h�9����Li2�����pn�}����<����M 	2������y��������+����=�M;���'�j�[��t�^���S���/��-���d��}���u�Z��V_y�X�Nw{���7\���W�W�Fz����)O� �4�[����
�I��b'l7��s5*j���kg�)[	~F���e����_/2Bm��W��(���F#}�I���X����B��~�uH�s�����dJRD>�NA���!�ix�����Kt���I�tE�:��D��7UV�(t}��{�������A�220=�����G�-���������q��X�9���<Ga�"P��V�[6�*���J������9
?\B`>&���`���24H6��0*�i���.���~iPf"��rwRG�rep��p�g�B0a���w��${�/�~�P��w��	�qk�M i�k\>x�f:i#��@���j�8$M	H��R�I&���Ez���i�\�X��;��B k���?5��FRo	�+�VL���h����(b_o�CE�vO���!�H��=�����!�����=������	[l�H`���6��W�+���A -^�u~��^S�~W�!-���&��(�;�]SA4FLDDDW���x""""#&""�K{Ey�"4�"=�����b�lE��c��2Ak��[Eb��+k�����}�z[h�����/��i0�����1�S���r�Q��.S��Q���tl�j 2��grg�]C�X���@x%��\����4m ��h�r�;Zcz�~m��&�L%������34h\�^'bX�@:��ByI�A����x���
>����B%���D��y������GW��Yl�9G/b
Z�����<[�p�"K}!.�c����,�W��v�f���'��R�C�D�<IL�*����a��J	� B������P�����^��]<�����:��w���M�e����l���:.EL3Y�b��p����SuiS�����X���|�Pq��qgV���C�r5�}����,c"=O������\��U��g.F��0g�e����4AIf�x�x��E���M�������Q�o�O���)���~��zV��j���i(�v.��~�tFm�!�$�SD4��G�(l�A����A
�)�W������"l\0��@�jn��Z�e)O�7��x���V@0�	�d$��%	
�	;_��k�D\c�4:`��fa�)W<�b��k�;�M�
�I�S?dx���mEqi����CR��q��)f���9�(��+`�A�-�������������#��M`"�rnn2"��u�u@���7n�&���bs4�rJ���RI	}B@�jS���P��e�Zm���f:�Z�V%���V�
��)Z��JNa'V\������!�1��BR��+:��:��m�Rw$��c��W6�2��N�������_�b��p��-G�c������]�l��'*4on��r�T���<t���%�1��s����#T#�|z���<��:#�������}waG��{�Z
�p��>�a��Rz�Wj��j�7W�#G�S5��0o}"CN�����M�	�a�C�"�!-�fI�2��wH�]%�Z�&�+ld�n���\�����u��6�^���A?�J���G�!�Cp��4?Hyx>��'��+xeDjv�9iX������<�R��IH���Ji5��j���"XK���*�S3�i�.yq�H[e�[b�����C���% 
!l���
Q�K-��-%�ZR[ahXKm��q�m�{���oo���W��R�UX�YKH(�~�����;�� �� uAQ0Q��D�Q�?{�P��J�)��;������HB$VT� !Z
!	hl�X���ES*������$�I���A��:�����:�'���r�r��K��r��$�3Y��kQe�c���$�FHD�L'-("���1CE��y�	��������/���� ��&�j�g���d:�e�5$������4�TD#���1&��%"u���"R�8���DF��8z���$-!E$�(*��bA��XQ�X���t���S�z(�E��S*R��1$�h��*#�H�'h� Y`��EDT�,Y&q�i�[V��DRH��4���R
���7�8 �I�UI&�;N}���g�2�����S2�g�T���D�R�N�l�*p 7D��7$�_����������:�>4��^~��sz^���1#~��=��EwFY��t���
�g_v�G��y��$4��)0X["�=k��'�/�����lk�W>=�����9�����`#��raS��%;�#�J!��	���m�����!C ��=^�)�5l-��"""$�"�!������n�4"�'�D	$\E���ld���rBae���`��"C�h�"t�"!�1�"0�H���5ET�bn���'������N)�zq����3
*CO�tq�����][� H�Hh�4����C�QH�$�!$��s�G����eB��{26��8����[�!v���{���f�"I"+mz��j�m8��{x�O��"�j�b�.�<�TGq���N��:LwdC����H�c��2��2���� ��B��Z$�K'~�]N�����@U��QOB�oo\����!���Jx��s{��J���=N�����!�TZ(X9�y�"����6��A��Hv6�P
T��= w��Cg.��
0�N��P�^������A�Z��a������3�?~GP~��T;Q�J@��BKU~0��=��9�
S�K����?�"| ��/�i�}���V���]�6A���'��Mkjz`���.�"���d1��FoH���'�$Q��}�+��2�fEID�`���$X���,F~�
�4��a-����Px�+��0*_}qi\	���	"M���������\6� 0m�����UQ�Zb~��p�#���E���q�\$�i����C�O�MpWQ�<_�V�4�$������k�P��f3U&N{�Z�8�6UEa��`��,�I�3�fGI�	���&,�K|���H�XP�^�hs6YUZ��
���b^�h^!���R�3
�9�X�����?�������l^ ���i3=wpTP��{��#�����>?�okZ�����A���R}!���B�
�'@<Ic8.K>y3N���`gQS~�-��D(��a"���s2a�
�
�tY���{���������}�����<�	<����W��M������^a2m\�u�z����]��a����e,��V
|��g��XX�^
��)J2�T	fJ���>���vpc(yB�&�l��L��uy5������g�9g�n4��5�7��Gn���[T�����d
���u�n��~��^<|��{D��F�>�N�9Z\�s�2�
*��GUOR��2�N���B�Wm��>|q��|�"�u��o
���}����q���s�w��>m1�Ii�4��;\���+~��}i����Q!��c�)v�!~g���;�o_�|6Fa���G@���������"������#�Y���j��t����
#�Y��I���]~z����2
0~w�/?:��������$�7�]2D�V�UW?��i���8�o
�Q�A�����6"��CKRM
�B�H�d���R\��O7\i:�
�����}d�H��H}��i����`����UW���Lo,�	XB�(�#;_�H������(�~Y�������?,�L2��+�����p�
��47�g��35�S�t��o���$uY��� �������m-��NQ����~���	y��?�5��&" �Kq��[w�����
e��s7Ir���0g�A����Tw�P~�?��K����{�8h=���i[U����8����!�b>���/W�� 'o_
�L�X<��<����l�4?8���3N�`�I��]
DD���='{���U���c�>�E2;�
�:��'�{��_��2B7�j�_\��\=�U#��0���2����i����Y�D�v��-u���T����X�����>�����h9��=g��s?������"e�L&_����Qyw	������|0���",�oz�!@C������L�	R�g�G?Q���������G��{Q��a�_8�������|���t�����A?������J$o��0
��	�<��q�0��)��!��/�+<����H��$�������������,��������
����������:����:z3w�o���z<��<���q�����
S�Y&���d�0��A�5�p�74���[
�wR%8����jG�`u�*�)�t��.�T�/4����e/L�g�*�@�DNPi����{�?p������Y+�H?�|&�>�����N[��rS�_��� ���y��,�<�
�����]4�ol��Nx�[�n�{:x��e+������]v2v"M~��=O������^).�Li��	D;�Ps\D�J��]�}y�k�4Ty��w�T���Z�?o��i�n�t�T����:�����Ix/�$�m��I�`�5�QX �mj���mC��$��H���e�������7�����6�������AA�LA�^�~��m��YIT��
���*�t�I�SE9:����_KZ� �I&�N-A��LU-=��l�u�/�JJ5��6�NI*�)t�z"��D$X��������U�_E������A�s������O�x�����������9�s���9���kZ�V��kZ��Z��G��_�����	��8<�}�
��(��quQ����K�@�N������&"HHnf 	�G��+��9�<�[��^�J�/�E�
1"��6'��j��"(��9"�Jd��7���5CH��1��6;R��h.��O1���6��>�byg6��E��5���|�o�H�R7���9`3�����n�@�r����4w	��IEe@�QW�`o7H
�Ke�
�b��+��|A@��>C�Tl��\N����wwwj��s�@P�l�c��v:��v7m�]u�����#�I:#���kMV���;n��s(�+�{=r	*���x
�1�?��? 3G�A�9E��jFH�
f(:`t~;�s���������&���������"
���q�.����RT��?��E�$f���z$�����	�x)�<W��SK�����/�0@t�p�B���P�\^9�q���.X�����^a�����'O��\��������J���Z@�KH����Hh��TDNI��S���>_^<R�St�t��ToA�����W���|���&��������$	$�3����(��8QF��&n�����_���>6���:r���l�z�}XI@.~b�K����1���|��m��7�������'r:q:sK,��[����#����'�4����k]���~[�`!+u](��
R����z�y#?�'��!�V&���������:H

 Cb/ �h�>��|��g�A��J�����)����i��������3���G��_I�W��f0���z�C
���A�%�p��*��`��������/�}�����Z���e��o���vvX��D�9�79K��rh�6K���p=�6�:�Z�����^t�@�H�]�X�u�[� ��Q�R�"H@N��]p��'[-�""��������8�&q��fM��][�  ��0	�R��	���.�N����:� N���������y%��Gs�����?O�=��%�?��9�0=���"IM�H��4H�09�����^��{Y���'������>W������,!\���:���)����O�|�bQ��|�_�[���`��)�$��}3���i`Nf��Y�`����t�����6<����|lC����#d�
)a^�\5�:}���v�4������$R��r7Q$A!��7{(��|�^`$jv�_5��R:`���� F����8Ii��]��|�n�BH�`@Eo�y�3��.��~[m%��cA��i��$�=������jNr :�#o�G�����=t�!����3�1d�gwK����t��)�
Wk����lO���������~
'��4��E�q���x�>*��4/�M)�]O�0�����x��<k���90?��6������O��G���WY�D�k^n��y�hY$�l�I���g<W��x&
�Cip�J�l�p`}�@��{)G�7bR$����0�w��\�{� �������1�%4M% P0�VlV3eJZ�0SO�;{��zv��!�� *��a��5$������g���C�T�Z(B	�>�l�g�J���BR0���w�Z��S�q"�d$��[�E4r�5����IW���y��O������L����45�t�����*�)+i�`L�L���1%"������R����KE3<
z���=� ���|=�otQ�{Yje�ez�Fs�
���R�����c�]|��A[m��>8"��xv����IX�}s�\l������/�CH	R��X��S��pr�����h�}������z����������\�x}
9���T=*d�T*KM#�O��'	JT����1'�K	�
<�������UOtI�?�������~!@��:�3���=������x��%��
���w�DKu����x������xW��T��y���������TM�|s��%
�Os�������l�Cdo���O��^|�y��*�����+#)���
U�f�*�[�4��C:�O�K�����.�+����>����(Zg�<eIna��B`j�#e�����Q����j�������E����1>�e��Z~��e5M�7�����?�N�:���)���4�8o����+7�~�V�1�w;}���b�Gy�����4	t�����k���l�6i$v0�INb�F���u/�����P=	6�K*v�V������s��|���G��0CSO\����qdK��r��EV	�������(+���Q@#'�����l��
�g
�
����2��H69����%�_��O*�gJ_�T�%bx��A��>���v��C~�����9��1;���B%"Z�T��*B�3����^��)i�M?[����Y�D{d�I�S��,I��aXh�t����>�V�o
���f��/+���H���o9�S�8�i���>�kDK��[o	D;P�S"p����`3Yr�Ug} ��C�"i�hA�� �e�i����h��5��m�M��Y*���%�*�9����	t���

��A��3e)
�+�vy�H��$2���!6\|sLm�jK��0	�(*a�����n��Q�����O�������J������{��s5�8����VVZ��?������������9
�a��5��lAXs�h����$�B��s1�/�����N��v���l
Ir��bF�56�X�[6�R����1� �s-�@�q����UH;�'�O|4�H�B���D�
	���y��
y'/�~�������h�R�����$��!��
8p��I!�����/�^��jjYV>���m��7�i�i����p�AAAAC�W+U�s��m����f"g��,��.���j���<��,.:���c�P�����1�m��1c6�l���r����m���y�s����:t��(�[m��3$��n�����[m��]�s����C��0��4�U$ $  H���>�����5��U�~w��AU��|�\��x��S�d0T~e���~���������TG�J;������vB������y�D;4H��2e-��#zb���������@�_m<[�Rt6?�?X;�� k�������U-�ZHZ���9����������N�^e�q���!��gX�z@�|8�w�����	��7�q�X������Xi0����nV�r��Y��UfJ�=�-M=Yhfh��~M[v�U��V��I���%x�X�g�]s#�[���:����^����?���n���������_�����������rG�\��W�?�;QR��j��s��{}��?��>�1��	3�>o�������7^�pT�����
S)�!Z�`�U+P��M0UX��4�p�bE2��:W��3���F�,�B�+����%]�2�X�eMJ ��-������t�^�p���y��U�f���El�t2����4�>���9eUb��h�c����(F�^x�0l%9�_"������/K��a��[+��F4P���C*jQ�f�l�t2��5�'X����^\�7M��u:(5���
e��i4�*�aZ,E���'+��}����������(e���+��
([ec�WYD(�-WF�P���������#����y���T�Q�i,P���L���P�K�t`K�gV���6������F������dV���DV����x��� �36		�0<��SR6����&����([
!��+�z�� ���D����D�%%(L��:�&!U��sK�-������[Kh� �5�exl����"�I9�&��3�2���PS�C��UV)�)��N3k����]M�&J��+�ui_.�v�Z���a$XM�y��BST�+]��DDDm����yeH���[�
#v*�����I*6�#lF��aI0��U*�r�`��Mf�����[ER NU�H����	�TQE#��f��N�(���@����K4CD�Z����{w��^��3��t����ah�2:����pd���U�jE0P�ec���x�h�����J��X�� C��]�v�I)X""�����[z�7T���)(�39"`��D@�/]��y��s<��<x��|�u���P���z�&���iE�	��"f(����hH�g\��\�z�d�QC�ec������p���G���x�%w3�A�9��3���P���3[��Y]DP�ecpt6�jQ�F�1�������I���q9���)������[�����xe_�N<=�q��������,������k�����%��o�������k���W�������@j��6��[lg������}�>��p�"z"���nY�������ck�ma-��^�.+3��������C� ����9�*i��v=���<�G��'f�&R,%��TP�H���@�Ye(JV�#�
 ��v�uD* "%L��]���)���-��R�~���f��V	D�IX`H�F�$F���Z��L��Ti2b,�3kM�VZ�k*�K6��YdE����I���1$F���<�|�w������� lE������^~B����a��i�ca���������+���'�j�"���-����-D~��7�����6�FB$�&�1�o�A]��4$$�k�n�9Sj���A���3���'�tQ��Z�_��Z�������\��OM,�/���6���<mK�����m���������ye
��h��V�$�4�r1#����>��~��9�~a��p�����er���Cnfd?�,R���������ffa��hU$�U\�������n]�"4�]����w�~!�/WQn�7��9��
������tu�KO)�-��>kx��l,�aNq���8r\��N���:z�V��zD�4RQMI��h��-\�[��m{_WNg���&bV ���O3�?k�w�������������>�n�G5R��XQ��$���(�(B��h4$/��\�s����
*G�o���oc�l5�t?v�������"��^n[����8E��gb���J�2���=��S�n�/P�PU_Z��}�����c��{�0��GY0�����(:Y$���&��8�0?g�3h����!t��/?t�3�_(��])P�~��t�}��M�IQ��TX#,AET�|>'!AU|��I�<���i)�b����l+��1�Gy�!�������Y?���	�
�Kd���$���������0����G�g��
��.�?����}��rF`b�v�}�R�������K� �����,x9���	t�*��y&��D�!I�8jO���}����`�����z���^����N1P�����[�=,��7�����10�eVG�?��f�L�\t3������q��(t�@�-VIo���F����xjW��^��rm;?������/O{?(��*��y�Z+R�K�}y�����T|���?�#��7���?	+i����2�����/jP�mm*�gE�b������g|��I��ln������6�xD�#\�X�0\nn������n�/�w��G���z]�U�j��SK���@��:*���q/U.�- �z���#'8T���&n�B�s�Y��Klw�R��N])�;s�9�$���r��Ou'\�Z"-��OJ��S%�R�w%���P�����y�I��y�q[v��<5�������o�����C����
>]�5��yK=�4�>B���W��$��$���~B�8�~h��5�� ���nY[�4H��K���>{���Gb���zKj����{yK�"y��	�6d�����?����R�1�fT��b��$�$�So�<�}CO,8���9��Y �Co&����%X�Xf��5S-����b��sm6����X~��w�o�����)������E��8�y�_\����/c�	��g�z�S��i9m����Iz�o|�=�F��;��wd���&u���m�l���&1/X?�d�(K�����{4����cM
���c��� � ��b�
>�H=��S<�L��J2dCZ�}Y8�T��������F�$�,66��c�����Q!h�!�%I
#�������[Y�uu$�%r�a�PX�fCCM0`���c�dV����#z9���)��}���"���l��w���#�q4�O�|��Y���E��8-?�w$}<a+9&�@�ID�EI��"t�/]o��I^����^�mD�����g�V��%R]�|�cl�}*
��fns��RtJ���?q�:_�W�d{������(5T�B�z�H���&xt ��7�"W�>�(?�P�D����	�
V���l1��|I���w���k*{]�-
5���j��>.�@��Uh;t�������
(
���n��'9�I%
is�4��7��.��}��kz����rL?l�f���P�*
���f����q�����s�&�P��W�r�W����5	)�uK)�@=�x`�^��N�E����M��;R,��-�����2
�MNQfz�����V�
:a���_`z�"3�t}!��J&�Q����64�7z�1��4�oN^&�~by���{$M�d�R66	�@��6������t�
�JP�UTK$��w�6�#���!���r8�	���n��~��%���m�%�:
��n6����>���S;���r���e�������1���[���yp�F�v�T~��*#*�R�����rJ��(��N�W�����S���D��L��]P
�iO���H�j�eA�Hn^4���*T�i*���U��u�4���$V6����^v�a��$�:)�32�&��t ��d�Q��Qy+x����%�e�������Mt�,R�fDQRRI�2YD�l��$�&�(�$�2� �Z6�Ke
�m(0�_�I�dVW�`���H)��L�(+��0)&9/� ����ct-+-����Zl�"�L���!"2���I�2D	����.��A��R�0���=B�(����x(
���a���#� K�����|�\�#��L?�����>��=����>s�9�A���?�|�������e;5�~%;[8������S�����[�F��kk�
�?����3U����D�;���|�>�u������TA�|#�l�~Z=�p���~�`�EUI�q���������o�_��!��H;�|���f��dq;�����R!� 	��?�^�T2E_����?�?����cB��W��M�9�N��
�H�6EMf��0�K:m�i��w=����hZc/p���tD�$}d��LP�@M���c�����4U*H���
"�x��t��~Fmw~18q����d�E�
�;��
��!��x��8toO������O���h.����X9n���Dt��\.�����g�tC���Z�C��w���J�0�B�@P%))$h�$�@�f�i��pK����Q]�ygY�������b���s�c�������.��"�z7#�����W�#$�3*/1TH���x�	�K���@�\q������O���"]��dP����\",��$����
8���������wcL\�0v4���&$���S��9E��H��P3��<�����)9�v�hf������(����������${;�o�zKT|�L�L�+��FGN���I����};�.��m��[��0��H[0��P*�T�TJq]I�3�6���Y��MO����v��sN!�Hv�]�'��a$�7����f��Uh:������	F^�OE��B�8cQ�Q�2};7yx�w8�������Q�`nd8���J���+���t��lv�~da�����s��O{�#TDA�	J	H�]�����$+ `�3�� H����`S��\3��r�/���#�p�[�u���F��s����������%E���6L^j�����H���1�'x�w��iZ��	�����X�ma�u	9:�����^d=Z�5�s-A���Bh��i��i�h��w������y���SmK���e�s5�����?^�0*A��@P����;yg��P�������p?"L�Fb���]K�� A��~������~�Ra��[�fW�85H��:�B��IJ���M��iN#|C�A��W>\fn���1����w��/E7�����O��7��{p��z9??����^}�����
`�+��IvZ]c���8�|���~����tv=�O������o���n�k8�������K�c�v~�*I�����@����d���l_���Q��=�D����O#4�����0�~U�}���OwdT#�����{K��Q+�$H�sI�	*L������
��H�,�����z Q�y
��	�8n�����f��ayfD1������O���~i�
R���)�����e���[+�"��S*��a�Y��e���ue� ��>�$�*%)<����*DR�X�<��rS����E��`��
�+?P�_��W�rJ�J��bP���9���+�y��FPP�M���t��	��E��
�gR��������=4p�JXd���VfB��A9H/���5����$�{��$�9��<��H"����.���"O��"� �[�3�
[��;u�fQ�����W�x��h��������)�)>�gx�W-��E*�7����������.R"��0]Z��7������IOR/���l�s�`�?��
���64R	�������������p<p�yR/��8�*{�T�<K�����>��2'�U4���r�~3+U��q����
��K����#��l��kQ%�����k��H�Q��-|�g��3����I=��v�`�� b�l���S���0���l�����Sy�v
1��E����n��U���?1�
yS�N�F^�[��}T�����8>�������[^�%�J
��A�fE��Bchd@AN�xc����u�w���O>]��������%X��)n��:�+��}(��B4I�yv�I�
�B�9|/x~���WW��]}�EBP��n�����<�{�=q��yv���4r9��o�bJv�(Z}�&m�j�Qga�������L������k�i-���8����u�m�%���!�uq��x�~�1�}�,��2���[eX���p�B��HI��ra3H���KH��-o�����&���}qK����!�e�X������J�����FJf�E�TI�5��*bT[Q�
z���44����kE,��d��cR����b��-�Q������-K#m�cZ��mJ`�'H�dU���#��e�)�cg����N��J�-�.d9��W�s"e5J�d�J4��PFJiW
\�
mRV����U����
Z	
�r��ADAd��D�A��H�z	?��~o����*��D�|%z6?������r!��3��cJ#�@�dLPA�T_�*d<~���0��C^�^���!�����q��#�7��j����D���$<�|ODK �5:?��P�l��aQIN#������2�-�����?u�P����T2����(P��Ft�r"B�Q��T��5M�*�����_�j����c0�E��$���l6�n�E\�Z���J2p���>$��	b���8��B2D�sN�.�]���]�2,[)MD9�N�f��J{���_K_����wdC���Y-��B��RJv7��:�?c�/8��P�T�	J�%�%�e�����9��~�
��"��nq`��b��5H���D���&�PmI�t�����)D4�98I� �[r�f�
�B�A��Y!�b�)���:�~����^�DTD���^�:�k
zzV2cL���Q'�2r���%"���ps�G�=�� ���JQl��R��m�����0�	����Y�q%�,l	`�'�i�I(TQF������IYBZ�6�������8XZXZP������N����p�@�bD?������?��yQ*����`��b�Z�(bQ�(b(i���~p�9�2�_�-�m���G�H�r��z�B�����[� h�V�����^\'���b(/^�y�|�� Z^y��UU��������I$��V���8��UN���\&'�B��"�l#LX��F��TW�-n�$�P4�1LD4W��O_>C������{��}?��1�EQDU4����j�/7�[����~����96A&*_�2�B%�U9��h�P�!s.Jk��E���did%��"�,^���9����G/h����KqR6��/EI%U�"�����O��C��|��T��/����:�����_yp�i	�.�6�U&��0���^x��qr�X�\�5&7;|h�a����p��%q\[�4�%�,�ddH����f�<n��9�w^^�<<z��m&�mOke�{zP���j5f���#.DZ�g>.��CebDY����=���K���m��@H����H���s�.���"���3�%��`2a�>�	(��R)�	y��4��
#�������y�����HL���wy�|�=
�~�P	��s8�7�&�7�����M���C��7�������M&�&��(�0�R��r�`�G���4��=�R`�����E�V���.������Ey������xd����En���*��a I$��t���1��n~�
�X��8
C2���N����#r��P�
���u����Tv����<�
�j����l	�&�	pJ�������L���i����R�����=!���uL�8F����(��>7h��Th��2�����3��<v�	:���KEU��jD�jO��H�@%�r9P*�G��z��P�z�YX�'Yw��g����j������)v�������qY]o.��u�����5c�L��q���;l��p_7��w�m�VS����9s�Giq���w���jli�'$���'�G$�����w{�m9%Z���X�Nu_oy��������4�UO6���]^K]���fY��Z��OW^�n�y��f�S}�����=f�8��5U����J��r��u�T�lr`g[�����
�k9��9�Mpu��Pq1CQ.D��U4U4)��������z�i���9��ny����s�(����b��������te%_5��s�������w'���s'\��\���ve�7]�D����9=]t^s �f������ ��;R�����=WY$��M$��@��OZO�A-�A~xd�������1�a�!d��E�L�8c��,��~o�i"C�d���G�=�����}������� �|H=qD�������X�eArQ9���,���J�\�ZE�	j>��D��nJ{�idF5��I4'�����i?���L}O��� ������i�wn�J�fA�L���������y��0��WS��d��p6k$�wq
�qG<���v�g��G����,DC'����cCr�i��]i;G#t���u���I�_d�O����^]F��^�_
���~��#�w���_�034
�*
�����$#Z��-��
/����)_�	��J���9^�O�d��o\fYQ�z�8�>���@�����<���'�m���������JI����{�u���5k����rl�O���D�UVwm-|+���}-8{
��D�T��GP��e#���_�^�9}�����!G�B���c�!�l��/}>�<�������%��b���.ZFR��)J5���=��6�������M�y�mo�U����>�j�u��$1�d�@h��@n��8|��	]��S�����k�-mZ^�7/����~���\����{W�6��=o�e����79�����������=b����9gj��:-2�y�����������O�M��g���i����k�����2��M]_*�9�\�37�h�=-'=�0������K��GtQ���)��'��4��}[V�*|�@�",Hy�:�D<��Q��rA :�	/���(4��wy���`����^�u������g���pZ(��SI���#+�����cL���VF������
�r���!?/��l�4'��r���`�T�����t�`���U�S\�B�^e��g���A�����?�����,}E"rl,�R������	�I�� ��uBH�A�DX�V�M���$��$���
��O/a���M�������z�����I$II$�I$��$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I"����
��t}��I+�?���)L����f~3
8�j�����Hm�)2PA"�H(P�
Ps�?�����msMf�]���u:E)Jj���:�����SV����� {}�w������;���Sq�`�jF�$H�&L�x"�!
U�heNA�U�1�	iC<!E��*���������d������"JR;�r��b�-e�Hqb$
(IGh���A���UgS�%8��H���-��<��o���f�#r���7{��V�ke�{��AW��#��p��*���HP	!$��i� ��*L����I%CtB��D+m�"�H$;p���"z�����B2<9�UY�(�K�|��&W)rq4zv���q�I:X�x�"/Z�:�wu&=���F���j�*���7l=�^Y��5�����������/y!ys���3[i��b����f�H��X�(MF�k3e��U�~�s���K����.�Nwn���d��	�+1&�fp������&��~��E��^���M1E��aD�L4���8s�7)\I(wU��	�
*�R!��+@����:���p��cM�����J���!���!�r�%7v�;��+�6�4h.U�T\���r�y&Ed�&����q�����-Tfb��2����"h��3�Q2UO�%��$Q�@$E��4@^�]��j0.f\�������/�s�w���^�������k�{�ZZ`��LM�I��*��P��u��������jff8�K�g�Z�����U�05R�	��#m��w��[��nzQ9	�Q�t�#�
����[e����%A�hDU#��������6�����
[m�#�"����j�.�j��v:Q�"P�`5��ps�c���4�"����nc7�1^���S)j��c�{OZ<;��h��J�����V;����g���I�y�l��q>r8H0���P�(B�8��,�G�:M�J������^��;g�4v��?�����n�.��nS�u�{�>i��T���`���������v�;F�WB���P�CE++�#|)�%!�5����5�T����m�	 �*g��)�X\�5�[,9*�����ih+�P�����u�b��n�'�eJ�L�R�F�^��
?���|`��Kl�/�3%,�f=�4d
��]���r����j�p��i�����������%������g���u�g~���rX����=�[A3,�a%@����;pr3���9�����#e���]�������X�[� Jm�����P��)m)2f��t�eB�k�t�Q�w�'~����������r�r�*)�
��Aj����THd!:��V=������������m�Z���-��3
a�in����28p�m?	D���>5$}�B��Kg�S<m����]��N[r�)U5.psu���[c�$��nml�ws{��N��a�&�n�gWW�x�f�p^b�R�+�����|&d>��E!���
0cH��
�AZ�Am��@�>��R���wK�5�"��nZ%�B�_�d�G!���U���%���.]���U�~�\��l�J�$����g�r�pF�a�;�fF�
�	e$�	���}�	�pz8����Gd9'6H7z����uKoV���
_�Z�mD�����C���{t:j��U��=m)�+v�Jl�wVfMTm�1���h���������p��,�) Xk��DoH(]�&M��d
!��o��D�!L~c��q~v���c����5b!�f'>�K�_:x�zt��gA�	��$BJ}������P�������y�y�!�u���"!�`Ip��{�����N�[m�8�W���� ���]�
(���N�/��<�mH�#�f����B�$�?g>v�u�i���@BUX����&�����M����S��B �sex����W����PY	Bi���\6Y��|�\��M�J�F�9�����IT���sr�s��p��Q�U*�RYJ��,@��q|��2*�q�2���+C��T�V���E��LB��2�����9#�G<p�Hfc�cMbR��K�J�q6x�{�0na�Py�)��A>��|t�.���u��|�)�V���bI�B9��-��{�{��N�Y���Z7��5�Gs�*����I�e,�5����QY��,J���T�R��*DB���)�z����N��G����=��'�=�S�o~gs������w�Kb��"%Z�jB�N{���6����=4���h����L�v5[8q;V����R�P���lb����u����D7
�z�vO�F��R#,�ZW���J`:��I�v�4����=K��OV�0c`������>����-+���5B�.h
���>U�O��tw�>��@�j��&h"Tgs��zc9T�y�v������+����o�:��:,�e�/�P�=~��z.��[AOO/s�NC���A�a[�n���s]5�k���Xd�e��U����
�kMjk�-�+;T$��{����d����'\]���_'�������\KrJ�J�����Zu����[B0y�R#�eC���!-NcM
?P�~>�����t���z�����:��.�T�����rS���|'�-,��Df��"$P*%�D������v�(����FC���W��D`����(�0�7w��dns�|:��c�x'(�$)JJ�$�5ip�QR��)�J�/(dz9&�,z1�U`�;�<a�4Tul{��:d�����]j�VY����J���|+�f)�����l��8�v�L��{���PFU�����d7-z�u���4�WI�K�W�x��d�Iod���~#�=o��|�/�P
���O7��2��Cu�n�aT�����Q��{��`�@���{�\��AQ�i�0���V���a9�H�4���S�G��~�I�
���w�>���P���K$�4�XK0���l��3i	F6��@OG-j[eZR�FU���B�2����v���z�Yy���\)��m�9�I�/5�,�LJ��E$�QQ����-�h�[bY@��*M�jc�	bn�<�	r�<��"Z��e���uF�
 \������z����R���d
�!#x�c�f���r�)G>>�Vv<��;���C���fF>9�o+|pv��:"��D�b+T18R��%B��QH���k�Si;N)���5�7�]�,��M���FR�QjO^�d��\���;3�u+pj]y0}�g������=z�zP��]�u����^����ZQ�k�,Y��vA?i��������~�i����-{�����&�H��'N���o)�y���y��I����W�����z����p�!��]�F��('�|g,����_�S^~TQ��&�!!
%�FK*4�4IF�	b�1ce��x��Q\Z!���9�,����j��:o�*E��D7#D7#@7#m�1�@
��cA
�c7 4C�C�@7 4|4��s�����������6�������v���bL�b�3q�h�p����� fR�2��� �
�H;�d��6)�������Tb�e��3"a�;H�cUs�>�������<��"��-����tN�������	L�$���TS_>���q_.�\�d�+���T����2��@���C�\�Z[+�n��.���M*���9#�}�����>{��������������T��$s?^���4Z���'^�Aw��5h�M�n���nl��w���|�gf��:��Q���{�)Q�=������m9�+����	-�#����>��y���� ���VM� �<�wDf��F6� �	����8�B��*[R�04��:M�5KGJu�F�q,=7N�n����wu���g�<����f�j��`�]$
��^��(��j
�Qf�IG�R^�%�[f��R\{[�����Kg!	�w4L����"f���H���
�H�iPjUZ�!�pgN	�M!�
��bb���*5���p���E�H�����(/�7IB����q�+�8n�n�����
�D�n}?��]����>���W��1I����W��P�B(��i��#����{~!�R��@�FB���C���]�c���+�`�dh��W��o�������d����XfJ��!�)�~q��c��(S�U>W�?}�>z��L����75�j���'�B�9�O���W��YL���G|��M��1�i����d	!LD����+e{�^y�9$���g1�X�n��IYD-����)In��9��%85�*66����D��q�{��9�-	b��-�R[n��-^[o��,�v���2��|0�\���m�O�r������m������
�D7+r�U���R���(�����mF��"a����d�FX�3%�f\�f��B4�h������j8e<�Q�����Z�i��6������r�m�j���e�h"l���UKe���\j:3x6p32L\�����t�Z:X���X�/����FO�/=3��[my��{�
&0M��4�s��Q����r��v>��sNp�#m�G,�Y5fm��Rd�����i��x��E����[~��WU/�l��U���0T��C}3��7��k�\��|��kz<H��p	c��ciZ�VU�97���f��x����x@k��Y��^}L�DBY�I�������2������I��eIt�#���g �cm����qM,8�����EF��o|'sY�"iTa"��y��P�3EP��bs���|��G�ZDth�|����V!��2�����by��)�IJ;f�:S���G������>�i�[c-t�\��*�Yh������J(�9e:sT^�=�	W�GT���f����M��P��5���*w,������Ey3u�U/�W%o6�V��1�s�iq$��[f��j`�A��n�D
�����0�-�YKyP�g-��2��,R������7��c��5��y"�����!py�e�c�2$rh�����YU��s��g|��t�V����d/o_�l�F
��O�T��c*����nCwM��2������fm��sm�4�i���8a��4����m�����m��g


�a�������N	�I�f�(Y��&B�0�
��q����(1&�<.����^W;��33��0�T��.�d�le
�6M��i
�����w21�;39����[m.fe���rd.���-��eE7$��lc���
����oxJ�tsv�����[��� �:s98�}�1�B�����m����,,775�R8���b��9��<�\���/G��q6D������c���;�������t�"_o)}����?NF����i�L{m�~TV�_�2{_�Jk�K�~im��	�&$�;R7o���K����8N��$�`2d�d�������SO��"���}?/�^y�_{����<�|��x��0
2�d��l������������hHHI!$���
)�N?��#��|����\��>r����;7�yV&$��r�E`�o1��sm�����M����
���JqX>����Y���c�.q�Y[��z��bbAQ��S����f��2S�p|9���m��\��>r��k2��2������{q�c�7j�O9�I���uL����@�<��:0�DQ����0f�epF�,e0��a��X3N�;$���A�`0d�D3���V��5$���s���el�����K����wI���<��wvV��=����t����2�G8c�:���r��I����;��}����Y;����j���I�o:��I(e���a�8pdIA�0:iY��&�|�T�6�J�~1\��.o�\�LF�2<���j���t�!��t��W���3�o7��F�"���"������i(����wr8d]C�0�&���b�����>A�~>d�����Fhm��k�}rI$��$�IK&�u�uu�]]$��0���<�|�����n��p.�h��cx������ga�/j����6P��������\�Om���]���W'x�*I��]����m����/R�w��e�V�]���y���7���r�@Znjv���#��}���Pk����v���v�t���_{�s3r�	���7K����w���z�z�w��V?U��g�y�9��(��o��*�;2��t�M������5��,Nu�%�)Wob�dUs��E����E�mJ�nk�����T�Ms���y��f���|�\�ER\�������3��T��V�����7�8��|����kv�^{�y�'u7b��t<��gp{f���bbAY���\��M�9����%��N�\$��!�R-��t}<��J����.�q'p{����X��	��D�=o��C��d�4���Rv�9��8���8�f�X�
��rL�h��D��zDX�-,����K���2����cg���~M|��G@{�,�ry|�J��)U�����{��K����&k����s����������i��C�9�q!rUTvf�EA=q�jh����':DE��i&�YcHr2x��Fy�jmg2�����jR�np{�|�S2kn��s�9D�{�����|��y�/^�t<������������V�M��.�.��V���GK�z���P� InL� @5����M�=b��R)����IA�0��iw���s�$�BI||�8Q����jeO�+��]�D#�!����0���$��\BB2���%s/d�(��0����D�)BI*��#2�������MV��Qw��8d��|�*��0p�k�-�@X�&0:�[�K}G����������-��32����n��Er��5;�r�JR�����Muc�!�9�3RTS�
���&[�(����{�=��Y�b���]��Nd�s�=��s����2�j5}����v��p#ERjE�
<%,[K��-��nD*��S�t
�7R-����-���\\�Y�{)�*�������F�r�$�U�GSDa�DDD=���(��6z����<9�:��q���&J���W�V|�9ow���,f�������Kk9�����k��
�*�����6��4 DV*3cHt4�C	�{��8��V�z��E�+aB�`L�`���T�+���{�U�J:Y�o[�9�vw+���Z��N�7X%"�� �P���y8�IDDG�����/����.�LC'��=�^�O�n�����r�pT���]���o�!�d.�G��p�J�=��l�{];]��P��B�00a`�0a`0������N�8s���v6#0���a��nc��3�[so+%p�����7;#�&����kS
�>�����2$� ���������]� ���Q}���hS�I~Q�#�*ny=�8�����3P�H�t#���F�zF�a�b�:6A��du�H��ba"A����E��9�@f�w^r�4�Z��H{n�\�5&v�
kU�h�I�D9���o����b��DH��q�yQ���
�
�+e1?�����,�^
�X��C�0���H��k�FR�|�G6ob09�=~M7��0$!�4�My�si��J+�cnhmFD�f�j�AFFq@P�bG�/���0��FC�=��%��,&m$�"���P�h��E������A�#�SD�9��<oW����������G������{�&GQ��Qp�����R���]�$-�]�#���c�)+&6R"4��h����{�T�7�|DQ<.:��y����o-����J2��;WZ��B4�dw�$�9�&k�D 'HJ�l!�P�f�Bh�����bJH���9���o�����
E��>��f��!�\��=����Oi�.�;.BB���K����U��q)��Q���=����<�g80��86�B,��)���q��e��L��S�9WrQ�G����B=���Xp���&U����s,���E����3h4������L��8:}�>9�\��DU�����(Ov��:	���
���P$��&����Uy2����Dl}p�L��������q��u���}AG����h���)��f������k��n����n.����w����������BS(���y��;/���@���A��
�5�J��'N"�����ur�\�%4 �T��?*��0M���#����h��t�l<�Xi2A0��3���YV]��e����|���v��o�L� ������X�r]�l�m8�v�G�r����T$W��t�����c�b�i�r:�����__���V�@����m�C��_�����l��O�c�R�3�s�&,����N��7�Q?��}��[��-�3|JQ�.������C��*,�Z��D�6f\�*�� b?��$�u�U#f��p����.����Q�HE��404���FD�0�8t�!�Z�%L���80!K`�t�r�\\�m�?���u9^u]R��JK2e�e}{���5��0	2�:���-�-Wi#�L�0S��7�s�xNp"q&�C���7-"����^���!%�0�W�v������1����O�������/�e���B�AUs?�v���.�X��AJ���I$���5dB�������4��� \[x#u����8�z��U�5�<�*��X���h��'X���!��&��QT�
#�y�/������+�%	"�����z�,�~��zm
�l��B�	y�HQ�h��_����������{Z}��4(c�c��s�)!'�@�I#f�����a�I�y���:���~OG��$��q����=���p��;���*I'~���������q���>�N!����������aT����Um_���$��" b>����d_0%���G�v��Kpo����q�F�	`}�K$&iD]~��N�M�w@�
��`�CI1�^���9!TF��m���Vu����~��
��.�z��X[s<B	����R��������������G1��
Mq:��9">���ci
���*�������y:'�Q�A0��RCU��������2��iB\��o������B�O�hv#�i��c�W��}Z{�W���I 
fQK�EC��q�S��!5?.N��
`Q^����L���C�	?��=~R0:v��:��;����_��{ee)"�P%����E+>���K!�9R��x?�D�^!y@�2��P�D��,1D"��c0��T1��d.b���k%
f�	��������7��f���me�aq�D<G>N(#[��U�V�
bQ	 ��"�	��IDw����:�OoA��>�?E���d�CP}+�9�� �W�L5�}�;/-�I���!%�v�'�����y'ex����6M��OA�s���R �
���|�K
�l
��$h�sG-��1k�����	���=.����d�9�`M6�85$.��Q�>Kd@�R9H�i*�L�_�}���������X�B"I�4�����&��
��;����
	#�b�D-��+�zBK)�$�B�������J�$2���t��.A,l"6P~/����#K�U����XE��Vd���T����n�����J�0!�~��S�f��������P$���N*�ON��#�<,��w���3�{��]O��4����
?t��X����b��>����l~�����o�� �{M����X�E�������C}��$��K��E�J�b$��Y@9_0� ���2�G�
hWB��@I�l�����@���R���\�|�u4BL��@F�~��e�$������h��,� �H�)���)/�(���!I����6dXiS}|��R�D�9���%�_|d=��F����<Y����*�E���)���T���� !��.W�\�]����e���m�9VI@��z�
R)ZZu�/N��C�H���
�.��t�7Si��"7�IY��ua�����2�>��/�$���t�:a"}���_���g��C��?I"|$A�_�s!n�%��T�$M 2j�m>��������AN�>��c�#�`�A�����>�r�R@���*y�x�h�D��6�W�'|����u	&�q�G��X�)��A0�&LA[2�mN��I
��16�y�H�����O��x���|����v$����!��`��b����#���<�@�x���A	.Gb/��%�#�~����O�$QU������
c�0!�I["@�>�zHm����_������!QL�Y��h�`}�
��a��������_�8�b�	��B���Y���L��7��������<�V��.� >H|�L�Z�*@��P���/�)���l�Lh�� ���� �����a}��/�WN|"}��Y�����x�4�q�V�S�Q�x���<H�GD�G��4$����Av����cP�!�#$�}�~�Sl���{�<�� ����������e�^�m�r	��a)�I<c���Ct�z��Z#���8���7n9#.6�	/��;�V��ll@��G�
���p(��	5%���:�5�^�	��7�� 5��$%�%�������\C�
��b2��	O����������u���
m�v���V�wF�+�"VQ	�`x������uII��8+���?PxVi��F4��)�Y�#s�i�s������e�>�9�ZI$�:���C�Lv����)���[tD������9����@�)�D������uw��->���d
@���I# jF��e�q�L���$�"+\f��$�M���h�z�J�F�>p��."*���L��Z$�IqF�	�����]����g��N�b@}�(2J��"���5'��}�����'���?������8�~��D����I7>�c����O�I'g_R�^[��\e�����<"N�=�H�����;�0���Y�o{���v���s0/�}��RPjD?��k�������{^g-��Ek�k�W������EX������B�!��d��H������`_��>������h�m4� ����|�����5�����bP�
��]��V����]]��u�
"A��iJ�9����:\4���\��N!������wk�t�I)J�hSI,�K
Y2f�M]J����������R��]]��&fWR���)���!0L��1�D�0pr`��f�&L�v��u$�wu�-���b-c�[%*�(���j�PijD�%��9����]�D�\F.��v���K������v�u�������uur�����[� �vY�u�`m�q�q-�����T'Z���JJT��P
fR%�TH3���)���8_�����������h"R!�U ������l��#�/�����N���_�8S������yyyZ���h(~d�hZm
iY����i�b�Y��{��_s��p�n���9�gj,��zC��_�j�)�R���H��`2��7O���l�W���qa����D�
��I��H�����r���O��.��y}_���?���1��T�MPi@�4����XJ��I)�6d�P�D���;���r�U��r�EfLL�
w��A���9��;��7�)��dxt;����
��g4ybk��	y�uu2W&��]�� g��;���_ox����A�{��&w����`�d���;o�}�.�#�Oy_����!(������:�*��*�����}�N0�Ah �,m63Qj-Z�i�*���[:��-�J�����>�X&�izT���F�D�M��N��s`��"^tw?<PGlDN��i�b��"Oa(�Or��FRT�D�1"
��U����m��j���3"V��[Kk6���#�zn$�Gf����p��)i5�)��m2�M"����#1����MfSi��R�)H�i�#1ddkdR��"���E#1##V�SMR�-�PXZIJ�"�X(�V��IRB�!!D����	Ida�b�"��E5��5f��iEJ5I)VSm5���H���ieH�[y�D	a���R��Ex��S:���)�Y���H�R<)4-*'��I
�_3d��I����58KQB����9��DRl:��3P�i�4�Hsi��W�<�$�WK�8����@@�
�(r���\���p��FM����(�yfc��"�{�sC��FY M�%mM��QdL�f
�E2���/�e`���:�����j�{J����T�"!�M����g�Pc��&��:Bn�U��F�)J��'��+���H�,������eVW�.�2D�S.j�K)��j�����"LM�+��(`$�KV�3b����R�V���k*��(��Y)���%�@,K�D��%PbF@�)%�&S[E)��f�K�u�uq�����mytn�#-V�)��������r�����#S�c��$�,��
��[(]Jx ���o��w;�9bi��Z5�<8:w,@��7-��8�g��W�h�t�+�� �(��
��7��`���;)�����(v(�����=a���>crU�F=�Xmv��l�o{�8�a��x���AnFb��l�!���:�L&f���U��:
��8
s�9�8��z�jJ�4�C�
D)�c����N1F5m]uQ���-�'SH���f&q"b����4xz:M�a��4B�&�7)�
4	�����ITBal��X��U��G1��IaIVQ��r����M�����A�$1UR
!����7�|y}�����[:��qx�+�xII%�������X�"���
&Cx�����������>��P�."`�uC
�����m���U5p*����a����B@t���k��*BVm(��Z5��*[j/�h����@si��_LD�(BH>]���7AD��\�����u?��I�F���t���v����b#��p����*[	1C�d�^���*HeI�Q������e9�I
9�Q�%���#��,��������_}��Xg�����?@���_����0�!�t��I>(f�-���=�46���P�{%@��@��S�76R��.a�'$V��<�	��$f�?�Y���g��G�0�w�~f�`��!���c�y�T,�T:�e��9�y[s�sdw!��I�KIh�&m	���W�kZ����D0����A�+# �@�1���h�v���|R�L�������

a�~�?�d����_�-��o(Pxj���88���O�|@=�;�U�7�������~��JQ�Nm2��	4���3R�+U>�����S�{�P4�v��G�Q[���"��"�^��#��[�3Sd��|�O���!T`�,P�F ���NKC*�P_J)�� ��2�*ImQVM3$I����$��PBE�O,�;��e�<*d�EIt(�.e����0�	R�j�/���1t�X�	o1�'�>��tQ���RJ���C������I���O���C�����m<���h��$S5i���//C��/�EUM)�}L$t��r���jL�����'��z�@���S��)�g�|�G�
��� �yF��������(�R�H���[ ������g���~p���f��8��@)*�A`"�S�rV�����������,a.bjQ�J��!	H@��3*��
�B1�B���`#c�*�*f�4���{W����)�_�P����h33��NZ���D�������_n���t�M�>Z���0D���P[�	������y�*0z���v�I$�@�E�]2U� ��V&U�E#�L��]��wOO$#�l�-�ax����c�[������
/w�����������~���r���yCbm6 �A
xs�~�������������q��s�I�D��?���q�Z���u�7��q�����q���g�vOl��*���4����!� }��|	F��A	
F����<~�PtI  f[e�\[�>������9�L,�$��:J1�Rsh}���Jg��������]��P�bK�h�<�vkN���'�*'��P}W�������x �BI�^�����[p���~$�c�7���^��uu�?2��2�%�K��BH��za]��e��}Z�+�z�@a�X!��/���	�������O-k�W��r%���\�)���I�r�$���@�@5m���3�|�`%�����D!>_//�<rEH�8�G��z��$��������T�|����������*�ISa6.!�"(6���k�?b�d0��|���GWLjd�7"���?��]��*@�h)�G��}8��L�}���/��i��7?~�e��=����U�H:JBH�5��RH�'o/�D{�	����$����T�������,G�G�[lP*�>C�L
/K	
���By	A���>�����Va��)L��k3S�~� N�_x�b��6]I�x�v���~�V�H��o���GBU|84���L�<��UC����$Kc��>���w�uQvbI��A����)�GY�nJPA�D��A�X�����]��
�r��f�@��l�.�$�T���� ��	��&�����������	����_�
�r�HX��$P��{�~h�������Y���2�$� �"�
D6TC�1����O-Z�`�Q���vDL�D2�&������R;C�7v��#&���c��)���0����YH;��~�x�PUW�<�!	B������H����p��G���Ba4j;.%������#�	��O^N6G���Id��f�@�k"�1)�w���V���z��e����,��v�}{���dI)2G(O\�m�P�p�'�K��?��bs@/���9�;I)(Yj^��Q�X�M:��oX�J�@�������H����O���^:L�$��1�����<v������BB���!��<��4
����_��Dg����"�1�,fFP���9�(��1 �@��

��H(H
@}f�HUm���u���+���;�3�Ab@L������e��y*�Q����-EYW8+���[Ikf����Rb���`�<u_?�1qc��4�A�I���l ��vL����G�6�,F��%�M4������f.��s!d���$�n�0���D���9r���
rY>�i�G�
�d��)S)�Y�,Nx�4�j�l�I�w����eUc���uv�EF�k�U���h��,�M,-28�Y�Zv��n���R��"����*%"���r�8,L�0��(���)���,
��N�'D��d(d����A��������&��"�J�o� )R����p+�@�D
��q�G��i�9��F�$H���9c=^�g8R�b�I�K���PG�$�_�{	7�n27�I�0�4�?����"��(�ZU_fY�s��\m���6I�2p��n���UR�
D�YD)P"R�qD��%@�Fa����P:do��'#L$vI%�%A3#�Pi��6�f�,�6� ��l�m8!e��i��C�gv�,O=��L,�������8giE@8����3j��0p-�\����WQ`���!�J�G����
���Y��������1������:� r�eX��;������7w�$���� ,h3���
U�Z�d�[&�Ny��8N^�
���kHy��1��:R�����9�-���:J^���iZ#izs�p�%��Ba��<:�'[v��J��E&��@��Y\�����a$6R�&�"��C\�(N7[0�J�
�i
R��	8�QdFr�'9c��'5��~��1t��!+����"hj��I]�_�����f�Z�FX���{�i����~/�$�HM�:��$��\�	�P������j[m����hp�PM������B�D G��GHj��2����9{U9(�	��6���e5&K��LY��ET��SkiY"�	@ 	&(X�RFaei�R" f&�P��IT��d���	IJcfJm�E�Mbf�YH����`�MT�3B��g��=��H�Ow�d��)�
��G���?����~=^]�?�w6������) ����s$	H�����L1������k��v���U�3��OI�������Q1�)(�$���W�����k�u���~�7������'�8&P�?�	o�����yq��vr�X��t9y�B�p��^���C!�
����z�(���vm��c2r,�?���a^�+�c����'�=��eZ%�"�
�X������ �����Q%��v��Y��%N����_,sl��
��^QH^�r����E=2i!5�#}?��l&������1�<�5�Bz�\���$j��#���	{$LY> ��Y�l�������y�E@��A�5lA��s��`�fG�eUA�kQ�������1��	�X����_�0����Vo�4��?��&��������.D:9) MQ��2�X��b�c�kVks,a]��q�7-��wT���Ai6���y �H)�'E��;�F:�������KV���L$���=�z�G�<�j��"�=n�m=��K\�������dj�k��~����\!UhH�@���D���2��C
D"����]�I$b��3B ,����w��q3"��zI}�Zw�Y}$��p�$�}��%L�@f����P�� �!@�d�L���$����i'�����w�{�w�L,Rxe�0������b _"C�a,iD@F�����A�~'Tr�&�2[�\ *���Y���k���*�a��?:�{�`3F����,�����!�z&�
��Q�]�y�;o7��}������5�Q�Tw�o�YJo�h�YY�n��d�
A�$�-!>�"I��$#~
$g�k�t����Z�d���DU�1�"��MM��
������}DT�M����I�g�����D��h�I��W}��
�50����SH�+|�m���+Z�q�	-��Q�j{���&��T�Hb����2Y,������&�&�Ri6�����M%�n�K&��i6	6M��V��5t�T�K&��4�	6M�Ik�M��MBJ��A�A ��P 	R�XX�!FP��B`aP����X�!e$R`��A�bBRUm-��Kh-&�i4�1���k�s���=#jm]���I��� BG�N�hr������.=I�T�d���H]�:��A*����:������7I�[�K���JWK Q����1�F�F&�9����P�,���92z����
���8$���W}q�u�"H�Q5�:d�!�s�k*F ��Gc%�S
��.<���A��1�^eO�s8��w��|��L�����Kc�7@4m�9/�oJt��
&RL�3�(�$�2�/d"�T������M�QV�GJki�������.����X��Rk��#	�or�6[h]/A�QN�j�,m
;C�p�A��#p�K����<:�q�j, �b��B�nE����Q�G�*���w4\��Y�(;���A���81G�zIq�
q���x���;��>�������`�/Jyh�R�x��{�����?3��5N�.�UU~��u���{���'�2=��)%(�I����������I%�����<��h?�����U?VX���o��	�6;��m��:}��PEW�AUe5���/G������Ge����������QS��(�������v�e�Z�U/w]%����FR,Q�J��Xc�3v���q.�����p���$9F\kY���~�x�(��[mV����5.@D5)LbEr��[��HD�0B."����e��
��`�K3�����+��tyi�w�&��Tu���t]����r����O3�S���V���`BHR��(�TIz������;���6#��'���|���$��Dy�)0�?���=$S��ad ��Hz����?�?nAP�5E����	��aU32Bc����a�8J���V�:�KV�kZ5����(h�idk4(����s6�
����g7�����c{�a�HI`$���a����AD
t��i�6�����MpCi���5'xf�H��)�����]�b7��J�!B],O��4%a��Mld�H
;���3��VWlO8<?�I�Z�&{_W�~���B{��U�"�eK�&lI��Q8�L"rdrF$�$	IQB���!��XX�i��$A�^���*�*�r��s~#Q'_|�
��l�1��ZS���K/�T����i��S����.���qMT�������D��;=B������)W�\����=^��l��w��NKD�"��E�2 S�*��Z�9���HB>?m�Lx��8@4dM!	Dt��>�?����:EkZ�����������?��!(�>1TOG��/���_��8,Q��tCS�C���$S�����?H.�OHQ�����w����U9C����1�L�HX��=��O���G�?���s�~���r�i��4M.�#���0�7���}���?
��x��l�l5d��&a�2������LNg���^Q��;��5�6To��s���-�AR�U������2��^��*@�>1��,�03s�/vb;�M���,CR�T��)B(0�"��,H�2"������1"J���`� ?����������~�~�w��?�{�rC�F�����k���g�@�{'���c���hD�����I�����Fp[|,�����y�����I��������u�l
�	/,+:����������U��� @H���$�9�L,�I�C�$+���.��J#�1����"FQ,Y�;�'�N"x-����\5h��+��Y�g6����=����s����! xy�`���L��rP�bf6��WPnG{�����G'=�d�
����d���J�u�N,�+B'�!�R��}Z�*�
0O�I�	���/%V��A���@�H��fZ�z=zl�=���~�P�"��(�eZ��	>B�zX'��M{	%��	f
bI"9���?k��"fx���e|\��n�(
OVH���e����@�$�������e,�	(Y!p�(R���0<���H<Km���g`�����'|n��mt_Lu�.�@b�"'����%��~�k4l�I7�T��3I�b
y�)	{L�����VC(2��E��,��3��E��U��A!�Qv�Gg�9����|n�hf#��Q�@� +�ORh�@|y���R��6]l���l>����n���������!W���!2A�eZX�$'�d��I�������~�8@< ���"(��tA0D���������F�_��^��w�H1�|�C��O��_�����y���c�Y�������]���6������&��n0���mjw��";!E�H�hHi)�t�����|:��[��c�y�o��T�t��R��{O|���$��?	,���zs��-z?��%��m���J�K�����IJ��M�1UVV�6RN�in��T��V�R���2�e)-��M&�k���e2�2��l�R����PPPPPP�

��J�M����e2�jZjZ[R���SR��L�AA��ieI%���P�
�
�AL4|C1
&��@�G����_�i������	����?� �����������<�_X�}#{���~D��r[���"�Gb��!'�)�62.�7�����)JuBC��$�]
��V8?��o<RISA�a9 $4/�q�F�;��6�y����q���w�c�G����J���5���Xj��Exa���H����A�ww��u�a����W��6�,���2`�"����|�z��oi?�d$�T�>���H�>��B�?���?�:��v�
%�����H��$MA@�".��'�	�-��q����F�QG0��O��
U
B����ATR@o���d�&� ���-������9O�
���\�T��[�^\����5V�&G�x��9=~��1+�'���z}y���D��PW����h���Da�$T�������X�y"s�x���.fB�$����E�	I��a�Q	@f��@�3Y'��5��|�@L�2�N,�`t)������*��p��a��>�������?�22h�����K\��+E�
�&ZU�U�m�[���w���`��E������5Jm��j�n����R>J{a�W$hS�>|�e
���?BHV�l���4���[�Ny�GA�4���iR�o�)���V
�}[��O!9��������c:�w�����2�jT������dY(���
>�D�#�T|!������`"hM��t�����}���Y����G35
`X���4�6��������-$�Z��468&)���n��&��!�hRY���(uG��Z�&�����o��D��)��Xg�^}� ����8J��irO��1SDe�FS.��5kL�$XQ�D�r�,
2�cm%�1
�D�"��&70��(��V���@1qx�t$�^�����\�������F�)�7N�?�}*?�G�S�Y�|?t�������(���c���
��<�$~2M\�py�%�pKp��K�����EM/a����jI��k�������a��#�����I��;��d,�fi�!�����Dz/�����$\�4���;?���u6K��	$�s��d�_�@a�pp�hia#�Gv��$D�$�T����>n��B>�����}���Q��H��/��)�[8����#B����~cX�S��}��M;��n1�Gk��0�}�8�FV%�����>��u�DR��&�h�X�������	.H��S��U�������J7�����3��������-����W�������H��5d��`H0�$3��`�#���J���$P�2��J���r�Y����l�����.2��D�ht���In�)��D��*������V�L< �$QhTB�(U��
QE~�����C����~g��>@��r�'����K0L�_����FR�L%Q$���Ha�&I���3����$�K<O�����?��:?��I�Dt��W�����#j�E�|�
�d���?$�����Ez���"	Pe��!����>?LC=P�W>���N<������X���'�P��-R�@�/S�;��</Ag9�Q����'����Y������Huw!T/veBZ������=:����"��b	V��*(
�DA�$�C��~��4T�������>e�u�M&����#z@]#��D��T�^(^>�G��rK
SZ�Vj�
jF�KRC�m�R��<�C%��{��^$?�x�T�ER���t�F<C��XVX1I)%,���:4��vpnC��l��0��m]���i3%X�L�+2�Hd�%�J��:�^���&��Sf�j
��932��[sD���p�iF@B?J��z�����D��*EYB��{���<�A�&�����H���RD=}6�����d�m#��P��s ��P�U
�d@1�(�
�%��4�`"hC'A!%������s:��7�5�o�2!�9,�D�<.K����6�I�R�q�������~,��Hy�����<$d�LF8�,H��#�!�!�dd��u��)�eBr�!f��M#y��@�f���.�*���������:�`,�(hI?<��
'3����T�cE�
T���5(�O�<�vW}�5����R!��Bc���]�;E�b��?L��1$v$�\��dT�I$���S-�J�J$���J�*�m��d���+5Y6�����J�R��K2MkIm���kd�Ed��h�V��P�E(�B�R�,,%�%���H  !�B%`�a�i`!"IY���abED��%�Fe��5X�53Q�����H��ZJf@V[l�F��,������"4�0��2��2�U����3X�H�r��"YE)����E��ei�6m4�0:8B ��A�
��O��
���d�;�i(������11��2!"������*�g�k+���=2�N�������+��4��T��OV�h�H~	;������H�E��fD4����C��C��P��`�#��y��=O�$�'o%�bG��Gw����������RB(�I ���`d(����� /N����>�D4+������l��v�����4H�
�HT�l[{�g��Z,H��,�� �����c����0T0J*�;W���*u��J�/5BrJ\�{#nB2i����ii?���>dB��QaQ��bb"y����`�5�pX�����h�?hp����N���/>�MB%�dp���7���$��,}�����Xw������O��D�#�[��Fd�1B�R^����w���n��4�Qo��MSH����.;�v�.	5sY�~��|1���eI$��I���?"�*��*�P�x�p TX�Ox;���?�����I�x�����{���$'�.�#z{������#wu�WWQN�A�R^%���9:H���
2�%���<G�;i��QeT���� ����$p�A���D��3�E��/���v:G���<.�����a&�Q;z����g����
xOw,��P�qL[f$��N���V[��
�S����R����k��- ym�n�?	<��M��;;&�2b��$�.v�+��%�2K��	��hCv�Q�4&�P��n
���9L��C�CFOc3��A��!�
Y"G$d�mN��}��VM�k�Fp�-��Sm��@�vR�Cl�"&q7����0+"��<����LL�A.�H�[�1�{�����0%*�����9��������I����q�!��N���pM��w[2[au;��5^�j�j2��Pj��R�Z������W|Gk5]��tXr�v��[�'���|n���\1J���������,m��r2�X d��;���������*�:m�VE=�
�t`AL�����'������vO��Mf	�;�Q����UM����*
��#���~������$X��<�'(K��g�CqD�l_|��w��$�BXt!#g�{�h{�����z\i�OxG�,�#i��Z�j&�@�D�)V,Q��n�h�c��cW.m��`�9"������JmJ8��]9^T�V����M5M6���@��m��#k�]d����)Q)%4�����@�!�����.�.)7"�J���~��fD��o�����a�MR������JNI���z�@�Z��d3���<;�]��Y!GTW�H������N�nUn"c�������;��*�y~V�5�H��BNJ�l������k����\��O�	��%�����:F����SI�h<�������0L"B@������@4�J�HH�H)j��"��`�����{G=�����
���$��l,?��t�2�9Z� �
�3;$�"��3�#���6����Zxz�D�������O�������������������s|��u��="��i2�9;@&�a�V�X�*�����C��y�G�r��I�H�
�Tm�+k�%W�C�T(m�H��2���[����RRS7]�F�j�jX��F�1"���T� �E����������I��r��!!)�8J!Pb��d8�"���&m���%Chn��T?B��pQK@8j��"l���������T��>�e�7����-X��(r���a�,��}2���
���hz��e~'YM���S�Y�3,��m����t�$S����?�>�����(	��
�t9H��c���HD��@�.����0J3��I,A�vA�n4�
�2�&_���d�"�����B*��D�n�s���oZ�6rUNb)��<�@�.s�rT�������7B�(@#� ����*8+�~�/��<e@"�(�&�` �QUVb��/	l;Dw�H���:��R`�DV�4�Q��Wo��m~���T���Q��jO�%D�'N��OZ �hb������@�	��=���A��
����G��0�@��a���yXDD����F���W'��W�%O��C��DC�D�(��H��E��x��R��@�������
Pd�w�&L2{3{�6�e�"B� �$�P�I
��5M5}TA�?%��E�Ohb��b|$�	�;u�d�)-�}N�Kb�+6#W��Y[vj�*��(	@8�u�~�P�Y3���)�$���Q@�^{p�� {q�t���We(�zc9��ZH��I#���=�s��'b�i����������&�W|����MKq������VmQ�<�5�TTC��H~���o��s?���W�m,9�!#���m���;>�
����"kw$"��C-`�4KMc�6��L7��#���p(m-���nn�-���P��� ���F:��6Ah@�V�	�cBdI�-e!��g/��p���lj2���R����T��4<���UwmCkj��X��[cl���PB���$#<2I5��BL�D��&�~=�����i��2���V�#I��������N�DEd{�����>�f���:E�q8�:;��no ��,T�EW�N���wH"� ���������4��qZZ�*��U?|w��D�������[�}��fh��4	G{����,1EBX��-�����������*�1��yi��Iy�E��l�_�^��$�����|rD#%���^t�����f``Q��������&��������'���������c���29�%_�����k{S
�6�q���M���� �{Y&�8���w����K)!(�����au��8�3���F�CP�I�i�d�`��f����v����'`�o��%���%���!��&�����Y���F|LA��
��.c:�\0�I��o���:��d=����B����Q�N�J)�Q���YC��V3�	��4�����>����'�!B�����`N��`������IUd��	c�z�>TU���E�B�1�C}Jm3���
�lM�fB:��o����n���v����������C(*�-e�������d1���k�D �`H�Y3(M&�6�n��5�t�H�)T	(��Tj�Q�Kch���mBP��P�J`�IJT��JY��&	BP��2�eE \�������7m+n�uf����-��&`�%	�&��JlI�(J5]j�V��������@F	*)��aBYLL�$*`M�F��I�P$�M	D�BQ%i2JY�1&��[T��ujm��MfRF��m�M��R���%S:�Wj�v�*I�Sa%.��U�B�����ABgm+]�F�2�����HIK��U��h�)N����h�f���X�"1��SG8A �lT"�+4������v������&$0jK����7F����P���Y�E
���RJA�$PWd;K�|��{nw4�"���s�F?{{1���^;fYd=O�q:	�~�`(�~����m���\52�t�*�^ji
���DeD�I����)3���H�|!3�cO/����E�����s�hB�U���79��4�R��nR�4��7������kf��j%����z�A����{�OXN�*��H�Q%X�4�O���DG��)��������=�s�L����.����L����4I��b�P����bH�_mt��k&�Z�q���i!G��6p������|tIj� �R`�XF��nW1T�Em�EV�� ��)M�����&0D��p8h�{%����01S7.X��Jb�MY��dn�M����R�p����d�\��J�a�^p�Cm��-��GT��k�4�{R�dr�X�N�4��x�u#�j�2-I������$*h��2�m��k|Z`,;��L�A���c��V���&�7u��	�v��)��<���.��n�!�,)pi0s4�[USE�6e���y��I$K�il�Zm�.�(�[��4.$q��Zd����if�T�b���
(k�3qY��4��	�*��2�:����#�,~G��b�a�'�W�#�#�O�I	*�J�Hd��A�_)���!�_D���G�����%@�$���R�$���	g;���VT��5�Ye-��
4�� J��f*�jd`�&Ke�}���	���p����c���O~���/��V���sl���	'�O{k�&7	�=`�J
�'��B��c��� ���� s_r{<	O�>��8�������I�����c�m��*AIP-4�&�w������d��������$�$�H�B���hzT���G�����=9m��HPHd���.�h�z��2��*�R��K%L>��qJ}�l[��4�s�y-� {�L���Q;�nW�u������S���'�QQ��S4BR���� �4��F������6q<��������,�JiW��i3*�,UZC0`���t�8��3�t~�%�
c�`���w��������&%~H���Q�"�r�w��s���$�Qy����z�"b%C�����#"�t�2eD�M)��J�,1��	0�KA-L�$�*{N�M��G�(�DhNr���@������#����Mc��I��Y��ma���<g�vqa��_�u!8D�%,��DI=�!1#Ia�D�	��7���Q	KZs0IN�"���>��0{�<�E��P��(0 Ha���EU�n����Z�hB	g �)���|��t�l`����_��bN$��0��NI�`$�����(��R ��hX`�q��d���k����?�o���)��������S�r�V�Dq
"! �$	)$�
�{2����
���R��	b�H�N������~��6���g�56/�$��f#�H*�H	U��QQD�
1P!1idH��
��f=-��tL�Gy���C[�SF�c
Zu��;�`E(9��H�������p�H�����������k��������Z>��'?	���4#��`g��nd,�G-}�73���4Q�0{"��~��kk��Pz���S>���6CQD��_�����L��\{
[t\k����$�&��8M!���T����xm}�� ���#�1C,��U�F1��f%�	��L$T�D�BL����-a- ���$DAb@�
����t����0�VZW��&r��%bw����-�@���)��)� ���H��D�~�D�a�U_2���"G���V�H�6��O>��e�rKq���-�Z��K�����Fg����_NH ��!����!����:s�A$��4�-a�����P��|�������3{�\����<�����2U6i���}u9�(��UF�c �h�W�	����:�c����N
,<nY�����h\a$��L0�&�J)��JC��=�c.�����BX�N��
���&��6$�D�����2
��#<���	�Wb]dI����
�7��ba�����|!����h���r�m���7��R����z�
t?��&��
��g�$�i�bP(���O{y��x��(
�������"zNg����N�i�:8|�CX���j=��u���;s����qc�H�a�	������"��X�?c�e��j���i���^��v�S��$��#���bic��a
����mq��7��\0d�g�-���y/&�y��mP��4�E��f�L�;�#��o�E`����L1nrt��h]�B�i��(�dr��%��(� Q��X}�O��=I����jE�2��	)�����-���WBl��Q�b
f?�i��p��A�o�!/��	{=u���]�C�|��~�EsY�I��D�	��@�v���t�����l���?�Y$;�B���~��Q�������	H��}�'�8�	!�pP�>�����I��~��~��*�������ya�{�'�Q�UDv~�AAD	W���w��?E�����1#K����?}��C�R@����&"}mb�D�RD�I�B�AGr�]�by?&����H�NKJ0q�[W<a��I7W.X�{ea�[�����muG{����XTL;,aJB �j���[�k�������}�����~��Xam��%U.�4����}	�i2l�&�63D����tq�#��&�"�At"��������Y�D�A��
s
��x60��m
,��w��Dl�L��9Z��A��'�9���VqRHN�&��m��x-������
-�v8��F-�YQ[d	��MB�Z����,��jF�l22����Es��5�J���W�TW�P��@�8*@K{�"�h?T�D�C�Ao��I�
��0h���g��Z������jAH,A�eV���Q{9rHG����B6	�L�&�'N�.�1���	����&����`�~��d4��J�F\�S��p#"&&V6���Sc"���j4�Q`�Y��`����FuLD��]y��y�p!i�c��A�����
y;�(�I��z�#�96_�d���P:JOA��l\<~�����)�"!�C�����e�J�Q1+��<�6�\���l(b�)r���q@�y\D���U����w���&��C�wDV���K�����t(��/��Id	��O��G>��g`/��Z9�^�:~yf�;`�s%r%����ih��i�B�M;86&�������P�+���XX�#���������"0>v����k�aeXv��o[���#|*���*�|�	N"R�{�5�t��w��$BP$�&�b�d�1&���I�Y&��x�E��+���\��3S� T�QP,�]d�DM��g�`4�t���j ��Y���n[-��
D�RUC����%	&���Q�,��AH4��(����5	]	P�)]:S��):����p�l��Q\*��@���(�Y @}9�^p ��EwNHT��"#����y�	���g�DB�+H���I*U*W�[��W
,�A������\�������� �C��v����tP������*]�f� �,Y)��:�����}�dd�M��rI"RHH�1��������g��\��@����C�k�pU�@A��h�}�)N������M����!��(#-�w2�r��Y%�g]\A�s����~�}A�OOc��������#�4�,i���#�^}1p���O�Q0����)�������bP���":�����Oy���VI}(��q-R�N���0��YP����A"R��C&�
�&�%�.]���>���'�"�j=�N��.``�IB�{^�P������k��d2H�������8�.`���J�2M�RM$
 _	���'�;�'P,&�2C����Wt|R���I'a�Dr�A'�m�a;�N6�����:bc���L��B����fE�6`��fl�_o�V�����b��]���P��0+ =��H]�r�R�f�mfcKj���m��!8�B:����u�Ah��X��[,�l.ZtJRJA/��z���N�JSw5qQzz��:t����L�����v���%�z�:��\?RD����� lD����4N6�0�m����"�n���d��57u;FM:T&9�R��C�8��F�m�Gc��!�H�Umy*���];Gg���i�f��&&� �!�Z��2��jV�JSbSY[-R���M�����FE{��L�Z�kfP`�C5U����q8^��9&;I�3v��&�"m	C\~���C<�j<"t������� ;��>��{�����G��
	��D:9���Q�{B�x�$�X��J0��C�v;�C�~jVP#3a�2��E�+�������
+H%\�	

�9���vYJ�D%�m���}�O���sN0"��Sc�1h5@��@��C�w��] ��n��";��K�L�����'��0mPR�0M&�$����'���/8��0�c4��c"�<�%D�����ld��BF�6��L������4>�d�d�YL���y��s�D���=����fI�D��f!��-��GV�v�-���]_�o�[V�m��Z���'	��2���[M�]c��������*����f��-��xX�B=���A<AD�����_vU@�a��}zX���Y1��\�|1�P�R���j5mj4�.9\�m�wk�$B@�,� T���N9�'��y��kZ��.����J���$�5d����#�c�����T��W�����)S��c�xc$��u�k0	
h1@E�����!~o>��d���(
)P�j��G{�������:	;U�{�w��^����� %"�����L1���	��JU��+�RTk�L���j���%SkB���4�YM�B�}��(�X4��=�(Q���I�JP��)S'k��D
&�YFF��%{������x~u9��u9@Y�%B�V[=I�,���e+�D�!X���Pk��|�y����h�g���=�>j��U�}�)�u�;}��A���z~$$�'���}���u������Mx�O)L���BwI�U�������O��z���+�K[�f}(�N�#��(R(��.����da	�bR}`~o���xJw���M����C��K��hz�0	��J0i�B�m{'�����G	Z������i�~?a�8{��*��3?�\��]�1G���8�c��xO������G���%��q�(�L�Dw��Z��f�ZK���FM�~y������>�+���O�p�����H����e�;�X��{�O�@�%%���02]XD��A52f(:;���J�Gy���P�D1��=0�O�_h�D[���TM��,������#�����e4�(�!��;�z�U���A�e� U	"F@R�|���@�U��z�T�MS>D��I�!EMrN~�����qDH�A_��bb�oA���sE�QL�H�H�3AJ����[�kL�+U����V��.:�)�(�D�	�����@�`���HFE9���H~Q��������������:��X�Q�U�C��}��!��G����d�e��lr�&w~7�����=���O����[VYZI:)�p�KD����dRG>�MJ������������{�O�>�����4:T�LD_�;{1�G�L
2�2����q���%Y�����R���eb�J�*Q�d��"K5*���j�[a�c�*q�>r��?�r&��t�)���Dw)c�1
��1c�t�Hd���bJ�[d�R�*$�'���%� �
o�?}��/���#6��b�&�G��YaV�("� �T-*�R�J��"�(�6T�hm�[Z��)�F���)�D�IL����4��5�O@�'���5?CP�{#��L,z�����b���eo��x>A���#��S��	���-�:e�1: G�3�.E�2y��}bHQ,��H�VE��L�g���G4������<Y� I�d`(OY�8�!����I�%���]��>
�5�m���e~a��G"$�����9Ee	��
/��,��2w����vf6m��UK�\T��"L��H���������Dt�y4����j�����p/��#��NIIR�Y�Y�1�(!���rjE������Zv�`� >�����U+F9�U��
8��d�) @k�{��q�Ik�#���;�P�	��N���<�5�����ty<�0�A��}g�Y>��d�{*}�1$p���G;��89��J���v�Hp��(�6����T��w]m]�Jb��r�]M���S�EI]eV�f%f&����fy�!`����.���Z#",K~������hy�����0"�B�JY����.��pm7:6�r�P��e����	��G�
��@e�u�&�A�n�:�q�7��\�*�!���:��M�!���d�Md��4y]~����������������{�����:H�����P)@}>���=��Gu�TY��fT�P��D6L����c�W�>��/gnw m�]�=�x���Iy��X:=��*��^�y���}��l��4���q��
 ���s�8�W4Uw����n��_{��9�������Pv��uX8=J��5'AlB{P:q����XZ�C89�%������[�g�$\������z�Q@G�) U@5�	0��	@P���Qf*�D��4l���S��B�����A�(
����
�]��l�$��6�I��~������i���hG�lP%1QD��i�h�D40z�F!�A����a&RRDCSP����	=R�
jj=$��2z�M��4��P�#MyF�P�h�P�2d�=@RRB�"z���`���������4�����JB�i��Z��.�5��u�4����0�9�(>�������?A���{��zE���zE���zE���z��M�������>��
m���+���{}�^��w^�����k�$fl �Kh���K���y?i��m?q�d���P���(X� �����9
�?��}���y�yq ��ab	pL���:$@d~F�Z�Z����HaC�.,���?������B���G��y|�����n-�����^�������p�k�����[�g{nn�fc����$ $�_�
7
����+� ��`�������d
�/��$�V������8���M�+<��������}��R���1� ����m��c���z�^���{�=<������������/����XsQl�d6�e�-�ih���+L�B[��Z�'8|/S��?��������v/Qi�4�����?�-,T���,.��H�����$�,��*�H	�i��J����;)/�Oi�8.��Q-�D����;
���H���Pi�����g���
i&�b�J??��f��?s�����cQ$��g%w��Ija`��m��aM_�����u� �R�����=Uu��N���8�P����2J�k����N����p8��7�~hm�i�2D�\���-z���@Y��c[#U
����!�$��^�c�:�M^	�9A��n�Q�$b�����6�*��y���o�����j�Y�6�[{U�z�@��d�����M}��NU��C-���R��b-vW-l�=x&9p]}�QU��
��6��|��=���_�R�u��f����Y��0:�x���^-����|�'�p��������������oW�%y.�m�d��~�)�N�����Z(��U:Q�Wd��J��/.����{�:��2^z���|��d������=�����
�E�0�A(������o{��C
taN��d��0���ma!X����*�QRW�&P�M=6�c@4�VU"������e"��n����z������k�W�������s����]k���<�	�M�~{���C����x�N�"���=���!���lL007��b�*��f��T!:�
��r��!�H��[�R�Ve�Sd��"�Z���K>$�(�h�a���k��?	[��e��P��-
.��[����"PNI���!|���<mV�}�|tQ(�W��(�{�FQ��i��'���K�ba�d8xB4�C������emS-���6���M3��>U�w���|AH�(�C�I2�J��N��d4���F�/Yl�{d����<���.�U��P�0���7Ct�+��((�HT�5��i&D��c���a�<;����/������iH�B��I�CCBT�I%M��.��x>�����u�u�(H(E��bk�(�y�����,qd�KauV�g�Ff���]������n�>����w�HD��L��J���zSk�D�}j���}�f�� e"�DP�_%:�I������O��� >�!>��G
���	��_%:�����,$�m;��e%T�y��Y�I}��5�I%XafaI�U��#J�,�+~�,AK.�)������m��S�/�bIa��`S���%���D���#���sRK
	UuH,���
1S�E[�I%�0�����
\��E��sK^����,AYt�����\���S7�8�,�|J'!x~�J���C�����4h�wH�Uj.%
ebI$�k����<p+�_u�i��.,����T
T(��b���3M�
�_(����1�� ��T�L
4���]�}����j��������������-
P5)�I)EZJ��X��+�Q$�Ub������UR>{W���1IU���*��c#Sk'��nz����X�
�n�11113,cc����[���`I�M��M��l4���
1l1�4�l1���e��j�������w��%>z���M]��OI1��K�j�le3�d�'�C��������Q�L��D���!�����m�0+�d�YO���f�#�~3��?1#��<�'�����y���q���c�6�N��Bm9 ������r��V��'\a��?<e�j���{��,�9����#;�a/�J������4����^����r�"^��"'�s������{�w�1.���7����p�c���N�q���;��U��~*�E:�EG�T��_�o���ry*�G��r������<��$NC��o��EEZ����`��P[���Q���X�`^Ev��J������	^l*buIb�Uj�A�]X��aT�8y�?V9���y���Z&�.�oXn�@�4Z�#������M+������y	���:�� ��>*8���c(��F��** -	�!V%|�0F�M�*�U�b:A���h��8AeN�D<V�C��`P��Tq�J�l�**�&3UqU�z-���q��/�O;��>#�R����Q��q���VO�w�|���_o-�Db��C{}�gv��\��L������������eoN�}G/�����>���3����=��U���f��Lm��co����D�����do���^�*�������_�k�k��
CG�����o�U|������,�DY2l�$��d�b)f�d�`��fiI)%����J���ZJRK%��I,�K%����������-���d(�i���A�����o��:����h��r,�w�q����l]�\$�����+�K�5�s���i]0.5e:���bt~���v;G~��O]GV��-2-`��h\��'{��MiqpM2��8�6Ut����m�]�l��"(�0����<Qp�1��|�Y>�Y�Q����1�[m�EQE\� Ke��om��-��A��we���g7)�-Yw���Ze�:T��7".���K��Lc9��z�5����������E���%��f�6#%>�l���������R�S��,`dt�Lm�@U3[����H���8�-��J���+.����d�9\f�;�DLU�TI��YF��v&S6�wt'k|W��l[l������%�w)Q��8�-��x��=,?��Fh3B�lF�+V	��Z���l�e+2L�d�1(�*�������;5����a����*)�ZN�6�'I�����+��im���7W������q8z���tB~�����Q�����y��C��@�?r�w9k�����I&�I�2R�����4�I��I�K%2Id�T�i4�I���I))33�fe����D�������c\
8D�^�����4��m�4cDM�D�"%��.�o�[R��*�I�&e�V$�b;I��Oqy���;'k�8���2��5.%�-�r�dt1���u&�d����:aZ��jp�}��TgC���"��]]��]����pp�t�#X�
�\Nk`��Kk�J5��2��]���I�s�t�L9*Yqv����N �&�9��������;<��uI��t�7B�V�����z�;+�����Lb�,��''Y����E��Q�8:�j�9�4q���l6��t�N�#����m+:��N�)����m�u{j5��-%�(�a6D���b��TY��uN{�R� []\�s��V�Q�~k��� H��^���h� �������W���k��r�����JU�{��wd������4����m}V���V�������@�h� ��o�[6����V����y#��\G�^���J��y;�i��oa��P�zi�����s�yK1�z�~�)��pS�{���N�����[u��v
���vQ��;����#iW����Z����P����x�5���5r���*���}@�&��������6��|�M76���7E��^k��qx���^q��������p��u5nP�����������|����7@����Tj�����%-��?�F�I&����A���T���\��W�_GN��GjG(�x����_g��i������_�I<;�9�������z_�������Z���.5�F "#DDW���GM!�
>���������B������������|T�h��km��1S#d���-�$d��fd�[-d����5�I�%3*
��l����J��Z�V���]����&6��'���`�����{��l�$.���#���"I8����������Q���ZI��b���\�H;�wt������#p�9y������4�yw�;�)=$���p��IKm"���T�Mx����$7����uR������D���$J6���D���8F�N�[bIjM��-�#�v�D��H���1-������e��t�:�'����93R�.B}^��y.B}^���� -~��K�lv���I�V�I<Lr99�������=m������{���s����F�zB��!�#�m��I�{M�i��s/}]���$.���#�=���d�%]�u��IH������v��G7�#�F�$r���w���i���vw�RzI%�.�~4�T��!MI*����\n#$�]���$B���d��m3n	����Q&�bd��;IM�����d�7A�b��SM!!��:chIs�d�[��'���t�4�C�	�H|2Z��%�}�}�����������i�F�6cj�j7��m��������%�����UW���AUN���~���s�a��<y�_jL�jlc�3f^��oQ{�r�����A���E^��ES�@(��0-U�:����:fP�A\��P.:
T	%E��M�[m���=z���4�&�#��kmh�����������TE:���y���]j��=]rb����b���$Q�(��-�$f��}}||{�����Z�-����o.yqM�����.8���y���e�5�YM`�^��-GI��/Shi$�`�Z
���
��b�h�	QU�Ns���nk�^Z��?F�����6��y[����uk��/���>���IV��_�)�#��52-T�-���k)�����-JZ*�Bb�R��I%d�i4��h��41C*)��&��k6����$��i��e+R�)�K+0��-D�$�&�Q�cm[}tN���aZXZ�YDJ"Y�I����VPZ"��@��%�E����d�ww����337��d��3,�[��� ��!Um����,��^\��Y*����[M��[�HB<��e�����������I"Q�$��$�F��1��!rH�2B�F��N�rI%J�*H��F�nI$�I0�Y�^�ct�{N�F���t��A1��1���m����#��
,�
5��������P��q�TF�!H7�h�"
�����I�L���M�
�M��`sy!�u�Wz��l��q5_
��p�l�����Z�cci;W&�'amV��m6����Q9�z��W`snE�y�6{/S{r��g'Ts3��W
j����j�����N�T������)�r$[���I��F���T|�'y����y�w7g�u������`�~��Vq������3�����|X���Nu,;��5��r���� �4��
67���I��I}�$�C�A9s���������-
���e�����;��t��&Uh�Y%VX�-���w]w]w]]qF��r�u�WU�DDL�]�G:�@d�V�*(�TUEU%Q�*TjdhV]��8wwwwn(�wq�+� �!QkhQE�)�IQE=��ZG"B��u�n��r�:s�'u�t��t	'E�F"��("��*���D����'���UU�-h\���B��"Q.�`C���v����N���C������������A���TV�Q(��m�m��<�6��DFJ�2���;���7������!�_�����H^����G�{��%>	W���>We�\3����
��'Z���Np����"]��,m8��WC�%�-IEw:��!��x���Y��0[����W���;�x5'LfU�)�
+L������h�6f��7�q�6����8���Bt��P�]���6���a�C%�U�r4�Dz+���$���:���-n��Qy�D\���������������l's77���0�������L�K
{��b-DDe��Z��l�M�&��4%c�I
���E\F�Od�V�����2@�vjoS	'^��.��
�$w&LB�
�l�����NPH��~J�����S������|s�:1�?�Y4�)��S�c�~>��<� �u_�m���r�SG��~��+����� ���[c}�LX#�E������v���o���u:���.K��/�>�-��������9�t|���rc1��,��e�O�/���t^�M��^������iVv��.�jLG���y/��m�� ���>��p�C���������
`5�Z)�L���zeQ)������|���Tl�i,��Y�1��j��26�d)3S#VJiS,[1�2���fK13%�e"��Y2�)E�d�,������k-3"��4,�-�6��0�T�&2�f��N.���
f��d�$�n1����8�fk�cU�#Q��$Rl�i$�lUQ��UEmI���4�I��*J��MF��&MBRjm�i6�,���b��d��-jII��f�	���A�LT�RZH��QLY5v��}]��J�keK%��$���W������C.��=?.��Z�YV�[M�M5i�FZ-��4�3I��KMd�S�c'���z��
��Y�0���I�M�L���5���Z�cL�����������}w]u�����%�rqF�����g�9��������;���������n1�:����;���w�6���s�w�}��^��g����b���H��,������E�s������{������m�F�qf�7�=�r.s��.E*!#.���j���nf<jrA!�J	�"G7���������$�%��cgxw���!
���)�[���B+������c�D��oP��s�w�����{������m����;��$���m����\HT��D�N��%�w�������#������wq\�u$��b���q'�rI�%�I	=�\�p��z�j]��wi$7%����x�gD��{��tK1�Iiv%���R�]������j�����*
HB}�s�������\.r�s�P\�Fr#�W\�n��.�s\ �0Pb-�D������!�H��_���7���m���61���n������6JR�V��Q\�$�������s��Z���HY�:��t�r�J�������h��G��}~�����)��_��v����_�����t�N����Xm�u�����������|�[����'8��q��5�����'�^�8q��l������V���v�8n��v����,%l���q)��7z��z������'9�t����b�N������D_k���������l��<��u����\<l:Z|q�ZQ���K{��w}<�t����/��L=s�~���
4�j�h����4�->n�:t��O>�:����n���u��t}�F�V~.�����wk�c���:��>�<a��6���;���a�������,��u�;x�����m��y�L��g�y���M����l��M4�M4��8�c��f�v��Kk��^�zm�q�m�n�������>|��1����kZ�,��,���m��y�=��r���X�q��9�mk?*B'�3#��?:V4c�n�>��r�j�\�~�o5����]���"����F�����\Z�����u�[�{��+�������^K���e���q��K�.�C���sW*p����~�|����)�]]�������l���b�����u���]����q'�u:X��pf��6l]�quZ���x�G]�"�U�|V�����f�T"#6��w��r����d0�K�����r1�`�AE�{�1� n���sW<)�����!�x�84k*��oU�y��6kuB"0��w��t4:��9FZ�q2y�q1�5\�Ar�����V�����/AP��(U�C}���'��[*(�x�]�8k.~t�IQ��r(uAPT
������Z���l��<��q��(�\������t)��P��(T���<��Z����i�mm��=::X�(�\�t�IQ�|9:���*
�6��1�4c���u���ev��m15y�Q�.~t�%E����*
bB�h)��chcA�8:����0r6DF"
o{v���|���e��xN�V���\����<��gm��Ys���J��������C!�(<��f��<v,�\#�u:��0�f��'g�N��q�F��~q	�t&�;]J��2� ��aQvpx	5s��=u�/-.����xN������[�DU��>y�j��;��Q�CIG#W=2R
EB������+6l��;<�gm��$�g��Bo3��@�Nj�E:bO�/EEEEEA�2��n�|�XDF
_
�k|_>|�.W�������P�1����m��7��]�DE��k���Z.���?��/e�p�t�����J��f�&d�U�Mdk[��j�bc[Ca3�Z�5��L���eZ�S��rdk%�h5��#l��MjKI�Q���j��9�r�5���XY�3����U�/�r����g��K~}6(��b1�����$�cb�&"�L,�M��RF�D���3&��h�&���R��&�d��Zi�eSLF�M����f��LD�f�Mh�1�Dd�I�1F�$����$h�MYM&,m���i����$���jLQI��DE&Mi1DQI�%�I��iL�DE3L��,bM���f��&$�l�jSY������)-��L�(�L���I�h��I�bMi"�E&�b�%&�QcC3?z�����xw=eT����"^���:��T��f��f
n��|��66�s>v���3BBo�|2l���z��[�x���T����������e(9q�������TN��5T,t1�9@�s��a���3xn����mDo���W�S���t��WGN�����d�!�����&M�Rbf�|����W_��_?i�z�MI��X�I�i�e&&��6Li�
L��m�e�2e3%�4�ldXA4�)MIf�6���I�&Qfd�#�4�I�S)4i�L���&Mn>��~��fW�!)�T�&���A���^��:Rt���`������1���}����2��p�9��"������o�)�\����<�x���+��%�
����"�����Ml���%U���0��%QmN`�a��L�l����46��sg&��>2���y[/;�u�����gi��������b��Q�^Z�
��b��Er��������/5�la�9� ���a�/���/��a��8$�����@.�E��PK����X�@1�}����^�m��+�+�[�f\�q��s\�v��H�Q���a�����.����khc"#��b��cW��qs��/��ok����|T���o��b���L���id��j4dvH��� �v�5+��5���1����1c$�(@:B�M�eCV����M����3�[I���Um5�WT�����DvB5e��rKMr��\�V\�����kH�t���4eq���iHrV5����&q�)�����������RO�G�o����|���_X�U��qV`��m���l�U�U���|�����~��q�4k�D��'�9��8�$�;����D�u�Pd��]
����$�k�A��
�W���}-*���d��/�T�#���I���=��?�������w��|���y��#�>G�|�����$zxSZ����~
������_����x�+�������/������3����i&J�w�_#���{���=�d������v~{=���}�W�V��M�fd��v���Hu��ZW[��sM���������;�G�8rW,�j��c����;y������Q~���%`�	����I���#��;�����/���mM���6cM�����O�u�W�5�����������>��}]������``-���	�Cm�K����DYyo���;~k�w���.S��2��;����8��Vk0���.6��������=����������E���������G=�	O#�G���?e>��~G���\_����d{i�C
LX������^/��y��A\�j��Pf�Y�)�Z*�jP�#2D�$�qN4m-�����j�R�y{�^�~t���U��Q��I}���F���i��_�i�}~{[��������{�u����5��3le�aJ:���~�{+�~����Y���_R>������W�^5�{�f��7��U�G�G�uS���.�a�r��j�d��j��j����mC������#���� n:\8NC(�b"0(��������.���WJ���;���v*����/�%�B����Z��+E�W�{�37]Mf���L����]���'VZ��A�
�����X�� �%�*r��0	k�8�k8�c��l�bQ#&�Q������4S����9;����p���%"Tl�d������LD�k^Umw�k-�9WVK�L+&�"��4�JE�Q�]^ik�U��rO+����z�w�������5���������KwbQ�)���\���$Qpwq��{1
iEd�F#G����E(�C��:fd����jW3eU�V�(�~��J,�=\�W#�DA<&�K���n��!��M����w�������P2�����m���{�V��piQ�j0(�C���M��+0����Tj\�wIt���������LFHM��I,�F��H�	*i*&EJJ%"d%e$��b2�*JKM,�R�SI#d��-I2H���5%%�Y)�l�H�)RZ�jB�>�����o��:�TJ���M9L�t5:���4��pFE1�7glr`��thI�pN���cmk�4C�� ��,�#~�8}�G�T���/�;o!�����'s�r ��G��U��z�2Q���r�F���w#�Oz����OwZ�������Y�F)���X�G_��Z��_��q��r�!F����-�!�cs�C�!����*�(�~���
��p(�T�"�,������������H��$�$�e�J��PA2���V�����&��`���6�Pb�h���m�X�d�`6��T`�F��Q��Z�lTkUYU����z�?�~�W�t�������2��d�Re�$�����Z�-�x��!���6��JI$���A�Y�a��[ZM�������r�x���v�����]����Z[,�,�2���I5_�U�u�����Y5
<quQ�8�+�3F����v�X�4��$D�m��������I&�j�RA�I�a�P�����r6��j�&�%�[�V���I$�-2dm(�4S%ffl$�iF���u������Flz�WT��I��I)3$�6�PY�L��L�,�d[kr����X�j�1��m�UE������[6�)		--3$&�4�hP�f��}��.�U�|�Vk�����u�{����W3.f'�:x^
�F�AQe�[���m�z�KI)%����4�RL��I^�RN���z���w������|��gI$���)n���������7���sQ��4�e3-�I@�IU����3��=�����y����.���	����`iWA����J�T���VR��J��@�}���	i\@��ZT�]�%U�uq+���a.�J�
��d@K�N�]�+��(���)�@����8�2dLd���#���"��?��E�d�.k������-��Y�\������#�������0c���!�$_]x�<WxE����eEP��u������	��wKTU
�EJ?[��� H|1���^
���yP!e	3K �1����Z�
�Y�E(H��H�*T�HC_��*�i��pV����1&l)QSY�|�8�:���kk=N[55F�f&3�R��_���F�fj�1����]���I1���"��MJM3(�I����W
�RM�m��P$I%l�-Ja�JH�@)R���������L��fRl�5Y6��jm�h-!6���Jf&1m���u�^mj=�8�sl�����`�U����mT�����)-�1�iU6�cf���#�a�[R3e���0�m)*5F,�Q[&�Q��������o������� �b"<D��)hjA
`��Kp��s����c� �D�$H�0@H�0BI-|o��K][��l��y��6� ����a�X��N��D����x�$� �@�W����T��/�d��4�L��.���<�?W���|HI'��&�����:���m��}xP{���~�n�]�eCc2�0�FUKK)�D�@�Q&f34�4����4��)1&�3P���32�����
�h���Tm���d��smf����)+�@=�&y��v28���;��c��2I"I�I$�I$
%
*�����v�k��I		2$W~�������#���5 ��fL�4N�H5 ��S���������"�P��"��z������UG����w�����Y��k����f������g����nW��t��f���8��pT�e*}L�������q�;�&xesw��hx��)�H��lm�~Z`^QQ9�=�&����9�������'��
o	97	��P��b�������:3���\�@��g�{��
��1UJ�������8�|AM�pGm�vD�[n�9�L���jq.�e���e���DQ��h�"�m���������nDuK����)H������I$�II$��g������w�'R�+��q��.��n[p��+�5S��	�Q�x/
��c����@��ZQ=�	�/%��P������l��+b��u�k]����d��&eMZ�
���Q��(���{�s]���  ��������32M4��U�����gn�G��BQU0������V��28�nE��w�3���q������u��Bp�9Gw$e��;����������%�hM���
�T�D��Q�F
�F6
���uM�������1��"9UUU��L�\9!&(�E�������`����D��;�������wT���2�T����E�K��yJ[Ky���R�Qb�Hj{����\,����g�z����-Kct�z��]�1����F���:��`�p/�o�6�j#a�����8������IJ���L8�8G#���}�����d.�,���O�����%W��S���<��88���88�vs�������~���J���s������k���t��p��Zq�.5��O��ez+��K&�����"["V��ZMF��V1j�fKB��j��kE
�+Iy5��*X�%�����GU�#dq��MemM�&�����N�~���>u#�����Wcd�nV]�S,�nN���N2`��r���9p���U@��r�����A�J��J:���F��-����T�Uv�^U����7:����s/=q�e�*����r���q�Ll.��]W%�������^��{�{�t�����|��T�^*3�����������=�����E�v�o><�(�Eh��(�~������AU���fd��33w^�U��|��`A�������t�K�HB��T�h��6���
I!r������j�u������T����:,�gQ-u�S$p�$�K2:���kA�s�-��,.N`'��'�C�$"!��aCDkn]�Rz_�����mk�����O�/��[_>�#��w���h���������"����H�o!I��"�'(wUn���)*��b*�l��ye��r�
`� F������0�U�IRE������Z'ND;W
E��^oSz�2K���Lk5^�ku��U�tmj�j�I$�6�$��d�J���)��I-y��PD&���)��aAAHtCGK�t����<t�M�mp6�m��M4��YW����?i��RV��mF�iJ�m)Q���6��*H����-1�Qi��lPm���l6�<�K���m����x�
�L�)-�QGc9���V8�D�n�!��������5�[��i��M�1q��3Q�9g2����-4�C2M�l�)@�n�e�K���pq�xyy�&Z^�������W]�b��VJ �^.�������!y��[qq�*�`z1���RQ���S�rI$��I$�J@-���L���n��&L�6]n��2fH�n9�I(��-E-�����z������|d�>UU�H����+y4����|��R�7���������[��[��~�ff��u��|C�#�?������R7j/�B����)vB����	X@4����Wwlcv]���@���?��pT��!*��q?������8�L0�e�2a�Z�d���V,Z�2d��&V-Y2�ic��ZY2d�����_�~��]����	w����n��(�W�
�"����1�wq_�~�^�}n���\r������F�{<	��(�o<Q�P�2V�9������H_�*h X]���
2�c����.��#Nf`�����u���#���������1�L�2��hlf�%o{�yB+�p���D.�,�h� ��������������q���[	��k&rg !�������9������������
�����U�$�D�������S0af��o(�$��Bv��J�J�H��M����wp&v��m���
a���y�v�e��D�U�Q�K:i��@�0T���`ffB�P�Vw�����JT�8>�Q�w�[�t}}q7�����B�A��J��M�;YhT�I�FK�J���JR/n���y��`�0�::����	�H��C�BDB$	����h$(���Abc "		�q	�<�� xC)���M;N&�i1I.�J�-�]�f�M���E
x@�����HI�m�YK������'��(H8�!��#��D�$BA�7x}�W���=������[P**�"��P���%�����m���j��U���.�����^#�����P�;C(�wn�e���S'N�h��Cl�b��	D��wW1���d$/#L�X� ��k�a��cp��c�P�c*�"\$.�avCL%L����Q@W����F������5�|��������W-�wk��s�rZ��NKi����x����������f���9��{�g;o��'5��N.ne�Y��sl�l{�f,��ib��}y[���{��{���t���{}�gWE��Z��v����o��o{����=�������:���.l�{���s����{�s���w:�N����Q������^��v��������5��Y����9�{����76Z��������|�e������k/uw]�&����9y����w6���wp������2fa���s���E~�^�<���\���S0]�!B�is;�J���4���z�sZU#������|B�>���7��}x.���hL�%8Y�������s����Kv�������jZ���-�I���q��M5����D�����jIvI�����&M��G���V{�g���qO�`��e��K�����ds0�v�����C��HDuO�����V������7��������~�^<����V]������\V��.-��Lzvu:u:���o��9f�]4�Wd�j���v[��jE,l����f;NJ^�/i|;7w4��jf��d!-�Z�o|�p�)�k�K�6�c�6�(RX��\q�t�[���sY�3�������_h��A*'��J�yx������p{�2�6���2NI$��������K�&���<KI�mVU`V.���������}�ag�#�cc��v]J��B�H�Z�v+I��.�wVF�+wrK�\V\V&� a������f��7W�.�e�����-�;���k�{�
��e�YLVF0��,���Hh��S7L�����'���/s����������ud�.��B7L$�|F-&�B�K&MZz�n8�g=����q�:{c�d��`�����fffI��Y��%��x��*���_
���z���\�w����-Gn���������m[��<�����,q����n��7����rKk��6�W%���uTDT6�GUj�=�j*!]��Q�:�V�b���9y��P���9��T�U��E�\�A�����1���Uj��f[�P�����G�\����h��Y;u���>�P]^�W��*�r��KU�G��[�����S>s"���������8��s�;��{���l]��]:��a�u�r���C�V�Uu]�H
������^N�v�}B����3�SW��-_h�}T����������e{+�S���C�BS����~X_��t��VE	)����7	h��C���j�$+��y���U��Z}�e��~�a���(HtbP;h�]��e�����Ut+�{��*<z��������<��u�at�*������A��6*\A+�el�+����w�4�7���H�{9[�
����=N�����ib�
����$���n��� ��tw���>���a�m=�
�{���7889e]�wr�[���`W�V/�o����'���\�����������3�j���w?��k��}5��r�%Ry*�5����������q�=!�d�G�[�8������H�J���tv�j/�r|g����o6��@���g"T��{Ey_����"�v��b�[(��uW��=*?�>�H�
$��(��Z����}��"��K��S�����v���""����Oz ������RN�|����>���k�/����>5~���� �K�RA��y�W����z�;��}^G�����=����c����Y���)	M������V�<�;��<��>8��)	Nw�*=���t+�"T��
�E}����L	���������J�1��*�T��#��2�a�+Ui�F+2�cS&5a4��$��,��L�6��hi�Z-4��iIi��&�5Yff)��5�[
dh�f4c�,���0���rUW���#���U�>A!iqN�(��dJ�E�Q����������cV����j�alfL�M,#5b�h�������,��V�mZ���������
*Z�-�KlX�M�KA��%���,ZXS5Mf�Y$1)����,L��Y�&l��5��Z�cX������h���,���cc4��������4�X�����9L2�54X�����"�L��N4iq�����������KKIXib�cijh����0����G��d��Yc���^�+��������U��b�^]^�|�'%���Q^�����)	O����|>a�"[R��EF�������*5%��5���*�E%cS(�(���E�n��-!������z>>�z����p�R2'�w�|��|�K�t���<OzX+���^�K�w-0d���Z*{�K�	����J���?%���;|����=��5%^�W��P����>��(��!��{�G�g����b��mb��k%�D�c-@����-��jM5F,#2��Z-bkUm������a�F�L��U����,��,���$I��r00�5�G!.+�����<�2b��y�%� ��E8)r�8G�K=��P������������I�^��W���A�r��1�l~L��E.��	p�O�uQ�&>��r]|�{��?o��C�X���)Jy�~z�?l��=�p���G����s���:�S���z�@�?o������(�	N���t���GgQE'wN�U���4^��U�OT�aW�0�5�������j#�K��_�z���Z�
A�x�{���J>)v!�V�d�2��A�eC4E�-I�Hq����]_J�����85Y��.��(\����:��U�w����s��D������(uJn�����D�mVj�2��a2f�V�Sjf�������*���i��5MZ���F�icI�kBZ��K1`b�-+�R�����X���j4TfS���
+
�60�l[��Y5��5������43F�&6�Q��3Q����	�k&����Y5�mF-���m14��K&c�y/I=a~>]�DO�o��J�P��f�dl���������+���yJ��ObK�|��v���rq�J��v^��t��?����}t���<�o�l�Zb���N!���
�Xl��f�$�,��lmQ�-�mII%bT"�25
ye�������KdX���k;R��L��04�����MR�F�LU'K�M�m6�m�-%4�FZKiJ���*rJ�ll��[�CLR�F���uUq����H��������d�V<7�<Rx=_����W��[x^w�j=Z� 0TB^o���[�W�J����ll�Z
F�P���E*�����KeZ�����e0[6dj�2���)��Y,�k&K&���2��c5�%�P��1�hb��,ll���f�c�1+e6R��*Z��(�,�Y��V�,V5c+f��KVV#�C��'$qy#��Gg��M��"����!��4���I1�%����$������&M�b�&&4�G�Z���8��g:\�������/�:U����q����{T;����Ji3�[��F�2/w������E?�W ���F�����������F��;�����o~�c>y��E�������"h��s��>=�bU��]x�T��R�c�c�/o����(����0�h�
�e�iL�Z���#,MZMd�!�CFJZ�X����Ei��V�����J��ac�������P��_}y��������.���9>���������)��{�K�} �p��/�X��WAv��$.�Q��y����W�l �� ���a�~U�������D����F���q�I!�>�]���{���1��pr���������@�S�!�����\�}���c&��L��1�0j����V50���C
Xej��m���T��l��%��ZPj��5+,��)T�)��K4JR�e����K4�C6�Y��F�9U��2�~�T���*t��U{�����]l�.�nN�Rt�e:	f��
����I�jZKU2������ �Y��i��������d>��\W�L�����V��b8��A���{�wB��e�$c��N
���%�C�}���T_�������5��C�$kUU�X;��9�w��i��������=-�'������JU%%�-%&�+I��
i�
j������?�!��+�~p���|�b�����k����<@~6���jy=�j%�)�����`;��}���1#��!-�&����L��r$�	��������Fd������G��iz	�����������]���$�U��P��y��>�E�N��$����DE{{�+�����ZVi�Ur\�N�K�u]Q�+���!e^��('y<H���:��i��8�:����*w�:`����~���K6b����T���f&k����@Z�U[��-m��������Y�
�f)V1EcR��Da�SjK(�&���V�1����UU��#��9)V|��X��|��<R>��[�.�����������z���I}��y��_U/YI����9(%�a���~�[3M�f�7777*����6u9N97�E�3���
������}G�]��0��^Z'Z{����z�u�����9U$\����D�JN�U�W�A�yWgbG<�GU�88�>�@f���;���]�O�B��W�k�K���e�4J��g�%��Iz*=9���p}F���h+��6L/3�+Y%���CU8*vQt1�R�-����1���S�82Ft9q}R��v!o�
�E��X�"�<U��R���#���'\�=�1�����jI�UeQ)�Q���������*vQS�.��^&��c��b�+�������lLC�C�����{�r����F)B���qC��;�������_�*=�����{����+��xO�T|������'�nW���{Q/����|�Q���>j�Pe4,��jF
K+H�e�*4�I�VUe4M%0���#�`���I�1Vh��Je
#J�jL���5��/�mlle�K&h�@L���M�r�f$�&q�[A%fY�H����R]��'���$����l��N�ph�5S���6�h�1p��
�$�Y-
���WZS�������M�\�Qq29���*2NkgC22\6�c"EKK���n�2�����f����L��hV�M��%���kTZ���\	h�$���&�����5��hR$%#��Um�X�k�����Y#h�%�i,�Z�����4�Y-6�kD���\�����������ICR�$.(�~�c>�����D��<�Q��z��T�����IU9<y��7U��QX����S���]����I��:��p����\�	���w��]��zNN�������*��G�vIjT���Bj;R�x�@���\�U��>������>h+���d����C
��,4�����&����e��b`����y)P�<�8"��"����*|h��]t�#��_RJm=�Q�|U����?#��G���G��5)��{��qs$r���vB���U|$q��F
~~S�=�c��S���*��V���Y`�F���&-JX�X�hC����]u��%OQj�	��<EYA��+b�����
��Kd�j�����m)n��+����S�����W�I7~��y������������{�FG�e}��ekUL}v����~?�{]�M�g��^�P������w<"�w����J��xj�C�W���{���Q"�	4���h�W���8�(.�=u��*�/�/�R�����c5�5)�l����4��M�L�2Efi�R���d4���L�Y�L�1j�����e���_��){������,���|8.��
|��}�:U�w�b�.a����W�ERx(�%����;
-J���;�Z�� ��;dv�NH�6����c��v}=���]�E����]���r����\���xt�?ogw�w<���I�~���l(������������1�2c,e�2�M�<0����a�X�0��X|�}�_����*����.��Z�i��������Y�2�FZ4�fZe���ej�F��f��Kaec%�4����Y�Z�b�FZ��c������Z����-i�(g��{�$<����P��B��"���y
�aL�5!)����p�p�b���<�&���}���s����m�WM��tx��(���~�m�pu����C�T�
T+��\�U<^n�JZi��UI��J�[��������|XZ�O��Q�����������W���:�;�~I~AO�������7�4��=Wr��>RzG�����B?eP|�I����&R���^��Z�6��5�[T[M���6� �fI��d��a4�MJJ���[lckd��A�I���5�5Ij��hX������"����
��1��E�j��fF`�������4�R��\P�J�E�y:��8�^�'`;W �/WB!�TQ�0j�45R�aX�*����cmi6�����U�d�M�e�6f���#���&~f�
(�VO����.'��))��<���DayR::��v�/'h)���O8^Qw|j������������d�Mg"5UG~�����������������y�q�w���{{;��5���Q�}Y�M�gz���O�[�N�dq�������cZ�Y^����fg���|��{�y�������}��X�4���������v������p�^��lW����p��-L�G�p������|v�M8�{�&w�;z�#�_�Q�k����}W>wu�[4o|���}��y�������
:�zu���*<��J��D;������.�wz��:�_op7��=��nm{KA@!6u;iJ�����@��
�pi*PEm�>�/�iZ�����DA4��M
4�T�j�6���F��2h?T�(	OS�6S����OHP
$�R�P�4�=G��@4I���H�j4d4�44hRRD2����&����6��zB~�M&��4���@���	�4D��4�OT��j�(�OP4�hy���()�2>���0���a�Y��q+>�u~N
�#��w`���51�j��d�������1nouU9���0���+�a����X�l�%�h&�.��`x�}q���5F��P��+�S�kY5WK�S��;T�I�P>���������7��E�|���a+w�x�4e
�3�q��$"�h�%�\����Q9�2������{=�����Bo����9v��PD�/�>{����BI��� �1(�>���W����=������L{2��ft���:��������a�� �Qh?�DR)V�J5d�n)��) ���
E����F�qt8(�$��:U��w��H#�����4��CT���am������.����^8c\"�u��L���D����D|��6�l.�I����Y��'a�K��X8�4
�{�$��u���/��it��4.��;v����;��D��*i<�n�,m�#H�\�+R��5�����<��mymB@h���_F��-$�H����U���iUEQH�	��IIUIe�IK$��A�L�>�������h��?���*�_��'��=����`w�!#x�'�H�=0�z����aj�2��D�@P7�r��$w5�36-mq �t�C��L�%*-g�F�tv�h��������
�5b�6���&�
N��
W��]��$�]%�`�H�N�x�P,n�}���n���d`x�0�6.��r*N���e%6:�b�15mWo_b4��o
��u�������77��v<>_�UUUUV������x�=<���^y�-��HR���@��F��<�xt�;z<^O�6
���=����
����5k������1������_�9Q>��N;������I�����%�L�����E/�����O��I��<���`����
E�mfyw��v�<�X$c�c�6o�@ �1+D$�i-N���\~�q���D����d���6�d�i�uyb+�gf�s]y"��\�5J���M�,n[&�h�;�����F�����<��U��#h�AFg�,�Z�)G'	��n�=(D�K}a(��N��C�ov�P�Nf���iLLLV��Dj4�!������U�P�xg�W@�+Z�32�X'2�&fa���A�ffUU@���Dj"�M�U�t$U� �t*)��+��A����D�����a��UUP{L�<�E���m�n%	N�{�je��i?� �_$02g� ��bsh�Jr6O
F�ch����H�����!����������(nT���r��:�������]v(��v��l$�FD� J�K��X�a���H\�!!N��*T�$��D�%ICS���\�N�;������|<<8�,���+J�N�����L������<9�}��W**���8p�����SF	d�RSJ����
u�9f�V�m�0c��e\�	�RQ����33T�R����6YiZV��l�@�U�3��q������.f(P���BK�R����*m�����T�-�6�"��cu�-j�:Su2�l���/m������8��3�������T��@��D�M�]��0p�d�P��3=Y�$6����� ��B:L"�!�������i)
b�3���e��e���3mZ�z|�_����q��`�vjI�G�}��U����Z��-l����&�,&a�L&����s9)������v�������t{=����i���K����R��V}��^`Q�|f]�L5�g=���kV�/��`�T�_wTt�v������I?��~�$���s��������VJA��JB3Ed�_�~$��k�V�DBh�IL���6m����W���kD&�LId��V��� �1I�0V>�]�Q���%J�
4$4����?�M=����Rx����UR�����4�[{���S���fx��B���T�Ss5�"!���\��|���t����s����_I�����UUkY�tq6]]bL�[��Qm���I���J_������6�]����X���l15Y��I(@�(I��<!Bo�,�M�s��)Z�����7�<RIg5t��s�f���[M'��{�<���%�c���{UUU�c�����[-�H���:h�_�Y;aO�|������9li�3-dR�31���?�����D/��(jaAJ��ks�64�����<B�zk�EXC�)yx�b�p���	Ci��M���
�
�7����F���=�s^=\�^���(���Dz��oW7��I�1��1���#a��&I����f�����I?�R�H����
����R(I!I�
w
��26r�		j�F�.5��_���o�����O����!k���o�9�4|K�E ����H�����Yb����J���U�����9��&���:�9~z��nV��B>n������-wj�S]�&�7�9��[��<<`�k1��_}"��p$@�����pT���%V�Rc��.��
V4�����xH�9���������������������(�+5��x�!����T�������:����~����]����=Ok���K�	-�m��HH���k��w�UU�VJR��=�I�d6���V�m���6�~;�	�h��r�����Ccc	���������'h�����F�8�����UU���h���ml��I���7J7��V���!�a$LBV�m��L��3�>��4�`� 1�����"i5�Y,�d�QM�-��j�m&���8qX����@U���\Z4}_��?���"R�P�)F�MS�+Q�VVJ�p�$y%���U�Q4�mjZj�5��Tj*����Gi����{�V��T)
G����ZWj����)��bl���/i7��:�^�V+��M�	�k>59��f�B�ay�M�������;wx��sc*�����=w��T�"���54�Y��K�9Qz��NC����uW�36l���cn������M!o	.MW`�U�u#�����rA�
��	����
������-��������������[�yi������oa�!p�5�f�!��-"��������_m�uv��6������_�~�N�+�����*�8v����p�z=>sEyaw�p��{���;�{�S���|�F����S�
���!���j�TE�2���yuK��������s���
�	����yX��)������<�q����d������NV��<#�$����;X�U[n��V
?S���>�O��-������^�;wb\�2���U\�5z�7���+��T���C������r��qWa���;��>�YR���3#��|�;M)��zx�C�������r�V�4'X���I9=�a�:���O`�$��r}����������� 1��w�j!/�!u0�h���p+(������!8%��4�����2�k�������1$�sF��L~����8���y���*e�����-�J������������*4%��xW�<�����?�O���O�.����n^Od�i�)_��I1�JZ������1��J�Q��p�K9!1�e��m�&`���P�����l��nQ���]�b�F��*��R?���W���Y������Y����
�|�D�G���y�}��m�)�#��a��~��O��5�YH�QB����l�	����w����!�-��-������jHIu��� S�i�&1����pB[��*u5���������	��a�c��������
7�����z����^B��x�� ��=�uK���#j���;������T��M��e!�����G���n�o�[���QE*T��]�js|�u��d(����Q��:����~����M��1S�+��$��"�~;���$g���x��@��xN_q�K�F7������ �
���I6����s�����Z��U{����Z�%K�><�2��w9r�]�de�!&��^�UU^�2��*����A����%�c��8������h��**��GZ�DI@�HDDdP/{*���0�����>���?|��3��������������p�~
����|��z���_7��lSm�KhG���jd[���rd��6��%lm�b�kb�^���k�O~���YiV^k�MX���Go)����ot�������K�)����A0���c���T$t��j�_��=�Z�J-Ckf��-j������2����O���>��\�W��w�U���^����(�	46l��`AL%����e���L��R,�'��f����S�`����i����=����U�#<�7�sI6���=<������J�Y��b�7~|v����������R�6%3�BH@���l���g��O!������JOD�SY%��a��Y��g[g`>�V�R�%�()JI-O����B�xAE�
*�����GH�G'sY�myl���tD�Wk�"����wp�n��7Wd���K��e�����)��Y?���"%�n)I�������7�C@t<���o�0��
�f()��Z����*�|�)b�������5��4�a�f}	CU���P8-yG
$�	�R�����)�|�s��w����blR��|��F2���0�fwi
����e�>���M�~��.C�=b��=��{�'����DW�����r�6�
k��z����6=���%��b�a�T���UkZH�>�w%
��n����Wm�[xi>�&�,yra��eTj�9g-e�H.�P����q��Z@�!$!��]�;�����e4����&��=�����������������5k\��V���g
>C�SG���S�/���e4�����=��K�����ZE���|���ubC�i�]�?��L��(]>)i(HP!by��_y1 ������������*�e����)���O������*��,��?��o���Q���b�����`��������|D��_���s�n;MF�U���I�o�"=�4.�#`UX����������.�G�4��t��5`��#��'��;������u/[�=,x4}:v�W����5I�������wW^zBOF�mJ�~��j>2I�Z�U���iTfZH�����2�-cV�-��6�>r0U�5�1����B�52�H��S+E�l��,���k5�39.������x�1r�Z��G��L�UXUU���L���Cs�?N���K:��>L}��_�_>�^e�e2I�4}�$N��'����M}��4�Z�3?EQE1�N���6��73�X�UT�8B ���*��2DQ�!%��(���������6������UU!��bB��feUUTU6�Ne�&f�&�9r��|HHHK����0.r��#����$�,,~���������![*��	9z�a���\w�($oH�UUr*��lj�K�nX����4k�85y�O���@��!C���.�������+[��:���U���gxn��������r����IC�I�k[�����V��Z:���$!�M���WwI6M��[m�#"�h�G)AaP,��Z����>�����1��q8{c�<t��"!BRI�of��.be%"b�
e�BN��u""b��v�xb=V��t���|�\�;� ld��L���T�`�P��$���{����Zs���C���|n$�rwwT�hDK����F����z�Uck	��O=jk�[�[u�m�v�)T��DDZ��1=��<r�rA�.{�<��y[�{�nE���QL1���e�G2Yj�j�Nm�.�Wb[z��m���HL��N��1.������k��B�l��6ccc*��c#Ibm�N8c�kbN4�m��4�������k��M\��Qr����2��@�lC��q'�,��,z�c�UX�����{T������""��tY#R�f��l����\q�"#�r8S���E+Nn�.y��w��B�X ;�]H����p��b�C�N}>:)����P��9��\��t(U�=�<�L�wVS�=\������Z�����3���Y���O��P8$x$��e_<mW2�6)���������]���56��f�5	��cRk(����F��L]K�b�)���^��>SRI��4����i���������&jm�V)4�J	S3*�%f�ji�ii�������|�!�z��s�'�m�S�&��b���GrBu)��B��`������-���NnS�x��+y��`���5�\E" �DL��A%EJRfg�QQ�*�V�S`c���z�$p2�i,:��,�5�����;%E�Lp��]��A�{�L����ZD��=�h��G�t�����3a_�XH��L9�N�U1�5��kL�[2��&�>���t7z	!�	{:@�IR?
�����}����z���I(&a�s1P��=|=7$o	Q)�k0]�m�o�V*��� � &U�3-�H�!��9�t=�����=^����R�g��Nl{	�<������7<NGy��9=C�?c���n���S��/�I�&�g--������,t[���Bm&��A���J%#�D�x�ps��������l���hy�k��y_]L� 6P�Ms�c����cg��z�!��{������~Rf��d�]���9�3�m
 ��_(����'��;��4~����������F��z�l��6����F�h��R�G��>����
�����B@�'�i���4�,�D3W��b����� ���#p3a*��M12�B5�9[�ri��5FVVV�������\�s+��,������Gob^�����/�t~)�I4�Y��c)�K�,����|<��6�]X[����``!n�'P��i�*�w�u��c��c �zQ��������n��I9��|uxyM���/>y�����jD�NzT_����a����z2"#3f�����.E�\'�7�G��f[�_{Ogk���T8�TD���L:?���}�����fRX�`����.o,�Ib�E�c��������ok��a�I��A�|�f�1�>��$��W�;�B�&����C�s�9�M/�������3:�b\jG�Y��1�&4�,���8�LL�Q���Q�&��(���h��=��M����2H�����"�Y��,� �����B �qkZ�����5�0�'*����/�fF���,��$�f�{�hm������������V���p�V�:��N��x�L���e6yZr�Mr���
��Oy������>'���a�5X.+�r?a���|���<O���y��~�����}���x��:��H
�b>���G
�L5���l�s����&��EUZ)�'���eOY��.b���h�+2�>���y��A�~�S����;q�V'�]�m�x,:C��M4�m&��W#�����c�a��"�h+�$�����8�1��0H+���kS�xO:������cb�=��D�q���~���G�����:��������@���#����.������(�����~�dJ�%n�d'b�'�A�/Dq���P\?h������|��y�-W��n�q��lI`��(���xHdd����_�oL���e7����CccM�cm6Q��[+D�O!�lb��$�FM��s��IW�WYLW���c6D��;�<���dDN�@�]���������
(�-|�;���<Qq�����!�o�o���hv���m3�)`��7s]|9��DG�Cn�9�a���7��z2����_��
T��%%F�KHl�Oi�����V�H��/������$���n����(w��L���a��;���I;�����!�/����Z��U���5$�E�,�5m����o�z�����k
��e����t|U�O�'��v�j2L�P��F�1$�:59&�����p1�����^��p�������j���9����<,�A���/��uw�K�n0�ma�Rnb#����4f7����L��CC�e���O�����o����L.1����S2���6���8�wq�w<pB��Jm�jY�M����h�	EF��uZ�I�V�&*���F��������s��ea�j�O�����Y����~-�z��7(�~�L;GY���[cGC���t��Cc��<\GR)Y��B'j��nNe)kx�m;-['�s�|`�}�Kc�(yEC�$�0e����:E]���wJzYv�c\�3��A@|�'�
��9���������b�i(�!N�T��2&i
BHD�:�"�����������di��
���Q��kj�=ed��b����[�owX�8�\%kr���n�������|���<7Rpz�fq����(�U����6Qh������A��~�+��X���?����O��)�|$�'���R����?�Q�c��xj����S��T��:��e
��������=��*�F���8�|����7(�	�xh�HqaI���v6&������fZ;N�?'�Of�/��z����_��y{����6�G�1�A�4�����@u�P"q����1������~�~���s�o��X>W%��Vf��P����g�
V��Z�����xlA�a�������7��c����>R�4����U'�
=�st\)�=��GS�[�t�c�F4����cWK�&�r��+m���!h�P�}����RZ���������Uz\L�|��U�=��Q�4�3��>^�;I.w�8� ������Zs-���8��L�G����x]��Y��)�)=
��%�������B�����l��I$�I$�I$�I$�I$�I$�I$�I$�I$E�ff��'`��R=�i���r$��beQZ�W��&i����M�=���I:3�<�r�#�I����H�t��4���c�T�j)����.�Hc#T��	�YJ/��p~���mW�s���������5�������Um���.G
������u��%#?��k��/Z�>I1������A���ed��$��F
��J+�}��i�y����FF�vR����m�(����0�������w��w\1���JI$!(HB�.[%s(����(�4��2.lt�����a����� �b�X��k����#K��!���`�3)"&li�b$�I��Vh�|_/���=������X.iW��J����&��lm��@��H����[0��*M��F@�Z��B��Q�4k���n��.�F:������bVXt�����
����Zi��+'+-����u���*�,��nq=���6���9�jW�i��|�m�.���<�Ou�M��8S�`h��{�Q�j��r��N�����l��7owk�W�o7��cce�Y6����G(}��n���^�(���vE|D%�p��N|��3R�+�!��7��7�hF�����A�0��6��0������Q�p� ��g$�\��	y�*27�f��5�qd��EF$���+=�+�YX��$�$
�S)�7Y�w(�b�A�B&e�+s����9������*�m
�wKV��V�G?[�����i$��HI$��6�i*�$D"$D
�*�����`��VKY���b���;����nD������Qx��Z�s��*���*�P8��ED����������U�ta�tDf,a�7kkmm��v�i)�����o�k<�����4��kq������|��{�}v���a�)����Z����4���y���s,��������^�L�l�����d�����m�W%$�����QeB��ce��%��s����i�D
�D{6|���(�
�����:�E:��T��N�`;cH��Q������m�F'���y7��:��o�g��dq@��
2<�*�t@�{��,�hUi�b�y���q<�"Q}=*����8�`�n��G�����
���$�m��s����r9E%���UJ����oo9�3�A��fM������z��#f<�^H-����WT���"�""��4����36��N�����a7��:����UU����>�b�c.�R���,��ok���A51�g"&��q�B�v��r�l��'b"9��������as(��dp�$�N8�}3��J���m>�#lc�����X�xX,=p����sHP&���O		���`�a��\����E5fy���jL�=\��,m�,�������V�����/�x�{'�
'n�6*P����Cbz�����.
���tm�>��
�$���Z��%�u�3��J"#�Ar��.�!�VJ�HTk" Zv:;:�k��+(��@t<z�@�T�G=4�0D���&���
T�j����/��=�8a��:�G�TYIldH���Y��l�y_
�������T���a��w~�G�/v���u;��]I$�����f-&���^TDM0�*;����Tl�%��*��a����
L��������b�HSWs���'�d�*U��goN�[�P�;����9��oZ���G4�t�,0��5�Uf(�����=,TD;�/-U���" �h6)(M0�reBw�PDo!Mn�ow9J�"oOX��=+�x��Mg���
Uw0�C����&��oZ������~�����-7��4����o�DD��\$�%�6�c���d����t����q�K4$�X�l�1QRVMhD&���`��p��f����3��j`�c�v�^��Cogm���5�tE��_:��rH�B�	a����0��4�����D����X_	<���� Hb�[d�S^g.��s�;�q���x�?B����S �$0��O9=>��s5����[{2���U
��c"!$���x�b��z��T����$����+�_����#[I�JPDEBF�,_Z��y|��Qv<9�������f�Bj�v���:��5���,���@��i���X%�f����iT$i@&���I"���P����[a�x�[t�H��{G����$�m�eK�B	Q��ZI(fV�	z���g��L< ��hlA4�M7�&gf��sy���-�%������d[�utloc�p�:��Uw{����2a�3#IF52�I{�U����w���<u7�/c8t���o�<N������%$@$3��&
��i�M�W��#\!2��N�$��c-��xU.6+�o��mF���[��������0������cs�$�rw��)x���8�s\�����t�� ��d��o/���*�,�fm��
�s��hk���f�I�4�X��0��K��A^3�{�������z�������\�t�zC|7��I�d�ZE�^��J!�	����J��cp��t�i���xe$��T��D�x,va���Q�|�N������������
sowtL���1����j��0�xn�%Q�M#R�
e;4��"b���a}�����YFL�*��Z^��b��gzD�P�64mF�M���G_yQ������f�-�a����Ud.r�8�}�����I������}+�����=a��_�mP��]`Pd�����K�R6���z��1�mX��k� ���X��|���l���H��O��I^���*SIc���+%eJ��6�� ��%d��R�K(Hr�fO��K/(�W*�V�Jr�Ji�����X�D�h��ad�2�H� f�1oT9�WWE��WZ[�)��32�����@8����c���9�L#E�n�A��3a�X�tI7V�;.�F�
����a
ua]J�B��j��UTL%a
F`"��b0�42) ��dl���h�_����G�V��3�M)i��%�N�����E��2u��������k��V��vU���IS����fe���u��o
{��p�1/g9�p���wtl�g8l�p�
���6k4�LY�Z�����
\kC����~Z��vnG����T�����(�5���Si������3����k�[��u�$���E�:t��\�;�r�Q\|�i�%����\��)g�a �'���$��3��V�B�I�����r������V�v�MM��_Q�+U'�BB�S��+SI�Y�n���]jd���k����
�c������U�m��%���	$�''�\��JSMp�bK���2@:�e.���mb50Vs"�y�� �		J���c"�1V�x����f[����@����[���|�1��"�el�J�[�Q��P�����Xa�b��Vv������
�/+��W~���J�J�CH���I c�D{���N�!�2b0BHgI.p})j��)f��)�tB�����B((#�Asg�n���$�x(7�=��w�ff�n�������n�k�DA��$�J���=����Bn��gK��^�oz���7���)T���r���$e ��C���0o{+�*4��0�3�����O9�����������$�t���1o�� ��oH�ZTBB
A������J�Q��n���(����,��O]����w�8p8
G 9��p8r89���Hg#����+�O���9��z�,�u������9�G
��>+9�>X7�?��=�r������?`��
�	'����?���9���o��
��ug�$eR�j��la�������[�mQ-���L[�|�2���������O�v�����k�5�M�m`e��_8���(����}e��R�X�N������_�����'W�����37X)����P���i���|�?�I��+���y��FlfD��fN~(��"�7��v|��t�=W�������Q�USA����s�U�w�]��r��)�TG���cf/������O���9������s��xv.��tOg^�V����(�A#�/���Uv��p�*�?j�s��@��H�?0O�|��|�9������k�H/5%^�\��+�����x�_�B\��/����y��fa�hd�4~����e�q)�[��_�^��������x_
������w��_�����}��5���6������9��:{��Q��#���t/�L�/��(�����,�=��y��|��{�=��O��G�:��;#��"M�>A��Q�+��	���:Z�����o�V���}�k�.�IQ�<<�>���J.J���q��a�j\$���{�J����(��j����&Ib��`|���U�{J/���M"�Qx��R��R�%������*K�1�%IVJ��y|����i�;p/J,�_�T�	w2v)?Mj��������T���
x���;;T��]����_��~
�T�> �9~��w���U	}�IQ��J.��_d%�g��+����2�Y,���uy��O�a}=G8�<���c�XB�z�z����^7����ue�r|O8����}H���U.S����W����L���btX�����C��,��|I:|}	^��D�~���CMC���=����.�������=�6��OJy�W��y~��^�����v����eT����m���U"��>)"�?/�`~i�y5MP���T�P�-������FBL����������A�R+�!�����w]n��
*�V�� �b����p�k����iR�Jl����

�!B��&v���gN���9����
*L&`�@�2"L#TD%����:����WJ�m6�ew��WY.]76.���&�Pm�6��%�1����3Q��v��_���������K9i��;#��9�\J�,���6K?������Ry�����X�6bl������y�y5u�lt7JR���Q�Q?�x�A���A���?��6(�)�<����;'�Em�k��h�LZefd?t�"HkW{�1�K.d����Q}����>2G��ax�/�v�������y�/���z����@�O������v��l8x����WZT��)��f4��R� �UY4�ec*3cM�efE�����1i5�Y��M&,ke%J�)�������3cL��?�#��Wy)2C]�x�C�RE�B�G��M���N!y�S�����j�-MM2j��Q�j����5b
�H���G�����
����5��$f��V��45\rG%�0��C�%��ZG��3���NZ�*�<��������r��������_~��v8b\�2ZY��]::�X�i>d��O�&��O����x�]�B	���}��Y�i\-}��2&�BHA��x,�w�����k-z,Ea2X�T��Z���,X����4~�8+w��������v��7���(?���#��]��dNi�?�����6�~�������}���$~������|?�|��
I�	��x@K'�M�3M�u��;���/�����)w?[c7�5����>�^���x|�>~3��������tz5zm��$��K��b�������4��yj���Y��������Wd��$�*|�	�o�1����?��q��{t�A����W������y��7JJ�A�G������}���N
�ZR���d��2�F����G#ir������y/������S���Z�����%/B�@q#��y��w����Q������t�O���'��������vyXU����S�����N�-��,E�g4�&��z�6����T�0�2b�G#����o�8�S��=rY��+���"=jO�����I3�K�>	�{�����o	*������Z������5����i��=�eA*�[YE���
�I
7:����>�>���#���=�GC���fbbH��B$>�z�
�
�������>����x�u��O�O�"
�H��I~�"�t�#�x�6@�d�T�����$uN��?m���3��-��>w>�o(��z���TsU���G��p�ut�����j��M4&�����I�.zR],B�C�O�OCl�k377
Y�U��|���UU��T�<{+��:�O�vYz\�P�9���V@?�����y�#���������h��,-�}�S�Y��j6c���%>��#��u>0��JgK�V�1�5��uC�
�c��v���6
��_�d&Bf���(�Q�m����Jq{"���JG�����f�O=!'VTL��(���4Ti*�&��~���23�!�2(���m�����N|kqSCh��6�����sNrD�
�ds;��u�\�]�<c��I�C ,/Vaq��(�����L7��T`��l�1�}6'�9 E� =0����4�{������/O}�����s���}���U�ekl��>������I��5l[&����m4�bY�L�J�Q��U����j1���fM-M�4�4�,4}��S��K�y��J�����X�y��<�{=������,D���)o���I"JV�]���v��(/��'�9Gh��z�A����I��%>1��Jb&�x��#��>QG���>���t�~���W���z�������|Q���������_WE��}��"��9�����������W�nq8��}����Tw��h�� �d=�n6W���8,����%�8���q��T�rVv������<lR�J�l���%qq���Sh�2��(��mN{y����&�w���YV810������t�QQ9%$�PA�*{��PL!]0k7�����4�
{3���" ����l�	�#F;X�������a�n��UX�C�-��m�����/Oc�yV&�GX��Z��1��c4�F��T�[+2f�T�Z����%��M-LV��M�����,Y�SKm�����K%��2��C��Ct�������d`�3=O]N �y<
31�Z����io$���l�v�q9��!\�`�a�(c^��n��`�T7�L��!���4�e����}�\��|��}=��m1�M���e���
�D(���y��8.�}_V�O�5�������Z���id��A)�4
����U=��zY��1��_���v�.��D����O��^���FfU��~+�)����?;��N�����iS��/�������_���%����=��2����H���J���=�%r}��t��U�z��������=��#�n�X�D�^����^%�����:��q�I��+�y������}<_n[����TvT������$\�W
S����I:x���o�������)����vV����SZU��Ra�e�KP3������Q=����G���������S�����^��TUy�����.��n4��;Q��wn�	��W�tx7��;�����8�����$���!���[9JV��;�;%^�/�I��H����B|�9�'���������O	|����W�*�}��Y^K���Q��~t��U;Ju�4����Y���s�l��������v����,uU�#?������YKCET=���o=��'�$~����8p������8�����"o�6�����m�mO����4!-�y�C�������k����0�cVd�����L�&fd�gL��RIm^�o��R���cLj��T�����kif�l��4��$��&PPP��&�M��4��O���0�D�-Q	��{�����v�+Q�Ctr(�{W���6���i���	�Q���$�,2�Dc$�{z���
E�|I_e'�a���E���]).�59����k�W����O���N�J4�<���e*�Hu����k��������^M'������;'�����^����w��%j���XZ��nm��b3Xi��&�>U��]��<�8�����&��9��Q����8���K����bw���$�\�����y!� ���2���h���6�E���O���n5�l�O��G�O��������b�WO������5xo1&d��,?��s�t�=�{yAxDM�/z��G��y�/�te�Ok����J�|m4�:#a��;�\dH����X��d���;z|=��e�����G���������H�o�^i���6<��O�����L���|�����ru��R;��I��y���r��	�SI7�e[;J�����G�wW�)1�!�.�>F�z$k�*�����+����_cIY���J@�_�o�}�w����2:���;WD1��a�"����1���>J��O�1H����O������b�X���/�"=������D�T'G��f?c�����f�_��f3S��v�p���H���\O���{=/	U�1\�s�=�HY���������Tz�$<4�� ]���^���v'��B���,��,g���#������G��z�6I�c=Q�������-�0Im�4�F��j�0�LBK3k��4����`���fRIFMiD�l���IF���M��6Fj���#2�h��,bSM5�2kPYiV2��CV�f0����	�R���F�me,�-5���7���]��
��������D�����u�TW����U;��"d��|��]�]��Vx����R����'�A���,�}������h=H'��c�t����&��D��Gg������0����<�9���~�gm1�2����z!�TO�la��c�����a���;&b��_g�=&�!�V����x��cK��q#%�q���^O�S���I�����L�?>�����r��U�]��H����uHj�0]2i��kv�8��]9�I�$�����m"�X�9'�6*#����jdG�*�u��K��q��=WU����*�N����'�C���1��c���������N�����4�)�����eH�L��E^s������c����&��4��VOj�=g��f�3���Hi�'U�wE]��Q����$./i��������H�\�r(5X�U}�Z'�Wj�c1G}]���ZUh����%�3�	�������C���uIfzR�_D��7�����'��O�L���bh��o����>�K�/���r�p����
)[
�x'�������iQl{��?y�������'�c���W��R��������������jiI�&����WGbY<�yH7��I���Q���Gs�D�������o����?k���H��<����p8����W�G������C�����F5L�����N�J�E9;xS{�Lj��d.O�xIy{���U����)B��@��O+�Q����y������u�G5w>�������[x���d��{����_��4�1��U���'�	�A�$U���\�d$N�F�}���F�j>��{�$���US���"��Y|�����	���N���*=�iiidb�j��5MSCJR�����	
Qj[u�Mkne�	��j4Z*[&A0�L�hL��J	����ej�m���BP��Jk�������@��6 ��������
&j	*F3�4����V	���C2���c*q'$p��1��9(p��NH��V�H�[3Zk��!!�y�X|��� �������pC�7�����Q�"��}���>���v������?��yIO���u��A��{��4����$o_��MX�o&�o�c��(�pr�Qn�4����)�(�US k����SA����8��rW�E��9��c\��d��kS��<{u��4��|f�G�^�y*<j���R�%'��;�R���I���*����]�su��8���/�lST��{C���z{��/CG��=?������)���V
T�8�����?W�����	�E������x4�~,��)/),Lh�LG��p�G-�t(�%vN��������������
�$>�C���af���)��~��Q�i�^�3�%����C��0�T>0*p\�`�:���IuH�a�S6*���r�X|�����NTW��
e�%����%p���(��+����EwMR�I&Y�d��T�I,��L��c�S�y$�c��������"N������
���v1���L�pb�fn
����N5s�
�$c�b�Y����zp;����~L'�Mrl��J���7�
'�~�I�=;����������b���B���UW��y����*��uH@�xQ�W����cl�f�e��2=�t���
tZ[)�[��?���t�yU��/�u�S�hi�g�K���L��f���f`�F��1��}���
�,�T��Wz_�������z�]I���2F�/���`��N�nO?�J_g���K��W�����G�������U������+%��������.��DjK����W�>C��1fUVW��'#�
�ik+R��/�]���l>���4�KH�k�Za$�m��R�����Y�}T\R�r?<}��A����Ig
����$��s&,�.��M#�|f�h��'���l����y�u��MT�������!��M$l�0t�?#��$��gV<R�
����x�*&� ^N$�(��0da�F0��&��0��Ll���$�c��l�]�:�M�{�V�(��1�;=t����g����{�;\�bv�Wv�I���M�����D��9,H�9$M��0�����5����gE9rNGW&��25���y-IY�6�$�*��#h:���F�`y��0��0������*e�9m8���6�I�VX��r�:�=#Yl�������#q�$���I�9���&�,��t�M���B�1�V�O��!���.�]��4�Y�i�5���d��F����2k6�]�;�=�u�q���x�%�QmV�mJ�Q�/��@�CF����6��5���T�JF��Zmg#������*:<�
	������W��$��/R��}�Gu�a��'�"7�d�x�`����]�2R��Q�
��DI$�s9���~�����m�t�����u?w�[f�^A;�j�c=�{�0��=I�{l���iv�W�#�#���"��I7��
�Ut����fkY������&!���ke�8���4SV�0cR��3�����EQ�?(WUp��j;���,c���=����!�����=�w������zR�Ad���7��*���PHr5I3'�JI\���fK��Tx�������������{����WJ<��X���P���I����bGQV��.�!#����Zx�xC0�{��L�U�Jj��%6J�6&mQ���Gt�������s���}�Z�����T�������!h����&��<q�4�G�=_��N�=�>.��h&0k��^�]POz����2���d��,-5���%d�
�h��������j������-^5Q��qo���������$���)J|������X��Y���Q$��#��-r<�R��<{�X�����lL�g�����=o���z\���P��c�\���f���jID����b���I�a��
[je��4��������.��HcH;��7xF7;w���"�(H��T�
#57Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#56)
New ECPG idea, was: Re: ECPG FETCH readahead

2013-08-17 12:08 keltezéssel, Boszormenyi Zoltan írta:

Hi,

I am restarting this old thread... :-)

2012-04-24 10:17 keltezéssel, Michael Meskes írta:

OK, I will implement #2. Another question popped up: what to do
with FETCH ALL? The current readahead window size or temporarily
bumping it to say some tens of thousands can be used. We may not
know how much is the "all records". This, although lowers performance,
saves memory.

I would say doing a large fetch in two or three batches won't cost too much in
terms of performance.

Please, don't apply this patch yet. I discovered a rather big hole
that can confuse the cursor position tracking if you do this:
...
That will also need a new round of review. Sorry for that.

No problem, better to find it now instead of after release.

Anyway, I moved the patch to 2012-next (I hope I did it correctly) so 2012-1
can be closed. Let's try to get this patch done in the next commit fest.

Michael

I had time to look into this patch of mine again after about 1.5 years.
Frankly, this time was too long to remember every detail of the patch
and looking at parts of the patch as a big entity was confusing.

So I started fresh and to make review easier, I broke the patch up
into small pieces that all build on each other. I have also fixed quite
a few bugs, mostly in my code, but some in the ECPG parser and
the regression tests as well.

I have put the broken up patchset into a GIT tree of mine at GitHub:
https://github.com/zboszor/ecpg-readahead/
but the huge compressed patch is also attached for reference.
It was generated with

$ git diff
221e92f64c6e136e550ec2592aac3ae0d4623209..870922676e6ae0faa4ebbf94b92e0b97ec418e16

ECPG regression tests are now Valgrind-clean except two of them
but both are pre-existing bugs.

1. ecpg/test/compat_informix/rfmtlong.pgc points out a problem in
ecpg/compatlib/informix.c

==5036== 1 errors in context 1 of 4:
==5036== Invalid read of size 4
==5036== at 0x4E3453C: rfmtlong (informix.c:941)
==5036== by 0x4007DA: fmtlong.constprop.0 (rfmtlong.pgc:22)
==5036== by 0x4006BE: main (rfmtlong.pgc:45)
==5036== Address 0x60677d8 is 24 bytes inside a block of size 25 alloc'd
==5036== at 0x4C28409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5036== by 0x4E34268: rfmtlong (informix.c:783)
==5036== by 0x4007DA: fmtlong.constprop.0 (rfmtlong.pgc:22)
==5036== by 0x4006BE: main (rfmtlong.pgc:45)

The same error is reported 4 times.

2. ecpg_add_mem() seems to leak memory:

==5463== 256 bytes in 16 blocks are definitely lost in loss record 1 of 1
==5463== at 0x4C2A121: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5463== by 0x4E3E153: ecpg_alloc (memory.c:21)
==5463== by 0x4E3E212: ecpg_add_mem (memory.c:110)
==5463== by 0x4E3542B: ecpg_store_result (execute.c:409)
==5463== by 0x4E37E5A: ecpg_process_output (execute.c:1777)
==5463== by 0x4E38CCA: ecpg_do (execute.c:2137)
==5463== by 0x4E38D8A: ECPGdo (execute.c:2159)
==5463== by 0x400A82: fn (alloc.pgc:51)
==5463== by 0x5152C52: start_thread (pthread_create.c:308)
==5463== by 0x545C13C: clone (clone.S:113)

The last two issue we talked about in this thread are also implemented:
- permanently raise the readahead window if the application sends a
bigger FETCH command, and
- temporarily raise the readahead window for FETCH ALL commands

The cursor position tracking was completely rewritten, so the client side
properly follows the cursor position known by the backend and doesn't
skip MOVE statements where it shouldn't. The previously known
bug is completely eliminated this way.

Please, review that patch.

I have another idea to make ECPG building on this huge patch.

Currently, UPDATE/DELETE WHERE CURRENT OF has to issue a MOVE
before the command in case the cursor positions known by the application
and the backend are different.

My idea builds on the fact that UPDATE/DELETE RETURNING is present
in all supported back branches.

A mini-parser only understanding SELECT, UPDATE and DELETE should
be added to ecpglib, so

DECLARE cursor CURSOR FOR SELECT ...

and

PREPARE prepared_stmt FROM :query;
DECLARE cursor CURSOR FOR prepared_stmt;

can be analyzed and tweaked behind the application's back.

This is needed to detect whether a query is a simple updatable
scan of a table, and returning errors early to the application if it's not,
without actually sending the UPDATE/DELETE WHERE CURRENT OF
query to the backend.

For the purpose of WHERE CURRENT OF, I would add a ctid
column at the end of the targelist that is treated like "resjunk"
in the backend when returning data to the application.

So, SELECTs would return the ctid information of the tuples.
The cursor query was a FETCH N with abs(N)>1 because of
the readahead. For this reason, the cursor positions known
by the application and the backend are different.

The extra MOVE can be eliminated by replacing

UPDATE table SET ... WHERE CURRENT OF cursor;

with

UPDATE table SET ... WHERE ctid='...' RETURNING ctid;

Of course, if the original query contained RETURNING, the
ctid field would be appended in resjunk fashion.

The new ctid can be saved back into the cache using PQsetvalue()
and the (position ; new ctid) pair into a hash, both can be
looked up in case the application wants to modify the
same tuple again. Some protection is needed against growing
the hash too big. But usually[*] programs don't go back
to modify the same record twice.

[*] This is only an educated guess.

How about it?

Best regards,
Zoltán Böszörményi

Thanks in advance and best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#58Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#56)
1 attachment(s)
Re: ECPG FETCH readahead

2013-08-17 12:08 keltezéssel, Boszormenyi Zoltan írta:

I have put the broken up patchset into a GIT tree of mine at GitHub:
https://github.com/zboszor/ecpg-readahead/
but the huge compressed patch is also attached for reference.

I merged current PG GIT HEAD in the above tree and fixed a merge conflict
caused by commit 673b527534893a4a8adb3cdef52fc645c13598ce

The huge patch is attached for reference.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.4-v17.patch.bz2application/x-bzip2; name=ecpg-cursor-readahead-9.4-v17.patch.bz2Download
BZh91AY&SYY������������������aU�{�JP���v�v�1��^�b:;s��u�M7��
��}��o��!5K}��Y����>��������z������������/p��z7��^���)}��;{�5^�]�:�{L��������`�=y��N�6��������Cv��v�����o��q��������3�^=�z/gx�kw����
I{�x�N{�������o�����n�����T<��uf��Uf6J��w.��tx������>}X�e��<��>����S�
k_&���X������I:�@4O_A��������{���N��:���������q�V���kE��;��e��G����Ws�7�k��{�����Vq]���������W�ykA�w{of��w����^���:6�}���i��s������}�Q��0�}k�"���
�U�:GCv5T�����1���N��l�m�{����}x�6������rWmZ�ki��o�w�>����p��	�7F��l�2���N����s�V��^W��^�o^�V�QW�
;g�����c�]=4U/{��W�O�:��g�W)�����%���=���#o���a���A�tQ���-��i�M�'��'���^����a��s�\��q���Pp�������U����G��i�m���u6�m�l�������r�@��n��{��Q���/My_G{hH6��}/^:����wxB�����	��>g]��lI��g��G�N��7I�j|��5�sZ�P>���z}�}z���3#���u�
���[{s��7�r-{�=b�u>�f�/{�1���U�������2��v������$H&4&���LJ{E<MOj��mM���A!@�	��i�6
~�~*oT4�G��@M"E&F���'����d��	������(h�OT�H��M�O����d�3H��C�2#!���44R" 
i���OIO���T���l�~�x�f�TI @���������T�O�Q�������}�&HG��E[`-�-�,ZLm_�t4Z����b����*d�`L�R���h6-��R�I�&�BP���H
A
h�"V�"P�@�h1���&�M3o����W,�]�0.���*�wv��
���D��
	KHDc�k,�n�k�G�QWW]�b�t�,v�n�1�>�sE�$?��� 5wT��u��%�m.�����+�Q���"�K��\�uu�n���#U�V�5���4����t��;����Q�S��R�2�����+3W.�@3u�t�u��p���I���$������$R�C,�%���/��O�����%QF�������a��E�a$B�����$��-�{��s�i�+����1m�0�d��
�a��L��Z�Vb9��v��������������2��37�(Hs1`'�(JBf�!%+���t^u��$�����_��L7cY���Zz���$J��$�C�/|������:���-z��zh�F�����XG��\������%`��z�$BSw9��|���rk�W�l�C�A:�����kN���C0��(���^R�f�)�7;�Tq���3	��;��M��J	������������53�V00�<��u�^QH�
"	yu�JNL���w�d�� 4
���W���;�Mi�7�N6"����$�o��s����,�S��NT���Z���u'l����` ��'�'���Pp��	�Y�)F�a�pk{���q+��*(;{0�]k�U��8�P��2�����{#}�y���Ml%J`��N��I!���8��p���1,��#(�I*�C���i�
�v��j�o���|W�{��E^�,�nb��A����jY�S��n�v�D�d*�X@���G������L�d����8��)��(���AQ�*s{b�YZh�[����m��*�e�a%!(@�+�����A��38�mp�
�R��gs	��:��� bbdgD��6��9�@���H�z���7�R�R���q�-T�m�z��e
�R���%��u�t��*��F�)�Y����D�V�b���V���z��<���'3�s�"��&��ik
Bs1�
1��I$�������;��:���00���4b.W@���R���jKJ��J��]�{���(Yx�L
c|��^_w�0��NarGP����$���Q��1�&�#5c��5d��C����q4��>u2Sy71���_^�j&g&��2�0�s�bYZ�fQ���"�R���'N��=��~:���B�@52�����C�5.Z4�d����&8�$�2Si��BBM���KkKN�dg	(05�Ch����##�S���0*F1�������_�~�Ou�{�3�;6�+t��@�S
#"�����p9��
�[H�5 m�*��F��g����<`�M"f;=y��)��Q�
 ����7�	�`(�{�7��4H?2������yp~}T�=�i��u�P���S�J������sZ�e���R��1�=t(pL�g9����"�/����5KN�dGp������.��H1H��l@��6���iaM�����y�����H��#A�o�@6���{��@^�u������V�V,
R�
��L������\�+ ���%�����=�#���A5%y���h�� ����VfE�*��M]�����]�3R�C�0VA(	V(2wzd�����?Q�aK��]�]��~��[4~����&p"!]��HI�XN��w��k��&LQ�`�h���\���n��*����N��t?����
S���I�EY����t>b��3��8��>���
=fY���m1��*��~�7�����l����n��W<s.h�nX�:��s2����)�&Blg���������g�%~����"J�?����
�h��`L�v�L��
!HN��*���\�>�w.+����E�����������s5*i@��Y2�m)�S�lW�^5#�����N��q���9����}mU`Y�i��N��������C�!@��x�������U�����g�S�?+b.j���1^U�w<�����)\r��Q~|K�*��m��f��z���u��W�w���X�����<�94hV�1X
G�� ��RA^
���W>2�m��(�.U�qaF��c$�Sja����$�}0G����r\V���(�&O�U�x)	*:�T��Vx}�1Q�7t"nP�/f|g��rL���,���>���I�Ry9~��r|��0Lilg�"~�Z!_i�JX��0��{H�/��e�c!^L��S��z�3)����$����\���;���������\oS�}}8os����J~��O�j�Hh���L�F�R}Z>�gpz��u9�|���;��3�Fg���.�����g��3�X�~>n�?�q���,��`%�'��J]�&i�����d����-P�v��
<
����:8���F&2��N(���
���K��M��Dm9�4�N���FI��.����4!�!�I*�g���U��f���:p��B�b0�th�O����6XfL�,�(l?�H��5%a�M�����l�N���M3:6S�����a���������������V��������L�:A}�����h�ru�P}�}�e/�a��"����P��oOb��,����7$��������@�)tf����<�K�Noys�`"��T��\�9%
�BR��s�;*t�w�o\to5oS��`!�I$�=���U��v^�����tVNKrt��o����� ���aQXh�t����,����k�W��@�4��V�j��A�W�,J�N��`�Z:.�-a�	��E�Z�w��ke��f����e��8s�qE���&D�
��lL{fjQ%V���N��"TR��QMh�L�U�qC��s]�p
sr��vi�k���
��
�!zu�e`�+�f�dJM��JM�`���Kw����x����XHh�U�����%�(�IM�!��� �#�66��*-�1��k��������3�����e0e "���t]����S����x�I����}m��d�=z�
�6���u���a��O:k��o�����[�3��T�!�:(~��5;�H�5��@��8r�\&[����� m��U
���+%�&R���������7)eL�.v�'X�p��{#�f*��M�(s��a%�������`B�
�'N�)�5M(S�*��/�_�z5&�
���~��=��2
i�z��q�Gm�]e0������<�����iD+������,�2N�v.y����������e^oH�����]�l18���m������8��?�����$����c�������V��wy��x�:ax���~��n�D �n
i@XdB'�'#���Xm�&������Uu�#�t�bl�p��h���V-8�������R��p��Mg�>������;�T;�q���q������������Om���pWS��/�����e����|�M�`l��gFw�wg�����[+���g{�3���������UUV��<���>w���[���~���(n������g\����0|�]�R��[�k�Np"5p����Z�1��&���}.�
�lt������������?��/�g����>���O�~�����~���AE��_>R��=l�@P�������L����3�9���X!3V�f��akV������J����p�o�I����L!����*L!II���V�(P�]��|�j�9����v@s���^?]��u��`�`���"'[8�rEsV�z�#g
4������q�e���b�I�k4��D)U�����V��lU>fG2�a�I��A5�@��TDT����������@�n
a��!�!"7io�6)�������rPI�����D������z?���nr�%�R�T�4�r����Xd��X�����"���� �91s�@�t�����v��49��q���q/U��
�/�b9�a�2DZ�)p���n*o�� ������eMI���#"[�Way+l�T( m�m�+�p�6b�]P���j)�JHJ����j����$Zz�nI3�I4�/��]���I��J�jU��}��P�������00��};	Ld�3���"��Q	b��5�$��c�k������������e[�m�����i��5I�:O3p.�m���m�v�
���L���\��M[����\v6��Q$h/�s�A�Q���R$Lp�;����Awcm��e�}�{x�y��9�V����a�Oc���0�
(��(P����aQ
x���aTL���&f%����F�n��wwwpy34�i*�v*�r���#����y�����]
�Z���5�X�ug�m[l���u��s.9�����V���m���e���>9�Y��Jh�p'�%
���UD�!7L����\LE�c��� ��f,Lo��M�!���$7L��4l��J3����	W&<�t�����:U��i����l��nI��M�3'#wJ#�l��nI�9R4q�	v26��,>)��sQ�orB���y_��
"���,�D�!�0nO"���d���8��fdBF�Y���2s���R������������a���yx�k�1�J(�����K,��{�<<����������a������������^39��3��+�Yf;��Y����2�aM�7[��!�"#���FwCC��%4��cD�K���pL,�fgi��I�D�%ID��ywww��n��Z-��i��D��(�5-K�81�c8P�BAAA���&���[��UOF�����2����.��\HIH��
4�`F�m��=�/��^s0�`K�����j��J�,��2��,K���+�2"H��+�
Ve�b����j���I���J���)`����<J(�FY�:��Y�o�bSLAi�����1+�)�s�I*�97���V���=o�9Dt���>M�5"�^��o�����B���q�)�R�L%�����M�JSf�T��Q��L#S�����1.*�7�i$g �Ki\Z�����s}�_��v�{�Z��C�-H_g��������M����JV�g�.�X�����K,g-<1X4�*�E�r��jP��
{�K��f>���h��W6253�����{9�{�jo
u��M���b����0�E]��������v��	��W��d[�V�6���>�G(f�(�C��v�h��aaq�[:���9-��h���OvU��)v���7���P�o���_�e�G3=>6@8=��X�F$KE1D�������w��'~�U�%���>��w7>�>��u���i���e�B�����������s��P����~��������_���Fl��3���uds�o�{|o��;��?����O�}�S&�n�te�Z|��Yk�p���j��W�5��M����w�9��r��2��=��mK��|i:k��[���d�L�T���?/�����e���o�}��2�O�)�cr��7��	;���ne��#�$�I1���;c��8=�b��4����'�����G�.�������8}�~�~a�\�/\9����������6*?7b|�����_����u�gM�UZ����z-�`�?�"��!��HTHy��g�fITJH��i�����GK	�iKe���H�-�k[������L�x���?g���j��l<����P|?�P����i��h�����_m3�����c���zZ��W��{�*����?����u��+���N�G�1H�/r-V���9_3�Nfy��K�l��������j��i]@$��U�)uxO�H? >���:�e*��("�S����M�ES�A�$���z�qo+*���_�.�� �d!����^3&d���VK������^�q�xeUEy�~��~��3:��t�A����i���T�|�l��$-)B*
���*��E��@G�_��d����������ev�s��+b��e��kgz���x/�`#,��J�4�$�?,�^�{O��e�����]�7=���i�L�Y<sU��mS�Z�w���gf�x>oIol�s'0\��
���*�f������Rs������� +�������<z��S�-�6����������1����9��5BNV�������	#s�,e�1�'t��O2Bm��W��(���F#��I���X����B�H?J;$s:o����dJRD>�NA���!�i
�yt�e�%�T�I$�:"�b�"D����]T:���=���BO�F�0�FF�o�D��<���E���A�I��U(�zs�_�x���D��0[�ml�"���`#Q+0_��g�r~���|�#��*�)!udh�m `T�$���/v]\~N�iPf"����8#�rep��p�g��`���]�/l��t�1��f��M��_�iLH �X�������O��
��}S����D�o'J�I&���E{��2���cBX��
���6)��Jd���W��E�6�)���RT�������O����!�H����g�q���D^����g�������VC�����^��A -^������O>y^��	l,��7��F����4�Dd�DDEy+���""""2b"!+�o��!DF�DG�4Qz���G�QXl�_����V+JR���g����G����D��o���>���N8d��	�:���VI�mFf�N��F����Z�2��gtg�������\����K�����-�h�@%Cy�!�o��i��1�w��7�a/]$.������@b��B;Ib�`8�3�������U���}. }�!G`�<J!�u���%�/S}�����Yl�9�~��6�
���x����^��.�����~�?t�lf���1�[�d�:��$??��G���PE_��O����4S1�?�up�����o�]tX�o�]<�����z��w���M���K���5�y�%\3Y��T�MX�u7V�;���w���v���1��,����X�F��c1���������\����y0a�=�/��P|���
K6c���r/���l���������p�O���)���|+��[�X{W��<�$.��_w�����l���V�l����eS�Oy�NR���e{����;&��y�9j�^�(�Z�e)O�nG�e�K�1Y��&!��4i
�������a�dE�=�C���Q�\�\�������>+��$�X�}(��F��Q��G{��
K����<���{��\d��$��%x�����������������R�M��DC_CZ�M]�G���8����F'3HW$��I�$����D��
)��h���/kPcn�9�f-s+���+c�R��B�%'0���.JD�j�q������!)QH��eH�	���6��;�	fHI�p�r�,0�!�U�����A����u)�7�����w��+&o[8w����e\�/,�ObB��Ib�@��l��b�:.b1��s<`'���\���4�,�k�=��U
���	��h4oc������R��-vd�����u}�4}3X�s��p���?����a7,����h@��\� 8{��qhl"��p+ld�n���\����v���^�'�~?��������Z�z=�/�>�>_�V���8��0r��]��/���RX�)�RiM&�VMR��dK&��%4J��)��f4��L�M($-��-�eeb����bB�
,�p��bF`�LR"�l��I`���Z�er�b�e���cg�i.������b�Qe
������y���>���*!F
"�"b�H�
 w���*�BU/����8���C���B�D����+AB�!"
��V-%b�T��l��ov'rM}�5�(������}��R85m����(D��\�r��$�3I��kQe�c���$�FI0d��D*�i�1��/_���� ��
�K�HI�u�L��*L�r���0�h�P������]>�tF���*+��y�D����:�kA��% n��zuDih���C,�������*�� �@�,(�,Dz��S���)���Qz����
�dD��$KD�AQ�F��I-!JId��jZw$	H�����TV�bE�={
$�@z���a8�
�=RxURI�����a��Y�5�+G"!���L����
|=� ����&���BA�A���W������T����\�1?W�R�<�X��dH����G9i]�,��yEkJI��=<��#��V��R��&��J��	���=�{o�DgY2o�������5"�9��%��J*u6���i8�>D����p/w�E�2��"P�!"g��E5�Y6�Ko�""""J"��>>d�[�M��B)"y�0d�l��-����PNBL,�<�L��Xt]5.�"fD�t�ad�U9y�ET�bn��zOw9i!l7X�R1������3
*C?�:8��F��Y��|	2�
V����P;��<,9E$�P��G�3 ��������P�d^�����8�r&�\`���z�#���QE��$y{�������D'*����]y�TGq��V��tt����}�#J����vv��2�$prph�OAeh��,��-u;�C��,G�E<��:=�R�����A���Jy�t{��J��l�a������IZTZ(X:zM"����6��A��$;F
�v��E�������6q��CL/P�S��(��5�������*�>��S>p#�G�;�v����U�.1��$���a�1�����)O�/�k���"�`��/�t����$U�����M�c9}�����=P~W�.�"��d2�@��:s�I���E$C$����fu�Y�Q��U��4#O��
'���9���?��{��>��(WY`T�
���3;�2D���;r��3H�"l	j@`�k�����bS��F���z"�gc���a�����C�O�MpWQ�<_�*�%�4�$���3��k�P��f3U&N{���qvl��
�i�������g�;L��<8�(#p���.f�%"Qa�){M���eUk��p�!��A��v��7��Xb����V-3�0���[���h�&��^�j3=W���N�~/v��~{m�����[����}sf�x�qT�Xs�x����aR�>mu��F��]����4�:�����i���Ei0�BNp9�0�x�����~f�;���������}����y�$��b�Y���Io�.y��j�X��|�Q��G�f���Kf�YK �E���0{�zK����q%)FPJ�,�R������7�81�<�J�`�Hj�|�:�Z������g�9g�n4��5�7�����Z�s-�kS\�\2a���K5�%�~�;����uOh��(�������+K��bTFCbp�E �u\��K�e* ��!(��\U�wE��)7X�
v����!7��� �\}�Co�Nc>���|��������#I������6��[�F�}��Y���D�Q�D��xB�/����)oo�};#0�XI#�HG�507�K��ho?�!�,�	��K�z�Y	ds��,�J$�������� T�(��>yy�/����	~��������H�(*����Ol�����#xm�3�ZYt��TB4���i5$��*d�FO-��!�����:�H���o��?W���&�D&�C�6tOV�o#f��~2���$
QcydJ���F�3������e},	G#�dW���:���s�e�NW��#�����~�o����]�_d����Ko�N���{���������6���PXGv�8�Q�����z�^�b"�3z����S���2�p�����"�0g���=���Tx`��?���n��}��Oh���}�n�I�P�H�H��(Ai�]�=l|�*!��������`]z����73�O����C@����!��"u��OO��j"&�
3��w�/�U[-��>��J)���p)���<��������zk�}���<vq�eT�/����d�"[��SLV�������n�h���:��?�_�v�>3��y���G���i�!�����LU	-a2����E^��	������|0���",�oz�1��
	�9��R�g�#�����E?�A,����^�u:�x��$$�xv���_1=%k�qjrG���=����������}���zx��!G:R%�C��_g;<�����':I�
_����������w�����?|D���������u�����|sw�o���i���>��_@{~�?^��"!H~k$�Q�C#"l��yH1���Q��t���Yl6Y�H��[�'�$3P?0+��V�Ns�fau�d�{�e%���)}ry�bU�6����?.W~�_'D5�J�W��&z�f�/^v~����.TQ)����>����/I������A��cC�S��������8v���b�m�/gO)|l�v�zt^~K��@��I����g�����V�%���>(�u�����R�
Y'���o������W��5��W����f���7�j�����j���7�G7�^+�I�4�� �0d� �& �[E�6�����[�bhb�$��3�=��}��tI~��O�����6������B ��$� �
l
�d�����Ie$USo+Jg��1��&UM���^������A�I$�V���0RI�
���
���e��IF����I�)%U%.�BA�9h�y�	��8��?u�C�t�������u~/��^��=~��>�_N}<z�7����9�ps��s��kUZ���kZ�k~�|�>%�'�������px�� O�P��b�����D%� }cLL�DL$$7C������XPL�(��������O�T�!+��H�!������UDE�G$Q�L�4F�����i16Ld(
�BC���� �)�;�i���/�B��Y���Qyy�@������7��V)+�q�NX��;{����$�������3��%�D}~���� EL��`J�3$	.$H���$IBe[kf>�237:j�����{��
���X�.5�`�5�8�a�`�>�8G���$��{^5�5Z������4��J��]Y�L�@x}�`�b��U�d~@��'L�.CR0,U�[,�N�t������5_~\�m
�����:=b �|N�j����%@l;�y�]Fh^���@L.y���w����y��4��:^*��s_w�(���
�����S����r�����2���������/vJ�w�o���z���������H�`�
U�*���I6�
}�O�����+�7M�^:�G{�^���u9������d��-���l��K��8E���WN<h�M�&o���>�)�J}����:s���� �L����]=%��S=G� ����A�O>*����������_�Y`�?=oS^���������$�lkZ����2�f�e����JR�_����3����1���!���u[���|��Ct�E����c�?g�������d7�	P�����d��CH
�=����WT�6]�H�.������a��+��������K���0UY���5��������_�����KW3,�����/�����c�������_o� 7��~��?Nnl���Tm~�{�H$	�z���.�ktD�"J "0�WD@	H	������$�e�DDAQ@�s�'��7WL����k�tDQ 2�W�A"]���	�tw]]�	�t}o���)���/o�o'�f	�_,���Q�����G������Jh���E(��A�G����&O.2������$>��G��,����-�f$��rg�( �.�L��c����	^�������T�q���j��x�>����� �>����������|�����6<����(|AlC����3d�
)a_\u�t�gY��$L�Gf��dC���JSp{�z"�� $92���=h_9W�	��+���08�G\������\�i-2�K�lxJ���$���V���@���V�t������h-$H��gN[NM��'y��(<�tCRs���:��g���^z�"Cy9����'8C�\�d3�().-Wk����|O�������������T�l�"�8��}g�%�O�>�)�}�4�3�uu>�����no�������#��h��Co,�<j�D�=�|������W�w���?�����4pCG������|�3�0W�K��@�d��]����HCc�/u(��|JD�=z"����9'4��,�o��i2V����54U���R��UL��N��z�V��D=a�$+@���$������$;_S��R�h�e&�}�~���g�~�D2s��_�wjo�����di���y�j)��3]/O?y��������������L����45��=���3�M^c�`0,)3	hbJE7MWm����5mCb�j�e��zS��S� x��4s�������Z�S/+�J3��l���'F�(���J���2
�h��X��`��
!��V'
$-b^�)r�BD{?����HH	R��X�����89�����p�~s�vC��=���W��q\Lj�Y�>���O[S�z�"�
���H�i�����[��@/�Y�=-������"��$I�_�������~a@�8;{���7���|#:g^\t	x��oJ�����K{���&���#a��:���|�=H��������eD�W�1=���P�4�8��IIH����l�����i�h/N��?�}o�EA,�!B�2��	0�_�n��6���,���M/c�G_�,4W��s|;r'��i��T��%�
|�TQ(�W�fG��1�+0K�_�``
c��D��2�]F��O��j�,p�{��2"���:d�
�l��������BO���r�y�D�������&��\�����o����{�=����
X�Tl�H�a��j1_����:������`z�l�,��}c������wm�����D�LX}}�R0W8HsD1��/E&�	���3����{�*PWI	��FO��'����z�L?�%S,ei��<ltc���<�\��h�T&3����\�������_���V��������9��	��2)�R���P
h�z(yp?j����T�������n:��#�$�H�(r`�H�S
�@����_���um����>�i��������@�L�����?����P;K��8�Z"]J��J!��������#���;+;��B�D��hA�� �e�F��R���"1��M6��d�&����(���	��J
;���Qei�cL�JCl�+�vz|�J��I@��$�yfm��K��0	��*a���dVw����oG�y?�*����*��	2+�i�3���j�'z��'��E5�U�'������_v>�Q>C.t(������>(��I��%c��c�^S!��
!:�\�^��l
Is��bF
MM�V-���T�%A��A9��0H8����UH;���O�4�H�B���D�
	�����
yNY���?��IR4S�bcp���m�m����8I�$����?�_�<�_�����}�c�}�ot�t�M7M4���������V���;��|	��$�D�o�Ye�]�qf�U1�y�LX\uUU��H��Sm��c��m�b�8m����*��u���������7ww8t�EQ<��wNfI�������������{�<|@����@s4�UE��	@�QUTU~s^���~�r�����!VG���rg�����p�`��+�3�
�K�������� ��.�x����vB�������qD;4H��2e-��8�G�#A���9�)�����M�Rt,�T~w,� k�W�K�r����-$-UI_���K���gvm2b�m���72�PB��b~	�1�����/���	�#�����/r�����82a�'�O��[m�~0�/���U��9ji���C3G��j���\Z�m����,�W���Nq��2=u��h|���~��)J����)e:����V���.|%&98��}S��J�.�D�i�,�����\��O�� �~^�r������=���=����2�l���N8*fY�h�Fr�)���T0E���o�&�%
��m�Y�FJ7�dU2��q�+�A��M�k#u�F�+��3��/WM���C-���T��
QB�+/9z�Q�bp���y��k���Fm�QB�+��F)*�q���v��Ub��h�c��P�qzc�����4Q}Ey���U�/WJ5���l�t2��,�B�+��D�(e������ASeU�CAkm�������y�v�{^s���y�����b-�����"�wng����L,���[+2�� ����V:eu�AB����tiE
�V{y�[��Gq������T�Q�i,P���L���P�K����R����Vm�|�������Q2Z�������<���������(���i'8�2��L	H0�G�l��S(�y�`h!x2������ tR��fNMD�0��0C�t����W�a�/T����[Kim-���xH������T""(�}�_i�&��3�e�'�2��'�����SRA��3��"����^L�%�W�����v�Z��'k0�,&�<���BST�E��b"""6����^ZR>t���-��UUUXI���k��#aI���JU*�I9b0G
����im-��Q@%"�^��3�!1
�(�v<��!^v1I���(�}pl���(������O��2+�����4����ah�2:����pd���U�jE0P�ec����]4WZ��]�[�;� C��]�v�I)X������,�����RU�l!�k���b� 9�s���,P0P��X�h8�)DN�-I��m���h�)F�^"!��������(�����!A�3�a�.Z�p�c(�����e^��k���=H���Ws0)�c�c1(��El�s5�jQ��E�V7Cn���jC��e=/\�Nn�������S^�W���o�����*�0�&�N����f��k�����Y�G�.
��%�9k��K�,:�[[IG@���N��%
9=������������N>����}B�r|��	!�IY?�
:��Q�6����`F|���K������+u�wP�h+6?��l
�e[l=���y��������r�dH�*�*"�b�z��Ye(JV�#���8��z��4	�9����7�N��������(����P(�Y�&�[SkM4�,�FJ4�"6L����5�e�*�I�fY��D�E�`��Q�+,���2�I4�l�����}�k��+�3<���Bb(��1OW����.�~�w\6�F6�[IH���s�.��~0�"(m���-.�"�G�$r��^�}���2�)$Q4�����R
��BBLf���'*mP�(�3�0)�<k*yw��������9m�l\
�k�����[�Y|s���6�g��w=?��V����H�Jo
7�P�N�����j�A~�Ig#=��>���g�~	�����oXe�v�JSI��B�D2s3!�2�)����������4c�
��
��UUT�3m��$F����^������{;��Q���MHls��~���Wl����B��G��o%����,)�;J�k��i�z���=�V~iq<�7�
�SRj4)eKW<��{[^�����0�{I���%/��������������^	Ux�CW������F�o#��
��XQ��$���i
�4�	0�l7�E7�o�e\��#�\-�T��u���F��������@�3��_?{��~��{1F����������fS������=6���`.�U�'���>����=��G�#a�4u��P�w�g����H��ro3�3�{s��F�,���o��z|����|�
!u�B����{����hA�ce�����QU6_7�r�*��
��S�>�JsX��S���q�F1���>�<��7��=$����&�*LQ-��5
�������O��0��{������
��.�?���<��}�H�PC�-����t�`d�]�L^����������U��MZD�B��q��>GW���N�����_{����R�{7�Jq������7"y���7�����10�e[��

���4��������g�P�G$:��R��$�^\�#fM��^��`��^7�N�����_�����dm�y�Z+R��|�F���z��w���$z�f��y�����>U��-�b��6����t_�46��4�;��H�{cyi(����h��M�5�U�����+x�71���������-O{<����5��SK���@KM�p@�8����d��k=w��#'8T���&o��v�&������������S�v��s8��9����x���sh���-=+��L�g�J���V/�CO_#���m'/U�m�������wt%}6��,��v��X(Q����W��Y�wi^|=�W��d�����}��C����t7�O��[�V��6}���������#�1ZhC�n��%(�V�e7P�(�!���V�!�����|�)R��*TE+j�����M�Y�C�y�p��N����d��
��G�T?�*���5�f�e��Q�W6�cm5Q��
�m�C�o}�9�M���Mz���K������^�i{0H|��>3�R�CI�l��MZK�}��	_@�?@������l�Y���h��09�Lb^�~Yu��P�[l���ii�Y��������?���@��i����N:}7�H=��S<_�L�BJ2dCZ�}y8���� �����F���,66��c�����-wA����[��I�uu2������e�]I)I80XE�[AAbXe�i�&��t��"�w�\<���g�O���jrr(l������S:��b�ID�����v����X�S����t���%c�$�"J%H�*H�Fi��z�|������7B��9Z>�c��K�Z��Ixe����=��6?�3s�����U��Y����-~�]����:�����9A��z����jD�GI3���P���B%��������I)~�4�
V����c~���
�K������.�#b@H%�Y&)0]�|R�A������HQ@o�?���D���$���4�xiL��s}_z>Mo_T�����"�:0��-A
�i"2Gi�"���������D�J���|b�J�,m��P��Gd�����8�:���m6^.u��i���T�#}�D�.u�<�2
�MNQf{#����V�
:��"�C�x�s������z`
D�@D�����!�w�q��q��k���'����N�'�D���He%��6���`����/�`o*R����u�>���X
�Hl�f(B�#wr���d&�`hC������4����%�NT�*|P�2mRq�~�O��&w#-�}��p3�K?�Yj	�cw��S��oT�5{�������QT���
S���P���GG������(v/l�&(Nda�(Be6�����h�3Jt��ESP�*%`�Cr��T�!P�KIVT���S���i�* H�m>]W�|��K�����d��$�R�	��v���U��E����T���	f�F$��c�.��]"K�Y�T����iL�Q)�)$�)I��"�"���F-P���T��[/�d�r����X5�
{Aa�v�&#��%��I�-&&	&bR���E	~_>��)���I�2D	����.��A��R�0���(=b�(����x(�_�b!��Jm(g�0C�A�>�q�����:���c��1���i����g������|����N��v���S�����2���E���o�)�~2����q����������y��~��P���7q����b]�c��* ����6��=�����?��*UF�G�D�1~���r&�#�=��@�$4���w������h^�G�����D8�e��W���W�?s(�#�@�j�4/�k���m���b�i�.Cx�1��QSY��Xl��6�l�Yr;�����hZc/p���t�
H�I����\�>��3���9���`�5*H���
"�x��t��~Fm|��m�>��G2I���<�3g�A�I�@�2���(�NKyA3������T��W�,����Du��\Z.�������:����-W1�_'.�J��L&���	JJI�H�
�m6�
����X���yw���f2�����K�4�Z
��T"H^�V��j�������F���&� �A�QzJ�bD��3��O:_N���R��8��`�>�r�d�v�i�P���z�W��=lq����Pa��i��Ix���.@;�f��,��S��9E��H��P3��<��5R�'"}G��hH;�|�2� ��)\�������S�y���<�G�����b��@�dt�z��D��>]����� l=v�0L(�R�!���U8���EWbb��
�a���`�G��#P��mj�������m��WDc��*I!�M��v<�xU[Gd�I���a��	�oa�����su�����M;�t�IMU�K7qB�

[I�%S��g{:��,�0�DRK��s�8�8��F��
�F#��9~\�
����$+ `�3�% H����`S��.9������.d�����Ay��dk%�]m9��BA3���+IQl�w��S�����g��%�eLC4��'��"�V���sk�{x�>�X�BNN���q���V��c��Py�8��$��4��4��k�;����S�Q����SmK���e�s5����/�L� ��0|�|y��Y��t8�g��9�.�Z*Q�����R�`i�p�p`7&o��)0��^��+���X��]!lL��L�V&��iN#�C�A��W>|�o�3��c��N�1�^�nN�����?�p	,������W����^��_����V%������GK��q:���"����!���{�y��A]0��w���Y�HO�X���]�����RH���6R�Ps&���3�I�~�F_��ND����O#4���"���R����z{{Bzj'm�	?���B:�D���"��&H$�0B��Z�� 7LD�e���.������n�����T��h�a*[��dC�N���~D���'���P�)/l��j(K�^�n%��b,�u1"���5��v\�X�`FY_��J����zV)�:+�T��N�Zx����1�����t�o*V~���������\�����9���+�y�����d��wHz��!�Z���u/��+���s�p>�\�.O�O��I�|�"��n`xz�	%e���%U��J8*���$/�+�����I��$Rd���t�KcY[�n�L�6�e��A���$s�-2<%~$�ym@�p
O���5�r.�J���{%�l�4�����|.�i��������IOR/���l�����?�hm��m6�@�A#�����o����C#��x����_sq��P���N��..\'��}�����ARX�����A3���^����K�����&�e�+X��.>���X(�����u�Y���#����}RA��i'���
�0W� 1Y�CFK)���In�l�����S��|c�l���%�g)W���&<u�Ny;�q{]oB��R\
"�d���C.NWN�mz��(L63I���=i���:����?Vy���/���|��������%X������:�+��s��
2�rS�P ��beK@�1����W�<<�`}���(((���I�
��N��{�>��tg����$T�p����)��H�i�q�����E��:NK�w�BE2�gJ8��WH�[K)�4q�=����-�%��� >��=����s�`�-���D�����l��as�n�X���	5y�������N���v�?�}���`B{�
>���BI��J��T�6)YT�[Qh�L�(���3f�V"�LJ��j1A�f�r

1�l1�K5��4k��mE�0��)�_��$����dYmK��e�jS8BC�R$(���`�">������F�;���T�2�����&SP��F@���A)le*�M*�K��M�J��Utj�p�@��������8�J�Y!����2�X��A'�?/������Q�H����;c���X���!5��;=�H�"b
�J����� �����ae�����=��!��,���}s���K�8��l����Q+���-�P�(%�,U���l����������#��?w0���yl�-4����J�T��J�U��T��
���NDHVj?`�@+��LN�~�%�����%/�.�a��)�JI#�B�m����:�y�Mgc����|�9\%�bVD�L0�	XAl�0�)|Y44
lI�1b�Jj!��v�6v�S�L!J/�?]��*c��w��/��/G����1H2�*��7��;
$�����$xT4U%BR��qIi�g0��w�f���B��H�07�X&$��
R9?p�5��A���RA�9�htz�Q
(NN`�?N��Y�B����i��Hs��r���V?Yi�/h"*2�9�������_Z�@fLi�R�$��NSp2��R�9����/�|K>1��m)E��)J[m���I��a7����n�Id��C&D���lRJQ�gem6����0mu�.B�78XZXZP������gY�vO��BI��������������V>(z`�9�D-B�1(��14��t?8{���q/��&��G�H�s��z���7+T�4a �����?�����PJ@^�������@����*��7WTUT�I$������4�EU@S��o	�	��Sj�	��1b�?��TW���L�R����b!��O$�t�}}��PW�������t�"*� ��������s/���-�^���~g���9K ��=�����dV�|�=\;�����OS�[O}�������s5��r7�!��e��a5�������.��Q��R6��/]I%U�E�7C��������|��T��/����:������_�p�i	�.2�6�Uf����-�{3�.�����(;3�����+gaR)����H2K$����Iv���D!"�4�N
�� ,��X�p���L�l���Z�G��X;v�ViLz2��E�&q���k$6V$E�-�(#��>B]n$�m��F�����:��=R��N��QR/�@/�D���4�����;�$|�0
W����H%���l�HbG�(X���^�}���9pf��,������?v��o�J!0c;�.@��f���O����^��?k~A8�;x�A��I����A0��%8��{��AX,����]1���1�|4l�h��v"`�K���q�����^ael�>��9 �L��H�b�Jc�HI.�!�{t��k��,zFDI���\Kd�'L`�����P�
���v����Tzjkp=Q
�j����l	�&�	qJ�������L���i���r�Bkag���o���L�8F�]|
,Q��|���@��R1�*>Z����G)���I�#��"
"��iE0���hDH�J*	o��@�<Q��~��"T"^���H����<wm��W�v��qK�t���]��++����n���rv��{����>#���m���7Cn��<����{j�v�ssg.v��.3����s�����NI+&.
��IS:��{�m9�k'7V�S������Tf�_V��n*��|s���%��Q�3,�g-_n���u�z<��3e)��b�����g�e���J{{%J�9WS���j6903��kx����������&�:�V��8����"i���*��[�rsG���{��q�����<��n���gRGc1�������y�2�����f9�vur�gv����S9��{K�{��;2�������DT�I����/9�u���^syBX�d�v��kegk��w#�D
"#0��OJ~���A-�A~�2R?���������cmY?��j�8���$�����"q�����DOZ{S����t������(���TTI='��o����%� ��}2�����L�ZE�	j>����mC8x�%
j)W@?�������c�1��|�z��AlN�<��F7�GBx��!0J��f`0��WS��d��	0�����7����Su��C��/E�X��O0���SCr�i��]i;G#t��:��y$��/RI�|������cZzQ�5�n�����3@����|��B)���O�_�����|��R����X����6�G+�|��y�8�>��� _�zd�mW���v�����f~W��$��r_E=�:���������\�+��%�9UG������}��r!|��=
��	0��
GP��e#���_�^�^��}"ga����|������6d���������?���{	}7�W�6��<����(�����:So������S:�W�F��eX��
��
Q�y��`��5c��a��������t�w����}f�R�����r��2�y���YN�c�������iiKU�������k����U�k�������5�������,�����k����V�~J��B������L���"S��9�Lm�I��Zj���>`�A��z�����Fz�h�-52�.��IU+�6f��%3�HJJ0b8L�2����Je����r��*DX���veD<�sD�^
��	�I'�D����~t�w���`�����e\�����g2�Y���QO��#bFW�MqI���`5���
k�3���	���??��l�I4'��	u�d�E*u�LCsL:r0Fr[U;0����8���������������J���O��NM��JS��qU~��7)=�$����)�i6U����$��3c����������I:���8�
�l�}8����TI$�I$�Nt�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$��U�_T�����>��~�TU}�1#�)���������!P?E��*���$R5Usj��5���j$�}?_��f�D�D�A��0C���jHUAU�V���kb�M��f��� ��RSAb����V�n<lMH�$�����x	���*�42�'!�U�1�	iC<!EO�W	$V��_��XY���t��IJGu�X�LZE��	*B���$��I5����=���{�}qR����qVW�O���r��Y�kR7/*mw��Ej��]��aqA�P�}�@����H�**�

�ZA��T�S�3!$�
�:���B�� R.��C�����O^?���FG�L*�7	G�O��\�����m�1��$�b(M�r�z�)����1��$�0����UIU_MpX����{�=2Eu����{yb��
�Yp���M��TJ��E"PcIc`�5E�������~�s���K����
%�,�
�z����*��s:�p������&�O�����*R�[R��A�F�kbX������)�xx��U���u\�� ��������������/���)�
+�3�zN:����V� ��6��j�Q��%7v�;��+�6�4h.U�QFA{�2����������N�$P������Y��^T��Q�fa�J&J������[[��i+[��{:�&�Q�3�����wMU�>�f3�������z����gY��ii����k���D�"UB;�����i!�Q.���������U�@5R
Lc'�x��v���c��nz�UQp�d��K"=��j��JD�1���
46��k&���U�*����3�����T� D
{�>�5z���t��D�{ ke�46�)wl�R�D�-�h��C�
l�+;�;9�?#�q�� ����w�����SJ
�P�jD1��r���8��!������M�A'���A�P��M�3{�xN�D|���>���'�3n�����;u�����g�����U�R�Jw���.��i��T�L`0G^����6�E�4��A\Q.Z�BA
��@�r�|����C@{��Q����v}={*.�C0���H��at���l��P���&'y/x�!�0%��\n�LT-���2�`D8p�d
W�sF��z��o��������Vz+�Hg�n$��mr�DH5��@��K��31y(�e����]�<�>!�7l4�\�d��L�Wg�8�S��P�cJ�|E��m����J��&;|pE���bH������IN�F@c��nn�	�U�A�T�������^4�*<�%)�
@��t�!Us��')���:�UDG*��6��p7,�)�x#��B{7��~Wq��P�%��)����.R�X�$	
�>��n[r�Y2����2��
�cm���
����%>�i��#�R�J[=���nfV%����r�\:k�n^���C��3��2fe���ws{��N��a�&�n�gWW�<0u����^P�]�����1j�M�p�pU���������#�P�d8�d�H��c���-�������q��Cu�Y�/a���i��)����C 7�&���: u��Rr��\��l�J�4wK�g��������xX���*Pf���������h,V����I8=_�Y@v	�����h5$��J@6�"@H�G_1��~��V}����<�e{k���[��SeK��2jj��Z��z.���������`�	I�^���#�AB�y���n Q#� . �!
c��77/���5��m&��	�A��d���o��R��:wF��y�C�D4�$�����[D�d-C���gs��t�*���@o�p�� ����|;�s���e-���*
�� )J��W��������^%��\2�(�p��E	�������i�u�����cBU���G��T�B��]�F7�E����d����������.9������LL���z���]�FF.d��'�*�Z��N�B,1�`t:�7.W9�
�WM\.	e(Kh$��O|=����|����2_v���'�����W.W9N:H�����-�,eQ���Rv���"fL�F�����
��)�~o��Hn�����S��}�����.��v���:�V���bI�B:�-��{�������%KV�oz`�$��H

�p!��*�gwv�u����b�Tv
�|���J��l�B�#�N^]�RjJ@@���l_J��*ie*���8�=�g3������s�ox��^gjK��A�mM��vzis���%!��xMdd��{om��b�F�$j�������v�R!�0V�����~r5�:�e����fe"S����O+� ���N�Y�^ke=[����cC2/���b|��I�qB�0'�+�S�De,�u8c]3�4�M�4�`����-,��r�~]3�����  �>�r�uHe~j�FN�a1����D�p�[:�:D�4	������({�p�]-��
�m���H�&C�c!����z����O�s
���I�J�ID�+~y�-DJ������������1%ed�QD@9!�����9�6\�2	�%V�)�2�!�j���B�`���Md!������9��Z�|k#��������<�7�{�o��%��S� `H��������*:No�WmT��Qo-����&�;�D���h<"���DP-���04Qtb�B	)+0�l,����L!��x�n�*��8��)+����6�{X#���6A	#�x�NDF�e-�S��]
��_E���r��>
����������V�������f�:-H��su����.��HJ@�
h�fQ���xw�IVH$��K����t��s���>M@+�"�<og�e������D�PD,Z�V�`�v���-�@�
��(��R��X�
� cM���gR���-��Q���`���J 3z`��8�-slx&4�S�R���7?�=$�I�P���o���{��TB��E�����Z�������e-��eL�������:'T�����p�BY�p�
&���P%dh�'-��ED2�.a��LJ\�@e��1R�bh���5L0�����,�Ij��������4C������FCHw
�Y�^y�~�:�I����H�i1��39��;�H���*oK:�d3)q��L�UM��}n�F�9�^*��d��DL�.v��d�7"��v��"��u�)NfqN.��/�����e���u_l�����r���\���������5.yB9V#������1�G��Z����4�n�d9`b��D���b�_��	��L7-��E�v��-|�Q�`��� D��$1�b�3�r���<�����	�L���Yl��+�-�y��0s�����C,�#6��'�|g,�,Z�u:l�-��3����_o" �X4d�2�I�A�h0�(����I��Kle��1,�~3���l���^�|���H0�I�D7#D7#@7#m�1�@
��cA
�c7 4C�C�@7 4{���s�z�|������m���n��7i�1#D7#@F7M6�XX���nF�nH!�$�A�nH,CrR��D��!"M�EdD6�*n98���2�H��Z��D�"e�U�H�e/sZ���W���	�t�z��mIE-�YEF��j���1Pb���6������||�ys�������2#�<�3����u��.��H��HX1�"�X�2�,�n11Sy.��|�����o�S3$�&~}p�;�I.�G3��|��E�^<|yzx���^5h�M�n����E��2r���&gf�;1�Q��j�	2R�0^���i�����W���([�,��g��r�)wvY"�l�Y�e��FnA��	cj����[{S�j�+Y���!��@A4T{��x����~�q[�+M�\�7����~�b���O, 89��EC[S�����T(hCgH�����`(f����]������p�.=[�����Kg!	�w4L��6nv�DY�Cs�;
��#0�,�����
c�:pLi+3
�j��T��(���'�`E�H�����(/�7IB����q�+�8n�n�����
WPAj��l���4�����ci��z�+�&M��v$P�D�4�Zl�H��-�^���7b4�R9B�(<;/n2h�C��0xT�,KIW]�&k"D�e��4���d����%J%c�Q2��~97�L������S��@���x��/�3���������1{�R���8F�3n�uk")�5v��b/����I1"��L�$)��M������+�j�����TBF|
�3���E���IYD-���R$��s����7klxo��V�[V��x��l�l=��9�,�'��_[$��Z`�y������m���e3���8�[�n"|���>����E}>����������.���0�
QU����fD�	AW�L���fK(����=f�i��K�3��x�p�y�F#�r�j�j��S����Dc-�Q����fm�m����GbUU-���Wmq�p�������0\�)����/(	07Me�������sFO�/=3��[mzF�{�L`������v���fM��Eh�����9�d���9����xGuOt�5��(�������'�n�H}���=��r�v��W��*����W,�b����w��Z9�*��x��n��gf4�����e]�&������M�g;��K<��l���0E		f�&'�/�U�d3�y��CH!'��������cS
1U���xxVq���+����N��15p��k8dM*�$Sy�tI�<�D��w����_K�`��������!��1ZJ�4�b�\�X�>lO9�;))Gc
��o)����f�v��Qyg�������=s����~�SJ���mr���5E�c���} ��:�G���Xf��54� ��!����B��RE��~&k�mxN�����r�h����{����(��J�5�S:���3~��$@�h���a^Zr��
*�[;^:��tX�;�����N�J�1�Z��l��MZ���2����9�]^��A���pK\el��T�V����U=3�x��"�Ti�����nm��eUL�������clfg
���fffe��p4�JR�0�
R�fa�g
���fffe��T3��E�,����.ffd.����*(��6YB�L�0���o	?Co���F�:��t�:�*�-xU\��\��6���1R�l���q��7t�6���6�2tV�V���B�F��76��fd�����)����"���`�TS�R��30�-��m72���3��'s%��cpH$����N�xAa���@*�j�f�s4��T
�j�Wse��L^{�zjG_8�-v)����O��"r��Z{|1��_���]@��[�Q:q�/�����1��O���rP�m0i�o��������L������z8f��/PI\�F��C�I|�G	�D�$��$0�,e!�9d�5?�H &b�?�~_���{��m���hB�0
2���12��n�oi�!!$��wwDL4��8�o�<?����Y���c�.q�Y[��z��bbAY��.TV�����6�.�1����y��1 ��]���������\��>r����;7�yV&$�%8�M�jIs%8�������Y���c�.q�&�*X�.q��Z�����=�v��������	�����$�H
��$���"(�gCN3t��8�N2��Ye0���,�K�p�����02D"��N+�y��\�N9���2�m�okx��\��;��eKe�;�+[���v��n����u��1��fH��RL��bIA������q`Y�,���kY5Llu$���pY$�2��K0��82$���a��4�,���t>W��6M�R��+�B����q��D`� �����P���#��a�����a��C����c�(���\8�d\\T"��!�C6;�NG��Hq&�����v)�(<\��
����G"0�8N�9��M���UUUT��I$��R������cUUUcS��k"$���h 8$��	�I�\K��f���{q�Z�t���9��%W4�.��ge����['��M���}�+��Y�$��.�sy�6��X�k��v��r��+f��vp����������9V�-75;Q����]�����5�Yc�;aev;p�t�v/��9��9r�����%�X������y�y�w�����o3�^bNa*�&k��A7�����r�)Svcky*n�sm��d�j
U���A��\��A�q!! �G6�R�=���(|��U"S\�8)�vy����n_*���6Nm���5;�3��t�V�����8j8�~��T|x���\�9�U�'�b����:��C��Fw�oj�V&$�%r�E`�o1������;�pl�y��^�H�.Tx��x��N%U�[{n��u8��j��Kg9�t�(M�%�5��z�J�����V���UrUmK2��������nI[�����^��4�K(���$���p�1��1�����b{����%l�@o�/��n�U}���{�����%ff���}{�y��>��&��."g�r���b�H\�T��ZB�#XMM����H��p�#�����R��w�^9�jmg2�����jR�np{����d���h�<r�D����� �=�|x�/>��ywS1��=����-�����=��]�q26y)��J������"O)H#5�9�����M��<�N���|�q$��A��4�;��1����lm��Hrf)���'�,���d����dp�3C�*6nI$�W����5mI\��Y(�
$`�0�br�$�P��J�dH���xl�d4�A����]��N#1�2M����SU5,���� ��l��^hI����^���y�������v����d�6������U�b�W6�aw���{�L=���x�Q���D��
���&[�(����{f=��Y�b���]��Nd�s�=�v�����E4��O������HH J�����7���~F����	��W��|I�,'z�.������-&���KI,r�����Z��a��BI[t��J�[j���o0��"N�y�1e;�(���2�iN��Ka�:lN�_9ow���,f�������Kk9�����k��
�*�����6��4 DV*3cHt4�C	�{��8��V�z��E�+aB�`L�`���T�+���{�U�J:Y�o[�9�vw+�����
���2�D��}Jm����d�$�\x������%2U�'X��`��;����������.R�
�������P#�jR��x�3\��u�_Xc+�u{];]��P���4���:;��1���%���,a\���L-��,�a�v7����������\*���9����I������������o,6�;�*�"��'in��nH)G%�T_v�8[Z��fUf
�*n�{jrg�1}3��4�=q������m}�=�_���[oi����|6����
�*�HgV�:V@��nr�4�R`7�:�jY:�h��YJM����"�:����"�T�)�S��������IP[���d{�>��rr&�M��a�kI"sq��2�C��:3������i��D���`{���u�U���������	)��)�[
���Y�B���f���~�4��$��TH��i�%%*5u�g,��	G+���,��Gge�Z��jW,�M���$��}������LeM�=��#��F��IF�b��9Y��G�GC?<��)�����.f}Ky�b
��yB=�*d�>"(�W�v�P~O\��@La�0��#J�G�bJ�#�2f�A����1r������}:�@'�=�9Q��pyG<AQn�V���;pNL�	�5�Z��0!�\��=����Oi��n��!!E��%�LD�*�@8��D��y]�Zs������3�H��X!b����y�xf��B:P��$r�����d06�(�Q������0'�2��o�����!(�#����y=:h^[E��)>j��w�,��q��*�a�no(O~�tw�+���9a`���I���W�������,����o(TB��������>�����]�4G_V����fd]���79Z[��b��wM5�`C�H��% �V��{F�Vs�t�~���X
0�Z�l�m���W�8:�fN�]3����k5�@o�H;����������3���ew;�#�{:�>��9Y+F��������������Z�]�1������/����
���}/K�-��N!����Q�\��S�����;\�r>I}-����*6�w#�~�UR���,
�<����	�>��V�-���g���w�����G��G�3||��u4�����W���(����	u-��.3�JQ�.��A���C�{�,�Z��D�6f]*�� b?�B�����r��8�?�������.�����N�� �P���s.O�2$������
���A*f�^�p���[OkqZ����U:w��������idf`�"���������i�����S��l����]�-Wi#�L�0S��7�s�z�i��Y!���@� Sr�.J��"��+�BK���/�-���$�	r��P4�^��������_�md���Y���k|H�9v�����JI� ��Du�_������F���t�o$of:(��I^�)UlMpO���z�y���wG�3�N�I��!�@]&�T�
'���_��d���I�rE�?�%�)��%�7���8�o�D~��~*9��w/�������hJZ��-��8h��CG��G�	��t��S�S�A�L������L!MpK�]dn���(LZX�=���p�w�$!U��lun�HzI�8�H�>�FC+�S�)���B����h����*����/�$��" b>�� cBiq�d&����9��v������dD�m�@��I,���Au��v*���P���0{��4���>��v��U���oj��;if�V|������B���-���,��d��3F��1���H�/���{L����~}�4G�y@�lm!���INE�EF	T����DH�
��&��;������Zx#n�X����������"��������v�
���\l
<���a$l����_��\w��vG.N��
`Q^t���L��L�A�t3'�H���/��)������:}��iI��-����'���)�9R�����B�|���d'�B��u	q�$�U�D1�IS*��d�f%dZ�s�*�(Y���"�]�>y2�G+�aq�D<GN\PF�9� ��E��Z�Si�J��'$�e������7���/s�����d��P}K�9�� �W�L5�>����`$�e�J��P��@��v�A/}*��%A`��
���3@��Z5���?3|y���2u	��$�5���}g4s����������pA�9)#��SM
0�Y!l*pjH]����|�����s�#��Up�p��~��������X�D�hhS�Q4M��<�K�=4$T��I���J�������a��RX$�H"�H�*P��! ���<���N���r��#e�����_c�t*�vxI4$! 
�*�%\�����&V�}=h���3"^������N�P?.�`�m%H��� �1U�78�#���Y���;G�
g�����_�����>�i����c��*��"��/���c�G��
E��e'����i�Y$�%��/d �RC�JM	��8K���v��0���T�I_�K q~gd����8H��m�N�I&	�K?Rna�.rJ���s�����E��}����A�s0pq�L1��� �,�rEaN�ZH��8P�C�����	���jgI2,4���>|����1Y�����!!u��ph�OG���
�A(y�Jm%��,B����p�z��U�W(���C?`�^8�o��Y%�9�A�)����$/��=�-8"�������:_�v��D��c6���;����P�O��tH���H;��MD���=�Zt���_���g��C���H�4�3��d-���x{������|w����na��?^���}M���Gt��@N����h���4����xT�q�y
$M65~�XW�Z}��5ISR��#��a�0���X��A[2�mN�$���'�:d4����o~h����6�y�'��Xw�
,��"�q���('���I�8E��2� gD��
����4��w B��!{�Y����q�>��EW�7�\RFL���5I+h�������	������I����f-,-�k��?}�-�����������=����c*�������[Yu�������I|�J'83I;�:��x��!��-���@�EH
�A�E��$�,K$J���V0��?'�'�����a}��-E�J�j!�I���dq$��y�I��n<������dtN�zkQcBI���BnA��E�� N���|?���g?���j"
i����1��_�(��v�n3����$���1�k?8�*�� ��:�Z���h�D���K��Gu��}�E�,GD#�����p(��4������/a��H� �������
}�M�������N�����g ��~������
�@�����z�Ek�����wi�a���x����\�[;���|:#Q��)I��	"}��IdN�e����"&
4r�����"���'f���gO�Ns��I&��t0�w.�'e�B	H��\(��0E�!NrHlc�m����[�M4�����i����C j��IR4WK.[�����I2"��j�2L4�=���pYiR��G�S��EQ��FH��B$�#K����y.�����c���KF��W4p�AS�l��G�O����zI%�({��/��;�@�����m$���W�~*})$��9}
-yoR�q��[����:���"��[lg����vCyf���k���N���T�?�f������>�|�\$�G�����A@�������!�1�C���V;�g�����G�2���)���	=�=?��=��'�cF�Z4o��~������I����#]��O�����h�+8�Wm�U��p�WWr1��p�H�p�ZR���r.�"�
)t�W8Ap��r���v�����;�@JR�Z�K6R��L���WR�i������a)Xb�d�����aL � �!pHL0d�a�0L�$0&q"bd�L*�DF[m�l����h�5]c����w]������]�,��]����K���ME�b�Lq�n��[T����I��m�[*����HwWW+��������e�G]�f�w�\����qP*,+0�QJT��P
fR P�THf$��:�GA:	�o'�l������?�>��%3#���C�� ���A�m�O�E�����S�{�/�i����KiD�<���TY��������������B�5��"H^��R��=r��fP���d��`9����_���1OZ��$�G6(l�q4��-�5}]�w|��:'po��OOh��{���<+����� ����O��o�_��qQ�?Z�:�I�
(��`!g�
�������3fI��tL���U�JsiUfLL�
w�y"k�8C�����e���0m�sL�4Atn	$�x�a��J�F&X%�X�D$! ��Q�%���AC	��y�Z���w�j����$���}���t�{H"�/t�%B��,t�=6��� �Kh���~d���x�1m�b��X�lf��XjI����9���9j i�O��	���6�q/��{��x3x��������5PD����<�N�":�9�J��~z��=��)=�3
=XD@1HI"�1"D6��K���������d@���E!F\\<Q�^��	#�����^�12D�MeJk2�L�SH�6E"E#H�ddm*SY��e���R)E#H�Y��)�m"�H�H���T�
�*E*�I)QB@A @L�JH$�!
����"@H�P������l��SV�������4�(�F�%#J�m��6�)�2�&)�Y��@���*B"6�h�����:!��("A(������#��B��p!�QP���Ay��S��[+��+"*�U�����1��;M���C�M����|�/��d
��U-Y(r�G^.B�B�K���xJ"�s1����A;����%Y M�%mM��P2������[�RT%���*���q��b+����+Prb�R���q7�&�1�r�S�4����HM�zB�����2A��A�<���A)�����d��t)�&��sVZYM��V�T�d�bj�j��Y�R�(`$��K2���	 �B���(J����%�@,K%FPX�IA�T���	��T�e:]3�����M���k��t�aj��Mev�.�n��������^7	��di��fX���-�.�<Dm�7�@;����i��Z5�<8:�,@��7;1�q����W�h�
�����B�D�h��!��h$�:�O`2�iG�eUf�&����RHY�Ys�iL"YRd���o��%ObG�Z���-��\^���9~:��D�e6wC��#���N���ij*��+[F�������%!��S��m���N1F5l��Bb�4���	E3y(�H��J	�l�k�D� �Xh�R1[[YJh�I��a��
Zp��4�u���cq6����,�p�������vu�PDn�UT�B���?��~�}����������^r���6�L�@����?u�����%=fB�D��������_?�<?��(B I|`S�]"e�x���&4���L<���>*��5$���aIf���m(��Z5�%�*HZ�K�z�>�������E@���>h��Q�B
$���T� E���u��o� ?�.�z��h�o���WQ�h�@�����q���$!P�K������y�|�2i!�B��K)	/���������q.��S;��AC�$��P�vW�-�}�hsI��1���0am��>��_�U����>�p:�
��������A�����'N�xh�p/����i�|�z����1��n�D��t��,�k����R��!���/����Vyl@�p)��~���QZ�L�X��yC�"%%-P��!����c�����VS,��xi%����5��(d�m��[q::��������\.�=��l��yB��V�"�$@�����!t�G&�Y9
e���
�.�>��N�2��i+o�v���6��o�_��v����(���^�>�86X����1'\����u��y�=m����>F�J�Q�[��!��b��"�D����"��T5�8��R�\���Y�EI#m�*��j�&b!o�����^H)JA<��N�u����%�@b�ri4:L,BT����{���]�!�[�t���F�}ff?T���}�*~{�`��^���~�!���_��y���h�O$Q�D��-x%������QUSJxS	Fr�z��y��5&Y��m�|��P?<��c�f��o����i�$�2�w�q[g��&���4LrJ�@�L]KM ��v��l��A����>����������.w3|�@)*�A`"�S�rV��:�D5���W�ic	sR��:U%@�X JB�D��U�`% T�����UCIP�S0]S$�A��4ST�L��NO�L�q����=!���8_-�`�p�����u�G~�t���1�����b���/
&����>uh��+���"."���*Q]���iD�Z���~n��xy����!���E�����C���25 �{�g����J>�����==?����QVP�@2����O���?
�RiG��D�j��1%``&$ �_����v�3������-��1���3�<�=�����U����h!>����b-h�JIX[�?�����$�0 	I  f[e�\[�>�J]�i��fS1��,���Z!�Rpg�����������G?G�T:����/1���H���������0�_6n��_n?4~ ��C�g^�������]���a���*!@`�B�2r@2U����B!$rQ=!]��e��}Z�+�=n�0�,�C��mt��j
����v��5�+��
���?v�_���U<��|sP�������m���������&���J��G����'��$T�S��@O\��#�>���E�R���v������mS\��ISa7$��T?�$KgO�����f2Q����e��Q����"M���G��/�������B(�������K��[���m�n�yv=�L������N[��
4$��j*���ZF����/�
=����D�I����@�}�a~�d���G�[l�[j	���F�����A���,�H��f1iK�3�&J\�2���$�C�����Z�
}�l���|s��o�����)�44(��d�q��M�E�<D��n�P;O��i9������� ��I5��He ��E�#���%( �B~�F�c�5��+/y!����(��b�#b�4���&��7mHjJX�3 &�X��j&g�!4-P	���	��O���M����29�-���?1;`'3�8	���M
�+2H"	QA(���CeD?�!~�����V��>�u�l�5R���k\�x�{�#�>�����1Lt�:L>>�:�yF1�b�BA��E;�c�QM��I&�y�B������
�����rk�����A�tj;W���<�,�'�X��n&;^;]\����-4�IK����5�F��Z����C�m`������4CY��c��3
J*K�t!=�!��C����]n���.C�~N�S����������5u����!����A4��	N�1a��b��;��)�z���gY�@���%�l8�Mhu�`D�m�D�G����G}�AU>�;U�/�E�u�z�	�RA&b` @
2 �8�������#*Z�2a!`�C�0����B��B��X��mb(��fCIV��-W^Q6l���U��E!�RZ���pW
�l�D"��e�AI�
�pI��o�O!�I��^�
IU�N��Px���#0c�fRX�z�`��5��m�!���M�!���d-����s!d���$�n�0���D�����"u�n@�"P�eda��%�J�Kbm*e9�9E��&��X��i;����[��%��������0;�@h i&WA$��R��Zv��n���R��"����,,,�lB#�v�8����2Ba�VB�!�Z�c�Q��t��)����e���%6��9�I����&��"�J�o� )R���Z8� |RDH6���%>�?��ch�?�4(�����=~�g8r�b�K�d������"��W�m�dQT�*n���M/AO�w�B ��c�gA����;��wb'[��b����g&��&�"T�B�$D�
A��3Q$1	P"��L����8do��'#L$vINd+i���(4�pD3F[�a�X��a6������������K���3�	���M�E��l���J��XX�o�����L��Y,����
��2$�zq�K����@Je��nX��������zXs��!�vU��h�����;�����Z#E�Cl@X�g(o�`)WYk�3${,��:fs�pg���\�7 V����'� �Xi�	-�01M�6��%QK�����.���Pt8���!SRIF
�"DR\(
��l�tf���M�jP��$W(k�)�C��R�
�5��M8�����
���r�8����_���:���������"hj��I]�_����v�����3����~/��g�%��Q��%���JV�@!&g2�8M��em��SR�m
N��C�B�6�,�~F%:$�@<�9:�T���D�	��S���14F�6�����v���v��dMiR*�R�@�PH�@
(LP�2����,(�,�D(@�M(�#**���+(	
cMSF[2SmJ,�k4��f��[LF2h��)�C��:Ogz������b�b�.��&|���V�S��{�����~}$_��^n '���� �JW[�9sk��������jT�qZTWT,h�����'}~����V�L�"JJ%HAC0L��:�5��`*_�����k�k�_0����C���%�.&�6_=�����g��Y�����M|U��x;����)k���������<���8���M�fOo�]I����;�,��!2|���h �<�NH���:fp�Q���,�K�=���a�*w>���E�����&����*���;)�<r(����I���h�0J�t��&D����d�W�	��=2GS�����|O`)��G	~b�!)	�����	��1h�tPyMF��{o,����.Y��9UP��W�[D>'Jk���Q�� ���	�(����
��q�T��DwA�A������!��JHTx#L�-��}1�5�5��0��Y�����HK;��Cs ���V��P�08H)�'U��w"��M�X�T:B-Xf�0�.����=����B�����e%�CA
�����B�$�\�eJI�6��R���*"��X�$%D��Xe!T��E�iUR:�8��a�v�hD�@X�"<�
�ei��)>��Y��&P��$�$�|��%L�@f����P���� ����������1:B�*H�+�a������X��e�|�Lx2�La$
R����T��V&$
�a�u��'�����D�,�ovKwA
����|�9������R0��ogsYAZ�4
�.���.9�'�����O"�6N''28��)�$���2��(�&�)�8�Yw��4��5
+����R
�N����� d�KA28`�F{F�w�2����;����uLt���SS`���n-7V���*M��(J[iC)�b���DD�@5�����t$&���������#�������o���<q�<�y��zi��C�>d����M%4��Hb����$C��I�]��$�*M&����[I��-�Id�ZM&�&���J�2&��J�Id�U&��&��$By��L$��,�,�A#�@�
�$�(B��$!(0�*��02�$$+�B�H��	�����)
1$B�BD�	DK����� ��~x��x��O$�)(I$�RaH��3�p�f���8�r���.�T�r���R�YJ�j������:�������Ch��rK�)],�G6h;R�,�A%�������\��{���oH'Ur�Wn�!��w�W\�$��\s�Ot8�yMeH��h�d��JaTYE��0�4�&1����.�).��6��eF%$*��)A ��M]P
p��W�(9�)&f�Y��u%o\���F4����ap4_�2����� ����0�N�q�PC��'iz������5��o���l���J���T��AP��0`�J��n27����nS�������

��I�a'C��=8p���� 3����O�@i�����t�;��(��I"n#9a�"���q��k�
����{R]y������O-jU��[j���W<��)�%8s������}���[PRH�=!��)��������`�����=�I.�u4�M��Tb���������������|�
�>9����"*�*
�(s>.����qX�J$`T�+�e�����=�"��.s1����]7������������Iz�{�FR,Q���&����w�<�����cEcc���<|��W���k5�������U@dQ���������f�:��~u�5dF�^�������'p�;�����`�K3�T��@."��"��#�.����wI"k[e��$���r!���^����o��V���`BHR��(�TIz�y�14A��5y�m���s��~^�E�@�R��{x�x��f|g���v����
���N�{qk�C�������~l�����G������B��P�q��%i��9i�
� 0��02�!!!�q�����@ `}�����vX@�oa�� ����!�������k�IPT���A���Z�� �Mnu6���;�7"D$AH����iwm���"�<��B =W����
t.��amV��
������x��+�'���h��	������"���g�hb@����6$��(��G,"r���IH���	5,�m��k%��MZ ExO�:���&�C;���\��?1����*g�[4j�V���&�������o;K���wB�.���.8���&+J
�<�<p�DI�s��+���(��z��>�mo�,�hv��vPqX��l��@��TE
�*��9P�J�M!�>��l�sum�XmY������~���������+Z����hB�K���%%��'�	�0��/��W�|<;~(r@~��4������)��r��?@.�OPQ����������9��M/p`�?:���H��:���*n[�#4n��z���BHA�I4M.�#���0�7������?>�M����T�5.B9�X��p?��>��T�?K'�S���g�$y����WB �a���b����q�Y,��*��{���?��}���qX�Gv�����������6����
K�RB��M��$���"����2���H��A+����������������?T�mG��'�Hz��}��|
z�����T��M�'�����"���&��a�lU���4e��D���]r:��~���L�����Hs�L�C�a�����v�z*��(*��UL=�0teQ�w������|��q(����m!	�M
"���t��vqSS��6���Wz.W��g|&D;��j��L-S$�d_�X�mH��{�Js������Y{TL,� mIw��hb���&�"�l��I��NS�z	���w��'	������vH�O��ON�����-b?R�JxF�)��,��g�/���'��(�+���;������G�*��\{��b��[�!�w@������`��|�{����*�n�0��q��L��<WL���0��
���1�m2���t�<d
@y�������)��3L`�1�w�4wD�]���fffVTM3�Co[���7x	��]����%�HU�D���������`��������&�����4(&2����BA^�#;�?{U���
��"�K��PP��b�����
���$2�.�����9��9�0m����s�$bsI�Mv���"���p~��:}cy���������uR�(������@
��?�n�9�'�Xn���*a�'+#,H�(h�L1D;��K���
��_i��H�@O)�� ?�����~����������Y�������]�
�Z����T�.SVJ�
�N����Gd(���)+���p�|����|0��u�^Q��:�g�*R:�t�}A�xo�$�d	��@��x�i^3A��6���2������*��`��xa��R�)UP�����V�6RN�in��T��V�R���2�e)-��M&�k���e2�2��l�R����PPPPPP�

��J�M����e2�jZjZ[R���SR��L�AA��ieI%���P�

�%2�����AM8$?���l�M��x������	����.�$AO�7gGqN/��s�]2%|=������>����n�)j$y��BT����R�����y�8���<���)p=Ep}���V8?��oTRIXSA�q9 $4/�w���aY6�y�Bp�8���w�$�
x%�� �"�5 H�0�	A��I���[Bj���h:�0�lTo�I���Wz�e~� f@2!*���:�������R��P"�������>�*I���9b�?�u��;�Q/�/���2���H*���h(D]�H}� ������J����F��%:E�5�l��$�9�"
�H
�~�,I�H:7@6KVd�������h.&�rESEn)y��I$Cl�+���x�`�Yi=>��0����E���}����d�������7��4y��� *����$�0GC$^��#����X��.&@�%����J�KRF���eXj��@�PY���P,�I�i
mt��3+���(�]
hp�dd�!%A�HAv�1S�<���2���FM
Bj
���-b��Y�2e�Y�X������'{��oZ[t��U������Sl]SW+rC�A�����!\��N������Z�X9�����e�C�A���XB��L���:�K��Or�_�~��o����D�$���_W�|�zo�prG���������#����Z�9�s������>����������1����2�����	���C����Y]�`��f�95�#��4';D@�@5x��A���kR������i�*H��6I7���B�����C�;��jT��f�����`�x���)��Xg��N���}v�%
A@�4�'�?F*h��h�e��f�,4����&��X�4�!���l�+���F�D���%@���~���o*��n^(�	#��s�6��C�t;$G������a<���Zd��B�����$z�hG����3�����3�2!YL}X�!]p�����E'"�
���(���[�����������1�����O�I=�mz��K������8%�:�]a�V/�����:�3� _��$G�{��/�	�� ��w�q����}��\-�3EHv�a�pp�hi`S�	���DP�d$�D @�^���B?����}�������3�D��T�%�{j�o>B���0����w�S�8�m����������xN�A�IOh�����Q_���Q���������j9y� �{�����W��7��k�=���h�$-�����$����%���%��p��=��QUUQ|OQ�[Dm���$�A���!����1N��@���yy5�9phCh��M������{$��`I����=����p��P#���]��m0b��������0<�@=�H����("P�-)"���?�N���d��������=3��'o��c_�r6�,�2Er�mKie��dM�������2�>R	��F����|�[�}��[���>>�9���o�{��x�0�?"��\
�d���?)q'�:jB�8�J�+���F������B��x�����u� 
!��'��S���A���T�D�]���i�{�9��*��I	y���A�j2'����.��A�U.��~���|���(X��*Q*���C�C���;��@hww��a�&����uv'�_�\$�l��Yb7��1����R$G^�H�B�B�z5[�W�WaB�kV��C\aF��CB��J���Z
�"e�Yc ��m#$��!$���u�2&�
A���8��f����&fd����i�X��O�8{�.��
Z6:����i��h��2A�&�KeQ��f���!�N�F�D�7r��IcMm3J$��.��R%�������^��|�<�T\$aH�����>�'�8y�'�Mu'�!�H���RD==6�����d�l����	�B��#2�5�C� ��!J
���p�`$�M����&LHX�@���n���fW�q�9,�D�<.R|�d�l2���q�������}���Hx����;���Q,�T�d�*��r��oYY9a����6r���ry�����0X�l�= !�]e�TX�?���~������8;�'��a!��{�W�C�U��@�����1
J8G����@��(k����R!��Bc��������>BT�*H���a��=�Ov�v�'~�U��1L�
�*(����#@J��cUi�����mI[EU%k)cT%�&����j���V��Qk4
!U)B��U
Y���
��IC��!���@������$��LD��0�"�HH�#2�$�
HL�(��1 �����%
� +B�KJRD��0H�$��4�;/�v�M_��VO����b-!\��"�`��CR`�P���C-3	���������7����y>���&���IEH_:��|��fD�KK����J�J�W�d�������[���N��d�-$$��
��$!���M��(8�9��eL!&
�������$;>�j��s���6��>�X{||����;�P�������M*�D:IG��	��D�����P��I{���4�rHA!%����Y��Y��84��EH�B����@���
Egf"��~j$��_q�C���S��zMO�l��x���A���)���!4�e��Z��}�����	E�F����]@��?9�0�#���LD��@�����@NU�O��9�*��K�dp���7���$��,}]������A���'�;��'lR���fH�*$���3������8����+��CH��X\*v�%�;qd�BM\�B�_q����#��zFB���'�(}�!�,"��B���
G��Aa�����Qf��l���P���'���������;$��>����*����5+�Ob:�����}"G_{l�d��j�|"e�	#&R�<4�D�����T���5E�S2G��A�=i��I1��RAV$���Az�����4��X�`�����,�_6a	���_/�?��O	��wnT)�`���v��hy8z�fdMB�c�k��;#�Oc�2�+�- ym�n�>�<o��o�*4�?"��D�b�;T��Y�S�a
 f�G��M��j7
��6(<a��f��#a�_m����}��C5�VH��  ����8�&���<�9,NJ�"
�{{p�Sx��M��4wr7
��AC)O�)��F���4����f#�qo~Zt�F�Pp����5�2�9q�$���:8�	C����pM�B;����-�i��x�zU�9��k�A�mKIh*�O5yQ�����j�l��&���7�d�JN����$�!v�A
td:�`��yP6��8He�.1d���|����$>���i��Z�f���������*Ory���t�n�)�33)��1�w
2�031��+��n�1e5�|�D�!�p	�+9O:I������Y��C�0?��~��"�{QO��;;�(���������7�q
b� M�����4hQE&�U�����)���0SHdd�����P�x����R�'pY��A�"a4�4�+���������0SX"K�dC�D����.�(	���l4	�0L��R4nE�ED5}�LY3"YC������PnAo)xXu	I�|�|�g�kX�[,3��h@��tMw��d�Q_�Y"C+ow�wSr�q��iJ\�p����@��t}���(�0=P����1fkZ7�RCO,-s�=�$r�\�Jo"uM����]�P����f_�d�0�y�B��22�	��*�! "P�AD2$�z�G��'�u���8kJm#+�$��62?�sG�q�b�Qt�����Y��������%��G)_��C����5�;����IY`�6��>
���ge����}���$�,��|���b{�9�VCI�3��m�5k5����+ )(D>�	�c���i����J�����7&m%W�CmEZ�m�H��2���[����RRS7]�FU�MX�j ,Y\UHRH�1���D#�"C1��
BBR,p�B��qT�prEqL�F?�E
���QP�*;E�E-l�M�X��',�����(�2yn��[z�3_2���nHqigtX{�!��~J��R��<�fx�_y�S`�����>�'*;�����Y���?dW��)����l� ����o�r�*@�����6�&g���`�.f/�Z�X�x
)@�!��"��;G?tObg����'0Z�D�n�zs��oZ�6r��S�y��1s�'*�[cXYp?R��\�v!�&H�&$�I>^�?C�VC
�� �51�T����+1W���;Q;�����v��,R�"�Qo��O�d��3MP?��b��#R~RW�H�u���"
��*?��O���'����H�!�����*��{���/��L�|
�"&��7�5��j�{}����D��<�Z":$qD%�@��2.D*@�F��e�)�RaJ��D��@�nb�y;�d��	*�@`����ST�P ��DS���H�����
�&@Lk!�X"���	lR"ef�j�����K��l-@�����Q �Y3���S�H9n�J���6&��D@�c��)@��Qa���z�Qa���G��!�z���,��b�MLH�z�q`BI\�^K�Affc&���������6���<�5�TTC�&�H~���~���~!����i���G��U	��t>�FY�
�B����kT�d�#D��;�lo�{b(�$lH�P�Z%������ZN�(mhB�]�Z#[v � K�z���2$��`[�o_l����:��T�chh�y����hyeM�����! VF�6�F�� 4d��&Di*#<2I5��BL�D��&�}������i��2���WHV����l�(�buz�+#�J��������jO>J����� ����sxQ��R�_�A:�g�#��!l�A���25c�Y5i���$��dU������z��#�;�{�o��W�3OTn�i��v�9"Y*R�(����-����J�wb>a�h
���X�jw��$8 64�|����IM��������B/���4?���m

_;r��<�/�_I
������D;�Ts���n�����~��O����Xci*\j=�#��6�j����v��a�]=;����&O� g����$8�3G��E
BE'n8�4�N��� >sf���lv��0z�}������������C�xwG��C���9� ��!P2�b'_X���������H�vcb��.����y�$�T@?�w��(�������2�fL�:����c?������'� B6���� �>;2=BcG>��$tMU�Nt'���$�UI B�8��g�o������1=�b8SC�@H��~\�@��S�h�P�!�ZTATqk/�.-
Zy��x���Mx(�$@�	�&e	����m������)��%*� 6��Tj6�lmM�J0J	LI)J�P�IK4��a(H����eE \�m*m-tE�����R��UuP@�J0J��	Bi%6$��%	���)"b,)�J��a��C
a,B��S���n��j�WZ��H
T��4&��J$�d��	BbM+v��U��������Y� �e$�5	�J�u���V��T�`��J]U*���	��+n����V�1�Be�Mmu������h�)N����h�\���h8���)�J �@D6*e�2K��CVc�8QD9�����M.�b��jhs9��������nDP��	)��A\i������_G�gq�h����7�J~"��)
	�����4�jO����9���)�#1�����I(m �*1
�C��TL�~����L����H�|!3�cO/����E��[��������-'�n7��PH8L?M��P���������Efjb���E?p�J�1#!H���t�Q]�U}n���J�bi���� ��:SOg�y����=ts�FM��B'���nl������V:����%��{��$�U��M=��ie��h8���6p������|��:$�A��b)0�`�T�6�7+��L�����8H)�A
Sn�kf��"w`84q������L
P�Yx�s	LR)�6����c���R�p����d�\��J�a�^��K��W��kt��k��Hi���.�l����Ko���������b�,��l,��`\�2�m��k|-0[��������i�ZS��cp�����������k���<.�6���o�f��6���j��6 84���v������d����f���*4�Y$�.��Yhm���f�tk�pAvF���!w5�*�(Y��"X�-8���G&�VE��u
&5`��!����2N�Cz�����!l]6���j�$wDq	��!%X	TCI��A�(:���y6�Hr��BCi��A�"m	H2�U���������`,������f(U9�
%� �R�A���MJa��� far���FRd�X7��1�O�i�7y�M�����d����*-E��F�dg�sY�
�G������&�=g�	A[���(Z�}=x��~�D��Oi�������x�sO�nB$�I��Z�����E ���T�^�����������"RD"�������#1
����C��h
�������({@�RR!c~�s�7����������=��K%L>���}�����&':���r�$����BB7�9\�u	��B��-�>I$$��UL�	KL>&`�A�\24f��v�������l"�!(A���M*�6M&eS"���Hf���,��d�#��������;v�C������!�D?0W�Q�"�r9���4�G{�FX�"#l��.��z�"b%A�b0;�dP�.�FCl��B	�F��!BG$1��	0�KA-L�$�*z��M��I�-XDKQ���
I�{I����dmM�����$���Y��ea���<g�vq`�z/�b:��"[�@��z�$�����~�L��.��V����9�$�}�m@EP���=�^�"���(S���M]-��RH��m�Za
P�L!��f�-��s4n7�*[$'d�W����$�����o&�p��EB,l�1���JR
H8�#��a�Y����TQ�fU��h��9JB����9��V�����G��-X�+��S*����xu���8h�����1	�$l�HB@g|m?�<���
wx�����~"K�6b>���IQT�@�Q{�E�dHI0�#`�
	E1�(�pwA��[f%�S5@Q�bl"����h�a�N�,�H��
m���G�x�����{�1Fu��3���o
FI�ex�j����(�(�$���<��;���Y��0Z�fn�z�3X
$�ee��U�;O-�0�����}f��
DAs4C���~�\�OReV�����~'������\cKb
�Q����9�����
��X���Dc0�(e��\*�YH�F10L��0�I���H��I� V0���%���U$���V\�)2��y��������?Y�,>�7��s������I�gV�H��-iH\a^��D�_c���^�M���7L�>n����"G�j=�/�q�2y�Inm���k����&u��!Q��.$VC�(���R�"H�����8d�
<��� �f��d���Q��`({m�KO?2����B�$�F�\����9�h��NQ�f����FNnJ<��������|g��&N��J��c$�'��7Y�����w�)�V)�o{aCi&o�5"����i���3# ���&������Fki���zdM�IQ+b��p����G?6_�����p:
@0) )R�&��	LD����D(�f^3�A�d�2��v�x6���a���]�h���B�FrY�j�3I���G�����^H��
�#�{v�DG������n�z���N�!���2~j�}��Q;�Dt;s��i�������hi7IA`?2ED��I��Z5Orj���g��-����}I�z5����m�>J��7�^�Zz����8W%��[|��x�zF�I���
��@M�[���B�i�����+vvBa��ss����M�w
O����P9���%k :LQ�	������������U�m!B*�P�^���y=�:.����5h@��w,~��
��K'�y��{K����( >K��C��#�]u;f�_	n����.��������@��l$""z}���g4���BUN�P���?M�Q�������	H��~('���	!�pP�N��@xO4��}D6�?���D�Y��c���x~n�	��hUQ�����PQU��3���O�CO�@���w�����=�zjHU{��O�X�Q4�$�}E��Q��We�O���"�R,����zV��a�RM���?�l�:�suy?;M�n��x�Ra���ku_�����A���N��c���y�$<_\{6������[d����UK��!rA$��{��i��@4.�$���p����:���F�+f��I��qfMu�Rl��E�u6��M�������"6`�a����@7W��|Xby@4�'D����S?ZC�		���Z1{68����	��� ��c� �
��P�V�l��k6��&",�I��5�>������ hU^%B�a��R[�����Ay��c�D;��=}����5c��N6�)�����Ok��
����	;I��<��^��yHG����D2l���MN�\
Db`�&'�`�&���H�'���
"&R�&Q�=�sB����I���IF�`��{�)��wD�_���B3�����>G���_<���B�����M�T�����'ve�6�ON�t�����b�(%�����e���������=�D3Hs�4�[.��m:T����\=1��h���J��J�T�SZ�����B�|�"Ij����y��tB���IC`�0J$`zA�8_S�z_s�s��_��j���r?������'`/��Z:x��:~��u���^������v�4��4hS4��J+/7-����08�6�*�u�w��u�@`���[j��j�q2���f��,�����}��y�7���;9���A)�J]�y��+�;�D�I�	<I��v�$LI�����q�I�f6D�a�]���{W{|V�i����*|T$F�Y*�j2������N��MB��s�4���g2p�1����T^��W.�E�^����F5 �TPH"��ZW;|�%t$B ��W��u���G�D�i�W
�k�R�^%�XL�+�B�����!���3��rc"#�a�D�����T3�DB�+H���"�"��oHR0�����Bk$'���,%?�!��7�je����
����.T�%�� �UV�\;y����8��,�$�A8"���%$��#m�]�mX��z,���CY���4��	%8`0�Y�Jzn��]�)kYQD�a�|9R���2�AK����"��N �I�@w6��/��~����N�^��� 5�"����G�4��i���G�^�qp�����v!����L�U}(�!�u�^��f<+����#K,���Q���Z�(�-g�as""�n�s-iM�u�!�9�����.������%�+X�������E�A�00H����=^���29Q��)p��& �4d�S��	�q�\�����[@�&�)&��/�i0!/n� &�@�G��	N0���B�hDN�(�l���"����:bc���l�F����@u�H�@�B�
�+��������$ ��V���Ce�Y�R��.�A�e)s3!�m0TE��\�!g��������-cs,Yl�C��\������_��j���N�K-k����������^�R<i��BYL�&+�6��2%�Mu�|!���{y���o�bTCi$/�-�MJ���h��J��<��Y�x"Gy�
���I�!�Q*[mQ4��@�N���*�bh�8���4�c�JV��Z��2��jV�JSbSY[-R���M�����FE|��L�Z�kw�ad0��H�L���v��1�LI����7qh)�
s���N��]�����GN:�"y*V�^��Q`���M��+�n�����!�f$,�IB�u�RGz*$�X��J0��C�;��	>yYdS3a�cB"��
�;0��8�h��5h|��ZT��
�9���vYJ�D%��/���.�X��`D	����b���W(���������b�&�$uK����4���1�<m��I��F�6��}��F�HX�����'���?`���������&'^��?VI7�����ld��BF�6��L������4>�d����|���?�9������$��@�
��?����#�)�{Th�0'���P�xPMJ��(
2�:�f_Vki���~�p�����
�I�0��tG�}�G���_g��"f��W������-��5�^������LEh$I��*�v�%��[�)��������r�]�M���������)VF&f*��:- &�r���5u�mnUu���Q��V���x��,1��1U$8U�t����T�q���A�,`����B`f�.�&�=9��zu���B������QX~K����d�%�(RFM�K�����A{��
�	R��Pe�JHb����;a2�	A����n�B����&h�k5J��U"W�<��n�~�3j�!}�=��pI����
!�9���$���aq��2v�@�h��di)�Q��������~ys������&S(�[=I�,�l�M+Z[J�	�E��%�����@�������0G�se����O��qp�~��@���1�6���	 
����
>'���&�_��)$7 �=Q��r<�E��f��4^�I<�&�a�B�9�����5�Fg����{�
EC�d�H��G�XBaX��`����O	N�Pw)�������<$��������\�	����=z7�K��$mek������V}wSD�(z��n��k_��*������3x|1�|�y�����j��H�}�}�_�W��*���������*�ID��2���%� W���������;��4kg�� ���;�ZS�!���Ow�#�AIQJ��
`d�D��A52f(:;���J�gy�Jy�(x(d�vz*n�����A5�2g�*�(�����B	��~�
vJ
L��(�!��;�{*��@� �2���BH��T�7���!������5L$�0�N_?L(��c�I?�-w����X�����k22��E#*��$����
5�Y�6����V�A&I�(ij�v\unSVI��KK*fY~��4��,.
B2(��k��H��_:���_I�������S�K��uu�b�s��R�O>j���H&]�7*Rgw���{PW(IO����~?������\B���V ��&��O�tq��\&�%C�x�Y0��	�d��=���Y�?�L&*A��"/���wG��S��L�D(1}.#Vc�m�-R��n�))I04D�ca�gIdF�~&�5[#P��)�����iC��q���Xb#?���*-[R�_K	��!�rt��R�H����I�V��B�F�����C������RG�8��?�2T$
A �"�!B(I.EJQ$l���0��Q $S���FSf�4��U��!�IEL�Qi@	G���#H���	=A�#{��w�O������d���1��H����w�k��C��2�1: G�3��"���1�A�|D�P�fE��!*5����}
9�[R�a
? yI� I�d`(OS�2!
[Q��y�%����]0���tE0��J?`ae���#%�#&NQYBqs�����K&�����f[;3���n����z�O���6I���b(��������?�n�O&����
P�=����dyR��)*B>��4�<3Q������	x�����O]��v��P��V����-��r�C���
��k�z�
{/p��0��-v�A$f]���Y#apH%�C!v�pQ�.Dh$����C�O���6+���I��"r<�z�yG1����NZH�\��(�6����
,*ZR@� �%r0%���L��LJ���"���'~G���4�������s{�[�e�c3���XP�C���E.s��h����1��
�|�M���t��hP�2��
f���t�������	VHu�����(x�:�`�.V�T���
�9���.�`�1AY&SY�`|���_�x0�����������`���=>u|�I�`=�
P}>����luD�u�TY�����P��D6L���=�z�|@��2��w m�]�=�x���$D��Y`������}�
��;��S�l��4��}�=�
 ���s���W4Uw����n�B�{��9���}�}�U�`�R@;'WO\@R�wi4�$��L�p�&�q��oOC�
���
;5lw[g�	E������
�uE

�CT
(QEP	(��� �XC@z
:�	H(
�QMm�j���@C}��5@�H���)�	�I�h$zj��!��A���1�	LBT!5z�F����I��$�OTz�i�����$�JD)��o)=����
4i��R�CP�OMFQ��=G�m@@��@h����4��LS��)�z����)�mM
������(�����R���f
}]F5�$�j�L1�u��>����~#�O�~��^��<���^c�<���^c�<���^c�=	�07?��Iu;�D�D�I$4#J{	�C��O���������di�f���bT8*�9�D�
'3Q�����	P��;�>��*;�q& ��c�6&�. , ���"{I�8� 8b}�%��� ����g�@A#�\P1�>��������~fc���;���n���S�~���T�T�0����6��b����+���(�\a�k��hP�bI�0C�&I��#�?�V<� ���rA�� 7��Lv��f`������3E�r��c��+}���W�c�=;�J���!	���$�I$�C���z�^����{�=<������������/����XsQl�d6�e�-�ih���+L�B[����Np���1����U���N�^Qi�4�����?�-,T���,.��H���+�I�&Y	JUZ��W��h%��vR_���p]�V:�[���Iq~;
���H���Pi�yM����k����i�g�(�30�%	~?s�����cQ$��g%w��Ija`�I$�A+��H9�Mtg���!<�?Z�z�����C��q�>����ld��~
��;aVg`�P�T�����8:C�����1���h�A�F
����XM0�gg� "$*�Ze�k���L(9_
��8��S���?h�2��7�x������[��U��h���P����c\!Z�^�h$��s]�F�<�"�+8J� ,)v76�D��
\V����|
��YN	�b�����/�)
�:�����|����j���w����vc��c��8rrp�������|�{���_�^#���m�L��'����t���9i%�"���S��w�K��������@�����[S%���Q+�O�_>^����L,!N�P��^�
2�J��z�v��)��7���F�J OS���k	B���u�aT����a2�Bi��������_��/"&U�h���a����]��{_'[���r*��Q�����<r��Dc�@8�Z�B#B*��g�V����x�N�"���=���!���lL007��b�*��f��T!:�
��r��!�H��}o�K;Y�uM�pn[��Ak2��,����a�!��C���O��J��C,����.�hQu?z��f=��rN$�!�����j�������E�$IF���2�|�HWQ?<��]K�!�����>�o�P�+j�h^%i��$�i�4�������>d+�
FQF2�ZI��V�:tg�!�>�7�z�f3��&��|�$�$��Us�
f�����n�%y��e��
�&�"�$��\lp��<l0��}��e��t���)�P��#HhhJ�i$������O�7Ct��.�N��	�����M}�O>5�^�e�,�ib.����(��������o9���O��q��W��IHT�:t���0V�M7���*���jHBR+�E	�S���f����4����F ��(e*���&��|������������'���R)���fI%��L,��$�a���&�Vo��+p�R�����,�D��& r��}��}O��5�%�a�N��|�F�������I,(%U� �n��4�N�o�$�Hp�����)r�,_�}�--xhK�6��e�jQr��L8���P�5�(��pTX��%����m�BX*i��V��'8��\J���I4���x�W����-|\Y������Q!$�O��f�\*�Qa���1�� �,&P"�%ED��nU�H�7�(��D.U��Uw���W�hR��N�IJ*�Vj�e	]:�%*�� ?��UH��^��0`�y%V^���"E��I6+�or�
m &��mC!��d2��1F1��`���k`0Fm&�6�M6i��&T�SJ�JSM*R��a�[M��,c����^����]�������$�cij�@$���f-��@N���w���IJ$����	3�8`�H:�j���������i1<�t�z������q�bX�b��K,X�c���H�e�:�Y����F�jQ~]�t��z�5&Q�f���6Z�B>��y1�JaO��0L��@�30&x�����5P��1����1�;����{�w�1.���7����p�c���N�q���;��U��~@�"�U"�#�j_��{����R��<U^���9Z����C$-PvCAj���**������:�� ,f"��������+��`�UO��@%�J�aS��Kd`Z�TZ���z�
����Q�c������L�4Qv�z�u:�����]W	�u�����<BE�@ij
DpT
Adf1�EZ�#iW�����m�#V��UU��1 ����Q�k ���'P"���<X�;����xQ�����n��rl�:��d,�%���DV��&3������8�r
6�O�n����*�q���[��������Z�������W�u�$'{���1n������_���?w�}/G��+�K���z���I��K�����I&B%f�9�Q&D���#�����>�_�G����_�k�k��
CG�����o�U|�����,�DY2l�$��d�b)f�d�`��fiI)%����J���ZJRK%��I,�K%������GF�����f�2`4�X����kf�c7�p�TvKN�x�9i;�8�Z���.�.kTfGM����9��L����2�t�U�:?hA�;��T�'���tX��e���.^w��i&��8�&�Wfh�*�[kWY�����|�@�}z���
(�]����{g%GF��� ��ll@	��Er`�-����������E��wN	���Lt�Me�Cs�i���S�����R�[���t���[����������/J���Y�H�X�Vl�b2S�v���Ki
��%-��o�97C�k��spe\
�kp�p���3[���^v�QQT%e�����L�G+���`�H���j�4���/�Y�.��bf�n��d�o�����m���~���.�*9 �'e���uG�����Jq�f�4,��k"�`�L����6�!�R�$��H���U�O�������/EN���������I�����>�|e�J�������l����	���prTk8�=rAC�:!?RY�x�Tp.|�u�8RHp�b����s��>���T�l��%,I,�J�H��I4�$�S$�K%I&�Jd�*J�����31��fY���*'u�Ve��Q�r&��k7��
vioV��h���4"�D4KK�\1��6���26U&�dL�V�H1R�v��,����S�������>E;|*><+�-�r�dt1���u&�d����:aZ��jp�}��TgC���"��]]��]����pp�t�#X�
�\Nk`��Kk�J5��2��]���I�s�t�L9*Yqv����N �&�9���{�?�d���#��R{��>��������8���lk��S��,r���tj���lq{N���i�M@��w�
��]1S���0�.�[J���k��c���t�^��E��KIb�+D�M�/&%����p�y]S�����W9��~��j_���"�"�0W�k9 .�|e�3�U�%6�Z��s\�������v^�v��=�m���@vu
�u������kuR�o��u&z�0� �3l�������i����)���(������x�P�O�}���oa�]T5^zje���\��2�t^���"��N
}OS�y���9*�V�ut�c����y;���s�U��F�v����<|T/We��'����M\�meJ�+}�P ��������6��|E��4�`�c	���������^Q��W�����p��u5nP�����������|s���7�H�������>�����A�fd�@�����f�riB�_}�������������8���������c�;y������O~�?�?�vt��?�������u�R��e��lZ1"#���_o�4��4�v^��^
]
�_��~���o��j���kj50�*dl���%�d��2L��Ke��U������I!cd�2���F�����DTAj1Z���v�������d���?��<36��^��M�����]�s��$I'��������J:���I4�L[��K��v���X���8�nG!�6��y��&��.�gxE'���[�����"Im�]����	�]�$����\rN�X�zC3������d�F������^��i��lI-I���$p���������%�x�8����B6��g_���[��&`*Y.B}^��y.B}^����!-~��K�lv���I�V�I<Lr99�������=m������{���s����F�zB��!�#�m��I�{M�i��s/}]���$.���#�=���d�%]�u��IH������v��G7�#�F�$r���w���i���vw�RzI%�.�~4�T��!MI*����\n#$�]���$B���d��m3n	����Q&�bd��;IM�����d�7A�b��SM!!��:chIs�d�[�����{����%����/���-.K�������(�n�x9yU��Lr7�T�Q��6�o����e���-����*��Ght�
�uE�+���������������&��1���2���z���!z���x�8���*���*�rF���j�y�U�w)�2�&�
����q�j�I*�Q������|z����iFM�F*)����U��Ur�^:����']U�9z������y-���Y���S6D�1E�%�d����o����}��V�kl��.��v�����<x��2��y��>������k)�K�����';��M���  q�Eh*�Z+�t`r�����$EVM9�����}+�Sz������������yys���cv�������?RU��/�����52-T�[E�j6�SQ�U)6Z��Uj��F��b�J�d�,iQF��2,hb�TSY�M�6�m+%�3ZII��Y �V4��S
�Va1�Z4�I�M��������C$��������D*�(�-5����E���������Q������������]������nK4��U��������ys�{�d��G/��m6�Uo!!�2a�n
�VP���F�nI$�F��6��IrH�2�m�#�BIn�:m�$�*T�#nIm�$�I$�
�Ug!z1�u���8!C�I�M��:�1�zs����
,�
5��������ZP��q�TF�!$�oZ �$D4
�Y�M����!{n�Bn�B;���B7����������q5^��Np�������Z�cci;W&�'amV��m6����Ps8��%]���������M��6-��	�eJi�-B���&�U3�j�I��n+L�v����k���i��f%:��I8���g�oW�����������r��U�-Y��/f����;;�fe�b�{�tY9����x�3���R�� ��84��^B�${��%�c��I#�A9s������	%QFZQ��#Qw	���s���'\L��
�J��Z)�w]w]w]]qF��r�u�WU�DDL�]�G:�Bd�V�*(�TUEU%Q�*TjdhTJ�QUU�VV��J�7q�+� �!QkhQE�)��(��y�u�#�
�!U u��t\����	�u�] q�I�Ydb*+B�*�2����L��/�>y�
��DZ�(�U�(�Z!tD��.�`C���v����N���C������������A
%QD"��B�Q�eUdU�`����Y��~;����0�S�I���� �m��`5h�����L�_�\R��r�OzU�����m�l��j	��N{���]�k��WPwD�[BX�p�7V���K�Z8��:5\���N��y�t�&9� ��f�lo�Cx��)�jN����S�V�[U�=���l�1�lF�[�����O�'vR��H��@t$����~P�nUy�<���d��4�������r�[��T^z;*�$���u����$.1F�	����x��%��w���S5C�C^��X�Ql����[1D�i	�j
	X�RC|p�QW���9�i4�)�L�9����D���/��B��������'78ej���+���TY���<~��9��9�����Lb�*�>F?�'��cg��f�����V�nSjh��s�x�\�	^��u������1>�Z��nO��o������S������{���In~tT����s��G���G&3��RU��?$�9������~�{�{���A���i;�����q��w7��5j�]K����K����%_]/=�@�k2�S*�J��y�Q)������|���Tl�i,��Y�1���)�dm��Rf�F����X�c6eE���bfK�E�T�e�&R�*��YK(%��kYi�51�mJ[$m�"a��)��2�f��N.���
f�[�����6����3�f�h�5ZR5MbE&�QV�KF�U�TV���*�I��-2��J��h�d�%&��F�hR�MPh�)l�Ml2�����Vk�Z�D�d�Ah�%���5d��Q7kz����4���T�Q��BJ���z���7e���{O?��=�VU������,e��S(c0�3�jd��Y1������T=/M��V�1f�3I6��Zd���1��TZ�+323Kj[&j/����z����~��-{���78_/ns?{����	^��s�^���n��K����s������=�+�y�o���<�}��m����{����)����N���oz{��\�:M�q��g����iNf��jwns{���"�9���R�2�I(&��K��c��$��$���!$p�}m�H���[o�K�_|��6w�{��B�q�I���!����!���l�8��F9$JZV�
��9�}�z������/�9~������.�HK=���������HJ�I��-r]�{�A���-�r9~��?ZWw��RI	&.\��y�$��\�t�����w�������'v�Cr[�o���p�tI!z��/�A$�$��bY���.������<��*(I���!��=���9�����,9A���`7"9Up��p�����r��5�s"���A���5D>i+��}������s�d!!3b����&i9)KL!M��;;�r�@U�f���(�����g�k��HY�:��t�r�J��������H���>�s��}?/$�K�,>_�,�O�G-n�_����_���
Xk�^N��m�5�
>Z���J�����wW��_wt�)GV��m����V�6���9�Q�����^�{5��d0�1�t�xGt�w��_������H�1��Z�3{��YQV�wz���4��V�n��>={�u��gn�v�q�w[��%��<���<<�3������\���.���y��zi;�������y�����<x�����\�n������_�2\�$��=�����o7:��.]��^�q��<$�|�W�������5I,q���wn}�t��,Ie�YK,��e�Ye�����t���y��y���b�w>I%JR���4h���Z��I-
R��������-d�*s��Lq�q�rK,��9i��~����_
��c�6��fg�##��>�:V4c�n�>��r�j�\��j�k�+���aEo_[�G]���.-T��vrK�����������k���F���y�tl����2��qe��x��Nj�Nt�zO��o[ 
w�Jx�Wl����r���6P����d��>pl�;y�����,wY83f��6.�]V���(�b���Xie_���e{�����6
pj;�d�-t8�<	t���MW#6((�o=�8
�� \'5s��=��`��7�G��Le_5���/6W��n�DF-�WCC���e���!��.�	�����
.So=�p��y����EP�`,���g ��Ml��������Q�����%DOg��C�*
���R�&'r�ukZwXpi�fLx����Q�����%E�t)���QE*_,�y����5k�����e�ztt�aF���O��>�E��*
��M�az
��3���l���C��L��xz��@>$����:���$*����X�1��e�ew9h��A��n��W��]�6],W�u:�����f��i��d���F���O��<������C!����6l����8�e������y�+6l��;<9:Z���"4e3��OC�7��t@*�h�w�A�aQvpx����N���OL�MVi�5r���fk�c["��|���aF���5�i!��Dj��@
AH�S��N�<&���cd����;n��&�>�8��:x��DQ�9����=�y�������#*(��\��}w�	!�EEEEB�A�l��F�i�|����DX���n������������O*I���E�)^����d��*�	��kb�Q�T�Lkhl&`c#YY&�����Z�xYG&F�Y�����Y
b1�����������f��S�',SY,j5���9�9�e\�� �V�~����io�M�"4��b""2h�4�������K&�E&#��&$�3L��,�(�I�m����I��$���b�T���m��E&��1�&���E4�Dc4RbLQ�I%&"1I$�VSI�e)6�f��3I&�i��DRi1I�D�LQR`�d�h��S$QL�2h��fh����iI�4�$���f(��#iJKl��&�$�4b1i�)4Ri��D�H��I����II��X������7��A^����r�>$K����'�����2������/������g�����hHM�/�&��G�7������%L�*`K.�J��?���#�09U��Z!���\�����1��� Q���
��66�B��`3_eX����9�U�:���M�a���C1I
��L����|�W�����MZ�~���&��I����F�,�LM�2l��2��$��Fd�fKi�����i�R���4m#3L�dL����F!�i�d�Rh�$�I��-�[���_������HJ}�8���GFf�����Q��'8�$�f'�N�H�����s+��s��r.�����6�b�����y�����?I'��]*B_���J\DC0V[6\���D��S���$�-���6I���T0��������������2��}��r�Z��7�����xpv/?����`��=��~}�q��������e���}��p
��7���T*
�B���@{����)��.�=}u/r:�.����p�����mz%�kh�h�I\c2�k�V������G����l�
��������.�|�YdDu��X��j�e����$���{X��gT����h�6�JdEXH[&��Q� ���E,gi��I�\���]l��.��hDv(���(��96M�
X\CJB4163�f�8��lA&��Um5�WT�����DvB5e��d���uf�n���;K�";���0�5�Dh��Q�����ki�$'FL�VS-�����G����I>a���T����O�����VO���~[m��b�V�Tg����ww�����7F�t3�\^>q��b�f3�^i�3y��>��e.�t�1�$IH2����@��<�g;J�632�����-H�w�_���Oa���?7��������A�<�'��yG�y��b\�Cx1��Df�Qt/�W�����r������]���}������+����{�_e$�]����~�?_w�}G������u�����g����lU���l`��6�������a+�����I[;���/a%�w*�28rW,�j������k����z?��o��71��� �	�	r]��?o����QI��W��������f�i��{��I���	��Mr�u>��"�������?goq�mo�O���_,�k�m������^s�7��������'z����9Yc/:������g�j�f����?�\v�36y���n_��������<~���<�}��q���<�~}���S�|/'�y��e����j�G��jb����O�����R�~�
�H�TL��5J��M��U�R�a�&a&��q�ilEo��(sPfJ�k��E��G���yy~GR_r��������;���}�_���������[=�*������f���`0��umK��0�����ffkYe���/�}H���(�=?�x���s��6l���R���?�=GU1�[mR�6�3�M���*f�il�j�6��2.jd3"������q����rE��E���dLDFav6��T.�q��#��?�����31
�nRUh.����w�{�37]Mf���L����]��jN����\H��b'4�h����
�%�P�Q����c`����FM���~�S�<�?�M������N����f�\u�]�*6Q2
�me�JD&"^��*���me��*��|��d�D\���)H��4����,��E;����v��N�.�P���[.73s��a�M,����b�k����1��	\��n���B�QY6D��z��z��L|1�b�lt����[Z��f���V�(�~��J,�=\�T�U@�Mv�	����������w�o�*�l#�T�h�#�m�m�^wc
��.
*4MF�@��L�C�'��k�?�
x���qk��������LFHM��I,�F��H�	*i*&EJJ%"d%e$��b2�*JKM,�R�SI#d��-I2H���5%%�Y)�l�H�)RZ�U!X�]U��A��W��J�
%���r�f�juY��i���2)��1�;`��Q�F��W����6���!�hDUqK������5�gg��9��}WlW{R��/<n��%;�}� ��z�2Q���r�F�����RL��z��HCz�c'��z�������,����,p#�J�r-z����<c�.-��D�zxN���wD�m��l8��j�h���Q�z=���  �
����N�q\V���
���i#'$�d�I��
+��AX����[__�FM�h�c�m������"���h"(�m�+&��b
��F�b�����eW��v����I��^=�fc3% 
�je���$��(Ii
m}���[V�[C1�8m����Iii$�,��1�mi6�vg��W����;�-v�����]����Z[,�,�2���H���������-m3,��<8�:���W��f�~�]��0EM!��6�v�jj�a&i�I�����ff�e�5<�lm\��������u��U��f�I5KL�J2M�F���	$�Q� }]u���������1$�m6�JL�6���i�$f�6K&Y��������-��Le*�cQd)����V��JBBKKL�	��4���afm>������_7���f�h����]���:a���q�2�18\a�;�x7qE��o2*M����-$���l�MI2"�%z�I:g�/<�����������|s@���t���-�y��UW���}�9\�j9}����e��(�*������z�<��o^��
��.�=	�,��J�
�v]*TR��<���$[W���{r��;M��6yt����J��*��WWH��4]��'D`���.��:��V�PP�k�pJ��Xa�����DG��CHG�+�E�~�~���\��.����[���mr"�F;8�#�
�{���d��O�qA"������]���\3��eEP����r���{Bq$���B�QR���x+�=����?�o�{�������E���i�I�m,�"�$iH$R�*k$!����]4��8+KJSb��6�����n8�:���kk-N[Z��X3��)[m��Z���E�5E��[�U��II$��ZI�l�&�&��d���~f���)&�6��($��R��0��$d��J[`�U]Rq�&Td�)6E��M�`Z�i�HM�#3���[m�|�}��U�8�sl�����`�U��	jl�5o.�:f3+31�iU6�cf��#�a�[R3e���0�m4��M���h���66?�����e��]�A�Dx<x4&@q6
v�Sn���!V�B	L�"D$I $I!$��7��d�u���+����GM�����������"yB=v�<]D��^�"����Up3��1��-r�5S(��xi/+������_I�8I�m>{�!�n��m��^��|����t:��m
���d����SH�P�	��L�fi�i���i�dRb0&M�f�I&fe{���lV���b��=op�-����Il�[�����y+�;\�����1�����$�$�$�I$�����		\�����[��t$���+���������Rf��,�������j~z�y�U��s����"����9���85�UQ���B;����oVv�����y�a$du+���n;����g�0��������9s�th����������q�;�&xesw��hx�����
��66�?��*'7�rm��8#�:Hx���9�2xUXSx$8��'�Cn�#�g������XG�r=^�>����+�!�b��Uo��c�dp����v�����������]3�'A�����'Z������"�F#DQKn��'p��<�Cp��#��\�$��H$�JD����p�I$�JI$��<��\����r�K���=����u�m�'ht�T�L"�&�DV��;7Ns��8�2Ouej�a��ZQ=tP^+������v�Z��������g�S
b"
�s�5k|+��4QF�(��+���e�t��� ���oo*k�;x��HI4�24W�Nw�A��O" �u�BQU0������V��28���(zO������8�������:�m�8p����a�����q���v����&���YF*d�"J�(��T,l��6��I��u*g�����������E\&r.��k�����h��
9w$B-�D�&�K<y�W�wT��
�AL��'8��Qp���R����xwqE��X���x#�\,������z���Kct�z�]�1����F��V�k�0`8����Y5���^�QIYJ�u��K)I$��*�0��A�9����9}z����*�2���
�H(�*�r�D�9�WQ��v����c���8�
��'����$���nb�y]����{������gn5�r�]������W��O$���W}���KdJ�6KI�����-Zl�hP�-RU�h�R�i/&�r�K������Zdq��]26Gd�Vq��"l�~w��W�<�G��{�����;���[����-4�[��tpS��4������E\&r/UP#���.�i��T��t���pdj�s���K�R�U��yV�vK�����s��@��9��������;��U1��G#�u\�����ww������9�	���U�{�/
Rx�2Tg���Ew�9��9�{OiGim�U�����x�EQ��(���z�2�f�AW�����4���{�W�u�|W��o~���_�I.q!y���{���
(�`����Cp�Sc��������k��^W��:,�gQ-u�S&� 	 ����o*��;tE�����������Hz����D8�,"����bT���;kk��Z��j��y��������H�����)�V�,�y�7����EAAA$T�����FTB��;��j�m�RE1�T�E[������C�0b�#a||���R��DRT�@�j��NM���t�k�p�Q�k��oRFIt��4I�f��mn��j����]MZI$�f�$�6�IT��%4�I%�9�����9\�(()�h�{�����������m���k���o���J��E�~������)l�%i-&�h���������j
�������Q������j*Ll�*1_:�[���+m�|Q���aU�)�E%��(�g6cQ#?+L"�[�)�������~��?C��~���M�1q��3Q�9g��]Zi�d�f�JR�;,�n���]���������2������<I]%u��.��Qr�`t��o=n��/"��n.2�\�6<c�9RQ���S�rI$��I$�J@-���L���n��&L�6]n�2fH�n9�I(��-E-���������/v��L��U~H�����N�M�H��-��i$���wc����z��t��~���$�x:u��zC���c���)UU}����a
K2V��
���T%a�,B��]���m�v�	vW��~|7��A����O�-{p��N'2�Ya�L�e��Y1eb����L�2b���F�L�ZX�'�L�4_������~J�]��������_�7ri�m/=+��K��t�����.�j������cp�)��$���J*M�=���<UC%a���>�*|�BB�k���aw�L��f�1�p��F����0ZfA�FL:��l��wzYq�n����&u�i��463t�������8T�W�Ut4TMI����A������8p�w��p�[�d�L�7��g�
IM�v�B�Vf`Y�m���^��\�*�Yw�`�@�UUKa)�0�@�C��Q�a�b�;[L�H�H�V���vPZ��;}����U�0�Ww��;D2��U
�t������4�C�u*Bn�033!P�T+;��u�	��9Dpz)�*>��qn���a7�����B�A��J��M�;YhT�I�FK�J���JR/n���y��`�0�::����	��C�C�BDB$	����:�A��a,�d�!�2 �!�b�D!e�0�@X�)���M;N&�i1I.�J�-�v��56��I)��w�v�!'���e/_W�L�	"P�q�!���' ��q�����^dV���kgg����TT��A�(\m���wn�B�����Y\<����e��^�v^#;^��JGheC����c,����d�����m�c,P�!!h�1����:B6C����i�kd��v� pA�,c�c�lxBJ,c�BS�B����A��f�J�+�������{�������1�k(��k�����n�[N��y����w$�����wn�s���-]���<��1fs�����v<�;KNk���\��j��������v�Y����������������y������������������s�>�{���9�y�{���g;��us7�\���y���o7�v���7���u���s�z��__y���|��uw�Y��k[2���xsv��31�nl�w-�w/7/��z���}��$�^���XM����r��Ms^�m��f������d����x�1������:y�����
��`��B:�-���v9��sZi�Q������Gq�y��x��|}��fn9yt��]�Y����Jp��!�+�U�b���e������O2��we�[�3c���|�k�QY�#���Z����w[Wk8L�?b��h�������r��L�K��������#��,�ax����r��k����5oyyb�9S�Y�xY���~���������^+��Yw<��z��q[����=1�����Ps���l��qt��]���j���n�]���&L{�e��9){8��������R	���a��|�-j��m�1�r%����3Y��J���X�(�y��'��$�e��z�5�qAs;z,{����������W�*���������p{�L�
����$��K��JI.�(��2n�@�S����f�eV�b�]|�������v�q�B:F6:����e��]�.��E�b������udlb�w$�%�%e�bi��L��vn�cuq2�vZ�[��r�3�:v�7�����\�T�dc���,�$��k�3t�I�lt���
�+���Uv�x�,��fe����F��0�v1������E�U*>�2>:v8g�8��y!�&"�r���s333$����Y����kR��TQ���n����jd�.[���^Zy���vIcvL�N�������
}��^b�8�Iwy7uG��v^��%��W�q���2��"*t����^��5��Z(�Z�l1SCU���k(Z^]�F�j�*�\���.j� �f`�A���u��Tn�-�s9���(���<\�!��Uy�f�
{J�N���*�T�[�x����;�3�3���F^���yW�v�9�����{+Lb�e:�1���Gg`(�r�%*���J@mV�mU<Z�u�����u5��2���j�G���>=�Nu��{+�^��N'�RTx�{��E���wM^EdP���+�3w�KG_�"������=�+6�WK�hm�!���
��a���(HtbP;h�]��e�����Ut+�{��*<z��������<��u�at�*������A��6*\A+�el�+���g;���g��W��P�=����yzk������<�M,_�^�{�'��kvg�����O���}�l6���a�or��ss���U�7w.���
�Md���\}��~}q�U���/�]���O�?|yU~��}U���U��r�%Ry*���}G�j��HJz��<��d�G�[�8������H�J���tv��_�� �OZ��o��@��z�D����������"�v��b�Q����g�y��}���H<��Q{6�����_�R�uD��E�>�=�j|w���B�_�)�T�����G��wS�G�� �>5{^������U���P��/�]Ic���^�6N��D�:=�x��/=_�������{��������HJnv�?��������ur'�������������z�}s�\9�_hW�+�b��Q0&O^Iu���d�)�Ae+��X��+�Z�M1X����1��	���&5dh�fS�Ym�[K-e1cKM��5Y���0�1Lh��b�k#Fh�0��f�af�������!�U\w ^*G�WX�����;���J�J�E�Q����������cV����j�alfL�M,#5b�h�����*����e1�����������
*Z�-�KlX�M�KA��%���,ZXSM��k��
����Y��,L��Y�&l���2�d�6�lm6��YZ-,a�*ji�X�+0�e-ij�
5�3
����-V�X������VdY��9���.8���50S60qiii+
,Y�6#�Ms[R�7Y�����.Y2dVX��"���G�y#EW�����d�X���W�_I�`��{(�5Ge��)	O�_����|��C(��ca�f,��fX���[(�ZJ*(�Ml�E�L�d���4mK�z�S)
���u�������UTv�����>K��{�oc��_t�� <O�X+���D�H�4��#fh��Lx��I����J���>�K�eI]����R�RU�u}O
�^o�D;��G�Q)�!����OaMe4�3��kB�KV���Z����f��LbYaZ��kD�fS5,��dfT�&�[
j5�fcHkj�I��M%�J�D�#SZ�r���W�������6O5�$�H�.QG�x�g��p�r���p���}�tDW�������p��nLj���QK����\%S�TjI��{�C�^��������)!��R�J��O�����B���S�\G����sQ%y{��������UQ�?_�����(�	N���t���GgQE'wN�U���4^f�U�OD�YW�0�5�������bG�%"��z���Z������Z�x������d2!ZA�$��i��P��a2�9�9�������S�E���
Vff�s�$;��N�#�t��v����"t�\G���:�7G��rV��[U����3L����Sjf����������[U��K���F�icI�kBZ��K1`b�-+�R�����X���j4TfS���
+
�611�6���if�V�������43F�&6�Q��3Q����	��MY�$�kS#�bj���fL%�1�4O�'�A���g��[������<~9�Y6�x2����|��9����>�����_O����m��'|����e�^�O�G�R�%_JG�����F�%���h�1��c$i�e�����L�l�O���&�����V�T��V%B,�#P��Y[_}y�u��4f��������$&�
0�kj4�T����I���f�M�s�IM2���R��l������6m����r�A�U\t��;�8*
����d�U �~��h|?����jBT�%�v�uU�����*���||������61����+A��j4���c�6L�#+Q���j�1MS�fF��(�h��,�e��f�d�j��,af3Y2Y5
�3��)��2���,,�k&0��C+��a��f��e��f��1b��[6LZX�����J&x�#��-y�<&54��I&l%	�i���jI��(����)$�T�F��2m3�11d��{����Gy��K����Z9%��3�^}������_������R��!)��n�q��}-$�?j)���]��4'����G�g�5�����H�{{�{������/p��x"vF0�}������w}iW��u�$���K����|��� :4~<<�F��0����h6I�i�3�����5,d�I�1
)kUcblF��1[VZXM+2Y��&/{��R�������g�~
]�>��r6
}2>'OU��|)O6{�H�^#�;��)~������#���!u*�g��u�b���{B�R�Iv{���:��r{��%���#K�G�����d.��)z���c�<��z;��Q?~�����G�:�p0����1�2ji���1�c��*�cS*�V5a��Z��-�2��fl�-�2��T���Yfl�J�)M��Y��R�+,��4�Y������h�G*�V�V�����EN�4��U��l �A*K������%YN�Y�-��D�5�,��d��&
j��STS�	��i��E�����d>��\W�L�����V��"8������{�wB��e��c�H��mR��Jq5�����_�������5�qC�$kUU�X3��9�w��i��������<�~��������S33�3���4���4��V��z���$>�%y�+��|4X�z�~����|���j�>�����_����^��S����I;�3��m$��KsD��o ���(���P�kB�2
^��T���#���4�������������r�WC�%��'�C�{�$�^T~o��w���I%�(%�^��
��9����SJ�:��K�I��qN������P���U�('y<$EO�~����\R�yxJ���#�}�E�(�����cf3U#6dY����iEfD����V�+d[i)�#1-��VjhY�U�QX��f��)�%�R�V�I*c�=������G'2rR��+�<q�����xR=���K�.��������i��YS���~^�����^�����X��������:�f����nnnnU?1S.l�r�rn'��1�gG���(vR���w��a{*�tN>��>��%��;��.���$�<����w���� ���������y���%�Pq^]���w���w��"*��
�E�}^����^.~�(D��P���<����.�Ty�9��p}F���h+��6L/#�+Y%���CU8*vQt1�)z�����1����Rpd�����>��N�B�����&�*E�x��2�W�~��J��(k�{�<l3Z�j��R-(W�JW�T������e<��{��i���<_rw���h5,���*�A��KvJ�ar���T��N��8���}����9�'t#��
T{IuC������^���IQ��&_[.^�}�_c��ID�J�j���
�w�#Tj�)��d�+R0jYZF#(��Q��L`���)�hY)������d�M)���D�ZS(iU�RdeL����|skcc,���&P2�#+4��*VbL�g��m%fY�H����R9I�N
NI��c`�k&�+���j�1�a�l3��rb�N�H�E����KUu�9��qll-d�e�5#�j�0�r�$��p�1�#%�ib�$Qd��j����*2lMZ&j�.��J6�lD�,�[J�V�KZ�p��-�����I��p�+�F��
�	H���[u�,+�����Y#h�#Y���j�J�f6��"�%��mh������"��+���]���5+P�B�����3�?.��O������(}tE���I����U��t}��+t���=zuK�v9!�*d��#�]	��.U�p��)'{��"�E{�p�w�8#�s����Q^R�RLD���!��E<5P:�8W,�h;�}#�s��`��
��?	>L�.��Cak
5��j�	�-biYf,�2*��*���-�/��)�S�Dx�u�����}I)��v�G��IW�O���O��=`z�����=a�T8��8T���B���U{�q��F
~^3�=�c��'U��<U	:�"6KRe�1�b���)bd-bL�z�-u�.���=��;��xE9A��+b�������T���J��l���m)n��+����S��������n����!s�(/o�+	�$/��*2�]q�]��m��U1�����K��#���n�=��5
>�A�|�ZWs�C����?BU>���$=%x���_\WRRS��dM�+�=�|*|1jP\=�zk�fU�_�_j���kZ��������36�T��)6�2����mJ�fe���&e2�dfY6i�Lf����i�W)	O��T�k����t�H�d��f��>>������{�1w�����+���<
%�E�<k�����R�.�N������;#�A`���%qr������>~n�E���Ao#�8�t�!\��*�!W!�{<��'����.����i ���������/z ��*hA�����,��,��+�e-
�.31�c1�1�2��lW�)/���t{e�zv-Y4�X�VMXd�,��e��Y�-2���2�i�+-Y�2���YX�c-2f1kF�cV��a���X�5i��,�����-i�(g��{�Q$��bT'�P�fH���%B�S+
HJl����D8R�Q��4�N��������h�m�������:< ��Ow�M���:�u��a��0�U
�"�1/'W&�����i��f����A���F�0�R�\�;-�/%H�I���!KB>UJwR�����b�Y�W?�8o�ix�z.�o>2y����t�~�����`�JBZ'j���_�Z�6��5�[T[M���6� �fI��d��a4�MI��a�UmmJ�f���&�j�d���%��f���m{n�/*���ry��J���5Ec3#0L�L�L�X�F)^:�(l�x���]xn?������+����x*��d���
T�V,J���hX�ZA��`����kUc@AM4�FY�fim[ff3��L��\Q<VO����.'��))���<���Dax�::�L�i����B���/��z�����C�f`D��
�2���h���N��������������5�N����^����g�Y�^s�)��������n����O��w9����M�����6�4m/[nN��3=��[��{���t�����{=�B����|����C�y]��}�������}�D}�*���|����Z��Od��w7��z�;���x��zs�������(
��8���^��on�P��w�1���S�F�{��_��I���#�T{%(*���V��Qy����@
_n��m;����%���v�B�p]���H�Y�N����@
j���4�P#�CEP�$f$� tn��+�
��o���h��O@��44�mM3P���d���S$�CJ�j���`�2i���QD�S�<�Jd�hi��h���L�@	=R��)�@L��6�SiLLL�@�
` ))"���<�O)���e?S!?A��5<!�=C#��Q$!@L"h�=d�jdyF@6�������<�����H�a��(����(��SXb�e��Y������r?���WvX��S��J�Lq�_��N����US���1lkR��6:���1a���Z��jr�p:xqv]��880��Tj�qC��WZ�F6��j��+����~;T���(���sJ����7A�+u�
�����F��������T�1�uy)�F��*���5ouK����k�N2I	����H����A���g����%[W��#�rGk�/�v:�s��x�����G��K���$$!�T�<Iz�w�pqD���U����b��c��A�E��
�X�����N�l�Yc���7��|�:���F��
����A!��8�j���,-�[��U?����������i $���������q�4qA�������]�������zZkD=�	$����������1/�F��Z',���_a>���E-=v�m���Z���m�j;�"+��)6y�������{�B��+*ZI$���w��~-*��������������6��I%��d,�:>|���u�?��!�,Z4�E�iP<���a>����,60�5�	��<RFa��������fW2k)�vuT�����z^A�pX3b��
�A�d18����R��x�k'Gl��J��9�\��cV+sm�MBm���i`�{me�j�Iu�PJ����u�r��P,n&~q��	�e�m�a� y��*�hPFRSc�,f*V�vuu�Jzm�\4.�_���><G����Nc��������W�����x�=�������[�<�>�}�� ������y����;z�^O��3�=����
����5k����J�1��m�v2��r�}e�lw���a7��m���KF�k�[sF�_-#�����^8��^yu�����UN�`�.�������y��H��l��0bP������;3�<iq����n�9���[�(�%���S�.���/������~]����d ���Mt��V
���,����I[����1����x�y�WQ����6��D����\7L�"h%���ps�A����7�y(m�3z��`4�&&&+
���5
���Vy�m����I�3���,�������	�]��S�y�Th�kZ.���c���uX
n��;��� ���������
+R�g9�P�����H�za���
���S��C�y#y�y���p{E�U��.Jm��T�I�������
���'����;�����Q�X�?55�5�///(i�e�!��5 �cqN8��s��T�.��i�@-�%���L�*Q�|9��1�������	
m/dQD�r��J�����D�+�9S��9�w�^�^�:p�0���,Kn��B<�b�=D��]����t���0�\TUG��p���U[n��8�����U[n�4r�*����4hc��E��&�����=\�]�V�+,�0���,K�8` `*�����q��yW��\�3i��m4����L'���"?G/��������J��ET�2������m`p�C�m%%)b���&�L�k}���b�:8�P9n,m�k��,�*^�gn~I��v����zz&B:fZ�������RR�$g�u�e����e�����{�>7��x��~T"��
�$wxby>��L{�0��n������Z��%4�I��i895��-��^�h\{�=�� �	/�M$$�]^�Z�������������k���[o��[,��U��Sy}�Q�\u��.�["�$�f��i$�?>I�.Z)g��
�)H<�dR���Y%���2&��Q�=�g���W9����O���e4Bm���J >Ek���	c�#c�0�e^��*P
i�!��������Y4�d[�s�=Zz^jsw���������m�3���s��N������w7��_����|�����u+��goS'�{��$��y��������.��&`���[(��S`��r��/���L���u���
�S,q�����,��~� P�$�l�7��f����x��
��MkS��)$�����a�c������[M'����<���%�c���������s+��[�8��#�t����d��>}��r����cMa�k"�I��y��������+�1vK�s,qfYs
�+�u������g{o���S]R*��K����� �0JM���h��L�h
@V�����J7u��������K�x��"",DDDQ��r�7�7�V��IP!��Ug��9!$�HIf����I?�)d�x�xx����hr�LN����;������]��5i#}��a����������O����!W�>�O�cm�:�S(�����D����
��/��?���jm�_��-�3��l���S����V�iJT#��y<�H^/�R�qv��5�m�~C�w���y��}�Y�-������S����;��yn0���1�e�xiW��+Bu��������UM:p`;a��).�8�� 	����j��R�[�G����O%Mz�*;�/�S�>=���,���m��������,�\��In;o�u�BG���_������Z�R�U+�oM�!�����[m����y���'I����\lj:q
��'7��w%U@��E��Cl,�h:��K�t��m�9���U��8�7��
�$n�o���h*C4�H���F��"��@�0�����b�@�#�C6RP����d����E6 �$kU���b3�L��b6�4V�V��9qh��U{��T�o�|IK�C��m5N�G)YY+������j�V-D��i�i���b�Q����TO�;O0_mH}��S�5�B���RG����ZWj����i��������^�o�{u��
X�U�/xH}E��T�6��Y���56*�����z������e�d�R�~=�	��U� �1���!����e02\ ������r��;�������*�e�}5^t��BixIrj������v��� $���X��������oo��e>?l�_��~����3�L�����{�F�+4I}�i��}�����2�l�Sj�j�d''c�Z|��8�oa'�����$�a�I��"a��uw��
���v�G���xw��b���(�����oW$��cM�Cv/��?�Q���'���.^|?Gb��n������!�H��9NSS�)'�scV�e��vYE��������xGI��v�����I.�~����|�<Dv(��/�wO2���{{���G��Urh4��w
�����f-���A��K��,����wQ<|	��6�Oy�fGg��v�S/�������������V�4'X���I9=�a�:���O`�$��r}�w���������� 1�w�s	~��Mt�'s��7�}�C�������!8%��4�����2�k�������1$�sF�>��g��8q=��E�����N����W(�?�T����'!Q�,]K��A��6��������}�w�FM[r�{$kM�J��I��Q��4D'�=1���7�)ag$&<�M�^i�%�4����0h�$������bX�����J�#���?ey^�����?�u^
?��o�h�H�����^�o�}���!�ds;�63O���S���nR1�P�z��~)����w����!�-��-��>���jHIu�! S�i���xk��!-�	y:�B�H��[�@����c��irbQEt����_�^����/!s�~:���~/q�R���=������lN���xX]j��/��I�4���2�j��8
?���*�N���b��T�m��������$�Q�/-��'u��o����
�!Y�b ��Wh)�I�
E��7���H��	46���A	N����(�`"�n+cme�-P@UI��mm�v��T>���5UJ��r����R����^��W��fd�F32�U�HBM��>J�����eQTUp/V�A��� �/;����^�����]u�@��E��"H"(�B"#"�{�P(���@e�����5a��c�����<g��������������p��?2��W���_-T�}'��lSm�KhW��J.���G*9�����m��J��(����P�.G%�	=��
�Ie�Yy�M5c�����L<��1���'N��\��w�34���&�p�~<�����/�W��|'��A�iE�ml��e�Y_Gi�)L�p�����O���W+�w���������hhM	E�6MF� ��@�{���k]�kK)_�}��������18�yZz��~_t���Um��#
��M��x�O$t$s��3R�Vh�t��
���������������)
����!$ |\��fff������1�z���'�\)����X0�`
b,�l����;V�R�%�()JI-Oi��$��� ��ZU��IJ����N������/5��� .��DD��� ;�.��.�	rn��Gw\�me����ADh����,��&>��p��R}E�� =C��
���'����xv�� my���A��� ���YW#��KG��N������)���0;�H���]B��k�8PH���(x�J�R����w=��~���v&�)�G������,���0��P/'EgC.���%n���p:L/,���p�'	�S��k�M^>^�{�d�-�8�����l�
-;�:+D��)���)RjHb�U�i"x�!��*{��j3��]��m���(�H�����%�YQ�8����! �wc>���+��b@�!$��_����c���s��E����M��{���!]����!����i<j��a��!�p�|F��[��S�����e4�����=��K���_>���)P��3��o2����w����]M"{��$A�|�!@������bA������g7}�rU��U�<S�o��������*��,��?�o���Q���b��R}i0���`�"\�������3��x��i���������1-��G��m��UV=�������u�����
=�n������~O$��g{���^����}K
o������,�
Rx'�;���������S��A������?r��I#��Q��2T�*��I�Q�FR%�j�e��&�C�F
���f4�2�Zf�Y"�0Je`H�m������
f�fg%����W��f.X�V���������
���V��[��nc����#U�ig]WG����������W�eYL��������������bd�I�O�e�Yle������&I�X�Wwv�:B ��f�� �"��	-kvYe�a��1���l��I%I.�����M1!Fi��������kY��]�dN8���HHHK����0.r��#����$�,,~������y�����A�����rG.;�7�T*��c�65b��7,ve�]z5���<��'�
�@�n�!C���.�������+[��:>��U���gxn����7������M���B�'
��5�w�)��yV�0u���$!�M�D�WwI6M��[m�#"�h�G)AaP,��Z��[i����cw�pE����	:�NDB�6���4�h�2T�(&*T�]$��c����#)�J�b<�����!������9T627U�R���B46�6!	$j%^p�B��i�NOR/xC���%C���*C�"%�F���z��*���g^�$z��)o)m�DE���&7���V"0���x��D(�:���A��<�'D�q��kc�'����DX���)�B��4�����K-S-T�������KocYZ���I	��i���%�x�8at�3mp1(T�����llb`�Rrldi,M���qMlI��m��&�Zx:�Mu3����-[-��di(q�(�[���D�P�����!�J�����]��S^R�R����ou�d�K��rhb���V�pWyu��$�I��4^����i������<!�*�YS{xn���R-|/&��] /DEV��9=t8S�<{���������B��V���<t&];����n9|��%�3#{;���#c#�!n��J�$nDi���6��l����q�uQ����`�M�����Beh����5�f��������MD�a!�����X�O�$���M�������CSH�b��56�+�e����L���k54������^�k���H2�`�����}�(>$����Jc=�q��x�{E��[)��z��%o4;��������M�lt7$������I>�um�U"����lK�bG/= �F�������4�Gd�����c���h8B�q��0SR`kH��m��{�J���S6�%��T�����ScY�mV��5��,^�h���P-�9I��I�PK���J���������}|��}���I@q3+���w{��dL��H��S"�`����{b�-��8r�eY32��"�c��C���9���0���`�k���H)@q�9T�����r;�Ty����<�������>������m��r���k���z��.�}��M��cc<3s)D��~bh���7;�^�	jX��v�E�
y f������g����jk��Hfv?=M��a^;������S��8(�4�&��7a���e}����3t���[l����h{`�����?:���cS{lJ�����g�y���M{7�G7���8.|0�u�M�p��T
Xw.G���>#L}&L����^���s�r���j����������4���p���ni��f��YYXsN��c�r��,���T����A=^E>!���A F�%�*�N�_��>��g���cj�Q���	*���������}�tn�����y����1�X�2
��*�>?����}�I�u�����o��{����\w�#R'
p+�z�������	I�""36m�`~O�R�]�B~�~��e�mQ��W�d�v�I:�(Kn���\2��~w|?;��"��������Z��2f��Iii�����Fl�Q'{^����}6/�L��1'�T$����������h6���A�eE��0lf��Y��r�.5#�����V����Nb�N�N�&I����F(�h
D@�Y4l��muSykrdL�%"&m&����e��"H?KAj��K8��kZ������g��We�����3#g��O��P�?�s�t��46���]NN��h�j��a�J8u�Ti�����������Sg��/��-�����t�1�9#��v�U�D���?a�s
V��\����>g�w�'����<���?i�q�y��q���_pd��1C��#��a��Xj6V9�{�u�v�����X��G�2�����1V_��Y��Y����{��W��
?~)���;q�V'���m�x,:C��M4�m&��W#�����c�a��"�h+�$�����8�q>�����y���\{��|��3�O%��b�=��D�q����f��?J����uf:uEw�I�k�r���#����.������(�����2%D��r��t� ��8��~�.�4}�Y��{�x�y�-W��n�q��lI`��(���xHdd����_�oNX���M���~0���l�M�p7��9���v��lI=GQ�nc��#��U�{���+�M�V��"	��`v����DD��9����*X|��7:".�����zm{{9����0c�9�>
��<Z��a�6���R�M�5���M`2"8��6�����9�}���,�}�5����K-2RTj����$���M*��n���"����H�\�������x���9]��3�!	'~���I�2�����5Z,�#RL4Y0R�CV����v�����l�����Ym���G���|�=�����Q�ej�F�7��&1���5�U$��������4��B����DW���EKUO�S�*��a����(9Yt���W}��&�
��5&�";�*�@Vcxn)Ld�<d496ZYPN$�+o��6�m�t=I��>0z��fUU5���y��N�<���U�4��Y����Y������Tj_�U�t�Eo2b�Xa�tm�`L~;�z{�{?.V�����.�z��h��������<�cq��QG����u�y��4t>>_GH��6<]C��|�D�s�d���,.��IH�X���i�j�>g=7�G�d��8���T:�LCY!l
�3�t��U��S�����x���G
���:�%���(�� �E�j����������Y��KCT�!7bE��������u�s����k�gl�+4s������S�y�y��]�;�e�riTt�.E�U�v��=�s���M����}�k��
�gK��9���E��r����@}�����>_�c�7P�>���?s������/��K�j���G4Q����T�m�������l����s(l����?'�!�?|��[f���$Q�SRs����'���q"A{�ip���eH��c�x�b�����u����g��~�����t���_��y{����6�G�1� ��Rg�
�U� :�(
8�m����������w���nro|������kV�������c�q�g)Zg1jb�K�Y�����;��w�4g�����O���zF�����wp�Ag�7ne�JK>I#����&����cI��X5t�2i�-�r����b�e
���H��������q�>�x�7y���7�d����{��K�v����gK��TU�U6��2�l�3�M���w��tN����5��r�������)>_����x�]�|�f��I$�I$�I$�I$�I$�I$�I$�I$�I"-�37�Rv�QH������a��/�m�<���:<�Rf�~��i������N�L���&���Rj����/"{�59�q*��E8?�9��db����RG#X����#���3�^L��Zy �IdTU@!P����c#����TR:<c.�=*)��^n�x:���rI������f�01��+���y7rm(H���2�q��S�X
�-�J_�m�`�LfS�}3����|�P�W��p��OL�$���!
��������bU����j�`��Q�;���o��(�r�X��k����#K��!���`�3)"&li�b$������i�������������.iW��J����&��lm��@���w��[0��*M��F@�Z��B��Q�4k����kC�s���9��|����0y�W�5�B�1_:���i}]��\��j
�l��8���MFY�mf^�W5+����^>w�n��<,�-S�|SjkN�_�/�^��p���\����d���[36�����U����^��ll��k&���Z(�����;��e{���������t������q\]��>�	���h�.�$R@,I���]�`7!�$F�����!4�9$b��� K�0��s�K)�����S<�WZI�	�V{HWl���BI H�SLn�@�U	X`��
�$cK�`re��������*�m
�wKV��V�_K��������ko����|�wp��P���*���TZ��JW!Y-gV�
������1� �v~��QxUJ-J����V}��G�*D�Q'%*�j����/%Ve��9����p�����e�]������{����y%S��i�b����;���||�{�}v���a�)����Z��B�4���y���s,��������^��l�����d�����m�W%$���4����F�a����Tp��9���`�4�"��"���>b�fd�B|y��"�*���N��).�ty:y�m�F'���y7�%�.:�)�<
���h��kQDl�;s���
�4C��"8a��N&���g��(��q���!r�.�l��,*�������.�o��r�Ku�B��E�%���s~6g�k���e{�$2�)(F�y��*�[�
������.�Q�T��)����u�n��|<�����-F�m��DDT�9��tb�-�����Otv���&�3a��D��.5([.�s������Dq�������y�9��.S!)	6��j��zg��/46�;:�z�%�7������h\��4�hM�`T��p�=4��B��oUr(Y�3������Rf����cm*Z)K/��������mN'�����B�4�� �<�B:�+a
�������*�^�����&l+4�F*�k6��H�-�3��,����XH�*�������V�n�����w�eYqH�����[";�:�iS�D1I�$D;B�*���X�]��� ��g:GE���&�\X��������<�������mZ�V�|0����M������u;��]I$�����f-&��K^*����Vy����r����c��y/k}�����p�l��!��u���g��tN7���*T�����\�D$�~w6!!�s�7����9D�i��$`*8h��5�w��Z�]���v���w}/-U���� �h6)(�H����'��xc~����7�<J�mF�����{O0I�����E+YLb�a�M�%�Z��7�����=]{�%��������M����w�������luS^l������Cx_.9�f��K�m�� �*J�����8�n�l�9�2fb���L�v��K�4P���A!#o
n�{����k@#��2P�p�AXe:�,�3�M�0-�fw$��Fv
��M��l��lY�1lY�My��g=���&�=7a�zk�L1��Z�&��"#C�,d���B �f�T��o^V���
�Ct�`�P�$���\���\�|[DV�����I>_����|�^��p�m&�)A	�d�m}������9ClL�AB!��m����SM6kM��M-6�ye�m����3L�vR�.+6m���J�#H�6��<*I�������s�z���*������ ��mc.:E ��h���V�hak�]�L_^�6��`F�I�B46 �a����3�SV9��e���ZKIl�\�-��:�67��8m�^�*���zTf�0������P$�]������8���1��:��,Lr-���m�
m��y�[`$C1`�m��D�e{��5�#.����@
0�2�m��P��b�����m��%���/6M�Va��9�����!�1?/;Q��0�lAo��������k{0���c���������V%��l�����.a�HHv����:F�4�MI���v����^�
����M$�][�,%��w\�:�����
���&�mi�z�Xj�(��&��z�U�^i5��]��XyD��\�����0��*�R�f@~�n;����[v��[m{��������:c�g	��sla<��4J�z�F���vi�:D�]m��cA�c\���FU
���B���0�8���P�64mF�M���G_:yQ������f�-�a����Ud.r�q"�!�%��&���QX�����Gw����T/�6�qA���
2}���V���)`�}:��1����Z����Y���U�>MFa6[F��~����X�1{�(�KN��Vj-E��&���!���Qj����bC��5>#��f���,�
����M4�[T�KAH6@�
�6X�B�X�!���Fc��j,��"���+��'Q4�Im	���@*7el�X�V��&
�U�
9x(��8�lF��d&^,O�u�Q�tf��/f�P��
�UB�WUR�B�a+R3M��T�Q��i0�+���V�d�B��$L��8����iKM�I.Zo~�>�L��k;�M�6o���������^)�</$��M�7����Z�f���c�o�������8w��H���2��F���C�zs�9���z��1k��u��[�M�oc������M�k��vw,�b���~CN��t����Ci��I����������zF�������~<#������<�6�O;��e������X��"����{����F�
I%���d\���������.GW�r-����	�m�����4j��P����������wVd��k��{���P����*.��t�����BJ�M�����Y���:$�Vj�-w%�Q4��M!~�Y�(���V�FN\8m����Y��Q��� HH@��BUkX	��C�U�d�2�2B�BB��>j[�cB���Gj��c�����r�:�����)NEgl�H��A�����y�y�0���(*i�:��
<�Q����H�d����	!�!�C�ky-����e<�S�8�U@��AA^AEVL=��s���H=��;�3<���n�������n�k�DA��$�J���>�]��7G�0��!���k�������;��(���{�j���
8Q�B0�KL�(�8*Y
�l��@h�5&�k��e����7��^w���$�d�q����4�?a�#�iQI4
�clg*�
�FdD7�g�J�B������3�����N�:V��@���t7]��v������t�Cb�S;]�������V�\Mw�Kl�q����s%����Z:l������s�����h#�'*-����������a$��9�g���'1~c��\p�F|bFU(��H��h��~��
�����������U�q���?�I����#jw��MA��l�Xc���$�>��v��4xQD!<���,���/�������&�I��">_Lff�>R@j���=��G�3�nd��2�.���
3c0�%�;0�s�E'�y������������?�o'Wz�:���
mw<!�]wxu���/�"��D~�h�6`�����j%�?�p��n��H��~�������������!�?�H�>+���x�]��.�?���O���� ^�G$v��'�>)�>H�������k�H/5%^�\�W+�����x�^��B\��/����y��fa��d�4}�19q����-lf���{O�;�=��.��{�%G��O���*����/������_��l�Z�Q����9C����N�?�O0wB�D���b��q�HR�^3����=������������8�����I�)����x���X�Qr��������{M�����C���}
x��RT{�?O�=�}����������5.rq����Y�T|Y��S���$�`k�>S���Uu^�E�U��W��/�JWc�Wa�Z���}#dwJ���dIRU���^_=�0�`�=gn���E����%GB]���O��S0��>��'U*�~#^'�x��/���������#�[��\U*��?�_��_������/����.����B7�C��3��m������X,�Y~
:��w���0�>~��F�s�I��,!H�d=O����z~�����>�^n�M��\K�*�)�=��+���H�$�������2/j<��\��hN�BW�j��/��|A2X,YQ88��a�tiSp�����vvM�9���D���sz����dO]�:���w��i����q���p[��S�O�H�O����G�o&����j�j����m���h�I�"���t���l2��@�E T��e4�+���[�2�J�����H*X�8vA3�5�un��T���2$8qB�h�P��&���h"�����kt��#CJ�	�-(����IE�����i5�U��[M��]�n���K�M�����I��mM�j�F��ke-*��cs]�������p�;�����Zi����}�m��K=c��������{�)<�O����V.��U�%(/(1P%��u���aHR���Q�Q?��r&��E,�S�|�HlQ8(R?y���v8'���Z�����1i����I"$��w����r�N|m�e�?8�/���?o��QC�]*J��?	[������P_���1^�=$���c��O���A����(�b�����)��m2��2h���2�VM4�X����jYY�j0h�6LZMd��ld�I��IR��ifk-%�+��65�H�+��JL��d^2����wP�����m�T'��p�)��]�ck5i����5`���5a[��MX�i�4�2���5'8���ej4
e`��#E������
W��hFDL5��Ixr������.������O9�7{37<x�\����;gx�?����]���+���fjN���8O�)*��I�������#�aP�aq-_m��cZW__���t!$ �`�>
u���G%�u���g������~[M�,cd�Z?F������H����|JO��
g��Iw�����v2'46��E:+��B�?�#�!h�%� GX{�	��";���G�����O����������{���n��n���8��}�$�=�K���m�����v��t�zdw�}��Z��x������'������m�'����)���@}��M�G���xU�8�.��`��vOr�M�����v�c�;�}]�F b����D�����@tu��N��O�DI��QF������pV���LT�$�����6�����9K�$.���������)N��j��:����W���s��e���UG{��2"M��?��nO��e)��������!#���r��_Kw����[��X���iM	*?�mE�V��ard���G}wg��4q���"z���W���"=jO������������=��K�{6�=�%]U�r�xKU����5���1
7{'���%T�k(���PI!F�Q}4W��_�d��RA�@�������"'�!�k��h�&�TF��w�e����7m�����
�~�h�"Dm*K�Q�IR?w�����LEJI*y�rGT�����f�T$y�9ow�����x�<����RvD?qQ�UV�G$�7�p��t���A�Up���O�|����.zR],B�C�����m��fcf���>���W��}U[����G�b�������e����5���.��d�<�M�!d��z��5r�<oZ<'�iI��,���51�nK�H�#��5>��JgK�V�1�5��uC����������
�����L���'���G]�g[��)��E+���������f�O=!'VTL��(���4Ti*�&��~���23�!�2(���m�����N|kqSCh��6�����sNrD�
�ds;��u�\�]�<c��I��*�KHBg�5v�*�xp �C	*0Rd6r
��{�9 E� =p����4�z[��O}�/_K��?���
�J�ZFW�M���b���b;O�'ox��l�V�����fm2�*�F2�V�Z����R��4�6T�������*�_
]��?9+/s�r���������H����t�D:������ZI$�)Z�;W����#���D�� ��:���!�<>:Nw�)�F�
)���
�G��~D���Jx�������{��_z�)�z��;�w��G�#�<S�>Zf�|]?vu�vD�G���B�S~��W��GS���s�� ����L���FP�#m�3����������j�
�/�a�e����������~����vT��b��Tke��\�+��x����E��L�G,�js��p{=��&�w���YV810������t�QQ9%$�PA�*z4��B�`�ox�i,�i��g�Gd$XD�#9+���!iQ�R�/7�{�I���W��$�|U��#Zv�w<|�=����MX���V�9�jc1�iV�+F�6�Vd����L)�S&K�r�Z��a��5-&51�fX�J�����I�,�KU�e%���D��%�'[}�V���fz���A�y<
31�Z��9�io$���l�v�q9��!\�`�a�(c^il�yL�$�o���XC�Z;ij�+J=c�����a�����=��m1�M���e���
�D(���y�98.�}_V�O�5�������Z���id��!H�)5W��'�\�1�0�!~�q�H��=�a��>����^5�32����,����>#�����;R��?�J��Ix������<�(���&�(��7_y�'����r��-#��q*n&��JJ����e�'��G�M���H����B<�D�l"rp�d9i���>���#�;�4Q�z�1����Ni'����~:�������z\�$����C�!�{(���'O:���y:�U�����I;+]�^�m��*�
R��0�������������{*���G�������N�)���Tr}7��J��4bCz�x���v���V"Gj50n����a"8�����P�t�u��'Ps�pu�a�%x��.�Dp}t[\�?�]\�|�%^�/�I��H���B|�9�'�������I�'��YQh���b�r�Y^K���Q��^t�U;Ju���������s�l���������v��G�:�����(z+�0�R��T���T{��$�|8�OH������8p�	�#P��OT���_Jr����~����ha_HCB�Y7�T>�O����X�}V3Fa����f'�#�30�����
33RIm^�o��R���i�5cm�jb��e��if�l��4��$��&PPP��&�M��C\'��]�i"}��������s�]�J�w��5�����W�
!�SW�<*8Yd���V��d�^����DQyW���p��������]).�59����k�k�t�����I���R%z�L����v�:����k��������^M'���������U�xR/Y�~���y��E�b�,-XW76�U��4����R��.�]�T�Wf����f�a����(���K�qI�������?�;�c��t.tmzSA<���� ���2w�t�
�>�6�E���O���g��M'����H�]���$����I��3����5xo1&d��,/�8�>�{��yAxD�&����S���G��?���|��<�:�m���M��6�#���D�z\2��\�]V'o@��\�]=ym�~����M
x���������O��X�������*}�FV��v�W�������/k��2L,{�}=����`O:�I�c*��Uv���={��iI��
It�r5��#X��U��<y_0��x�i+2�cU�H��-���N�1��?��~iN��etX~(�!v|r$���/����R;(x�K���=����;�:���G�::�Q��������,��c��2�������jv5�N���d��&#��m;G$��N"�������@���^d7�H���_$��������;�����N���_
���#�����;;$u��:�(�PoR�<�g�=���#�v�~�%���H�mI�R4�fkVI��bY�X�f������,��J2kJ%Se���Mk6i6�4P�������i�+L��M4�h��Ae�X�SM
Z���&6j�&1K4cVe��M��,��6��_�tw�4�c;�f�jIcLc7pI�rz�_ s�������'W���uvQt�N����=����)�O����^YD�;�^��� ��i��m��w��H���o��;;��M�/)�^4���	�CE���'����U�����#��9Q>`3D9�<���a���;&b��_?:zM�CZ�e]s���������FK���5������U�����]\���~mU�I��2�]��9T�+��;uM����'\`�4d��\��qb&�s�K����G���MF���x=v2G}�O$�.�����3K6�55^�%�
WU����*�]��	�O8��;��c;$�f":������N�����4�)�����eH�L��"�9�����������W�Rz+	'�P���T�R��Eb��4�����;����(�������2;��"��y.�7�)�
V<�_����U��A���Q�Wj�5��Z4:�#Ii���j)����p!���:��=)M���y_����r����I'���I�����0?���j��r������9D8v��~#JV��	�/�V|�?�4���=���������J_?��B���������{?���������jiI�&����7G�,�u����$��_���#��"N"�0C�r�7�?Y�_��K��Z��?�|��W8FyQ������x�������qK#�nA���'V��aE9;xS{�Lj��d.O�xIy{���U����)B�?@��O+������y��������j�}����A��-�@�����^�p>W�=�:Lb�Ug����B{�b�~K�k�1�	����a�Sh��G���{d���s����"D��e���Oz�^�'��i;wTz��4�����b�ebj�����V�^T@��(�-�����2��b�--� �L&m	4&PL%	��Mv���[���`
�(L�Q%5��j��JF�KD�	�L�[ikWZh�5�%��M$�j�U�e-fP���fX��I�)��f9J?��:���R%�������$<O#���<7�* �{B��e{�O���*8���>����]��(����|��c��_C����I�T�Hd64�[����E�5��I���F��4��[�GM4���
bJ1T��hs���x�m�N2;\��C�c��m���!�Y#�����O�tx�qE>N��/I<��
5U�y)_����)T����P��ixbe�������nT���6)�}I�=��2����yK���"�O�%�D����~
���U:�2g�������W�q��:H�?���?'���/2���%�������u���z�
/	]��!vi�����ph��:��x�~����XY��`�}`_����o�L��_��r�����6@�����4X:N�	}�$��I����L��9\�,>Gje���*+��2����9���E�s��x�������o���"���K��,�i2T��{M$�bk&MS�������u�1�
V�����m'I���$��q�;��bi��8\����i2e�\�q�nI��)��b������4u���	�)�M��R99F�!�v�$F����=�'r����":�$.x�U|=����b���T���@��u}]�?.6��kFY��#������S����M��-����I'Ig��]�����Jp�
7��ir�^��Q�j�-ff�lm3����:����#*����J�K�U�����QK�<���^��$o�����$������K���T%��U�8�?dQ�y��r��4U#���d��?�������c�����Iy���J���q6�,�*���}�����a�Z���	b	������A6E�l�B#H�k�-0�J6���Mk-bh�f�e$��������'����i��eX��2b�������9G�5��DLA=�P�({dlL���8��6�j�(������I
N"i#d)�����I'7"���*��U��x����QwT�W���q�NNq1�6�7Fq�:cf���H�&��cgZ�!��m�����F�I�����uO�w*��j��v���D����sv�I���M�����D��9,H�9$M��0�����5������r����Mk$dkd�d:�2$Z���l69$I�U�^F�u[K9�v0=��J�t
Y�rD���-���f�)=����Xg^�k-�:��y>$n4D��{�:�#b�u�$�e���	����/`������{�9D]�vB�wi�Z�cL���V�&-55Xe51�Y�P��������@����[���@<E��9(�e:��j�;jV���~<r�j��]�V����c3j���3V�GY��|dp�q�������ev���#��rI'����_���nhj$F���H���<+X>�1+���vQj�$����DC����II�G����}�b��������}A;�j�c=�{F0�x���=��z�_$�w������q��F�$��\M*-��yyj�jj�&d�m�u0L$,C��$��0q�#D�LZd��KO�����'.���~@���c����j����S��c3g\�Dr#��<�K���������HH*�~;��OX5�w#T�2pO��J�F����\E���O^�3G#����������
�zQ��@�}O����"NM<�:��d�v5\�e�~����a���x��-����VJ6l�1XlL��=�G�*��|����;}s���}�Z�����T�����=�m��haeA�T�8�l�#��y�F�g����K���	��p��T�_��,�*��f"�&����XiLVJRmkD���d����T���{a���%�Un���kZ���%��iJS��h���)c~�f��riD�Hl�]ik���g���R��O��,�bfk=%t)��x���#��^������W�r����Zfe�J&m����\�MS&�5m���0����?�Wl8Y�kMX�D�Y�HMl�M;s����N$&*���
#59Peter Eisentraut
peter_e@gmx.net
In reply to: Boszormenyi Zoltan (#58)
Re: ECPG FETCH readahead

On Wed, 2013-09-04 at 10:06 +0200, Boszormenyi Zoltan wrote:

2013-08-17 12:08 keltezéssel, Boszormenyi Zoltan írta:

I have put the broken up patchset into a GIT tree of mine at GitHub:
https://github.com/zboszor/ecpg-readahead/
but the huge compressed patch is also attached for reference.

I merged current PG GIT HEAD in the above tree and fixed a merge conflict
caused by commit 673b527534893a4a8adb3cdef52fc645c13598ce

The huge patch is attached for reference.

The documentation doesn't build:

openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:477:40: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:477:20: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:473:81: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:473:56: start tag was here

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

#60Boszormenyi Zoltan
zb@cybertec.at
In reply to: Peter Eisentraut (#59)
1 attachment(s)
Re: ECPG FETCH readahead

2013-09-07 03:25 keltezéssel, Peter Eisentraut írta:

On Wed, 2013-09-04 at 10:06 +0200, Boszormenyi Zoltan wrote:

2013-08-17 12:08 keltezéssel, Boszormenyi Zoltan írta:

I have put the broken up patchset into a GIT tree of mine at GitHub:
https://github.com/zboszor/ecpg-readahead/
but the huge compressed patch is also attached for reference.

I merged current PG GIT HEAD in the above tree and fixed a merge conflict
caused by commit 673b527534893a4a8adb3cdef52fc645c13598ce

The huge patch is attached for reference.

The documentation doesn't build:

openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:477:40: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:477:20: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:473:81: start tag was here
openjade:ecpg.sgml:478:8:E: end tag for "LITERAL" omitted, but OMITTAG NO was specified
openjade:ecpg.sgml:473:56: start tag was here

Thanks, fixed.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.4-v18.patch.bz2application/x-bzip2; name=ecpg-cursor-readahead-9.4-v18.patch.bz2Download
BZh91AY&SY�j�����������������aU�{�_l�cX+i�e��{������j�9.�}EK���y�o��!5K}���W�L�����������5;�`|�������������R���z�U��s�����<��=�G�����|���im�#n�
�B)�����V�_q�������c;�����v��qw�^������!����o�������TYV�gq��R>����J��c�Wl/�������,�dS������qT�C6���y��<�l��}�Ru��t�@����-v�����^Lw:���{'zt]�:��p�h��d]���py��s����]4��.Ut�n��w
�U���.mh5�-���w������j��[��a��:�:�=��zx�Y��%�=z�������
 4
��.�t7cUM�.�����;�F�M�����>���������������v�ki��oV�����qU�2Y��-M��h1
*��&��)���5v����������J*��l�o����:����&�{a�n]��l������Zn�l}	}�w�{-�X�F��6c+�yz-uZ:�����2}��I������w�=����	S����Fu�H�U=n������ke�]�����km����L�ww���`w{�t���R��n�zhb��w��W�P�4��.�������}�yQ_w:I����=�d������m��+$���T������u����w��cZ�P>��k���a���3*��Mvj�EW��;���F#�zV5�����t���e2e��}tq��W�=��}��D��@@4a4d�&L)��=�Oj��y	M4B51&��Ljejz���TG�h=@4$�JI4��j��c"�~��OSM?T�@h��)"!��S�)�~�6S�I�= 44A��""hA0�F�i L��<SF�l�zG��f�Q$��&�&E6F��OT�L��<��L�G�z�����}�&HG���E[`-�-�,ZLm_��h��5S6��aXT���
��$�l[ED���6M����CJ���0D� D&�p��c�)j"L!l�f�-��E4�Y�X���@*���$�����(�YZ���J�������	F��X�*�Hc"}P��H��� 4PZ�N��UU��r���V�:L�P��	e �
a�����rA�8�z3�"!���t�Y�@�@�4FH�BI f�(�������t�-�e�\6��Rt�kI.�u��$��P�(D��������>O���Um_��j��S��[�d(%q��c�z6�AV�a��������`8s������%�v$9E�8-P�h�����{ g'�����P;���e��eVM���Z539��Q9�I!N�.p��V��e��:c���g�����'B�L�**�E���y���~�su;����)��|y�3R�Cq`U�{�5�8��������X]L�����erl����&DL�	����	��wn��NHL���_����q|�5QLI�����7�y�L������{c&������~�>:�p��p�����&���(�I�����%'&wq�;�2st��
3!��ul�0��\������,b���gh�gwv���o,��,�����J�iq@�N�)C]@�A	OOL
�H��'Ip�� R���,����g�WlTPv��]u��V�z���BLGP����^��#|}����h��H��~�c����;;cI�b��6���+
�IKl(aU"$NV���r/���=�����7��UE����[��)�fAN�����QZi��IaB�#	\�J���0r4��?������v�������8(!J1%Na�h��V�1V�i7��q���jIH@J,��@0,����s���6�\;�@%��,��a7#'Z�5�cLLL��O8���{��`��;	��{�����)JYJ�[Y��R�Y�����e
�R���	��9���@�\��A�Y����D�V�b���V���z��<���'3�����	9�r�wA��b$,c��I�1%h�� ��tu�#�\� F�$���]&#q	�
������}��'���IB��J`S���������19��C�:�^0 �Ks-F�jD�B��N0�X�����d
�.+	����x�b	�94������* rn���1dQ�b��9-3c�����By�&������v������x��%4�@
!�p��k�18��3�[l����Jm6�HHI���imv���:(A�q�)�8I-��5lY�v�i�/�}'�}�#���KC��V��bq���2#�@�S
#"�����p9��
�[H�5 mC��JR#c������C�1�H���FF))�~}�tB�4�2"��#C�J���
������Q����nX�]$��b�51���=$��#VFEz�����������F��L�� ��O���;�2�9��K�����L���V���]�L�()��H6��X���)�^��]o.:a���0��
���}�� ���5j�c��d�|UJ�j�`R�m���?���^xD�@�z��5��>|����������@[��<�;	g�9�J9�N�j�����}H��K����N�@$��_��6�+_�`���u��9���j������l��v_'�������2��V��	�
���k��'���z��k�z���W������d���C��hX���=���;��<x{}��v8^3f[����������?1�Y*tCG|m�J�g��M�o#�[;fE,���-�U������#��5N�Lr��o#4��M��`�V���-�2���w�y�%Q��kA��4?��0�w��vA�!��A�����	u��W7����L�PU<��s����>w�BX�������<$e~�������]�x��G�D�_���>����-J�
bfbS�d2@�94gq����(4��_�H������kk�xU;�3�lE�S9}a�+�������<��+�R��/��q%C<V-�X����-iJ�A��\��|:�;jc�D$�%q����2���`(1�Y]��
�P�_���o�\�k\$���VM����TqM���/z�\���l�&�C��q[���QnL�^���RTun�!T���Vb�~����B���U��^E�32�?�&���K�Q&�I�������2��&��1���D���B�������0a�-d`��W\u�d+���8��'^�L�wd���+9s9EW9�����
�n�#��<0����G-�\�I��%?2^W��5e$4GPI&Z�#�[)��f��8=�����>�w��q������4/#�m��;��}��V G�������IP%���,�o>?i���f�\��zM��]���gla��X B�B@�8�G�H��fS6i��cT�����iw�2��UH���4`�>��[�@�#����@���F�<d!)!�T��08������8�*j���A��p�+c�p��
Vl����������L�Q�V���Q��
�&f"��HR$���PQ���"�!�!�rL�����h������p���)�G#x/���X^-�
��L�E�L"�$]SYju���TZ������B��4��(%.���1�����ix���.b�����]�*��K��$��hJS^�w�eN����������t""""3>�����d�[�������#:[�������(�����TVe\�7���,<��;J�A�.M%���-_H;�������K�V
����p����^��xa���Y�6o���-�D��{��s<<�!Dp`(}����d���6=I�J��n��;��
���Qr�>�y�������xN�5'Nq�TP�2�,)"�qi�
''�NIL&7�"Rl��RmC���[�0��.k�Z9���) �����QO�b`�IGXrJn��p������mAQh����;\�<�p�R8Nc�oV�i6��%0�9>����JB�b<���@�K��.c�C{B����*�AE)8z�����/���LiT3��T�!�:(~��5;�H�
@J�L�e��!��)DFX��	�4�v��0F���<A�C��	����I��\69�����.fz���qIf����j*4��F)	��Jv���)�cb��oo/��
I�Cb,-_s��L���h�huQ��.��lI����o5x�[��(�c%ySWP�S%�&I����0B"$B9
��.AH��6����'u����^k��q�M������$�2�?<z�v�@���8|C�.���X"/�`vO���5�+���(�D"��x�n�
����o�"t�]p���I�6p7g��sz��+�zlE��zk��*�8Rb������H����hv�:����o����{���{f��C� Tse��F_\X&�=��S79��c7���:�Q�������G�c���������0����f��G;�UU[��������;��8c��}g_)I���j[��eGH����`��������Mni�F��o�V��n����{�����`�q	������;��:�������������W����_����#aE����U�~��0({�?6��_{)�UR���9���y	v�&
\����{�L�\.)D�	)a,���d��ak��M	"�����-*����R�
U����
U�<s�.�a�]�+���5��6��u��D�g.H�j�oU�l����Y��1n0L��Z@@�@R�"��f����*����8����������U�2�;4h"�"�H"��������P��@Y ]H����{4�����_��e8�x4w\�����J)7"�YZ�H�����������g������)g*Fy�8Ns�G�1h��tZg�I��q�$�\a�!ey�h��&Np��@Q5EH(�x!�2+Y�����#��� DE�R�	��m�M��$v2t1���32VDdKp���/�q���`�����<�;��������QH��RBU'��UH�'U)"�{�{rI��I��J�wnI&��*��W
��_�@V�;�g���NA��%0��g��,E��<���Zk8�R^��)��������Awcm�����U��V��Rj��t�f�\v6���p�p��];��S�����-;���.�m��H�_��������R$Lp�;����Awcm��e�}�{x�y��s�����������a�QEP���r����wb����%�L�K���t����������fiP�U��U�{oxG1	,�U5U��&���n�<�����zZ�^{�=������[���-KV��#�=��Bsi�1N�Ti%e�1tD�8K�*��RBn�i�����2�d�����d�&7�,ir�n.)I
�wM���L�|$)BU���*�&���m�r'�}A��[&���y'SrL�������&d��nNT�E)BF]���C>
�)*�0A������������p���P��$3
��dU��Y��@�N8�������q7$���&rT��qly|�]�+��3�9���9�W��>�-ow��<���x��/�����r�+��3�9��b�<s���s�!E|�����[����t��{�n�[p4CDG]���24��&5mRJiML��<�#����(�Y���4�I��
�)*J��������qb��Z�Z#M4�M0�5)6Q�jZ�%�pc�p�"�"���GSrM�[��Un����o�\e�]W�]�,!����<i��������V���S3SL�K�����j��J�,��2��,K���+�2"H��+�
Ve�b����j���I���J���)`���s��
+�������-o�������Zj��ciLJ��?�r�%S�&���j�2����� ���:|B����^��@�����|�����\u�p��	E*����f����
*�vU_����s�Dj��K�_���;g|�����u��S�60����_�f>�������/�g��������I��#8����6]���e����K2�}�V�J�r��
���(C�=e��C2�Hlh�FO���i�Elm���-��6�:�y�n0,X�a��F�����g�'��8h�o3O���+��D��V�6���>�G(d�(�CB�;b4NI0��8�-�IB����sR>��Pb��K�.I����$���p�������\C���M�n�@,�F�p�	�%���_	�����������t����������R���=M!z�6,�H[w�";q�(x�y�ns����_���;�*J���?J3g��.Nx�h�#��~+��|_y�������d�'�u2iv�����kO���Z�.�|��Rs����>)�bV:\N�I����
��m������h�����N��]���K�g����3�~lO��,�K��m�����>������^���@I�&�ps-�12LT�����Y����������0�~���Jc4�_/������>��|��r��8ss�9w����o��������?U~�<�_���O�z�gM�UZ����z-�pP�Ajz��vD3�fITJH�����g��GK	�iKe��MQCLD8��2��qS1�Rc��������x�M\����<%��*�a4�i1�,O_�/��]@�f*��s72����vtx2
AXA����.����!\^eJt=��k��E��`��'�YwL����h�����M�3��s����76�c�+��������.g�	������l��_��t���RA����`�T�y2Lk�������~����N��!��BjPY�7�D��v�������I�����>����*����~��fX�s��G����S��KP?
I!���"���m���*�P_�b�?�?,_�����~��������)����S�Y�v�W����}3��Y�]���& ���*���~/�/������Ss���&������5\���:u�Wy���vo�������G2s��������vk+/���U';����Rn��)]��+��-w��)O| u3�[�;d�����N�7��9�4BNV���
V�A��H������wK���H@�p9cy<q���Da�:N��1�W�7��A��#��n�>M�"R�!��r4QHT���k.�-���I&��0�9&d�UZ��������	?���?m�����G�[q��[��^����Qb��f���9���I0[�kl�"����#A+0_���$�4�1	��#u��`����f�k`T�$���/V<��7=�%A�E6���pG��������������]�/l��t�1��fE� b����@�3��{c�]}�����R��_\���q��&�����"8G�C��90�Yr���� "�=jlS����2�xN�\2�e��D��')II~��������-	�C����{�����CEzc�z����������		j��������$��������������b$%��d�wE�z��h"""#&�������W���""""2b"!+���+�E�����/J��1�zr���_����V+JR���g�����_;m�]]����aZA$���@�mP�U>t��N[j30e�w�J4��:6t5h�3�3�.���t��;�}2|� ��^:n��;.��_s1�?&��&�L%������24f\��N�%T�:0�I�,�Ty����FI��xa���4�b(����WAA���o�^����(����V�������������=�����H��HK�H����K�x_l�ao�-�x�jC��~���G����"������z�4S1�?n������P�����^������9�sv2��b��K����5�y�%\3Y�b������n�*wwa�����v���1��,����X�F'?,�CM4�V�S�����5�W5j9��LG`������>4h�����F�)���i$�'������|�aS��E3�|6�~����NZ���D�����8�FU��vj}�d�������������[�0��)�W���:r�"l[�c�y�E���E�+)J~�b=:�_Q�d���BH��(c`CsN��^�
x���{F�L�&�����c[�\��y�@W(�M`��#R�5-���-2;�]hj]�<��,���'2�%Q%l(3��������t���#���3<���Q�����k�����W`���7n�&��"Q����++�aI$%�����<q
P��e�jm��:����eb[��lp�Z"��[$���ue�H�mQN;rS��%*)����9�0��5'rA,�	:�S��R�Z����x>���jw
�}X�=��f�j
������r�F���"���)��$/Z�
cg���^%�FT�|9����x��s,�+�z��
��n���f4mc|���#��I��1fv�T���	>���g9�{��
8����*m��M�"':����h�|��2���w���(�v�X�c$�u��������X�E����}�('�yO�����8n5�g������d����K���iu������%�y^�%���-&��k%d�)�&D�l������b�V\�~��\�b�V�.�9t�9��#@������b��hC"�j��Q�PX�A�=\��C��@Y��o��).�������h(��h����P�B��>���v�X
�@��������'����
���P�AK����?'z�t�Q!P�YYPb@��h(P�$A�XX�b�V-L�&����0	;�h���A�yG��m��������UKH$08V�d�l�����Qq���	e�D�L'-W��1C+��z�T�@T�_�E�?E�s��d�������� ���o�I!(�}���9�TO�����&D�L��kX�)pES��#KG<����B�RJ�����!aF!b#�������_P;*��T�T FDI��D�N���h����JV��Q+���a!�	W9��>U��"�G�a��H`:�l'�����O
�I0����s�=��7�o����L�&D�@�������T�@l
J��! � �|�'*~��~�����	�>����z�V��F�iL�s�q����iEkJ���=<��#���^��R��&��R��	���=�{��DgY2o�������5"�9��%��HT�mC	N�����b2�	��^L������!C ��=o�%d�k-�IP�3����z��"}HE$O8�E�[,���p����,�)�VMDGK�����6�)Y$UN^�@�U%X�������ZH[
�'�D=j4�%L����P����#���e�yuo`@�(��oL�(�O�����QH��B<I�����D���"�dox	�9��H��q��1����c#�DDE
�H�tm�wU��9?C��N8U�}k�� ��Q���Zw���c�"��*D3�A���a�e�H��������'zY;�Z�w��?��/�
�y��t{y��gsy�
�a)�����hJU(.�}�{���^��:H*����@
�-Nl�$��/�A��&I�a�)�^��R�!���}B9�i��!�T�,E
����E�����>��)��#�G�t��k� 4C���\b�I�m���c���}�)O�_)��)��r�N8��?��=d��U�:���,��G�:k[H���_Y{�W���T���f��\hR}@a"���d��X���c*Vd`���������~�I���G0��'�@��v|��<
�A�/��ZWces�H�`�p�n2F@)M�-
p�X�NUU���_��4��w��{{��p�
��d|"�~��uC��"��_�1��HlK�:Yv��Ic01�2s�%����UTPVM����C,��bt`0�8L�b��b�D�A�N���E���6�3e�U��R��,C����kZ�n����ap�g#��0���[�tXh�&����j3=w���N�~/~��~�����[����}2fpw��T�@q�h���
��w6��c�]������{�U�*`wk"�]�B��&(A	�3������E������ig�$`8��D|~���w�/n�`�9h�N�sZ�����e��&����_	�������sa����e,��6
}�g��XXZ/
�����*�%J�W��l��x��&�j��L���uyk_g�O�_�����y��6��Z0��wz^g��R�d����`�q���]b[���S��x�GT�����|)��r��8�%Dd6'R	GU�����Q�
Q�����[�t^����b�)��r:`��wW���q��6���3�:���>m1��i�3�];?L���+}���|�I����Q!��c�)v<�/#������>� �XI#������o��7d��_�B�Yw�j���r���
#�YH�I���M+���~@��Q�����������%�_B��J����"H�*���I��DWt���6�F���]!�� 8�MI4+A
�#Q����ys�5<�q�T��7�N����Du�}"I!����[�����?U^�$
Q1�q%aV�Q���~8����F�������r:
��q�0�&7��#���
��$7�g��24��t!�o���$t�Q�h���}���6����
���D����<�\�w�0���-�������T�~!L|��d�.?����#����Y��������I�pq����4U����[U�`m
�Q�y�Ai�]=�|w*!�t�������]A���62�O����C@�����!��"u��OO��j"&����X����*�V��>3��S���S���x��.�� q��U���xt��cT������2��#D���e���5@���!i�~g�������:���������L�#�����G��LU	-a2���~[�����=�8�X����9E�=�Tf(q����I���*Vl����<�G��pz��8o�?K��`�l;�k�$$�wu3q�_A<��ojrG���zi�n��7O���u�6��n	���iH�, ���?6x����':I��_W�}���/��^�~��� *��������������^�����{y�����������o����/��R?E�j(�!��6H�
���s�#���H;
%��gu"S�m`����H����[c9��9������JK�)K��'���J�P!������r����W���
�����$	���^6V~g���-�T))�W��>����^C�;�?$�U*�g9O������P����aJ6�����fR��,�/�cWb$���:r����]�k���d�����C��%�O��i�'���o���������S������~j��=z��Z�������Rv�����K�}� ���A�$�kh��A��25V+b�LMC$�"U"x����"���w��Z���F�[������� � �& �[��l��������H���(V��qVc�L��)�7���z�Z���0@	$� 
�8�
I0AT�����^��/�JJ5��6�NI*�)t��"��D$Pwr����V�E�^���ko����zx8����O�==��x�����ffffUVffeffffUfffffVo�o�����o��	>�c��>���|�b�~��UL�!.��8Cbfj"`��!!��&mTO���0\������{�~��~+���bE!�&Oo�Q4DQ�$rE���Do;�j��cd�B���H|">���$<�Z�<����"!3Rp�B��E)6KL����?"@��#up���,!�������$��?�G�����(���#���
���d�[�V)� J�H��#�H>�>�����}rde����	�AUAQ��e���cb�e������Z>���9�x���kL[i����$��J��]Y�L�@w|w�7��3��������>�N��\8��`$� �b��W����(���Q���|�m
�����:=b �|N�r���=jJ��t��������4��\���>��1���
ix�4�U�������P��J������w�b����zhc��"w���+��z}��������+Ha�i��`�
U�*���I6�
|~�����W�n���9���:6��sU��q��)x���5���58��$	$�{n���(�{��F{*L��U�4��'|����!������g��Jr��\��?�_���yoT���
 Y�WN`Ie�=��9Mz�>��"z���`1��+��s��mXJ�7J'�})J��>|����'��!�V&�������hG�� ((�
�����H����{���C*������fF�����_WT��6](Hd=]����0e���=2!���A�f?�?-�`����$�b���}o��:����M���)7(Q����b��J��sq�����>�R����|M�4���k�W�:@ H$����H����bH�(����]$ %B�
����1�m
(�IDD@	wu�H�w8�]3&������ID���\Q�wtN�@'u��b�UF�_��}���8D��;_�����	��y�ot�c?�-��N��b����SFV	�ci�'��<w���[ zr�b��B>�!b���0�ofBK+�>qAQt�e?�����J��%����e���
�D�;�����|���	��:K.xs1�����������J4���x-H~�;��j�A�!�+�~�N�t�0�t�����[�Ht�)JldmDT��&T��G��*�#C�:�+��
����47x�7F�>�Y�<f�5;�{t�E�����E�Pp�g�L�DHz��m���$q�I3�-�&�H������E����[���������=t�!����3�1b�ewK��C�T�����u�������9��<��_�X_{I�*M6n�oh����x�>*��4/�M)�]O�0y��M��p?xW���r`~
�(m��O}[��w��c�#Px+��,>_����l8?�����p<�s��y�L�����"��w�r��~�
�����l%"Il��
�
��>��g���W����+e�(h���E
f�c6T��PAS4�������k������F�4���4(8���[��R�h�e&�~�?���+����2!���(��m������PD��2QO;�E4s�k�����2��_���|~��w��fVg����x&?��j��������H1��C���2���<���/��Ul%���=����p��A���_��(�-��1���d�)����^��Btnb�����YC ���K����@��YX�4���wW,e��`1���vx��� %JF�bw�'�(ps��]�@�|��a�,���o��6��6���E|>���ocS���"�
���H���z\��-������������`R=26US�o����9�a �h�P)�~W^U�����>��2�
������6��ma]���%�����x`y�j3��]��/�'�w��o�<'�a�i_��6F	B����'�%%#��f��7�KA���^�%z*����X�BJ��k,$��}sv�x��y����{g���s����
�j��?wV$��,������a��B`h�#U��c����i!#
X��-�h�h���'��t�k?��j�����w�Z�"/����.����}]�L�����$���������&<��o���5L(s��/52��.�/�q��`� h���V�G[��s���|#�a|\L^L��&���h�]� ���u�Z��d#��	�
�X}SR0+�$9����e&�	�������{��(+���Q@#���	�l�ya�W����S�bU1�M�������g(�-r�e�x���fT��%Ot�O^�~s�R�����7��=,s���
(d"R%��H!i��,���8P�(�����h
Zx�?����E+q�t�$�@!�r�!�
$�@E0�4�tB��>N�������������hi�"D0@@S������z��
iq}�3���!����v��&D�z��H�2X�����pHD ���iZd��"dt��JZ�cc�F6�����,�d����UE<�M���PQ��J �
������*�;=>�?�I�����c�M�������Iod �L�^|J��~�;y�K���U��UIUT�dW�>�XgS�n�N���N#'&�ms�0z���>W���y�����{Y�
�+`=-�����1P��o��:e�2i`�����������.3BPB(�r�����f�*U����q� ��o�98|nR����
4!�*!B,AB�h����.��S��-���6T��X��8p����cd8p�C�rI#d?��G���c��v���U���co����n�i����:PPPPP����w��v�o�<�$������,���B.,���1�1)�������=�m�1�p�m��B�
��9x�\�.�r�s3��w�������(��'��n���3u�����bV�p��x����C��0��h)Z(�*� $  H��^}~�i~?�^�������H!
�?_���;_$���wF\aA���,G��o8~�*#���we��I;!i.fd&t���?gn�Y�E�O�7�F��#1���q�S	�}��ob������A��g���_�/��v�[����U%����H'��vm2b�m���72�!J��>��h|8u�p��~����7���8^�����1�x
a�'�O��[m�~0�/��������z����y=)\��Q�;�v�$�
�<�W����(����j�q�({?��z���)�V��YK��%����'.����p�>s��*�.t����8�c+QR�j���k��z�}��?h! }C���g�/�����g��y��<�*w[��r;��*"��!������*����@��,"�����w��(U�?��C��*������
i}dP���I��QB�9�t�HAq�FW�2��\�8���z��
����y!�i������;`r��L	H4h1�����(M8�1�`�Jc(������z�����q8����>��xP�N|'�\N����>��.<(���Pz��y��V��:�����C��W��2�j�}�
+N~O�I�C�N|t�����
���O�(B(v�|1
�9���B
Z^x�Ys��<�w��P�N|t���	�����Y���j����
�����weD�H�*���(��[}�}��*
���L|�d�*����x�� �&����(vC��s8��R���LT�������T�@�D�>����r�U��/��������@ ����l�
���D[�(�:�<fr��8T����q�U�`JA��1����DV�WSk�����q.�+��WjU�\;	"�m���	�%5I!��LDDDF����������o,9n(�������LE$��\��
M�$�R�T�I��8n�5�eEEEB�� o��m�63�!1
�(�v<��!g��[n�Y��6d�M�`"��u����r(z�����>t!��#����]�7��`U����C��=�'���Ep���Z�*�����C���IH���(�^.3��/h��cZ�cD����u��a�FP8P��9��<�).�W����P���z�&���iE��HI���(^��21�_8�E��_nt(}V����.%AW��E+��'���Ys��Hw�@�
���������"�V�f�a��n0�
���O��a�s�h�s��Nl?,%"�r�GL�}���~"��Q5�3��r�'�O�������9=Innf�/�L�/ia��bs���9�9t��(�i��
�f���k�_��==�q�yz�@��#�$����<uZ�Q�6���� F\W{��������+tu���H+6?��L
���M����_���?��o AID�"�"�b*�V-��FT	dY��)Z@��4��Q����L���1�-w,�fh�:3aJ>�"
h���X%I%a�%L�&LKej��2��Q����,�Q�6YYke��,��ee�R�SI&���)�"7�G��	����h�>������{�S��g�yx�������gQ��b���R;�'2�o����|�H����CK�H���8_3�]��k��D$
IM4a���A]�4$$�i���9SZ��EA����IP���(��-���Z�������v��o�y�%�^%��<6���,5�����������FRSx4�8�h<�����I���)H�#��������������Q���\{�DG���C!�32�,R������}����0�F1���I@��UUUIQ36��"Di�������xd�$y9������=ls��-��.}RR��x�b��%��6h��8�|���OE�9�:ziV���z"o)(���h4R���y-��6����3�`~=����%/��������������^A���P��;sr���8S�B�@�,(��	J��@�Ci�7BL,
��M�[�����H����T��tM��6������2er@H�c|�o'-����7���N�������|;���`����^�������H}�����c��{�0���GY0���x��h:Y$���&��8�0?g�;�3k"�yH\��?/d�3��q��J��3�������H:�l�XB���Y`b
*������
����O��wG����^�T�=p�:���7q�!������=D����&�*LQ-���P�e�����n�O���N�1cm��lG�����k�2
����J��/�K�1M.��.�������� %�8�C����� �'���B|W�x�^�
!|��s�@1�i���pS�*
�����r'����x����3
fUp�� ��(�M�
:\�<�&xQ%$p@#��)h�Ku���5d���R�T�W��i���������g�u�_�^d���"�>#v|��{J������$z�f��y�����>j��R������Jk��S<��(fk�<3�+��H��z����c^�$�4�d�2�b ����r��3s�����Z=�������y�CZ��3�y`_����W����$��I���Q�����q3ld+�95�O|�����Dqr���2�,���N��+���=�:�2�mwZy�]b���R���,l_	COO��'�'.��;��j�c��G��wt%|���,������(Q����7��YZ����
{>&,��������}��C�����H'����6��$j���]�W�-���'aZfCrn��%(�V��7P�(����V�!�^:�����R�1�fT����VIzI����yP�F~8q��ls��Y �Co&����%X�Xf��5S-����b��s	��j�� �}w����zyq������s��.
^N7��8zt��w�!����AJ{��-q�8�i/Lk��'�H���i�����O��������6���"c�����Nb���`�n��;Mn:�4���!����?�[	�pNV'�po��z���q�c3����,$�D5�����5KK�	9>���kzM��ch^O�FJQ	�sl`�M�G%L���me��wWRJRL��XE�%�Y�P�L14G����Y���!n�nG*��5;���%�����y�*���L���&����onu�jR,])�i����G����$�D�J�T�h��'O���n�����9���h�K9�Lk�Q.�j,*����6��R�������5'D������PZ}P�|���s�r�6�������d�B%z:I���h��"W�>�(?�PgD�����+HL�>��G��^Y~���/t����� $
�
���.����)U�������HQ@o�>���!�Ns��J(���g�1oU�[�������iz�e�d��~����P�*
���F���np�����r�&�P���G��+������hSh��3�`z�����M�y��n�s������;R,��-�����0�c��m6�eWR}���o�y�w�r>Q�����$Dg�t}a�4�OH��zB�H�}�zd1��3�]��Mx�����q�$����8���l`��om�V�����X
�JP�UTk$��w�6�#���!���r8�	���n�����V�&�������xn���b��w��~��h�f�j���%�������1���[���yp�F�v�T~��*#*�R�)���(JJh���x{>U�Hw/iNLP� ��%<���ma��e��f���
T���
FTJ����H��B�J����I��]O{�����D�"������y�%�k����N����x��o��*�Y*�m��^J�*~��	f�F$��c�.��]"K�Y�T����iL�Q)�)$�)I��"�"���G,4�V�T���k�
�������������S�.��(/�L@���N��!a���X�ZV[���l��$E���~��!"r�! �hd����H]�0�����*a'>p{
Q����P�_�b
��P��P��`����������?�������?�zO���a�}��i��q����>W��tr�S��z~������E���o�)����\���3����Ee�����3E�~w�D�;a����}�����:\?�Q���������%��'	�
B�Ti$~A���(��#�0Y�!����a���;�}W�����B��8����O��� 	��?�^�T2E_����O�����>8��!����l�NkN��
�H�6EMf��0�K:m����4���d[����L��=E���������������<&=��L���R�T��Gi��;��;�3k��y�\�����d�7�zydf���!l_�!'����S�F���
���i���/���������k/�DG2SZ�{E���~rl��p�p����/g
��*��L&���	JJI#I#P6���l6��C�c���+�O�1�TP�P��R_���b�lv�a!y�=b��B+��b$z��;����b�EEE�*��V��"a<�|���Gq���0{����C��$K��L����z���z�$����
8��
V�i��Iw���.@m3c�9����d���$rI��t��f��J���;<s2BA�K��� �&��s2��v�r5��pCoM�����b��H�dt�z��D��>]�������5��	�
B�� u�@jcSx1)�Ut�(��&D�*>x����v��sN!�Hv�]�'��a$�7����f��Ul�!'�8g�Q��'���B�r�����d�����i����Jj�jUG!��!�����rU?�B�L�gA|c���#�E$�9�7>����j�j��� b:A)A#����Z��T$�b����	#B�L
u@��~]�n<e��1c�a(f�^%��YIA��KNt�P����������x���)����9�����1���w��|��u��`���={�M�?��''S�zw�����WF��e�<��BM{E�ung�k�;�e�~3�����I��������)�c�����<X �0�|�|y��Y���qX�ils�\���(�(f����X�7i�0�6����n����n����
,bN���&RR�^[f����!�n%��	�e�o��jSv��4��M���n�3����K-w����_����{�.�����
`A�au]v�P�z��'_zb_��J7�oh���W3�7c]�m��Q�������+�c�n^k*I���T�@�I��d���6	/���Q���'"c���O$��G����������}��}��%T(/���0�u
:bW�H�R�s$T�!U�Y�6� 6LD�e���.������l����~�T��1��*[���DC�N���~���'���(R���aO%��/O�	j�E���*��a�Ywu����t�c� ��=�$�*%)L<�
k�%vJ���+O�P\g%9���]���(j	Y���^����TJUpc��'/�� �(@�9^��:2��4��wHz`N�
-'Uk*��O
�9����{P����&|y���b/�����	%e���%U��%�x�e�$/��	wm�R$�)2	c�r9o���V����1�}����cye��3E�Gt���oh����i��A\��� ����Zd�f{���s��=s{z�ar��S����u�.�����mm�6
�E P ��}�|7��n��Ky�[~���}��5BC�q;C�[��Od>��1'�M3�����?	���gi�����
�M���e����<+X��.>�K���(��}��#f��_G��#<��V%����l�`��aY�C6K��r�[4��E�wn�T�q�<:��xQ-�p�yk ��a��q�������z����Q:g�rrr�vk[�$��Ba��H5���I�Lm�)�N�9��r����|{	���wvx�A���U����\g^%`�|B��z�q^"�N���0��"�#�8j�������%����@�������s�]�&nZn����ENF�[�IN�BEO�|�t�U�,�9�r\���)��9P��O=s�����a��j�0v����//M������5���{�e�0������(�Q�]�[�Y�������n7x�q0(��K�_�}}����B��)P�w���T�6)YT�[Qh�L�(���3f�V"�LJ��j1A�SU����6�h���l�5�jP6�HP��L/��$���fb[5Iffx��H�O�6>��HP4)��$�P E=M7c��p����P[\�s����Y:<�$�v�H`H��*�M*�K��M�J��Utj4������A!Sp�����"B��b$~�^���~���cwBA~������rh����z������(�@�TrU�eL������/d5���������z���8�q����{��������J%xB���_B�EZ��f��Dd�.TG�??���0�"�\��v�?e�P����P���j���B��R	��
�G�9P
�����_��bc>E���IK����9QE=iI$uf[�k�L8��{z�������|�9\%�bVD�wv�amv�������.�q�J`�H�G�������0z�Z�F(-�C���HE���)�A�!T�c|+�����\�y��
����JTY.)-3,�t�����HT7)gq]��6(���S�~"���=������\{=$��GY��j�
A.�rY-����g��(s��p���V�������8��������?B� 2&4�)Ep�S)�RR)^\vC�H��/��o��UkZ"*�����a��O�O��q%�,l	`�'�i�I(TQF�}����2J�����8�!��kvFc#1�c#/�t���F��@�N�	(z=��%�u����l�������4B��)C�ICCMC����@z��m0Q5��R<�F��������]r��KQ���XE,�a'���~?����m����^����{������x�]]PUUPbI$�P5qb\q����
w����0#_�jm@a6�,BV��s��[�I)PU4�1LD4W����������
�w����������� �i�{�v����M����ne}���x�NG��$�����;m���'_����f������dgD���;���
!���:����L&�x5R89z����
4�*F��%��$������w|���g�`G^5+x��)<pG4o�:�}W�\:��s�|��*���iLr
������%p�Ca�@h��o�c�2=5�x$�+��z��Ju�b"�kQ'�}0GF7��5�i6jz�����,�h�TE�A���gu����[��#%��z�PG��{	t8�m��	+.�R3��9��;����<������00��m��J�������
��H���-.	.�+��P�D�p4�i5��S{�>�5��/�J!0c:NG
��@��f���Ov����]��������y�m4���Ld
�P�}J���������AI���6��mXgJ&d��z�7�j�+cy�����1��#A�T)�� I$�Rt���0�B6~�
�X��7�<�u�#K�����33�i�n���-3�~g�}#�d������
7���B`�-�IV���s�����0Z�L��JZ�,/:y�m���dB6���gb�\����
�*Cf<eA��[����<v�	:��`Q�4����4!���[q8�*��G����~������H����<wm��W�v��qK�t���]��++����n���rv��{����>#���m���7Cn��<����{j�v�ssg.v��.3����s�����NI+&.
��IS:��{�m9�k'7V�S������Tf�_V��n*��|s���%��Q�3,�g-_n���u�z<��3e)��b�����g�e���J{{%J�9WS���j6903��kx����������&�:�V��8����"i���*��[�rsG���{��q�����<��n���gRGc1�������y�2�����f9�vur�gv����S9��{K�{��;2�������DT�I����/9�u���^syBX�d�v��kegk�����"
��FV��O���%�H/��JG��jo*�lh�1�����4�V��p��(�H�~O��'!�or��H��Or}����Jy�
$���A���!����W��N@���_�\���%H?d�E�[����n�&��0{��(�kQJ�����&����4��I���o0e�:���<���1��:��Q���PgD3�u����&`��I��d���!�N(���������\Tyzl��D2y�
���7(��Om���r1GO�}c����He�I ������`=�4�b* A���������`df��/�Aa�N���{�i?���J�L%<eE��������6�G����b��4GXB'�����7�Mq��{���m�g�33�?�)$_���)�i��Vd�x�w��rl�O�),���>l��Z�W���'"����]T��&7���J�s2��������R&t��
<Z��<�
�`�G��)���g������%O���M�q��������-�Jk����p�E2��ybk���u�m>`������������/�g�~O���(���}?��������iz}(���<��%,g|p�J����V���Y~�}M
�����[��z�o�=�X�_��aLr��'���O�iZ0����5����92pNs��N"�91�&_�i���@��'�&���
3�KGAi��4`�:%T�d����=!(I(���3��7&e)�L����R"�����*!���U��U��H=�I?j%D�
����o�pk������*�\�l�;80�-'L4��QOS9��8H��g���g���234��N\S��A����������mM���fi�����\H�#�V�z���L�<9�S�
�/���p�k������T?������l*����IH��*����b��BnR|"H)�G��)�i6U����$����$&��982"�"^�	'@�w'��
�O��UUV�I$�I$��$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$D�j���������0�_A��H��2R����Lp(���^i"�IY�E#UW6��3[n���THl-������7%$:
���]�5RB�
�����?q��46�s@��7 @��IM�l���j[)���A5#X�$C&�!�$
&B���8�0���Td�%���b~��I"��.������d�����"JR;�r��b�-e�HqR$7�$��$��C�����q��~h�ws��U���2yG��F�Vi������D����Z��W}���\DDDDy%�  �9�~��TUtH+M)^�ReO����T6����R���t$��
��zn����4bw��UY�(�J;�B|���\\M}qf!N�"�������������$���������gr��t��Yg�+����fZ�aR������mKD��`�*
�%D���(1���P����gd��?/�332��������k!4~�?�S���>�����*�GjZH��>v��fT�K
mJ&������L(�I��T�'v��+�%��s"AE������;oN	`��_�S)����2�y�9��E��A�`��v��,�Q�wjs��r�#i#F��\�dd�a��������~����HA�J�����d^8r�#��(�L�S�	A!$����*�V���z�v�I������������>PFm�F����u�+X���%J���>2��KH
���U��]T��[I
����qt��\��G������Pc>��������������U#�P[ ��G�Y��CU�"R dY����T!��j��m�)5Q|�^���Ft�T���@����������(7c��%��[�Cjr�v�U*dK R���DWzkdY���������mx��M��h����E��Ph��v�A��w*�C��=;��xr)�$�"}r8H2T9�$�SvL�����8�������6�?D�_7�#�_��|9vy��K�u[��ZS���tj�L^��PZ�1��N/���x�0i#�ip�<4*��)_,��:���:�PA��MD����qg�����T3
��t�h�LMk�NU��bx�RS]�u��o�	�~��d���+�����Pv�}��:\t��p�a��+J�|6�I��� 
@$�PH��K��d�U����L���Vf��A*!��KO�����g�������[��rX���M�[A3,�a%@���S����#��,����n(����>�vn�	�U�A�T�������]��*<0���
 a)]2����F�����O-f��#�B�,G��z
�5�pD�K����w��THd!:�CB$�&	c$��!	C}�������L��F72L�e�b�lp��m�x~	D���{�H�����z�x����p��r����*R�j\������m�d�G
���U���rI:"tU����-���]^(� u����^0�]�����1h�M`���V���&�2��]B���k ��G�c>�2�^{�����p�w����,�i���i��)����C 7�$���9 u���r��LRM6\%�h����>�����<b��c��dl@�@�RKP�j�<n!��;������hQ�Ht������T��o��{a�������r����Q|�w�V}����<�e{k���[��SeK��2'5jH�elG<�������m�Kp�7BR@�k���DnH(]��[���C��H�h9HB���-������0��d��@�6�<blX�P
�S�[��.��*(H|�CM2I��V5�H�B�=�6w:<�J����kx�X���""/m����""P������
R�S��i2-�{�u��K���cQ���h��@F<N���i���i��:���VUX����!V�W6;���ab�bX�"�����Ywo�q�N���p4��O���:U��a���^0��eS���S���cCl�$&q*J�C�T�����&�F���?}G���������g�����7FA�Ad�e����B��t��q$��a�s�3&I#Q��p���g�?_��@���A�����:9��<����[a��#rB*���I1�G"|%�9�k^�|�h��2����� ?%(��#��P"�����]�����b�Tv
��P�R%H��R���B�"�'/@f)5%  K<��/�
��3��]�4�|�y�����;��a����y��dq�-�0�5���������h���U�&�	2g'/k�n���Q�$��&_�(��yZH������a�D�di�u"1���q����<�x�������-�j��p��1�Lhf#��(-k����v�����"`OXW�gLH�X��p��e�h
!4�li���Q��Y�Yg�R�~������b�Y9r:�2�]~�'K0��TL�GR7n��H�"r����h�
C:v�	PMiP�6�'�C�4��8	������|��\�cp�d�RA6�����%���7���z���<�M:v���Dt��;}��_W��A3!����"8&Pd8�X��(V,;��Izvr�x��Nu��������������X~�����7�x��)��0$FhR��A��y�9�J�j�nr�yo~�x�59���&D f3A�h�v��.H�['��3A�&�B�RVa&�]����L!��x�n�*��8��)+����=���G	w5A	#f��g"#=q��)�������T_���W,�S�����l��K�ab����]nb��%i�hF;������2��T��P�F��e\���)*����w��b��en�`m�W��t��������S������A�U@"���n�Wk�X���u�����p�����������"k�%3*���[~�Q���`���J 2y�S]\[��6<	�1����i��(O��Q$�%(	^��y7�qR=�O��`:����@P��L�ib!!��(H*��?A�����`�FI17g�D�L1SL�(�W7J�J��(NZ)'J��e�6|��.�H��@A�����%���b��0D�*�V'`"\�Wq%�B&Cj�2�L�:��4b4�p���.�e��r�JO�h�BF�I���#����cq�c����<?������o�;�t*5����Uvx�$�"d� �66��GC�PD��ZE"
�D�Y�����j�n���X��6�_������r���\���������5�0����8��d7���=5��{�����X�'�3�&X�����~����NqAu��cK_(Tw)	�"CB�	�
����s��;�s����	�L�� �:�1����,�N�8�XFcHm!�u��l�	�|�������5n�����/�����4�
,L��d�E%%�lM���\�����xa,p���af�f�s��7���O$�D7#D7#@7#m�1�@
��cA
�c7 4C�C�@7 4{���s�����������S3m���y��F�hNF�nF��n�mH���)������d�1�N����*%$�	2lR+"!�9Sq��������EUJ�D:'i,h�y��{�V��������@����cyX�!��E��TA�B`!�������~<g�����O��������H�F��W!���v����L���p��(;K�7�����w|��z������O?]p�;�I.�G3��}_��T�x�8������j�p������nl�~{�?W�;EuA�G���a/�e�hn��{���������^�wX� Io��u�
^f5�����d�����y�F�9=�H#
k;Bf�
�M��P�g����2XU����x�������������=�\B6�����m���Y��;7�P��x�;=U
��((*�$*��
���G����}s����*K�V�,/22�R��Bh��q����Fff��N�k���A�Q���Z3�F#.\	P"e���
����p��PL��l}������St�+��
�����6���h�� ���Wt���,����+���g�u����L��\�(H���iT��l���[X�~`�7b4�R9B�
�<;;q��i/l��S��-%]v�������t�:#P1�2�(9$�����tO#�;{�7p�{E
|R��^ ~��<|�����eGjnk^��/x�S5����&��=$E1�������FRm��LH�4� I
i��llg�������1r0����R�=km��	 K������D�[|�f�m�
���j��j���-�
G�7�<�2x�PE��K]����m�[��f�[�&S-���� Z��\����$%b+���j���z���E�����!8�EE����h-�8�@��v�������u�����zB�����%Q6�	�O5(P���0��/Q��z_x|vG9z����~�����=��IUJ���+�y��}��o���p
��SU3ST^P`n�$��/���_^��Z1|�y��,0��r�&��4��43
����f���fM��Eh���
��s����q�E��������kh!�Q�����5Olm��}=4�q�q�V��W��*����3������ms��Zg�39k������?�}_=ejkYWa���K5-w�x�N�\AbYd��e/3tQ��oRa�{2��_�A;W��44�B{�>-�}�`�50�cm�����qL�8���TF�"�Li������4�0�M�y�&��E��^s����_�
I}������������CI*e��������:S���v0�L+yM��8���������s�����Ze��U��( ��{�\��?Nj�����*�A�DuH�;�4��5�jh A	\B#���$��p�L�������+�6�����+V����"��+l���L
s9���r��#
������c�q������1d�ij�x��E�b��HV����'����y���D[,��F�-�#<p�Y�#�E��^�J���cLq�8ZmZ�T��Y�qRE����c��76�����f��P��sm���1�)���m�����QaEI$�1�DG��8��{���wwwUZP��E�,����.ffd.����*(v���<:t���
�p
w�Y�=OsH�'ZZ.�GPER��
���������U*VM�U2N62���&�s4���N����6(Q(���������s4�e8p]�ad[r��nI&	���1���U9�)�s:��fU2N6�KM����I�9��h>����s��T��T���i�8T
�j�Wse������z��4�MJq�o���&����==�����d�.������7�����U���������4�`���}�+a���=o�%5�%��$����w�J�b�n�$1�D����p��II02C	2�6QbK�I#Q��A3���~�����n��CB$���C3��9�A���[ws{M			$$���"a�5)������2�mg2�����yen����U��gdG\�QX>��no���t<���n�f��*�����w��V��+f�qs*X���w�V�����X��Tw����}7��%����s+f�mg2�����t���c���wek{c��n��M��S�c�gt'W�;.T�) *���2FH���
8`���4�"�8X�ae� ��4�f�,vI��F�$�`��gs%8�M�jIs%8������-����%s�8��Y�,y�8���ol{�����Ws�e��p�Bu�#��I2��%jwCn���!�d,�8wCy�d�1�����u�d�P�I,�J8p���
�0�`t�4�G�M��^T�6�J�~�|=���9��3�z�B�S����
"�q�u�yt��p��������������I���Qd3c�p�$�p��4�aL!@?�b����� ���1�r#S�	��';���8:�����Y$�JX5+������a����c
����='�
�-�r�b��l���n��V��,�#n#�U�"���3���y�-��y��Wp�����,��xkv���z��,C5���]�9Yy�Ww�8^cD������f��P�����{����vj������r����]:r;��������B|��
����t�]���<�<�;��U��y���/1'0�e5������TgfT�N���1���7f������D�*��\ ����vs �����H��m�C���va�>r{��)�w��;<���\�/�Bn��'6�]�#�xGF�+Zp���A��aO���|��k����b��k�`�2p�Sv*��C��Fw�oj�V&$�%r�E`�o1������;�pl�y��^�H�.Tx��x��N%U�[{n��u8�N�%j��s��9P��f����c�8rW����Y[7[�U�U�,|��w3V��{��Q�o[P8K-:Xg�vQ�II%�r��a��0������=�zL�	[�(��������_k/;����t��Y��f�_^��w9�{����������8C��%UGf`�dT��S�����gN���=v<w��x]�W��f��Y���c�.q���[����q)�5�yZ9���Q=��|@~$�o����].�f3��=����wU�Sg�����#�F�%2��\9����xB!$���3P���������)>�����7\I(8Fr�M#N�9}�u$�HI/��G
;~Uq
L�������4B8a"8���
���I(��!$#/�[RW2�J0��3,���I"�!$���3(z�=�
4�ehi�|��H�w����n�����xD�H9x(�W�$|��p^���y�����_�K�h��m�7M���V	�CQ\�u��_����a���������&2&�8o�q2��E�n���1�����-����s$��=�����^V�p�)�5�~rw����!! �(�"TG�@�w��=o�{�&29^���$_����\�.�fg����c�(I-$��J6�fH=jLc=�cJ	*�;��U���P{7G� Dx�E��>�����L�C��_�Y�y|���s�����r{N^e-�����\=�n�7�����@�
"���X��� a!��8&���\���[]��XlI>p��
!�2$A�:W�SL�f����V8q(�gi�o��y�����os0+�K$l�����M��7�,��K~�t�{�o��J����?8=����T��V�M�O]�)GJxLI�<1�������&i�����es�������2�Vp07��N�@��������N�C�����v �t:w���4�������3��sy�B��yY+�]���9���6��w;XZ�V���M����'y^dU���-����(������'
1��ALfcV`T�Sg��C�>���`<6�od~J��pg������/�S�V��������
�:n��F�>�����U�����������
�a5,]X�4F1��&��f�C�/~��zl�v*m��N:/*9������)($���YA��2��'"m4�0�����'73b>\c�71t�0��M���	A����w��*�J ��'�?n�$���dH�al6���20���>	x0�'���u4��$��TH��i�%%*5u�g,����B�������������T��J���t���I[�>�M�����LeM�=��#��F��IF�b��9Y��G��(�~���S�����$\����h����{T�7�|DQ<.:���`��>>*�@%��
*�`��#:�Gsa%X����Lp��@��
Pe�YGI>�c ���*;�(��*-�J�W�����@�	CQk�U��S%�������T��������$(��IqS>��P%1�*1 ����9����W�2�$n�
l�1d�s�w������E�����(�G��W���aGA`�	�,�;����l{HJ'H�L��G���4/-����>��~�O�DW(��*�a���6�'���:	���
��XX8���B+vyU�e��Dl|��L�������!	_���MLLA`H���{����9��t��o�����-�N��nl��ze0!��w���7V�bzF^+9�:��*R���3F�/�rk&��N�"�����Ur�\Z%4 ���=�2T���31���n�Ws��?����zc���lz?}}��<+��{������XY��_�t��dXO���a)O�#X�AJAI��$v�G��q��O����;\�r>I�:[����*6�w#�~!UR���<
�<����	�����sq���_�?�?����Oi-|U��Jyi='6LZ�z]_vO$����K�l�X����R�qt%�
T�
m]�D�6e�U�d@�6��S������p= ����)��]���%F�!@0�����\��dI�
��Y25�h�T�������1
[(:�q`��j���u��t����D3����g%H��0	2�u�?Ck)vT�\q��2D�O�����H&��#{�C�����M�H�*'i���$}��{����'��K�LJ�������~�K��	��&�3)����7k|H�9v�����KI� ��Du�_�H�y��#<����y�6��pG�Z��[��4X��goG<�N���sbw@I�)9��$�BjM��rx�H��HI$��!$X�Q/iO_���C�o���8�o�D ��?�
w��O�4�������nk?���fe0G���'�%�-� |UO)OR���a�Y�z��;���_���y��&/P\a�����CI�V�;����m6[�r�w<�x�_�!������R�I�����
�GP|G�uT0���/�I���B~������������m��]�{Bw�'Y��i�B���Id��(����1T���xu����gq�T���~I��{�#s�����FuR����#��v�k�����x�����������L}���|O�w�	�!2S�=���Qa��������I%9�%R�K7� od68���8��n��IPd���	qz
��}>�� lz��1�N��&
n'T��y)$L�H�kz��_;q�p����dr���p��M+��A�J��`��3"~���)@���L@��w���?��Q,�
QV*2}��o����!�����+� �'��FB}�*h�Q��$B�R!��Hb�PE��4.���v���MA@)�Z�fo�@��?Z�me�ay�D<GN\PF�9� ����M�M)��%Yl������
�@�_G���������}l��#�j�w�4�
�~��N�����,H�+�!$�%4��\�3F�]��*�����G[Jfa}D  �h��~���G~\��'x����;�i9�����-p3
������i�$��{"xye�<M���|K����G<�%W	��/��5����nb,qr"I�4�����&��
�����~��At���W�z�VS�I�%�H��I��D-$�=<��!BA!�yS��#���K�������(���Uz��6I�!	U	U���j���2�v�g���*���{��=�'�w����O����I��$X�c~"<��5�K�X��)��;�S]g�'�4�l|h��I����DUSD��_����>�xj/�{i=���kMj�&���?@����I�0����p����/�a�*������@��������6p��D�'H�pH	0M�YySp3
H��+��%������E���"o��	��U��1"�Bi�
 i��8�B����Ix�����!������jgI2,4���>|��I�LV@bt��'��au�@����F����
�A(x��Jm%��X"���Hp�y��U�W(�c.�~CX���7*�(���ad�B�z�<�A������6����WY�:���6��"'+�k�����5
$��@{�DH��A�d:j&�EY�����O�a��?��,�������`A|c�����|~������-�d�G�0�����F��>��c�#�`�A������K�R�`��M���y��&���i,�,� j
T��FH=I�����,	'�M#-�!g$�S�Z�[q�H��qN#�bm��<O���8Y'�E^�#DPO���I�8Ez�8� g$�b7���-�H!%��@��������b��mO�$QU���E��"��
@�J�$D��|Y���u�/���v����"FfIe��-u�������|�O�9������X|\;�W�����L����Nw
���I/��A��I'w��Gz�0%�d��,QR��~�}T��F�
��%X���g���������`����%���%h��?�J���dq$��y���7��*x*;�?Y'����H�V��������s�Xi��;/k���=������xy
AL���~�<�+��1.�@1�~�66�2M�j!�mg��[�$�#��+_0�B��@���@$�����!�~QA{���A�������&���m/��x��=��"{2M���
}�M��������'}a��O���3u�F1��� P�#�my��;=AJfM�'��cI+��
�'���Q
��{�#AN�)I��D�P ;@���i��F4��(��d�c'` �D7�;5$�:}2s���I6uc���z��d��A)8��C��h��)�I
�u
���!(V�&��a��S\s��Tv�!�5�d�$�A����
�
ev^$�Z���S��W�@�[�9��4Q�
���"��c��2��D���.��2{�0��A�7�?��~�������+�T�� $����������=���������!����y6�n|��+��%>��N��d|CM�H{��c�x��r{���[lg����vCyf���s���N���T�W�f��������g�	6����r���PP6�6��}Ao�`P�k������THY#�"���)Z;���D���R�a���M��H)9~�����������c]���������C2�l`R���]]��u�
"A��iJ�9����:\4���\��N���6��D�H�������4������#���@��mTS)ut���J�3+�]KL�$&	�2f0���5�NA��a�qX�RDGUPV�E�����e��EJ)�B� �&L�P[3�D�,�����]��:��M�K����#R�m A�TEh ���vCR"��&`X��,�����[[Sk��	��a(�*@L
(�3)(�*$3u��U#���7���n����Z����KA���������^�a�����?��~���C�k��7�����-ex������X7�����������B�5��"H^��9����J���C�f
��b�r�����@��Ob����G6(l�q4��-�5}}�w|�<tN��	����"$����������`�Fk�$?W�����C���J�jU&�4�S�A�B>?|+���J|w�f�.��6w.x))��"�=��z�2bfpk�+�\!�
=��(4X���oK��)��`I'+�18�����Nu]L���s�n��G����Y�y�0����M5��8�g~����pl2L�x������A�'��/����T,���������{QR[E]?��H?��z��b�V�)�����E��"��CE$!Hs�gpr�@�<����o8m@�_������f����<A��j��y��>y �;dDu�2s�� �5!{�FR{�fz���b��E�,bD�l+#�K���������d@���E!F\\<���w
F#�Es|=�,12D�MeJk2�L�SH�6E"E#H�ddm*SY��e���R)E#H�Y��)�m"�H�H���T�
�*E*�I)QB@A @L�JH$�!
����"@H�P������l��SV�������4�(�F�%#J�m��6�)�2�&)�Y��@���*B"6�h�����:!��("A(������#��B��p!�QP���
�� �����
p���ezv#��dEX���wB������t���#��0@W����)� T("��j��C��u��.�+���1�A��)�3�LI���a��bU��"V��(������S���!������*�zV"�������u&*�*H�wx"n��*��	�9����9L��a�� ��� ��NeD ���\�WU2Y_L��QL��-,��Y�W*g2H�15M�R�,�)j0QA%�hd�`��T!aFZ

�%R��I��R�%���(	,J$����*RKS�PA*L2���!�K~������a����5�������RB��g8�J�i2.��2�6Al�u)��#o!�H��<��MF��������b&Q���#�6p���x������������D�����w�y��;)���{A�;zfUVa���mlA�U�F=��mv��l�om������#��^XA��f./V�b�-C�"E��;��C���������������&he�A�H�� R!N����p��1�dwj����pHB)���ERD%zPO�f���'���H�mmmdh-)�)&Ge�bB p)i�O����V�_���m%�%XYF��C��������������I$�M"i����������x���z]�XY�,e�o��b�I'rz�~��}���G��� �&e����+��E���w��]�D/��+�N�>�����������a����T	�'���
Lc456�iEE�����
��H'��� �7O�����E@�����TO��!S��*b"����g%�����}�.#���l=��r:)�a
 �@G�����B��x�
�7���s&�T*�K		/_�������:���$K�5��n� ��%������[�������vc�*��	H���B����
����T!��P+0��l�}m�l�KdBX��t��N�: ��L�_�'������*9" ��A#�
������L�78�R��!��/����Vy�l@�x-��}��j����f���c�������B���	/������Y�T��K[(��yO ���U����>�
���������s�/����7�(<5jq��4`�������������q�l��=a�����C�>I���P�-%b����a�M�+O��/�x;T���
h�;/��c$C��"D��I�5���:��=}�����>f�J�Q�[�rC�
�UXE�Q
'�8E-�j1@0q}h��=�kd�j��F�TU��@L�B�?�����o4�O,�;��e�<*d�EIt(�.e���j1rH�Ka�����A�E�`��"~C����������*���xg����e����$�Z1�-~+i�cG�y"�i�����������QUSJx�c	Fr�z��z���,��e6��>^�P?<��c�f������
4�D�P;�8�����C��4&9%Q Q&.���
�I�[(!�G��z"���|���<=U�K���0�J��X��������� ��%�z��KK���D1��*@�R,%����)��@�$�@����J�8
����'"�!���$��f�r~��d;���Y���H!��	o��Bf�v�����i���W~`��%`-P��VLC��(�XL�'�����DWqD\E�%<�Ew���J%J��\7������$#��l�-�ax�����a����F��8^����A��%n�sk������9b�DG��4���(<-�����~��*iG��D�j��1%``&$ ����K�v��������=������2���Q=v�yv�U����h!>����i�K%$�,-�E�kQ;�����7#l����<��~�"��*?���[�\���� i��'�x��L���Q1�a����*I}
����)�8�3�������0��Y�p?}����4��u���M�F�.%��!�
�����
� ���V�&�	�0��D��v��Q�����Y�u�A`��_����7�V���O:,����6�_���}�����T���������-���l��g���[(�o�l��T|�^_�x<����q �"{�O��f�pD��m�>�������:[T�*�T�R������D��l���s���C
1:W���J:�cP�$I��(��_���?��>�t!`B�
N;��=N>�����Oi�U������2�s�����R�4$�:*���ZF�����"=����D�I����@���a~�d�������H-����a#
I���k?��a;+9�?T���(��wp�tE��D\�>����#2KlD��*����{>[~��$b
w��7��2L��G&�e�<D�'�n�P;��(�so�o���TA���k2!2��A;USP��z����y��aA�h������B�� �gEF��i��VM~������!Q��u�.��+�!4-P	���
��m���I�#�,ds�([�=dW�N��	��af`SB���L��TP@�$(=P�Q�_�������&�zdD���XY0�k�O��v��88;~)���I����R�8��0Lc�$�dS�������lD�I7���B�ZY�����G���q��r�;������v.	�����#�	��{Z�mA�`P���~��[��1
�|��<{g�=���-��mgu����l�P�EC�qN�'�D6�(v8b��������bt@/���:J;I)(Yj^��Q�X�M:��oX�J�@��t�����
k�������p
.��)K�p��a��k7Q^FHF�4I�|�M�$w�4
����_���_�_����%$f&�"c�,8LH8*&CCf R
�i�����b,0@"��J����`�/��u�f�/%]*4R%��*�p���H�Y2���)1AXn	0r&�d��2L�J��jJ�Bw����me�e+0]�e�p���;�l��&��4�	�M����m�z���{���UJ���"D�#��1�-���%��68��9���L�1g(�9������M'y�����+�]p1��]��RY�4��etHT���|������uov��1Qaae�b��}|O�M���v��������`���~�����S���!�t%6��9�Y����&��"�J�o� )R����p+�@��� �F�d ��>�H����6i"D,��3���n&vKL�����}nRHD�QN�������(�y$���z�/���}h2��.���eW��s���%Wk�$M�m��6�[�e�UET�B�$D�
A��3Q$1	P"��&C����l���;d�i��n�#�bqQ���(1��hC��qj�X�.{V�z>Z��x�~�q�s�r�N��5��-��$d��Ab������T�IQ|#38��s� \%�cK�@�����
��2$�zq�K����@Je��nX����������8��7f%(���������7�����p��4���
U�Z���&�N���\���!
����)*�x�2-����b��N+�5�Qkl�)�I����h������*R+2#*jI!bH�S$H�K��V9M��������J�d���
pD}&>y|Dl6p��;�"$���7U�7���q�����������������hj��I]�_|s����3���2��������e���Q��%�!N��h�Bn��v>�@4>�{���UPn96��7�L_�Y9�9B!�|8��
R�FY'?B�*'bh��m1MI����Z�����(��U�%����%�$P��bdI��XQ�YH�P���P	BFT U%R�VP"������d���YT�&i���%��d��LS4"��<�����Tz>�Y"���b�.��'���o�<�������	y��B*}b�]�
@4��+2N�ZG):L.4�����*��X����=f7{��z��6�L�"JJ%J ��&�b����`*_�����K�%�/�O�pL����F�/m�����="j����Fluhf��2`����s�T�qNEm�O�f���'��y�w�Z2��6�����?X:Ox|0��h �<�NH���:fp�`���A�Q%��X����i�T�}o���p���&�f�bUch8P������Bg�M$��q���*A�s��u�?����_L'���IN�F���y;OV�%��H��&�6�/�&�����y�A�5lA�����`�fG��UF
j���C�t����U}d�u!#!%~
l�V��l�  �p~`�����	H�����JHTx�7��X�xtMh�.c�
������BBY]P.a
�����V��!�`p�S�N�;��D��&��[�!��*L$���=t�w�x����G����w���He,P6;f\$����	I4&���Af_��r*��	�BTH�A���U�P"HaH�Y��U#�C��Gp����$G����<�I�}���w������q���2D�I��Q*`��20��\D�J�q�)� �������u�	Xbt�<$D�0�kpw�L,Rx2��>}Lx3B���������KG�(��z�:���H_��`�)�$�����E��,���	Nf�	meT��4���i"�+S��K��������C�I�4�n:B��4��M5'|_>&���
g�"��n�����e�<&�����|�� �$�,�=��"I��	��9ko�xc��-0;����*����kP���}�}w�Y���uDT�M�P�� ��2@������N�k���=s�=T$&���������#���Sq�^��^\��kYN"�o����v#�4���Ci������%�bH�!��%��I�I�T�M�ei���In[������M�M�i4��dM]4�&����M%�M�e$Bz��&BJ��A�A ��P 	R�XX�!FP��B`aP����X�!e$R`��A�bBRU���!J�"X��"%�C��[��y��<��w����)(I$�RaH����y�3Hx�b9Iw��]*M�tXU)e,�T�iUUzu��q�v�����2r���JWKQ�����!O���|*U��}Y�����rd�yIw�
��i+��A������$�"�D�����2�3X�0����T�LE�\x��A��1�^eO�r8H�w.�#1)!V�K"����0�h/�} � 4�I30����C�+z�gNb0�VdF�����|x�o���J8�S[�ha����R�A&��������I�L[|�&3g�D0bP(`&.�  ���m���
7S�h�[����/4g����t���}��@�M.����,r����.q.�e�ySI��
3Pw��b�x��U�$M�g,5�^t9�5m`!@w��"}OjK�2W��_\�)���J���a���"6�����1��s��<������j
P�����)[�mL���{��]s��$��{�6�<`����
�_���_:����>�M�����*�����/ DUxTVP�_GL��|���N�dq�]�����
�V�SES9��~w[.���g�����*�|"<���b����)7�]�u��y��q.���������$9����\)AP�����wt���m;Cf24j\�2�d��:��nv������z�:##:'D����WB�7� -���F�T�u@."��"��Gr]������D����zI�!��r!���^����om��OL�(���W�Q�����41��%y�m���3��~M�R@�M"<��0�/�Mhr����R�����hd$=�t������ �~�QB����u�?\�7����k?��\���'��8����1(Lm��NPD���gcw\llq�~��l$��ifm�f�r���s�Q�UE�!���7��]H"H�����
=��:[���6�I��xnD�H����:��(�����Ey����^��o�pk�u�kj���n�Fl�c�MY]�<h����&�k��}?��?-	�f}6�$�o����53���NY��	 	RTP�!&��M��-c$����D�	��QT���gq��[����5u�����@V��5�>�I���%A���3����x���������8��	���En?�=Qw���
���
 �^����=����+en��E�rZ �� �;���B�J���T0iW9�!��6^��:��,6��DHX��?O������oW��t����>k$!������B	E7*��!>&��[��������!%��D5<�~:t�;��$���l�����@y��_gy���_�S�z����#���I���#��(������2F�:�`w���f�MK���# ��4M�t��w��v����Sp��"t�)
K���a�2�����m�.������s>��IC����U��.�a*o��j1 D��K"zE\S�w{|#��o�U k8���P���;1�&�RP!�t*HZ���D�bP$RXFPXX@���%b��0]�VTr�����{�������>) ��wy� �K��x������d��2{l�Yh".�9���`+�0!Q��_<#6_�%T&�������q��*D���� ���8���:�?�*�owET~�C�E_�����F��?G��	
�]W��W���YAI����,)hwH���5;/3n�`o5w�2�x+;�2!�N+Taj�'k"���jD�K�
S���]����c��f����A���V�okI����H7��r���N�E+���8�O8��(�d�D��$�j���j��#�,d��ak��T���9~W�1<OG��xH�=Zl�=���~r��(��� >�*J@E���xt
�^�<~6
�W��<:B�a��3��>[(��'����H'�B$.��������_=^65G�y�m���2EL2F��1���Y����Aw�.����QYQ4��
����N���'�����u�.�@b�"'��F��B�5���O�����FhPLe=����&Fxb~��!�?�
��"�K��P����n�"��*��@ ����W�������|�n��f#��Q��b@V'4���:�|y�<��V��.�n�%���`�s�7"C�;�em �U��T�P>�"�HP~���Y&�#�B�tD_�S�7AYbDQCF��`��!���/���5����=,���Wr���������be�#�NiDD�$���	� b� E�J.�)�%K�����#�XIh1BCIO��������A���^��������t~�^:9�����$��H�$�
�}�x���Z�^���K�+D�Y>�K$��(�RR������$��M����[���))U�����X �R%�H�S�'e2�2��l�R����PPPPPP�

��J�D���L�	!���KJ��56�2��m,���J
�e,��;�Je����@	�G �B#���9K�M!�w��9�p�O;����BD�i�:;�q�M�t�������7���{��I��+t$i������$�E"���E�a����4�{��m�H��D��_(�a��I��$��4���CB��?��>
��C��'��|Y�'|Q$�S�,���I`���ZDP��J�'��Em	��������9�Q�1&�]�w��+�{�� ���_.�S���P?�PW�_����$y�h�$�$�X��������(�����2���H*���h(D]�H}G�~esx���%$���F��%:E�5�l��$�9�"
�H
�~�,I�H:7@6Kfd�����e���E�L\������$���bW����2<��dy���4y�^x�(����A�����%�~7��}+�G���$T�������I�G�'���q���!F����RTIBQ)a��)!V�e0��`*)T5�x�C[]!��beq��qe+���M,���F	PG��E���&*~'����T�������&��K\��+E�
�&ZU�U�m�Zr��oA8����CJ�v�ck�M�uM\���"��)�B�H��x|�?����y�0�4Yl���m��.1r�;0�N���O��1�����y���|H����
P+��������$U���u,�=�	�e���{���n��,�F@}��� G����!����X�("hM�H�M�[��A6������i�X"=}I�9�"���R���u�JCFH��2���Cd�y���4),�I�:���C-J�[��w����w���AJ��5����=��_����P�\�N?���lp�9Is������&\�C&'����[�k��'�Lr(f�oXjL�	O��	��O�-��B�"��I�g��2�;
'��@|u�H>��u��~�pH]�<�:��*M�Z}C�|����%����VS^7�W\1�q#��j�3����jg�=y'HMz���`�f/��;Y?1I��'���C7��L��#�����Y��;b��-Y����C="��l�������C��0�D7u��	��/��$����h�����e"ZX�w�|AQ Y�>Qg'^+qP���>��~��J���$$�"�u^��������==���ER����@�)�1P$��Q �$��4eb[�[(�����t����XU�H�*�a���$r�%����1���?Y����C�3��+����+���2���;��[�������e�F����@�0$J�m0k����USC>^MmN\Z�-��c�Q
�����gL�$��D�@u��|In�)��D��*��������0<�@=�H����("P�-)"���������|����b!��T��I������~�mZY�d����m�e-���i�6���u�I�e�|�=0�z+�� ��l= J ����J��_w��Y��
1�!�Z����mIb�7���\DI����MHW�"	Pe��11��$:�:�P�8 ]��p�%].������w�{�~2�*U$�'W|w;Zx^���r#
������ZBA����d	B0�2hUK����z�O��#�E*���[xT>P=����I$�w~�v"h���Q7b}E�5�M&����#z@]#��%"Du�$��/�/��U�U:��
SZ�Vj�
iN44*��5����L��,cD�M�d�4D$�0����~!�u�X�`���mL8m���LDQe(�erIg����> �)�wis��@q;�`d�0M:���S��]SB@�����*n����cMm3J$��.��R%���B_�/q��>�O4	R)B��{_w��<�A�&�����H���RD=]6�����d�m�����(+���<�P�����aC���<8p"lF��2bB�����v��4�ez�
#���K�`���`7u�?L�i���	l�d�?���x������}��q��!-
�(�RU�*:�7�����r�;�)]�l�7�1��@����"�8`�Av�U3O�t��WQ����pxO�>�CI��������n1��E�*opb�{��h��7������H��h!1�c{�_C���!*{�$gw0�I	�'�Z���'��U��1L�
�*(����#@J�
Y1����MVM������������Z�[h�d��+QY(��"�UJP�E(�B�P� ��XaRY@I!`�$ ��QV�!$��I��Pf$TI	YDfX���i	��P�$��PY����VdhU�iJH��`��F	�����e�������VO����b-#m����e���]����C-3	���������7O�~��P�/��4���$m�Is��2&2Z\FD$ZV�TP���/���&�9,���%����hA�hEIA��4SE������0S���$����~����o����P��0{�OL�j�������C"�������,-� �n�iT��!�H:>�XO�R%��m��*�/�S����I����BK==G���f4��|8$�ibB��HT���� ��qh�"JT�fD�f�r"�9�!0*�
�1N��5<N�@?�x�Y�A���)���!4�e���t3��'��@�J,*4W8������5���i��$�b%<����:��r�U��f&F�19[�}`>��������>�����p����H������#2E��P):%���g����,;��q�%TW�":��
O6��T�li��L$$��d.5��>��b9�S�d*�,y����aVBn(j<��*�}G�Qf�����P��!'���v�GL��A�x��a�1���I
x];��~a����E;�&�Ixh�>B�"e�	#&R�<4�D�����\���5E�S2G��A�=��!�������D��3�E��/���v:������7a`�B��I�&N����yg����<g����P�y�
���C����3"j�X�X'����B%�]D1� '9�,#��Y�G�@6�(�LP��j���"Y�$���B{hx
�y�rz8�c��p�Sb���6l86%�N����l���p��$rFH��:��6��c�5�&��K����{����1�9DDk��1���7��
�N�MTj5� �y�^-��1�{�����0%*�����9����������G tq��={;����x�w��%�[���	��+TsQ�8�:�V$����6U��u�GJ��;Y��-�����{p�}��)8o���t����S�!��`+����6�	�e�&,��t��u��d��T��m5�K]��6�8hYKZ��Z%��A�&�)���rR�!�6Y"�%�l@�Sd��a
��b��k���%H�2�H$���<�'(K��e�!��@6/�����!�C
!,�����=�w�>Q=�+�/K�3i�o�����yY���h���SM*�WM���x������u5'(�.:��I�6�N�0�
$��H�4�4�+��������M`��D�h��!H
�I)�]�PP	��hB`��5��h��1*��j�t��.fD��o�3��Q^�j:��R������q�=�`q�b�K���<;�]��Y!GTW�IQC#�����A;".�����6����?�������rB��9�,�kF��Hh��k�u���#�Z��Sx��H�=��T�m�x�����$�e,���($,*�#, �
)�[E�-T��YQ�1�4���o|��)���l�s\�����D�2�9Z� �
�3;$�"OA�/�ORK���R���|>`{��J ����%e�"k?�����3��B����	�?H��>=��=���+!�����6�
����@YT��"T�����q��F�kR%DCzUd���IU����*U
�")�Y��WP�Fm�A��.�`H����F�1"���TM����"N��N5!����!!)�8J!Pb��d8�"���&m��J"����(�~������6p&�,D�����;����2yv���{3_2����HqigtX{�!��~J���Z��=fx�_��S`�����>�e��M���<��F)�{������>�����(g4��o�2��@�����6�Y�8��%������ �� n���h��������������%�k
I�r����z�~���U�$oa�_I���HiX.��P���������"H��m$�{��O�yY*H(�Li�)�m��cu�xC�'���U;��	��*�(�E��d��X��L�5@�o��?��R~i+�H�u����
��*?�O�*�'����H�!�����*@�����/��L�|
�"&����7��^��_����<�b":$qD%�@��2.D*@�F��e���)	0��J�"d� W�1W����LP��T �HT]@��i�C��������/b{C�
��*e�n�,�e%������D�����k�V���h���d
�����b��?�2��A�u��u��0�"����D�
�)EC�Y��z����$�'|C��	�0���
a51#��#{J���]�3#Z��F���l?��k����s]�ED90�a������=����#��gHM�;<H*������k�{���7��9�)�������=lG��Q?�6L�A��.�{����P ��B
g���6����>�<�;s�wYLH�e�������e�QMB�
B�8R�I���6���j����k5�0�(!=�#IQ����H���"eB$5I4�����GHG���Wx�!NL
\(lqQ>���DVG�+�zk3�a�}*�S�[�����O���D��R�_�A:�g�	�a�A ���������4���$��dU���~��=f��������������7T��]�;@��(�2xz{���^{�������x�S���;�K��.0��$L{|��X�
~�.����@��m#�>~�P@����Qw����`}��HP����5�!��Q�z�u��#�BU�]?G�[���J��i���M���� �{J�a�]=;���&O� g����$8�3G��E
BE'lq�i���/@}&�
;
t��ww`�'`�����1�%�S��ie�-M����l�|t��!	/�� �1��}��L���v8��D���Yt��C���Q�n�Z)�Q�9�e�eX��'Bt����g�W�Zx����F����$H0���X������IUd��'���$�UI B$�8��w�o������1=��7S3�@H����>=�@��S�4`�1�?U��<����("��x����Mx(�$@�	�&e	����m������)��%*� 6��Tj6�lmM�J0J	LI)J�P�IK4��a(J��+*(�	�����DX��i[u+�5WU$m��3�(L�0�&�SbM	BP���V�����)+)�@P��C
a,B��S$��n��j�WZ��H
T��4&��J$�d��	BbM+v��U��������Y� �e$�5	�J�u���V��T�`��J]U*���	��+n����V�1�Be�Mmu����� �vS���q���������0�n�)�4 �`�2�%����	�����(��LH`�&�K�1G�n�549�����p�
�w]T7"(b����?��A\i�����!%�sq�"hB�5�F��Dk{1W�����bl��*u|����������)���n��Yb��6�t%���!��TL�~���!��>��d�W�;�4��<\n�X�����~�ZJ��}�F�>��
6��Z��6��W����������'���)�g�T�!
@�7H����W���$�&���|���4��W�y�'��b������D�p}����G��j��S4�`���~�~?��������M,�2���B�'��2�%-#k_ �<�m�X�r�F�u��M��*�(�-���$� �)�{��|��;�8��	h{`�L@�Yx�s	LR)�6������MM����X6P�ML���	B�,9+�Hm�U�Smn��-r��)��BR�����6���>��$q
Z�E�2���24C`M�v����j����pa���u� �\�L�����������W�'���\�o	���k8����n�#m�H������l&���6�'o`��6��RTl��ZB1��m�\LV���T��tk�pAvF���!w5�*�(Y��"X�-8���G&�VE��u
&5`��!������P������B��m��U�H�����BJ�����$��Pu����mD����ACjG��@�v���
e��	�I	�!�!P�G8��k|�X�l
�I��K`���?��<��v]�����'gF�Z�~N���d���P�w����>��R�J�D>2��^��j��p�5��W��=��H>�7	�=��J
�g��B��c��� ���� t_z{�x,$��}�q���?%��I&��k��2�T���ZiRMz���w�����P�I��@RJJ���+���Z��6���������X�JB�C$,6�w;���Q�\=���\b�����T�C��)O����y�f�G����@|�u���B(����L:��T��t��)$$�]L�	KL>F`�A�\ei��c����'��u�V�TZA���M*�6M&eS"���Hf��l�jQ2D�����R������j���>�D>�~)b	���+�T~h��e;��9���	�n��sS����H��P���A�2(a�]�!�U�,�%32�U!be�4A&�h%���$��Oa�)�v	?��j9�;��I ��q<�v�z�Si�r>�I#���k�������3��;8�0�zo�b:��"[�@��z�$��pSC"!��2v�@D��Z����`��E�}c���uzD�
(�OBP`Jj�m���EU�n�������K8�aN-J�s4n7�*[$'d�W�i��$�����o&�p��EE[3�oq(av��cN6�
g��!QG��TA��7�t?���(�1��r�V�"8���`@��L�������v������#��$1�N�#U:@+����FM��k�����$��f#�H*�H	U��Q���aBF*�d&-�cQ���3��K:�j��{#b��������]MQ�m#*�)�_
'6-M��������D�`b��o�g��������Z��_���� �y4#��@e��nd,�F�-}r6gE��"�i�^���~�|V���Py���S>��l�� �9�!����N.K'�2�YpA�Q��G��h��1��L(��o{c���������Ai-DF3b�X-%��%��$c�K0	��H���M� �
A�0�J��T�J��e&R\N���������?Y�l>�7��s��
������{c#��iJB�7��D&g�\?~����_���"G����+���m����[�L�S�[�,b�c��������$*3,�Ed=��_X�-�$�
�*���0&_�D:�JD�����!A���9�y����&(f�-)��G|u>r�������8���4r��8\:���c�dM�|�<}l�K���1��I�N��<6Yh����w�)�V)�o{aCi&o�5$����Y�aB�L��8�%��2p\U �f�-6Q0�,I� �*%l/X�j�+���gN1���U��GA���7��-�:� �6F6�����xihT��g��8��4d9g�v����"�7Y����&��
��e����N�`��b=|m��@vu��
��+�>@��htA�y��z{6����<GI��,5��,~V�����'u�����nc�0m7�X�R=8mm&�(,�H�(��)��j���i���^��n�C���H�3��<��F�����C|�lk@�\�q��
��$�?�o���+�#i$�d�j����&�-��(�B�iN��|��x����ss�����B���>�!@�����x�@�1D�=�����������U��!B*�@�^���y��:/��I���N���������d�/C��/c�y��_���}�HwTDz���i���C��k������u"a����
w]�$""z}���g4���BUN�P���?M�Q�������	H��~('�8�	!�pP�N���xORFz���z�pJ�d���D1�n��?k�B{eTGa���4-R-�^y�G�~�
O��bF����~�#������W�0LD���AII'�Y�uvQ���Z��*"�9-(���m\��5$�\�c�+���^O��h��;�,�D�����W�faJB �i=D��&8(|�������n�|��52�l�P��*�uq�f���G�~Zvm`�4
"�x��8D|9c�D�H#}��hm$���qfMu�Rl��E���6�����z��{Y�DF��8�U�����O��>�Y�
I!8r�:]��g�@��z���_q�)m���F!S�	�`���Lt�B�R��A!��������+�o�I�8�a����� ��Ux�
	�gH	o�"d@{#��i@�
(�wH-�y��;��j�=��'>R	�k�j����ze� �������6��.s�@��?O���!�`�t�"h�t���j#��Y0�=;��5U
$3��{Sc�0�����������9:q���v�vA���4�P����� ����&w&"O�������\Zy1�v���z��>��y;�(�I��z�#�96_PK�H!��t�����8��y�[����z� ����[��de6�*aDD����q����J��J�T�SZ�c��������I-o4Y/�� !RP���B#�a�����s��Z��/`a�8���]YvN�_�Z9w����~X��;`^�����v�$��4fS$��J&��<[��"`q0m�T#�����;����Z���V�U�&V`��,�5��a�k��z�tt�u����N�j�rJq���a����N���;�D%OnF ��G�8�^rWBf�"h��.��u����+m4��X`�|T$F�Y*�j2������N��MB��s�4���e��aB��*L�BX)Xx�4�N��PjF�g�($`Q,�����aO���wn�)�r�`�l��(�^� �W�l7��P�����6�:s$g�8"��DG����y�	���g��:�@V���E�E�����`#;�	2B�IX��HB���V�]�L���tP��Y^1y��D����8�U��������8��<��A��l�H��f�3�	]�m��Y����CY���4��	%8` ��PC�_�Ir�;�����^xgA�����d��pi'Fp  ;�`i��~�����<��"�@;�^;������R����${+�� vxi�;�tm
k��Z*��9��bP����P�c��	�9b4���/�Z�%�R���{&2!6�2����gXriC����c��W{G������Q
G�D�� ��$RP�d��}P����w�k��d2H�������8�.`����2���\b��3�����T�x�����"��<M/&�\$	�N0���B�`6��P�7�	����[n�P�11��Eyp�t���}�q��H��0l!F
�+�x�PRgd�$ ��+MCs!��,��
)d�Gn���wv=�*"����~c���A�*.��qZ=��72���?
��N�JIH%�l��a�8����7�m����C�z���Y)4��1{L�f+��6�������	"X.��cdG=�nb7�1*!��$��t�!���&�yOpvY4�P���9K#�H�O!�����:�:j%Km�m'
��o����������C�&&�)Z[ek#H�V��Z�)M�Mel�J�Zm6R�&�Y�u\������+���`9������p����;.�'�(�4!�:��C=j<"u�������`;�z�}e��#�7�����M!$C��HY��������TI�I�aq��v;�3�}�YdVf��d-��hW��=�)�JV�J�!TVsa�T�����J7��:�|<:x�?�`x
�2q�<&:�	�A�D�j"�H��$�AS�/Z�B;��K�L�����'��0ma"�1�������i��BI 7�.'X�L)X�d�D ����o!���X��!���l7I
�#!_iTh}����
0��@-�^X������.�����L$��1���m\�8����F��~x=qE������� N�~e�uf������������@�W���
��D|����bz�qM�:��s�.��j���Q���M����i�	��K��r��(B�V���x��i�\r�R.�X�
��4��@��[`����{�����4�e��P4�Ee���r���e!?q�LYB�m�*��8)�2�:\f=���~|�������8;��m�L�=����_����[$V��U����/{���G�oE���	���������h� w@�H	H�2�%$1S@�����h���X�ep�B����&h�k5J���D��y^����f��B�'�{�������HC�s
5I1)J����2v�@�h��di)�Q���;��~������/=%�2'1�������bf*'o��>F�;���|~�x�����<��-8�$}�I(��K#�k$��� ���=~IT���G��x���`+�4$���G�0��#��tXHIO��
I��6���A�2���5�Fg����{V�
EC�d�H��G�*����)>�?o��z�2���Sr�b�0B�� ��#���0y&�0`�k�����K��k�k��?�2�����4P�"NM�3"R�}r�HD�Q04��E@]��)���������dA��~�\k��8�����E���6��U�I)�D�+�l�UE�Q��B����9�����}��I���ZS�!���O�#�AIQ��52!L�s���&�Y�N����#�����<����d�vzjn�����A5�2g�,�d��zD���e�F<��=��B��	�V��8"��|s�Pz�DQA��I2*�#�z�����{ST�MS>�r���aEMr�=���
<��"�J��sz
���,��gJDF��Q����*�
Z���V�E�m`�e�\`9�$�D$0+/�s��������� t�>G�������'�dzC��"���R�c�F�d�����T�����D���	�G��M������p��.2&������;d��xEmYci$�Sp�L��	?�����p�(�=��i���{���`��?���*A��"/������Q�S��L�D(1}n#Vc��2�.��v�R����VIU����vu�Z�����O�Tj��VLK$*��;!�����P����W}�1��e��� UmJ�}L'Jd�Li��v$�B���P!%>�(�d)Tk~i��1~-<�3m��+�o�x�u�m��) ��AI
BIeZJQ$l���0��Q $S���FSf�4��U��!�iE2�}��}%���i�����F��@4p�&�f%6��m�
�d�Sw�cSz��C�����eC�������@�s�lH�����|�"`�@3"�	��������c�h��*���Q���X���@*�*�,�P���qB���=KI"�v�p���:"�w����,�9�$d�d��+(N.xP1>��n���s0"�����	x2���;$.l\9]��
��������A<�z��H5C���J8�U��J�$���
,�,��mDJr����D%��nb�2L���4��{����T�|��P��e��i��������B����Zk17�H�, ���	,qO���W{�{���L�k���I3i�z}`��a�^&�L9�������J&Tds99i#qsWl�,���{��x����,��9R�n[k�����c\�� ����1(10O�33�i7���Jm��0un�a�)����aC�tMC�~�\�Q(Q)K4P����<�M���t��hP�2����3k�u:���#u�,����0�u`w���h��XeP�9�oRs���.�`�b��L��������`������������D=�z|��O��(��|�w�
}c�$3������T���p������;n��on�����M�;�>�����s��=�Q����,���!W`��|�z�T�6aN�]["��;z�c��� [�>����E]�eG��we[
tU����^vg{���}��0}�������J���
T���@��Oo@����L�<�����zpsn_oy��V�;Y�a	E���c_@	���������(��a5A"�	PN��f�Q�����h)�
J!JX�����
cb�o`5@�^�H�&�h ����!��z�A�������@��!EB�'��F�
4�4�JB�G�b�~�OT�B����=�Mi�@�FA�
4����P�S�'�i�Q����������%$ �D�T�OL���j~���z&��@O��?����|A�V����f
}]F5�$�j�L1�u���@sAu�G��{E�p.+��\E���+�q����b	h&�u��o��p�
6�lR	���S��������������_}��#Si�[������X�H��g�3�N��������,~�����p��#�Q����pk��0$��,A#�������2D��41��BK��`@r?�!����2��L�F��Hac�_bG���<}�m���o-���y��7L����������[�]0�[������x���,M�BI�� ����b?G���8�8���xAm���T���$�
�������:{�p�Y�������t��{R���cA�m��m����=w�_���=���x���6���~����/����XsQl�d6�e�-�ih���+L�B[�W��Np�^�1����U�����v/Qi�4�����?lZX�k0X]�*���*WT��L���� &���*�J7���q=���*�uD������v�uB�Y�D��������k��I4��BQ��fa�J�~��%��<��I�5�J��Z������m������ue�Q����o�7Jk+�0ch�d�Y:aA) �0X���P��P��`�JZ�Fc*�e
�2D�`�&�6b
j���,_�`�j�Y�8�$2d�]U3�<AM\@r�������H�=��3�6�*��y���o�����j�Y�6�[{U�z�@��R�v@f��J0XhYMD��&�L�)e@3�L�L�����0��QU��
��6��|��=���_�R�u��f����Y��0:�x���^-����|�'�p�������@�M�u5%�����i��@b(����Y+�i��@b(���(����^��mL��T�V���J��/=@��>r�_�}������aa
tr��"�h ��rW�������N������:0�@��Qz�~4��XHB�c��
�TT��	�:OM��P
5��H���y2��Dr*��WF���y�}'�����r*��Q�����<r��Dc�@8�Z�B#B*��g�V����x�N�"���=���!���lL007��b�*��f��T!:�
��r��!�H��[���Ve�Sd��"�Z���K>$�(�h�a���k�����T2���]����S����c�('$�HB����6�~>�>:(�Q+�D�i=��(����uu��y%��0�2<!Y����V�U�����u�V�HBI&��M
�����B� �ec!����i�m��F|2C�����c=�2k���y%I$]2�����a��n���W�<PP���k�!j�L����
:3��xw����_��A_/h��N�^�1�������J�m�]�4�}�t7O�����P�P�(H*���Q4��YA��&X��v� ���,�����N�i_I���n�>wa�L;�_�$"JB�Q��X]��)����i��dUw>��RB2�^�(H/��m����n����vd���a�p�**@���S��Kb�JV���0RUH���e�q$��0�^��U�`��UY�24���KB��B�������?Ja����?���$�Y�:�
�Xa��N
B>,G5$���WT���K�:�U�$�]!���
���@�|D[��0����.���B��HxH]�E��_%0�s�B����pPb�Qb������Y�i	`���e[�@���Qq(S+I$�_O�<i��\
���Lh��qf�_*�R�D���LH*T1,%a,QJC���Y�aGL�X&n��/'��{�����,�*�{*�������)@��Q$�i+5b����D��U�W?��o���|��^i0b<��/qnU"�F���G&���JZg@*��[��������Q�cklcc���I�M��M��l4��*T��R��E�����e��j��������d��Wk�&�����$��Z��	5@62��i2P��C�������H�t�A����j2 2Cl=7[ddW"P���������C�}��������gy�hfff\�������������0l!6��M���������U���w�p���GQZ���^��%��0���"��������PicLbH{�z���s�N�R�K�:R"~�e��w����s�Y�u.%���=�{�{��c��V����NTx�-Ff�2C$��������y��J_�A�%W���V�X86������b��."P"���P?���		Pu�@X�E��-u�!6�Wm8����-X�KP����'Q$� ���V��5����A:�����:��z�%�h������t
SE�";|��J������x��	���:�� ��>*8���c(��F��** -	�!V%|�0F�M�*�U�b:A���h��8AeN�D<+{C�x�)^w�+.�������n��rl�:��d,�%���DV��&3������8�r
6�O�n���w�|���_o-�Db��C{}�gv��\��L������������eoN�}G��w�����1����
?@�^���m�D��m��4�k���q"f�o��do�x��N�_�G�?��/������P��U�/x�*�m����lLi
��&�bI-&I6"�m6I6
L�f���ZJ�Id�,I%��$�YJd��d�Y��������������B�����l��f�	�Gd��G�c�f����%���b���&�Fdt�]:\��#�D�J��q��)�NU[��B����r��=u[������,u�r�����I5�q��4��0�D�U��Z���]w���� ���D[�����QE����'�5���9*:4u�=+cbM�H�(���	l�v�������h8.���pL��:c��k.���L��J�4F�F�2�j��U���fj��O����5�����OZ���Y�H�X�Vl�b2S�v���Ki
��%-��?���0G@X4�&�S5�q�M���������/;t������[N�&A
#��h��I�D�Y5D�MAE��Y�.��bf�n��d�o�����m���}�	y�]�TrA,N(�Ax%"��K�����(�hY���Ej�2��[1�m�C,�fI�L�&%�W?��r~�c��U����>�/�J�{�����I�|E�|��J�d�[EjC6o�������89*5�N���!����Y�x�Tp.|�u�8RHp�b����s��>���T�l��%,I,�J�H��I4�$�S$�K%I&�Jd�*J�����31��fY��<TN�;J��Z65����M5�����z��������6hE�h���\1��6���26U&�dL�V�H1R�v��,���K��vN��q�>�;|j>\K�[��,��c�I��MD���[Tt������P��0��E8��3h�5GKN"��t�rF�:���:���l��F�k%�eqJ�3���,�L�t�rT������n�A�:M,s����=<'�vy�����6��n���y����vW[c]�*��tYc�NN��U�N�c���put�psN*h��+��m
����&F9�!u��Vu\+X�&Sg�������[d��(��M���bY���QgW��9�9J8�mus����[�F����@���[Y��Au[�-1���1)���&�*��-%����������3me�2�� h'��������J��7�����@�h� ��o�[6����V����y#��\G�^�����y;�i����������S/e�r�D��c����|R+������;'�;z���em�WA�6?������wW�{�F��5�Y��`��k��*|s��^y�~:j��k*U�[���F}�]�]������c�,8ePA�;��M������<����=���&l
��M�$4�$����/�b��s$l&!�
�(c��qp�~?�%-��?�GI&����A���T���\�����W���������8��|�_g��y����h��I<;�9� �L������u��`�,RB�r
 o�@DF���r�W��GM!�
>����#���.�O���o��=uR��{�+el�f�l���&(�$IlY#%��3$��k&�l�����HE�4��66Q�6Fk5*��Z�V���]����?RO�W�y��3jne��d�.H]��G??rD�q�	��-�-$������K����$���wn������#�F�$r�ikw���i���vw�RzI%�.�~=��$��E��<�`����o�Ho�%�$���7�3;���+��H�m+���/e�p�6�^�������[�G�,�KH�[��b[w�#�+��$#j��u�OI%�,rf���'���g��'����]r��������i����%i$���#���ZM�X�c��m�y��Yw��Kg9{��tm'��*�i!�=��l�����&��72����I�B�X��=����KvKQU�g[H�����I���wi��sy�8�nG!�m.�y��&��.�gxE'���[���K�HIR���o�%��0�Oe�[��D+���M���6���m�%oF!fI#����Y��H�tV*j�4���C�6���=&I%�,�����ihr^�K@���z��J����.���r��ID�UI�c������Z��1��~n��+.���u��:��I+F��%	X��R�������x���}�2I���d�C��r@�� ��	��XB�kM	F���6�^S�w)�2�&�
����q�j�I*�Q������|z����iFM�F*)����$a:�	Zp��a	@KB�kO[w��6�B�%����6���
b���F(��$�,���m�������j�
l���lo>@g�l?#���D`���}���mMd�SX6����Aj:Nw�z�CI @@���U��W8���;EH*���s�����<��5��i�������O j���P�i����!�y��!%��/����X����V-���k)�����-JZ*�Bb�R��I%d�i4��h��41C*)��&��k6����$��i��e+R�)�K+0��-D�$�&�Q�cm[}tN���aZXZ�YDJ"Y�I����VPZ"��@��e�E����d�ww����337����pfY\�%�I	B������Yn����=��Uf#��d��k*����y�0��d+(��I#m�$�D�nIrI$��$cB6���d�!$��N�6��J�*T��$����I$�`t*����:�|���!����&�c��co�=9�GWI�I��}k��Ww[�(BJ���*#J�H7�h�"
�����I�L���M�
�M��`sy!�n�wyT}���q5^��Np�������Z�cci;W&�'amV��m6���_0�q�/�%]���������M��-�u@WSY�p��]6:�Q]�,�'D*_�LS2�$[��A�f�!Q� �$�rB@�-��`��3s����~{�����j�5�{7��y��{3/�#�������|�����N]�z��#���|&����<�S��E_��*���	���'u�] I*�2����Y���N�����9:�eV�U�Ue���(�H����;����"0���;������""fJ��9���$2��QD*���*��*�P��P�#B�T�������UZP_���\��
�[B�.QO�H��)�����D*(�T�u�n��r�:s�'u�t��t	'qe����
����+#2�$�D��*��k@��TV��h���\�w]���5��".];������C�������(�EE���
�D.Y�U�W������A��7���7�a���m#��JM�^����%)J	������=���(��%^�w��]��wk����
	��|!"S��5���C+Z��������t=�^����Q��T��2�"�?/��P=&x��-1�����S��:c2�NHiZemW4T�{G�a�4�������|DF���6���Z�*�D1�'E����Kr���i���W�%�I�7GVu���Z��������Wi%%E[�����!q�6�N�no[�Va-��w�X*���2�b�Z���g�8�����$�HMcPhJ�r�������������I��H"d������&N�Ax]�Z�H�JJ�s�s��%j��]K ����"�}����^���>9���y,�c�V��1����=�1�>�W���r�������~���%v�x�2	������O����j���?�.�����o��N���K��x��������EOw������>�_4rc1��,�1�����c866�"�u%I��)P���-*���F���x�����<Cv�WR����g��}Og������
��
`5�Z)�L�����2����d�����S��6C4�kd����j��26�d)3S#VJiS,[1�2���fK13%�e"��Y2�)E�d�,���c5��������-�6��0�T�Sc
�Jm'z�{��q-�HrIV�x�\l���3X�k�)�&�"�f��I%�b��m��+jLTI��L��RU%Jj4V�2j�Sl�I�)e��4[�k&�kRJLe�5�L�d��2b��j��F�����l�F�r]����1a��,�j6������fv\��e�=������U�*�Yl�le�2���)�1�f��i52ii���cV�d�T=o]��V�1f�3I6��Zd���1��TZ�+323Kj[&j/����:����~��-{�S�78_/ns?����	^��s�^���n��K����s������=�+�y�o���<�}��m����{����)����N���oz{��\�:M�q��g����iNf��jwns{���"�9���R�2�I(&��K��c��$��$���!$p�}m�H���[o�K�_|��6w�{��B�q�I���!����!���l�8��F9$JZV�
��9�}�z������/�9~������.�HK=���������HJ�I��-r]�{�A���-�r9~��?ZWw��RI	&.\��y�$��\�t�����w�������'v�Cr[�o���p�tI!z��/�A$�$��bY���.������<��*(I���!��=���9�����,9A���`7"9Up��p�����r��5�s"���A���5D>�K��}����|6�s�fQ���o������6�R�V�Q`�$PSys�m�{�VPi�3EI0)�nc��YB�������t��z�����?���z8����e���kk}�:l�y����Jt�,/�[����b"s�����-�-����t�������p��)I���.�����xwxq��gI�
�wo��
�2�,�m/�]bS��xz��z�����n�'9�t��y�0����g{V"/l<�m�~������������z��i�����iG�+^V�r������n|�������e��k�%��\�m�p�DW+r��.Zr�����<�������N�xO8�������Y����N���o�>�;e������\��m�����,�����m�4�I���n�����k�m�u�Zk��]u�]vb�{x�n��yr���.^��fz����kZ����6l��vy���m�t�6W�<x���,��6����km4�M4���o]u�z��������;�]���9����HB~!�20��p���1��cF:1���3��W+���O�������k�DV����4u�/>���Lh�g$��:���=�]^������h�;�]V�'l]��N�&�N�	�\�����I�8���]���E��;,xY9[f��
(oG����B�8�M���I�]N�;���f��o]V���:Q���a�����+[�v���[��l5���� �k��0�a��K��	��cf��m�����D���xS���lC&����	�����W����������`����hu��r����d0�%��c�j�3fAr�����v���G�/ �QE*�!�����'��[*(�xo}�8k.}t�IQ���P�
���*������Z���l����8��k.}t�IQw�
{���QE
��d�t��v�Z�4����y�!�Q�����%DO���C�*
���SlXC�F;9�����6l�����]
�M^<
=e���T]�DAPS@�L_,b�w��2����Db ���j�������.�+�u:�����f��i���f��'v3�W���Iz������t��h�x��rf��&0��X��p����c����6ll��9:Z���"4e3��OC�7��t@*�h�w�A�aQvpx����N���^Z]�5�u���]���g��l�(���&p���`�!��#�
���)"�LG��u1�a���66N�.N3����i3��OC�7��tE.��QN����QQQQP`���l[����QE*����7��|�$<������P�1�����i�|����DX���n����v�������O:I�����\�xb�Z��2l��&�5���F�S11�������d-d��c&hlS2�j)��925��
����kl��MjKI�Q��S5Lb��9b��cR�SX�����hq'�*�
W�~�}V���lQ��c�DI���&LE�2Y4�)1����1&)�fMd�F*M3m,�52M&�%&��������m5�)4����4��(��b#����b��I)1�H�$���LX�)I��5�)�I5L���"�I���L�$�b���K&�E&��"��f��DX��3E4�SJLI��$���1E�1JR[eL�4Q&����L�I��L��$�E&�M&$��JML���3?�_�7��A^�YU?�|����%��'��VX3d����_P����O��KK�gBBo�|6Xd�<��M�<~����%L	e��Q[�1���`�*�r�D#"Q:��@�P���:r�P�0��?��3�o����mDp��V+���NE:Uc���A����d�!������f�����i���K����������4l�����2�eF��&4���dI6�2��2����e62, �l����MH��$�(�2b��i�E$�)��4��d�����}���C�nW�!)�T�'��s�$�{�u���I�cm�+:�<��1���}����2��p�9��"������o�)�\����<�x���~��%HK�I4�"�����Ml���%U���0��%QmN`�a��L�l����46������=���=OR����a52hx��6C�0W�����@*a�yNk��HV�S�����C�<�8�B�p�\.Yo6�`�jp�n�N`a���1�\}6c��c1@�6�}��D��cm��-�f\�q��s\�v��H�3��&�~�63�>]��6��������5�_����/�_om��r�3�I�S����S��ko=�H��v�v�V����A�q"�3��ml�R�]S\��s]�I�A��2H���,��6T5aq
)�h�����P@�;��QED�G[Ms�.k�v�����Yp����q!q&�$�E��B ��YM`I#�XtF��5q
)J���A�@�Btd�5e2�8����O����}B8����?���=���Q}����gf�v��9��D�D�3�?��ww����{7F�tjT���9��8�$�^F&�b_"u:�(4L��Cn���?��)Z�P|(�U��g[J�632����Bi?7�/��8�A����~#�m>c�p>s�|�g��|���#�>\���$zvS���`�~J������/Ri@��]R<E������$�����%��L���z�G���=���=�d������v~{=���~W�V��M�fd����eu�:���+�����I[;���/a%�w*�1��14�Uh0�i���l�q�(�*mu�|	�1���}HG��;�����/�������������a�������]r��Mr�u>��"�������~��������p�2Bj�{�����V�=Zv�Wd�]��\�+,e�XvU{��qf��a��\6�~�����l��������� ^�6 ^<����<�~^�q���<�y��������.�1@����H3Hb40���9�=���|������R8�2��R�(Sn�Up���Fd��I���h�[[��
������H���h�]�eJ$	s��|�����d������[,j����������y���f4�34��e�aJ:���~�?�����ff��_������>��������^5�{�f��7��*�}����:��b�j�Y��8����-����Z����-�q�sP�!�6��������yy��^K�b6�D`Qq�2�E�6���]�^5��[�M����`����f!V��J��r���+n�zfn����W�3�����*�'VZ��A�
���\��A�KjT���0	k�8�k8�c�`����FM���~�S�<�?�M������N����f�\����R%F�&A�����H��K���V�y"�m�U����
�������(�O�U��L��E;����v��^�]�k�m~/Q��w@�{��M%��(�����.c]M(�;����=��4��l���	���U�E(�C�m]Z���W+F��s[@�V�(�~�W%l��q���DA<]��qu�}�!��&���n��;
���U*�(�[x�x��������J�Q�@-�`�I�}�f[������<$����bCEJYD�&#$&�E$�M��#HQ�X�4�"�%��2�2�D�I1M%%��J)R����Il���$SYi���,���i$d��-I6DG�?>�o;��*����m������)�n��U����85u�k<�[��W/�Wh�4$��'GWV1���5�4"*��%��@ZHsCPL��lXL�IM�TM�)y���7FJ����cQ�w(����]�@R���)&HH�z�$!��w1����{�~y����fQ�|��8��n9�y��^1����"B�=<'qLZ;�"C���6�C�\5C4UTQ(�=��{��@��_k'h8�+c��QE%#'$�d�I��
+��AX����[__�FM�h�c�m������"���h"(�m�+&��b
��F�b�����YU����z�?�~�W�t������-L�1$��e	-!@m����Kj�+b�f?
����I--$�e�b�f2�ZM�������|�B���Ev�����]����Z[,�,�2���I#m����M.Z�fY�x�(��:q\W4f��G�������51"&�n�mM\�$�0�I5SU2��L�����m����53TY4�.�����L�I&�i�#iFI��(�33a$�J5������ub3c�Z��$�M��II�&��R��2d��f�d� ��[��s�%��rkkUml
���u�+f�%!!%��d��f�b�
Mafm>������_W���f�h����]���:a���q�2�D�q�@����lDo�dT�o;��ZII-&46����dE�J�r��3���^yUy�y�UU]��9�Y�I:d����<������������sQ��4�e3-�I@�IU����2S�]�)��(y-P�vU�J�V�D1e��U�n���R��&!���"�K�\2�������	m1�c��UwE]\J��tF��R���������Wt�
���
�;�<B����+Pc�C&D�%!T��lA���/�$qs_�����%��v�" �tc���;p���;��L����/}xX����>TU<{��/���'I�-QT*�(��w���{C�!�??5�����w�P�4����m5�0���$R��)�R�Md�5�u�WM6}N
�����$��**k4������p���������������c5JV�k�K\�Th�f��K}����)$��I2-�$���2���[o��p��$�&��eD�V�R�� ����)KlJ��'re@�K2�dY��mX��f��l���bc�h�7_u�������f�������$��f�%M�^n����%��J���7�.��
Z���,�=89��i�Tb���m�6������z5��p��H#���
PD��45 ��XwR��;�9Jl���7"	�$H�D�#�#$����l����IF�o7�n�j�7[����`'�w�(������tI"$Az��E�*�;��^8!��$	k�i��EP]��Hpw�����Ob*"#�2�8����Q��F�l|��}@��y�Um���[Q�),�)d����SH�P�	��L�fi�i���i�dRb0&M�f�I&fe{���lV���b��=op�'����%�y�RW��{�L�W������8��xq�n6�p��D�d�I$� HJT$%sWk�Z�n�m��dA]���m�~?Oh���5 ��fL�4N�H5 ��S��c�����"�P��"��z������UG����w��uKz��x�5����3	##�\�-�p�<��(�����yTpIR����T��{�s��pu�x�����\0�T.+�A@	�G�D��^(���m���`��D�!�vC(�d��UaM����p�NU
�v,�M���{C�=a/E��z����:�@��8���UU�����#�,���v�dM�����sD�58�P���Q��l'DQb1"��[v�a8���hA�2�EQEK����)H������I$�II$��g������w���Ws��E�]
�����:W�j�ER�+`�/����A1��d�� u��E��Ov�j�yuU|T�������elV����k����],�Rd���[�]Q��4QEQ_o}�.k� ��!�{yS^y��fBBI�����z4�z������"�\���UL.�|��8�t���6�E�'�����<q����9�'��u��Bp�9$";�#,?�����;9;n��]����X� ���L�DI_eT`��c`��Y�T�M]K��Y��Z���u�W]]^9p���rBLQ�����HDE��i��"n*$I4ZL��u^�R�(7�2�T����E�K��yJ[Ky���R�Qb�Hj{�����Yq�_���z����-Kct�z��]�1����F���:��`�p/�o�6�jh�gh�F�b�-�:f$���IJ���Nd#����|����9��<�R�!?O<�W�AFIU����&���*��;�d;��9�0pn>�>���y%V^���y�v�����oW�[�R��kN:���������^��<��3Ts����+6b[VdMF��V1j�fKB��j��kE
�+Iy5��*X�%������26��F������M�&����x��}c�qDz�G�u��������N�N��W*�x����+���n#�r*�3�z����ws��A�J��J:���F��.����T�Uv�^U����7:����s/=q�e�*����r���q�Ll.��]W%����]�����y��{�t�����|��T�^*3���Ew�9��9�{OiGk[E�v�o><�(�Eh��(�~?]�R`�l� �*��s32BF����w����o���0 ���V�k��I%�$Qw*_�
UV��HBe$��Pb�b�Q
lw5~wwt�v�*��]��e�:�k���)��
,������#��D[9�X\��NX9:N!���88HDC���,����������[_f�������$$Z���m��7�J3)�V�,�q�7���w������*[�DRA#*�I��[�d��J�"��J�["��YuF�\���1H��>sxt)U~")*H�\ �:!�����C����j����>���������Dh��W���k��u�Z����I6��I6l$��i&Ji��K^s��	�h2r��PPR���)��.`�O�.�nD�sm�9��1��m���~?����1��f&d�F�eJVKiJ�fEI��P@F�F�(�h����L��b�5&6K��m������}�(���aU�)�E%��(�g6cQ#?+L"J7P�lN���"F�+~^M7T�Ff\q4��b�Y�Z���E��HfI�m��(������u�<;/;"��K��^��%t��n��l"J�D����{�m�����^esV�\e����yG8qRQ���S�rI$��I$�J@-���L���n��&L�6]n��L�m�"Yi%�e���������m��]]�h��D�I.4'1Z�V�4�����z�W�V��<O7�~m���������0�0=������2G����OqJ���F�����%`J]���,%BV
 ��!,�������`�0�7e~���pT��!*��q?�Z�����N&e����0�-Z�b���+-L�2d��+�,�X���N-,�2i��T}��<����o���	w����n��(�W�A^$Z^U��<7w���W�w�����+�y��U�n���M��G�x �G���d�9vs�'�����$/��
�}=L��f�1�p��F����0ZfA�FL:��l��wzYq�n����&u�i��463t�������8T�W�Ut4TMI����A������8p�w��p�M��g&r�M5�
IM�v�B�Vf`Y�m���^��\�*�Yw�`�@�UUKa)�0�@�C��Q�a�b�;[L�H�H�V���vPZ��;}����U�0�Ww��;D2��U
�t������4�C�u*Bn�033!P�T+;��u�	��,�8=�QZw��n���{���p��(a��T�T�Xs���J���*�d���
���"��������
�s��,a�����
" N.�$(���Abc "b�! �BX3�2������i����d����[�l����zH�O�����	>-��){�2��Rd�HA��� ��< �8�H���<7x>x*�"�wG�[;8������	�����.�v�T+n���U��y/G������.<���Fv�=(��Q�FP���vX�,vt��:tcD-8Be��'HHZ �c��!���
��!!x!f��fs]�wK����$����P����!uK�Ba*d�W�U|+����o������YG��\�}��{ur�wv���8�%��$����k�w�����j���i�n��3���s����X�s__4���[U�Ow6�����b��v�,���������������N�N����ut]�e���o+�i���v���������K9��s������w��]�;y����79���s���{���:����u�k�o�������sZ��������������se��l��y�|���\�[�Ly&��Wu��n�L�3���k��sl�{7w����X�&f���9���W���������nE3�B�!mv�3�������Oz���75�R;���l���+��.[3q�����������P�����_
��=|K.d�n\H�^Zy����.��������]����I������d����Y�d��}(�Eg���|,���f
\V^n��_~��Ag3�o���.�;XD�GPt��{��i��*�*�<�{RH��^���*1PU�����n����X���gS�S�y������m��N�vK����We��v�R���1���c���������wsN�H&�n�B���������
��!���Igk��ey�����u�W<��&[���sY�3�������_h��BTN+���x�����;Wj��b�XG��I�$�wv��]�Q�rd������ci6�����
���8���?������!��4�t�lu�c!n��P��\#I�Z�i5�%�n����n�IrK�J����!d �q�2��B2���0e���������gvt4�tou!]��+ ����BE�YI
��f���Z����D�WciH����Y�t���$9u���a �c�1i<oB�K&MZz�n8�g=����q�:{c�d�� �����fffI��Y��%��x��*���_
���z���\�w����-Gn���������m[��<�����,q����n��7����rKk��6�W%�������m���"�z{l�TB��h��uj���M
Vr����iyts���=r�F ���q��1cq���
Q����P�����E�!�'`f�NT�W�! %���B�P���t�	�����/,2pcjI���������8��s�;��{���l]��]:��a�u�r���C�V�Uu]�H
������^N�v�}B����3�SW��-_h�}T��KJ,�Id��"@���B	<�C�ar��W�Y$�;J�L�����C���j�$+��y���U��Z}�e�����u� �JX��:�te��t������]
����
��|*��B����%e]v�]0����%v���n����J�[+J�{9����f�����)"�g+��7���8x�;z'�b���������^�I�����xA��h����}��-����c�6M�S2������w����ogB��_�X����~I�~�q�U��/�.���G��O*������^������*��W��W���\y)	Ow���K4y���_�<����LBU��AYZWGo����!�{�<>��~">%�9�^��+�����r/'h��/�e.��}��G�G��a���������>�O*�j����'�Z/��j{�������B�^�� S�%=e'�>����*<;���W�����������}��;R�E��v>�{���d���D�lIX4I
�/�&��?(�����l���HJnv�����{l�~����"y1�8����;�������
���"�"�_z(��&��K�R]B���Y-J_�A�A�J��V4e��&V��F�V2e���2Lj0�i��I�FY3F���V,��
-�����ii��&�5Yff)��5�[
dh�f4c�,���0���9*���������U�>A!iqN�(��dJ�E�Q����'SI������M5j�b���,��X4Fj���1�S%���,��V�mZ�e�������T�h[�*��b���i�Kc1&X���kMf�Y$1)���X�5��L���k3V����k
��ih���,���cc4��������4�X�+SK�p�Zb�j�j�iY�f�L��4����d��L���hq����4�g1��54e�mK�h�Yf��#�$�d��Yc���^�+��������U�`�G/.�|�\�����{(�EGe��)	O�����2}�J[R��EF�������*5%��5���*�E%cS(�(���E��k�T����]u�B>>�z����p�R2'�w�^�[��(���O�@x��`��_�z�.�����#fh��Ly.����R�s��}�K�eHw} �D�H��C���P�����O��Jx��A��#�#�SYM1L���Z�����k1����j��l��XV��KY��5����eL�j����X&fX�������4�\��$I��r00�5�G!.+�����y�2 d�+d�PK�A/�pR�R8G�K=��P�����O�����=�tDW�������p��nLj��jQK����\%S�:���r�9.�>@�����*P��)!��R�j��O���������S��G����sQ%y�+�������UQ�?����VR�b��a�w:���#������I*�]���/CQ����
������EfJ���kl�%1#�K��_�z���Z� �w�G�t���Q��K��dB��$I�4�
K*��-	a2�9�9�������S�Uk���U�������������]z���v���8����M��;����-��V�S�&L�i�������if��h��l6ejMSV��f�Q��X�e�Z���1i��X�KJ����e1�,C54F,�����el1��J�c
�LmM����Y�U�2d2l-b�������jf��j�e��iZ��#2d�Mjdb��MV�L���f0'���� �������-���BS�<�Y�Y6�xe'�=��������a_Q�z��=���B��]�.����`����J�����<���l�Zb���N!���
�Xl��f�$�,��lmQ�-�mII%bT"�25
ye�������KdX���k;R��L��04�����MR�F�LU'K�M�m6�m�-%4�FZKiJ���*rJ�ll��[�CLR�F���uUq����H����w[v����T�T1?��^"�ci�n��Zi�Z�@@���K�����z��i[61����+A��j����SZ[5�l�+U`�0b2�,�f��SQ��e0Y`�%��d�d�3�X2��f�d�j6f3-SCRe���XY��La��%l��VT�KQ�e�K1�������el�1ib�����y�p����/$y5���1��35$X���$3Q���&2��6R�X��QS5����[$���ch�kW�W�z,�K����Z9%�~�J�;s��#��]~��j�s���	M&p�wS���E��t����TS���]��4'�'__C������rRdG�B=�����q�w���{��"vF0�}�������}�W��u�IS�#�K�������� :4~��Q�kUaZ�Z4$�4�����!6FX����lC��������6#V�����-,���,��	�����R������g�~q]�>;���l�d|�����|iOF{�H�^C�;��)-b��������!u*�g�����^�T=��)�I;U)�_W�h������a�D#K�G�����|.��){���1��pr����������m)����@c�*�EWi�1�SM&Li���5X�iV��Xj�!��2�kV6��S*P[6f��S-(5MJ���f��R��Y��
�)R���CM��Y��K,�U�M��ZX?c�s��:l�����ol �A*K������%YN�Y�-��D�5�,��b����E���`���?���a��}"��rB��3�\W�L�����V���8�����������"��H���8*�F�D\�)U��m����'$gtX9���#Z�����n�8t�M������]������zZ���'������JU%%�-%&�+I��
i�
j������?�!�i+�~P������+�S�k����<@~v���jy=�j%�I������;��~4��1#�����e�\��S<d�A ��A�{j�hTfAK�|*�{{�{�f�������/���O�/�t?�/�I>����'*���}\���?BI/IA.�����W$)�E��4������$�^����Wx;����{�?�PN�x�?�:�G��d\R�y��;�0G��r���F4�l�K1���"�L�53J+2)f�����![ Z�QM��mmB�PB�R�b���S4��L���QJM[i$�c�=������#��9)V}�X��|��<R>��[�.�����������YS���~u^�����^����O�rPK�������f����nnnnU?aS.l�r�rn'��1�gG����vR���>B�'������80�������U%��;��.���"�<.�b%�RvR�������;9�*:���A�y�B5����'nDUwT>����Q�������K(D�"P���</:H��Q����\���iy������d�B�=���Z=jT5S��a�C/r��<>�h��u'H��./����wb�@��_,�5�R.��_�*���=>
Bu����+����
E�
�iJ�U?2;�(��EO8��x�|s��y_|�eV&�bb����d�������G
P�iz�EP��A���|����_�*=�����{����+��xO���G/��
Oz>������$�_�U5v�`������5A��h�V��5,�#�bZ��-Z�CA��hY)������d�M)���D�ZS(iU�RdeL����|�kcc-�d�(	�A��mS�+1&I3�B�	+2��D��fj���MRph��rL.k�Y4�X��#U1�[�a�V���p��$H��hn�����9��qll-d�e�5#�j�0�r�$��p�1�#%�ifY(�Z]�M[v��"lMZ&j�.��J6�lD�,�[J�V�R��p�*�KG(�%������E�������H����iU�YcE�C*sS�d\��,l�0�Ig����m�"�%��mh�����k3e�6l1�2'&RP��C	�*����x"�Q?�*T|�C���U)����IU9<y��7U��QX����S���]�����9�u���9q%��.�r�w��]��zNN��^^U�N��_h��;$�$���Bj;R�x�@���\�U��>������>�+�����3��C
��,4�����&����e��b`����y)P���8"����p��*|h��]t�#��_4��z;R���|U����?C��G���G��5)��{��qs$p�!���gc����GN*�a�����8S�P�9<���s�P���#`����F#RLX��,L��I��!�Qu�����s���W�����"�,��M��T��hF��j%�A�R���L�6��ur��u����~/�������t{<�\�J�����B�	��J����#�2���m����>�����~�{]�M�g��^�P������w<"�w�+��%S�<0�����h�K����"���R���w+��@o�-J��]u,��K�E�*@z@}���X�i��6ff���Ze&��R�"�4��R���Sd��[,��&Yf-Z���Y����T��~�^���qx:K$d�_�r��/a_rN���;�1w������W����Q,J/��;�H�(�+��T��k+X ��;dv�NH�+��.���U���w�,^)w��;G��d+���]�*�>'�"���� �X%4!f�D�P��b�G�.�������c,d�X��8e��*xaq������a�1���\�"�Iy����/H���j���Z�j�&Yf4�-eh���i��&Y��M��f��Kaec%�Zd�b��,��Z1a�Z��c������5�1�ZZ�"P��.���`�O��%BzU
vd�z��T+��2�����/j=�!���������vG���������l��nm�����D�����������v�����W9����uri��kj f�m�m)[Kt�[���to�T�����U}e<BP~H�H���y�Z��S���t�����Z��h)��������A���>������AU������N�S����)k(��T�Cj�Se�5�V�j�d�i�J�fM2���i��A�b5��PkRh��&Mj
R���hX������"���\��>�����QX���02�2&��W���)^H��'^7����j�d���D<*��2F
R���Y+%YP�4,m� ���bcZ�5��j)��(�6l�-�[3���&~��
(�VO����.'��))��<���DayR::��v�/'h)���O8^Qw|j�����r���V����e5�Li������������������k�:����aw���{{;��5�}����}Y�n}�����O����h�yi���4�<������y4�L���N�����G���={kZ���j7�,�����=����v��c�e�o�b���[�8����a���{'{��n����nT�����gy�7�=U�7�M��;�'�s�w[��l����%����v4������(���B�4��JP�}TC�a�@
^����ld����m�a��z5�A %@M�N���(@Y�)����*�$P��$��dF�;��A�����@�&M4�M��OL���F!����A)�B�i	OSe=�=M0��P
$�R)	�l�F��I�����hM4d)�@hRRDb��	������I��6��I������4�M�d��
�!��DOI��O��j�(2oT�P=A�=A�y����#��G���2��b�L1a�1�%g�����V����������1�V��������]��-��.��5r1�b���cl0u89�b�����
����t�����8pa~#Tj��M��:1���Ut�_�?������&�@�Jw��Wo��D�}kx���V�<��h�g���8H"D)��HK���!�sne5oeK�t�{5��$��+��H����A����/��	&��,��� ���~'[	_"�Q��x�����#��L��%���$$!��dy%�$<w��9D�-��E*�IB����E �y"�b
)�p�[kh�C��2IM��������Z7�(o��	$��CT���am������n����^8c\"�u��L���D����D|��6�l.�I����Y�"'a�%�q�RK	=�D�BQ:�x[��H��jz�EH��WIC~����"b��4�r�M���R�.�[o�����o�M� z�^#P�/p�W��eKI$�����o��ZUQTR>�ppRRURYf�R�$��l��A����z��w���b������@���3	��.�R�c�;�\��h��$f�L$��KZ��,-\`��A���h
����	]�
`��[\H*��bq�����E����N��m��0sv��X��V������aI���������$������!����/ �������m�7?��,# �b�/w"��XFRSc�,f*V�v��F����\4.�_���N#����N����*�������w�����{��:���������66��r<�xgoG����`��=�}Vp��5�&�{�5}i\f8^������W�NTO��_���6�L&�Rcm�4��h�-~�nh�I�b\�$}������-�j��QlE��]�7]��8�	��
��J��Z���nu��.?M����"B��B�kred�Y4�w����������^E��1�$�R�bk��l�����=���u&eE<Q�>�u�O%��j���"PQ���4��JQ��n��J4�XJ89�������T6�����@C��kQ�u�hj+<����f�$����EkRffUk�UD��<���0����������DX)�j���#$���CC���YQHYX���2\7$�m�����*����`�����($T���np�(Jt��S-��I� ���!��>����GrS��xj6KG����F�%��Y#��(CO�bdKh��S�*i�����"=���6�u��3���"D��$	�({/{�`_q�#��!r���:K��R��3uRT�%
N�Nr�s�;��������������"���+H:�(B:��2�J~r�8H��<9�c��\�����p���U[n��8�����U[n�4r�*����4`�T������c��*ff�R�IQEl�"���+J(�`���'9S��,'�����9���BJ�	/UJ�s�X����jW�R����������DV0h����M��Q�������RR�,[��jd�������-S��E���6�v��`���R�U�fz��H>m+�v�A�L$�u�"�!�������i)
b�3���U��%���3mZ��~7�����8�E�O;�$�������o*��q�-m���[�OfK0�&I��r9���NZ��yW���<�q�������Ko����I)]DR�H����]�|@��u�
|s��m���e��J�V�o?��:k��vE�kdV$���~�$���s��������VJA��JB3Ed�_�~��k�V�DBh�A��Dvv������}��64Bm���J >Ek���	c�#c�0�e>�T�0�BCI1k����X�i����������N�Z��u�_59�2��������33�\�5�j�Z��������6C�7���E|�������L�������Z��������f
����o56
M�.
R�L�����Z��@��2�mKa�������IB	BM��a��	�<�56m�s��hn��kZ����I$t9�{fv;��5L���i?��	��?��QH���N��UU]�;��X�h���a��)���5��N�S����s����-�5�e��Y&f"��6 G��G�1Q�mA���PR�gZ����:6w����5�"�%�>v�7���3����V�`#5�|���5[�����(��W��nk������QE"""(�W#��������0&4�1X�$l=�a��3332L��#��y�'��Y)=����y���E� $):�����F�[!-@H�e���k����m�#��#S����DHU�O����m���(�����D����
����V��ZW56����x�����i6�i�����e+r��*�p�^x$/�)k��W����6��!�?��������>�����|�
i���P<v���R�S�[�I�.���5X�&0N>��>c�"�����O80������m�E��
��5yE�Y�������OM{>*;�/�S�><���,�����n^�z����:�.�[�������������,��V���UJ�;��x�m�e����~���m��7��$������.658�������s�N����l(��q%!qt��m�9���U��8�7��
�$n�o���h*C4�H���F��"��xg�}a�i~�~@c��!�)(D�kd�YD����[5����M��&p��Q+V��Us���h��*���?���"R�P�)F�MS�+Q�VVJ���$y%���U�Q4�mjZj�5��Tj*�����i����{�N��HR:�H�8KJ�U���>�������M��N��������{BC�-g��9����_,/1��W}}��c�n���c,c �R����xOU���i��l$y
M6Vk)���T^�}�����1�U����/��FX��Q��Ij�&����&��y��:��Wk��rA�
��	����
������-��o���[���?Kilf���~�N{l���}����$�����dz?
��os}�i��Z�m�����>H��B7�������U�p�+������z|�����v�G���xw������(����oG$��cM�Cv/��?�Q�������.^|?Wb�����#��+�'C���br����>/X�q���km����n�)9[{�,��$�7f7��cUm��]X4���7���<D~(��/�;��{��=��r��#��Urh����'�������z������,x�������D��'z���>���{���ZiL�{��*��'�p?o��z�A�:��m�I��S
I�V��z�%�������'�o��[h?����O�=���$I�dOU5�h���������`��6�����t�Z�S�����R~o���rH�`�����1����p�"{u������������Y+��#�����5<DJ�+4�M��H>��	�*����>���#&��y=r5���GY$��)j�{�����+�Ur��w�w���Y	&�/jf	{�%(i*�&�/�Cr�����K�4�v�W$r��Q���+��3�����/�o[�$�?��%�K���|�qJC���v�lf���S���nR1�P� z��?4�ml���������Z���_8H��$$��� S�i�&1����pB[��*u���H���[�@��_����_	rbQEt������z����^"��x�� ��=�uK����#j���;������T�[M&������WW���~�[�[��}{6*(�J��k��No����L�����!�q�^���9��p��b��"
zev����[��~8����p�Co?���	��1�v�(���6�Z��A@�T��&�����>���_c�UU*�wT��kT��~���V6���.X������$���������`<�UEQW���6^�p����b��'=|�	�������qE��D�DQ��DFE���Q! :�&^����v�g����<����������9��>�p�/oe}{�����?������m��m��v�E����G;\��37����[cE������rZ�����$�ZU����V=Jm���
a��#��2xy�>I�R�Jfi3<PL9�;��8��:���_/�����I����J�E��e|}���2����O���>��\�W��w�U���^����(�	46l��`AL%����e���L��R,�'��f����)�0bqt���_T��UmR����F�9��[����$u$s��3R�Vh�t��
����A@g�{0<|���
�B�B�>.v�333Y�}��~��d}���.�@Ix�@��`�C�g`�V�R�%�()JI-O���$����AE�
*�����GH�G'sY�myl���tD�Wk�"����wp�n��7Wd���K��e�����)��Y?�L}������F@zk��!�:�2�hG���/�9k��
e>�����1e\��e,\|��;>���0�yM8f���BD��nzj^Q��@����C�bT����g������uN��6)O�{�^����dh�6����B�x�+:v�>�(�p�u��` �yg�_S��8OZ�R}�q4Ex�zt�S����xk^����_�a��8tV�-�S�R�����1�dH[��6��1vt�Q �JD�v���m"��&,�QeF���r�X�����oYWE�A�~�����<�'zSH�_Q�����{{��w��2Q������k�*�����a`Qja���Le?:��/fSK��-|#����n)�����t%*/��`A����YW����q���I��OY�?T�4��$(�<�a/���iwf���x�����.J��j��g�w@�����[P��U[e�Y���p�K�>=��[c���1ZL���>�.w�I��z����<f���`a��[p������r#���kB�B1U�;x��X,}^���w�>������������}o3���J�WR�u�������N�j�zS�<�}�WN���HB)�o��q���_�����$��e��[*F�Fe��i���#)�5i2�[j���#\SZ�h��d-3S,�d��%2�$X��L��lk�Z�3��y�}��w�3,U�{�pm�D�UU�U[o+d�-��71�����������������5�����U�YVS$�G�bD�H�xX���k��i���	��h��)��u��1�������8���1����T���"�i	,�QEU�.���^6���ff&f����$��^#3*������s.�35Y7)�����BBB\M4��1s�wI�l�'�a`���'���G�N9
�W�I���
�$r���A#zEB���V>CcV*]r�fP���]����C���|��
�PA�Gvp�D���=��Z������aV�8cI�i�����7������M���R�'
��5�w�)��yV�0u���Z���b�+���&�����nH����2Q�PXE;}kY��G�5�&}�x��=���:E���A+d���������r�0�)�E	::�����#)����P�Zs���C���s�������F2_�UR�i@[b�F�U�;�B����������� IP���0�!�������F�=�*���g^�$z�������""���&7>R��V"0���z���P8R���9�e���D�NNt!�lr��<�(��<��$*
cI���p�d��2�N���]8����5���4��]V�k�b]g���N36��L�m�l���&
U'&�F���L�p����iV�m�i�������S:��Y������d������	��OhY�X���J�����]����)o)m�DE����F���941J��U+f�*�!4"&DG�p���(yZsw���|=!�U�������hL|�����Zs�����O�x~?d"�����e�:�gB�Zs�������ue>C��_i+�}kZ[����|�;k=��I���j���l�����[�=����{�T��=�f���L�f�2�LjMe��B�H����U&�~p����W#��"S�jI52f�c2�3-6�P��2��2��
M���&�iA*feS$�,��M4�-1����,���$:�S�|��M��r$��� �s$3�"
���VO_C��rr��A{��[)��z��%o4;���G���&��8�����������TSlUH�b���!��H�e��Xum�k=CM�vJ����+f<�����(���5&����{��>��t�T!�u
f�����
�sp��cLk2
���f�4e��ki/�cq���=o�I�6I���v�R?*�������_"��k�4�PL���b��z��={�7������.�����+lN���D*����DI���:�Oy�x��I��6�Yl�1���Y5�:�6C�>f�����=�'�zS�y6#����1J|���d��m������k��=�E���d&�i1����\�Q(!��%����@M���BZ�7o�������H�w���~���@l�Z��"�������Cv��C���c��w���Hy�zF�����
hsg��A�Pm�=MLOp=�w����>�M������b5����g�y���Mz7�G7���8.|0�vM�p��T
Xw.G���>#L}fL����^���%���7�o�Q��	U�Zi��j������L�Q�2�����
N5��2�3�\,Yd�=���Oz;{����������HG�I�*�N�_��?7����^��{(�����~���Ksp``>�:�7[L�V����������,c��GJ�?��3���sD��������D�����.;����8����;>��!� �dDFf������EpP������l[Te{��Y=}��N�P�<�Q�40��Hk�}�����fRX�`����.o,�Ib�E�c��������ok��a�I��A�|�f�1�>��$��W�;�B�&����C�s�9�M/�������3:�b\jG�Y��1�&4�,���8�LL�Q���Q�&��(���h��=��M����2H�����"�Y��,� �~���B �qkZ�����5�0�'*����/�
*�k��
G�IR����{�hm����9;������(���Pu�>���X�^u����<m9|��n�����6��c�9#���=D�#�|���9���w.G�?�{���������[�_�|�����|a�O�=_���Q���4c
0��Q����_1�]���fl1:���?��=gVD����m������v�c��*�hQ�1O�G(���X�C��q������?@{�i4�I���\��!�,�{������N�����z"Dl� �fF��LwI�<��gV�K�F�{R
�8�������x�j?O^��t���������?w$�*��t����������������*$��������a���^����~���g���%�>i���^&��q�bi�%���x?�	�!���`;����<����,�n=��������`��l����V���.C���+bI�:��s�)����Z�b����ka� �}�����Dk""t��r���},=���Gw���z��=	����<�#�����'�@3��i�QK-������M`2"8��6�����9�}���,�}�5����K-2RTj����$���M*��n���"�/���H�l�������x���9]��3�!	'~�����2�����5Z,�#RL4Y0R�CV����+|�����%�*{5�[j����Vi>P����dq��2�C�q��������*�J��S�%!v
%�����"+��{F"����T�������c�+.��O`�����a���F���Gc9Ph
�o
�)��'���&�K*	��%m����y���\c����eUS^m�'��p`����x��_��2��"����^"�Z��K���n����LU�;b��6���������������e�/Z�
}�����G�,n4Q�(�^�;GY���[cGC���t��I���/�z&3���%�F1aw/*JG���/N�V����<Ae����J1P��b2�`lA��Wx������]���+���8PP?���]9O�n�53�yyr�f��N��R*TJ�4��$"d�P�X�k	R�J��jM���4�g�Qx��|5�N���w���j�v���7��[�Q.��V\U7H�[��{�>mp���8=r�8�l�k�p��oxZ�(�VnV���A��
+��X���?���iO�v���_��=)~�P����F>��
R���*s�*��9C���P�I���~>����%_�m�k��G�MI�r�p����������|G`cbo�����ve��W�����q���w�x������4�:�:g��L)�ch�{���
Y� Fx���\B��!G���s�/��'�{�o5;�k|�Z���-e2�7�r�����8�8R��b�������b��w�����g����=}=��Z��UST���AG�7Nn��3G�H�b�pN��s���U�p�j�xd�N[��m�Q�-���P��KW9[���|����K��o������r�4&��y\���'i%���Dp�?>���lZ������o�;�:w,�k5�|
OB�G����|�:;����UtW����I$�I$�I$�I$�I$�I$�I$�I$�I$��l���������3M_xC� _��{j��:��)3Oo������m�$���1���n[�t�5Q�PI��=��59�q*��E8?�����21eJn�I�����'�;{������.���o�+Mkf�"D4��U[ic����|:q�)1�Y����]�7p�jx�9$��o����n�01��+���y7rm(H���2�q��S���26[���
��l�D���T��|~���}�oK���5��2RI!	BB!r�+�Ee�]	F��Ua�sc���s
�o^�a�c��%��>�_]���]�
�`����I3cL�&�f����M��������x'�U�0\���2<����M����m��v��o�d8�a�.T�A�F@�Z��B��Q�4k���n��.�[Ds�B��bVXu�vd@f\G��K-
��}������>�u���*�,��nq=���6���9�jW�i��|�m�.���<�Ou�M��8S�Xh��{�Q�j��r��N�����l��7owk�W�o7��cce�Y6����G(}��n���^�(���vE|%�p��k��NqX��W��������t#GAu�"�BbLE�(
��)"4w���`�!!��#d!^c
������MjY3��Q�1�:J�i
��V3(I$	��i��h�$���lP��cJ���77�N`c$�9,�c���B����(U��������#��$��I	$����m%U"���D��V�UR��6�R�
�k:��lPX�Gv>S�����pW�\�/R�R�| #veU���Q�"T�����R�]����*�.�9����@�*Ml����a��0�6y���*����&-n9�S���������y��7%8T���[�8B6�����8�3�e��A|z��C����V�bl���{�2��j������6*,�Q�lbl�A��{o�0F�aCq��M�>b�fd�B|y�N"�]D*���^��).�ty:{}��y���/=�-���kB��3���8�Hj�y�
�� X=�Dc�*��1^���gE8�&"Q}=*����8�`�n��G��������m'�$�<Y�|4?WR���UJ����oo9�3�A��fM������z��#f<�^H-�����T���"�""��4����36��N�����!?��u������1��}����1J���w�S���B���l0a���re��e������������F��0;���U���!��l��8������+�_���@�����=-�����a���4.L[�B�4&��*z�\'�]0�������[�\�j��9�x/ ���z�9lX�FYl1�o����V�����/�x�{'�
'n�6*P��U�����{�D\[/F��f}S6�I#r��TK�u�3�$�DG��
��&]C�,�N���D@"��tvu� �[�+(��@t<�R�T*d�����J�P�H�JH�v�*U5a���K��A�~�u4�����AUR[5y��mv�6�W�su�r���U+l�gc��������E��N��WD�I$�:��p��I������L>
������<������a�����&bI�I�RXU`�d�)��������a
�*�b3��W-�	(_���HeC���7�lBQ#�a�A	

�l�5�Uf(�����=,TD;�w������Y4�&�
�92�;�("7���q7���V�7��^{��<h�&�3��y*��B!����L�f7�z��x��~����"Zo�Li�
���X���p�I.K�m��U5������k�7�����hI��h6�Lb�����7	@��n�N3�~��]I�ws�+`|����@Iz�E
���6�����}9�-hs�FJ��H+�d%��w����d���$�5% B���I����	@��b��&2��9v�{�Q��������
G�L�l��\DDh{�<���bDA��
�{�m����0T(bn������G]���SH�m�MI�I=�S�������^��MR�"*50�`��n������c���e
��)�=	�������d9���ye�m����3L�vR�.+6m���J�#H�6��<*I�������s�z���"����	 ��m[*\"J�X\���I@�0���K���y|:`A��Lb1���
4����������/ �����ZKdr��lwq�����)�l���U�����4�����%���%��V�����zW���&o�=����:����������%$@$3��&
��i�M�W��#\!2��N�$��c-��xU.6+�o��mF���[��������0�{����rIV��'��R����8�s\�����t��A+�d���/���*�,�fm��
�s��C�

����7Y��jM7V+�&������W����fzi$p��z�������\�u�=!��s��2M�"��H�J!�	��I��B��k�Mx���B�:�[�$�a{R\��&`��R*X������,������M�����
sowtL���1����j��0�xn�%Q/g��r�O~����j�����	�z�}H��iz
��#{�a�q��h��lh��
�5�����$��E�Y�����[��UW�1��\���E�!�%� �[���Eb�W�;i�*{��!Cj�����'�]�%j^9"�������A`��X��8����G���&�h����t�(���+�R�4�:NQ��VT�Mcj�B	�2VJ��)����(�d��T����r��Un��.T��i-(M��4Ha&��(FIC(D�bhca�C��ut\��u�U�R��R�i����X�Pj��0P��X�(F� �X�F�f�B0���n�Zv]����,-]h�"����P�uD��T���J���ECp�,"ahdRA�"��P-E*�"�&hI�[�L��4�����-:�n�+eo/���3F�N�{6j���Z���W3�z�%N�gW�������"��)������h���9�V������a������7�{�l����1f�j�zk|5q�Z���m���[�r>'G.��-d�7�D����7�*�L�<'eE9�D�fV�3X�r�_P�%t��.����z�����������M	-���*�m�K8vs	Y=L��!$�q��r�Z*M-7�[��nV�j�[�bhZm ��u�R~�!$ �%8j��4���6�Z����Mh��<V�AS�x����BJ�
��b��Q�;@a�$��$���K�4�Ji�N,B	~6�����K�d����X�A����x �2��%Qav��e���T<U]vJ3-�!�($!$(���&�%�a$��DY[%��!��Br��#p��$h�c�9���#�=#�!�e�r�����WiZ�R(i���$w���{[x��$9�ClFI�%��-\��,�����S�y9UHC�u".l�������"�|���w}ffj���N���kf�V��D�BI$�����D&��6t�:u�f����s{��^B�N�Z�/+\�@�Q���d8X�s��B�"�a�N�	�8�9�]���+/Z,[�_9���A1z'M�-��|�������D!$ �41����n$��iv�}*"�q�(��x���A���8,��pp<���#�rG�8I�r��A�ses)�6��"�P����7�����7H���G�g8��������\���?_�"�T{F�{����l�]�������������@�:��2�D5JD�0�GV[��h-�6�����L[�|�2������������u�S��Rj
^�d�����p&�P+�
����B�K�b�:�;u���?�oRr"N������37X)����P���i���|�?[s$����v�����63�_GfN~��"�7��v|��t�=W�������Q�USA����s�U�w�]��r��)�TG���cf
'���dCQ,���k��3u6�F��s��<;rG�'��S+W���(�9#�/���Uv��p����?z��s��@��H�?8O�|S�|�9��������H/5%^�\��+�����x�_�B\��/����y��fa���"h��br>�-��NZ��/z�J��v����]��*J�y~�wy�U����/������_/��l�Z�Q����9C����N�?���;�}�e	�b���$�`��^������w���d�����x^�����i�xbWd� ���}���R���g��������g�� ��@P|�x��RT|?O�=������������5.rq����Y�T|Y�����j��X�5�9�u�Uu^����?cH�G�^1.���F�����}p�F���%��dIRU���^_=�0���z������#��*J����;���L�_r}�rN�U����O�p��_��e����G��_���U�������w}�B_EIQ��J.���_t%�g��+����2�Y,��uy��O�0�>�A�#O9�$����^���������?
]GYv\��/7o&�b.%���K��h��}��K�W���i}g��]�>p���'O��+�5U����>@�hi�z���g��y�e��y��}���&���O"Q�J�}O/�^+���Az���<Sc����q���p[��S���$R�����#�o&����j�j�����[��h�I�"��]t���l2��@�E T��e4�+���[�2�J�����H*X�8vA3�5�un��T���2$8qB�h�P��&���h"�����kt��#CJ�	�-(����IE�����i5�U��[M��]�n���K�M�����I��mM�j�F��ke-*��cs]���������g������I���\�.%P�z�I��%���g���Ry���O��]16SR�z�����nM]k
�����x�O��.D�p���jqo��)
�'
G�O7`~����Q[kZ���<�A��Y���"HkW{�1�K.d����Q}���B��#����e������Q�J����?���$=Q��A� q'�NA���?��Ys������WZT��)��f4��R� �UY4�ec*3cM�efE�����1i5�Y��M&,ke%J�)�������3cL��?�#��Wy)2C]�x�C�RE�B�G��M��!��US�/1��?���66�V�jji�V
��V�W$��6�#KS)�Rs�l+�V�@�V��24Xji[���q���dD�^�D��)i���"�9j�����2�*�s��u�k����x��}�>U�Q�r��iff�t��c�}D��O�M&P�/���x�U��&"��_�f5�p���������	"����wy=��Yk����u����Z�4��,X���Qj��F	/�����D6��e�$G��
g��Iw��U��v2'4�����o���_�������E��i�?A���~�m���*�?@CU��:���Z�;����^����<�v������E.��U�3~�P|)�K���e���>��jC��<:�����O{�G�W��
2O���1N��x��doR<�mS����yvW�Xe+�{��l�>���c�W�_��S�8��=�d���l������y��7RJ�A�G���w�J�RO������0�5`e�6��.)9*�F��������_C�����e���M�I�J^�+���G9�����u��������I]��?����������[a���Q	�����_}�����[��X���i��?�mE�V��a2*1E����]��7��o��H�j���W���`���?�����dP�%/��'A��\K�i��DC�)�V����am��P���������U��\Ip�$��s����t��>�fI�NfH$a� ��&a������H}���4LL*#X^�!����R����Q�����M	I��/�D_M%H�oO����EJI*y�jGT�����f�HqB�{v:Ge��G��$"��G1U[�9$y���gWM�o���4��Bi��t�r���%��*�?�?J���l�f6nn������U����u�|�x�W#�uz���e�r)u���{�� ?w��w�.N����W*�����|�������,�#Q�&��)��29`�S�[`���t�5kS�X
GT>e��
��q?���W��{���e�?y�HH�5�����1;�'}�R>�
M>���m4�#�	8l�5D��R��j#EF���Bi'��i�![�S"���F�Z��XT���46���n�
���'4�$W#��#����
�J�uQ��i91
��n�����F,�g6�9e��Ha%F
L��A�_�}�t�$�<W8��O}���������P�s~���|�������U�ekl��>������I��5l[(����5�+Y*��*4����Z�ij���Kd���SK#H2�G�t�}|)w�8�$�+m#�h�����t<��z�-I�?�e�kf�����1��!�����kd���nk�=�G��>�C�������|��a�1S��H�v��A�!"�M��$o�����'��U~�uN�>(��xg�q��L��$�C��g_wdH�y�jt)�7��j����>��q>��^&E <D **�p������AY�3d�Q��34c��.J���>?���R���ViQ���Yr��.5�s��m�Q3E����o3���9�$�.����*�&����\.����M��RC\���DM�H��%2r�������mQ�VU,!����H��ZFrV 'A�,B��m�5?������������2[n�m��;x;�>^�����MX���V�9�jc1�iV�+F�6�Vd����L)�S&K�r�Z��a��5-&51��d�J�����I�,e�f���y�?5�n��]�N���3=O]N �y<
31�Z����%<�������g��tx^F�����9�j*�����+��I�������:���F�������-�Z��c������������X��H��DB���'�G'�O�������������W�����j�,�#D�h�^�{�f��a���=���E�!�Q4{�����E�[#3*�j?B���}3�>���S�/>��t�����z��H�C���/�)4�G�q���b}��-�-��<����hiI\�w��]2zb��={t9t����|�x
��N�D����r:��0!�|�"5 O8�$�G���W_��8e��_�-�j���;*{��r]��._+�����E��I:x���?�����5WS�j7$��w�|-����45KF�����f��'���D��S�MO�?jWW�w�Lw��#�{7	QU��HoS�0�����*�H�F�
��p�$G�������D{���c+�u(N�l:��o2lh�M��e)�:���s���{��e'��#��"�y�4�����*�
^�zN�<%����C*��U���*��"�W�4��9|����v����S��fSj��m�+��bvG�J����X���F)C�_1�������#�I��oH����~���8X���KFw����7* T�������~������>:W����M������s���}V3Fa����f'������L�������)$��M��S)AAA�����51je2�Z��K6D��SJ�R�i�(((u��I&���!��j���4�>��!=�'��~�Wn��7G"�G�~=��W�
!�SW�<*8Yd���V��d�^��x@"�Ng�y���Q{��8u'/�SIu���'&P�[_��H��Zx���zu"Q�����;)WjC�����]�>����r�i<e���'�������z�������\��,3�aj����B���a�\|���Wgit"�x����4~�,34���F�\��Ou/���F��I�K��s�k��	�t�t��/�d�?��R|(���_i?�j�����i?.ERG��>8v&��$�M=Q����y�3%���`�~���H��Q�����#�Rh�\�{�>�P:�����*y#�~1�K����p���wH�%pE�#������'U���#��_�/OV[}/�5i�OW"�P�:�>����6<��O�����L���d�����ru��R;��I��q���r��	�SI7�e[;J���C�G�wW�)1�!�.�>F�z$k�*�����+����_sIY���J@�_�o�~w������:��%;WD1��a�"�K��c�%�|�)x�>b��C��W��>������_�"=������D�T'G��f?s�����f�_�hf3S��v�p���H���.'���^�C��UxLW%���u�Vw:�!�5 j��=|�K�.����/rvU;�C�|k��L�c�3�@����K������A�H$�1����Sd��������	#m�&�H�!��Y&I�Ifmb�i�Z�kF�fCh�+I(��(�M����4i������Cdf��+23)���2�%4�Y�&���c)M45j&c���0��,��Y�kF�6R���Xl��x]~u��|`�/Y�L�)���$I�I1���'Q��E|��>�S���!�N�g�I��E�{Jug�\���/�Ox�|�]���'��:���B	���F�9G|;���oQ��#������K���u�Jp�^����R�_�����O�%B=�*'�60�C��F��^��nn�1M�/����i���YW\�<e�����8������um�'���uv��a�Ww&c��UrRhv�Wc*�U.���N�Sr��5	�.�4��5�E_��������s�����SQ���^C����xS�5�#���Fif�����d��U�t:����|a�k�!�������1���FN�d��+_���v9f��4
r:tC�cwR)�-��W����{�kX�y������)=����OY�*Y�L�"�x�oC��x��Wy��xi�����dw��Z��y.�7�)�
V<�_����U��A���Q�Wj�5��Z4:�#Ii���j)���j��xxRY�����Q<����x�9C�I������S$���lM���/5O��9R���dz��;~�?!�+aT���U�<��M#j-�y���/�"��������,{�*��J^}{�����}����mM)2��27��b��K'�o)�{	1:��=_���z�������^���?����}���Q�'�O�_���*9�{�xYX�>�)da�T��:8�d��t�(�'o
oy���[�L���;@o�//y� �*���T�(_g�v��~�<��]�5x�z�!�~��]����G� �O�-�@�����^�p>,W���:Lb�Ug����!=�1d��%�B�������H�O��Sh��G���{$���s����"D�
�e��xO��^�'��i;wTz��i����������5M
+R�����	
Qj[u�Mkne�	��j4Z*[&A0�L�hL��J	����ej�m���BP��Jk�������@��6 ��������
&j	*K��I��r��Z
���cR���8��8Sc�r�8~'$u��\�J���?��K���<�O�>&H�Y���Q����
�+�:|�~h��_B���uUR�_~Q[����|��c��_C����I�T�Hd64�[����E�5��I���F��4��[�GM4���
bJ1T��hs���x�m�N2;\��C�c��m���!�Y#�����O�tx�qE>3N��/I<��
5U�y)_����)T����P��ixbe�������nT���6)�}I�=��e�==�������=?�������U�4���q�=_j*~�U�2�'I���_���C��K���yIb`�G�`�?��r��F�������4��ySP�4U��[��d��y|���,���e>�/��J?�7���{������||� j���EN�,'J����]R$�vT���p��D3�2�gS���2��%O�)�MXLdI�-�CI�+�����EwMR�I&Y�d��T�I4��L��c�S�y$�c��������"N������
���v1���L�pb�fn
����N5s�
�$c�b�Y����zp;����~L'�Mrl��J���7�
#�?T�����_���{�v{��I��!s���������H��o�:�� z<(��������f�Z2����O�k�:--�����l����t�yU��/�u�S�hi�g�K���L��f���f`�F��1��}��[�Y�2�}�>���u]��]������=��0d��_{������N�L��J_w��P�j���I������/���U�����+%�������#.��DjK����W�|�nb�2�����NG><��V�xKL��v�j	���#d�F�_Ai��Q���JkYkF�4�(�%H�O�>$9>��=-x;L�+*������&���>\�4D������EB�"��aG$�]	�U�����&�6B�:n�����sr+��x�Z��'�x<]�uA�xP��gt����Sk�tgp��6ky
D��o���6u��N����V�(��1�;=T�K�������y^�N�%��������y:�+���9�q�%A���'$��Fqw����czw}��E�+�W&a"4�D�!	
�V|���$��2J�k���ig a�j���}\
+���I��\>[N%9l��R{��=-\���Lk-�:��y>$n4D��{�:�#b�u�$�e���	����/a�k��Jr��R�����L����c[�LZ4jj��jc&�j�5���������Q�>��O�x�'��rQ0�u��jv��5R���+l�5�������c3j���3V�GY��|�p���������ev���#��rI'����_���nhj$F���H���<+X>P���D�WuD�J"�	$d�����~�����m�t����j7��f�<�w����z��a��z���>��gz����_d���K��71$�R�iQm����U�SV	3&m���a!b�	&�Y��9&�`��&jZ|�~�^Rr��;���\,zZ��
A�1��z��fl����D{������X��B��0��
�������
A ]��$���i�Q�x���x���W�������Q}��������yG>�'�S�VP���I����bGQV��.�����xA_�<G�!�f�=�^&F��m�5j����%V6��������_q������@�`:4�o�+S���Y4�r4~?6��Z40�����g�d�6F���W���S��Gh��K���	��p��T�_��,�*��f"�&����XiLVJRmkD���d����T���=���h������|���5��g�%��iJS��p���)c~�f��riD�Hl�]ik���g���R��O���bfk=%t)��x���#��^���������M�4���$�L����+��$��Mf0j�S-La��=����p��������',�����v��rE8P���aY
#61Peter Eisentraut
peter_e@gmx.net
In reply to: Boszormenyi Zoltan (#60)
Re: ECPG FETCH readahead

You need to update the dblink regression tests.

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

#62Boszormenyi Zoltan
zb@cybertec.at
In reply to: Peter Eisentraut (#61)
1 attachment(s)
Re: ECPG FETCH readahead

2013-09-10 03:04 keltez�ssel, Peter Eisentraut �rta:

You need to update the dblink regression tests.

Done.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.4-v19.patch.bz2application/x-bzip2; name=ecpg-cursor-readahead-9.4-v19.patch.bz2Download
BZh91AY&SY-�^��1��������������aV�{�JP�5�i����}z�-#���#����}�>�i������{�$�{wr�}����7��k�X�7u��[y��]��w���G������3T�����J�|Av��{�`��nG\�A�����nf�]-�����]��+�B���{������^:[h[�@h�n�R�=�{�F���x�����,��w�mFa���������{ho}����J��w6����e4�����o�����97j<���w9��jkZ�q�z�
���@�!��(����7on�O���v����w�}�$��R�or<!"��b�.����/>�{�&�s���������O����:���_}���}����u������U=��r����u�z-���6���}������p�"�ap����x�7���AT>���}���{���u������>���};�5KJ������:�5����fm�e������p���9�u�)��D�Z�������F�i�����=���]vng��MD����E�s�]��]u��"����9�6^N��U����v��;��%�W���,h�}Nl�W�Q���S�O������������h�������L{I��-���\c������'7w���o�zW�7r��|0���v��mQ��{f����l��Z��T�y�}����v�q�zivS#yg�{�����@���6�����������1�Z�'��xt��S���98-Kw������k-�5g�����������]:�����k���w�_*�E'MKn�mh����33��@9qw��omf���>��}�0{�"@@  &�M5<���2�7�oQ��S�%4�D�AS�Q=���O&ji6�==(���(�D�)�2O%=#��Sjz��=#F���OT����C�D��@��
�D �h���4&L��4��M�i��h�4��T�OOT�Q"!�@&�������~�{T�=&���=C������#�h2*�l�l�d����n��Z�U3l^J��
���!T�5�&�b�*%-���.��5(iR�B�&����.!�t%-@�1�-�L���5(���;Wj���:��]���@~z�D��
	KHEs�k,�n�k�G�QWW]�b�t�,v�l$1�>p��H�L(�����n��6Kp�]�1���Wv�I�fEn�].�b�����u�*F����k��i�%I^6��p[aA�@����J �I7FVf�]t�f���l�-���M����ZIu��M�&R�C,�%�������.O���DQ�}@k~�U�����E�A$B���!#�%��m����:f����J���A��C$�Hh�
`��eo�5���s�����ku���: F'R�-DA��;�`@�����&��e�L�u%�J��.]�n3I)wlb���C�?��Y�{����`&H�1$�����k���1�W��w��d>|s�)��($B���~���z���z�VX,�����IG)���B�5�������@�"��u&k0#}��M��d�D���+�Q�����5QLI�����7�y�L���;y�a��dH[��������	��2D�L3�C$�����0� ��X�����9�y�Nn�@�H��y����d��a�����Q��UP�fwG[;v�q������b�NT���Z���u'l����` R�0����A�N��'
I�)F��,���g8�W+lDPwv�]u��V�z���BLGP�]/.�����������J��\��=��C@FHJ��vLl��"U,�j������cu���myH�n�� �[��"��d3EP[���e�k���d����]�����$(B0��A�d��o�#@(a��F���N#�Jrj��p:PB�bJ�����+M�}T�y����l2�0��� Y��`YB��G;���cr���hE�d�B��9��h��j���112,��aMF�;;Y�A"0Ns�)�8�R�R���s�-)X,���cx�T�o�K�r����<U��(N��)Z���1��)����yo$�C�x��NgF�zE�#MY�:����ZRl�2���i��U��������y�\�R��D�1+�d�f)@HMjKJ���={^w���rJ^:S��?��������.H�A�:���[�Z������00����x��� W(p1qXN&�7��N����� 
��Q����"cA�X�nq�V�Q��5"�R���'�r���`���C�	l�+�
Yd,�5#(KHa2�aU�sJ&I��M�c��IM%6�k�$$�MY��ii���%�hm�X�$db�`9�c���f�4���}'����������p�Ur�8�P���3��I)���[o��r�	�r�m���p6MHF�cR������`Q�!�|��3��=RS��|(��i�dE��F�J0��%�����m�����^�?�����g��y�P�C6��U�j���]����/�h�)����2����&n����*^�(���I��T��dDu�����K����A�#�c����k��6�~���L?��	H������ �����������1�U*����J��1�1O�������	���Iu�����'��~&��T���z������1	A��X�92	^��FoW6���:����.`��kL(4�4�5��"O���A��i;����{D�{,�[���&p"!E��HI����d=�$^]�e���Ze�.�Y��]|�r"}�����N��t?���b����c$�"�����r>�x��o�sS�Gn�W�v���9d��
���*�G������X�!�MY�0m�L,��x��9�&�N�N�$gw�f*i����������[�3�>�����75lg�wJA�4��G����{���������[��V�yp�\>���\���D����7c�K�v
��[���
���Z-�8%>��|��R:�L[w���m:�OW����\�����
\�c3&��r�+}��� ��46XX���}n��}Nv����x���~f~��\�3����+��z����NaJ����"�������V-�X�����iJ��c�R3��vv�T��I�J����Fem#
�Pb=����$�����r� ���IE���)�#�b1�J�)�0���U�}���#����r\V��W(�&O��s
BJ���$*��>������7(\��
�s���&fW��Y�un}��(�d��r���r}L�:Q����~�l�s��7�}C���F�u�^�B��n�u���gx�wi�k��*��5�dxouI[�g�97&�9n��:OM�)���?T1�#(A"L��-B�D-���_�G��QE>�\���:����/�<0���tm��gs<������0��`����X�}����H��Z4���Y�k�$�R%���x.��h)���u��8H��fQ43�#@�/����WD1�0T��sF3������8�h]
J	�'�S"o1-T���>+
'8u����y!�%��X�:&71]p��
Vl��������3�L�!�z$3��I*1L�E�J���
�9)��;=S�����g���r.����Z�������L�9�}_����h��)��1��}��_�����'���YS�g�Qk[�dC��IHfN�����MK�0��u<�1��^*s{�����`���<yv����M�E�_��i�Y���NOk1��fb����I$�=���U��s�<����nN��-��qB}0C������TVe\�7���,<��;J�A�.M%���-_H;��%����K�V
����=^9_	��E�Z�w��ke��f� ]�2���9�~���Ng��"�N
�l�v����M�F`�s�w����F�#m����|-sm�P������3:�|���2Z�����:���/�,�J���D'Y�@(|0��I
k�f. ��
9�25
)�x�+Q����&C�N�WIv��ch����I������w����3������2�S��d��'������H]�G���(�/��/�����`o)��PH�n��jy�]w���LQ$�C�@���j��1�C��v�����*�-wN��I��qx2��X]j�[�+
���D��P�M�r`&�.v�'X�p��{#�-��m	���vO!BFu
gZ
$&��h�!:xiN��kj2Qlb�P?-������6�lE����w1�vi��Lb���+v�_gI�mu������<���nZ4����M]CiL�L�'Z�<��Iu�eo|���La��6����'u��:���^����~��mIc/���O�����X�bA�������E�����cp�!z�4�`:��O���m�a�S����:j�\r:96&�&���o]��b��U�������A��N��i��G��)�~���M��\"���G�l���=�_	�f�r����w!���	�c|����|%��`j��g&C�'���#����Lo����� �/�Q.�����������;������w��^�/���{�M����\�����[��
�6�C���}f�������\>���{���A���3�����?����v���(u����S_���������?�������(B��J��D3t�P������W��d�T�5/�yi'��$A Ks�]]h��b��R���SVo�W!�Y.�V�
$��a$�RRC(��_���J)V��yJ���E��1�JPDE��L#�A���h��{I+	%����l����Y��1n0L��Z@@�@R���f����,D5���I��O������e�vh�)�V���k��&��k�	�_y����P-�����mHDd"�����Dr3�=m��	
�m$��������/�?������Vy9����K9R3���s��<��F5c��8v�@�hG@����#Nc�n�?��������7%����D�g{����X�gwL��J\&'������H.�d�cjSRy���O%�<�����%�����d��k����������'Y�������{��U"��T��A�Q��& 4�Mn�V\q��UZ�e��,�d����l
��w������(���J`3&	���dX�8�%Y�����oy�m�B����3����v6���p��];m;&�<�I�n�wcm���
���U��)�9�k�)�r�������p�$���{��X�"D����^��dv6��PV]��������9�V����a�O{���.\�m��lxJ�w^��������Q32K��������lF���www�3J����b�7+�{�9�HYg�����u��5JP��L��&>�JSl��������t9�����m�m��9s��������=���������'$��
��RBn�i�����Utvx48���w�S��������S��+���A��X�2gS�!J�HY�[���?�P�W"y�����7$���:��fNF��G6�3$��rr�h�)J2�dm�h���D� �s�"�w�n}��Q<
���`��<�n� �7h����Y�$n����������Z��)��^/S9��39��3��39tC�t�3�ie����9��S�qx�]�����39��3�;]�8�c^�jQEx��g���9�m�v�1Np���C	""r�m��811�j�SJjf0�$�X�c`��Q0����i��&RT�%7��������:�h�F�i��ajRl�t��,K0��1��Bm[Ul��Gc�N\*�Up!��.T���6��8��XB!q!%":xQ�C0#�/��T�"80M(D�P���BH�[UUWj��V��Yf�NP9�k����{�2�#++�T(R�-[��6�y��ZLd�(���,�OSq�8`���n#
*��'\��ie�W:������s��e���O���IT����t����������M�R�Q�W�D��_
n����E�h�)�~j����o^�w���&��)�b����+��o%(z�m��*�o�8@�3�x��!��p�c����3�>��������W��b�ajB�v}����9�i6;�g���f��V>�����Ic�R��
��	W�[W!Z��| ����fC��
����sSC->������e�����\/:m��X��bl	���q��A"Q8�.d���cyon�Z��R?�}.�(��$�vt����#D��C�B���,��l�5 s��e-���2�����������?��l���cE9���k��(%s�V8Q���LP���F:a���U��&1�k�����03*b�k���i���e�!m�����oR�'����,��m��L����RU������-*�2���dW��,g����_1S����c24�L�]����Z}�l���|e��I�+�S�v����BSwr�Rp��i�v4��n��=t.1����S�lWji)��������RS�-���zi����+�����?���r����������rd�p���p��Tt:�{��!m�~�L5���?m{wR�G�]o�������o)nM���
��7�r�*���=o���8�^�Y��>y�VS������=[�����������qa��?�"���T!Xz,�g�fITJH��i��s�t�}V�&��Q�(�LD8��2�>9��afF������Mgm��������%������M&�Lv����K��WP6���!?$B�D6�<r�,�C	0n����K���#HW�R��x� ���j��7����<&|����`\y�����u�q��<���<����	�����R�x����~|�(sgG\���gU<�Hv��n	9n����c^�=D8���xC�/�I�� ��D&�eE����I�l}8j�|��K�C��UQE^_������������$B<�,
0�t*��zZ���I���O�y*��E� 	#�/������'��nN����h2�|��0�e��kez�m�w/�`#��:�4�$�?L�^�������o���]�7=���i�L�Y<sU��mS�Z�w���gf�x>oIol�s'0\��
���*�f������Rs�������+����x4e�@��|E)����z�bzgl�Z�s|����7�3B��I���YaJ�H;� I����a�'t�<D���7�����F����zS%{�|P��$�28�����n�����q�*�`�B�^];Yt�n�4�I5N���X���3&���U��q�x�8����v�D�o��l�;Sn?���5�<���/^�k�!��<dJI0����[d�e_�	Y��X�]'!���L���������4�X8�&��z�������*�)�N.��?&W
_n���~������K���`4]�r6.
~	�
1 �= ��5Wow�T�?����r.4�I�u���i<��W���-<���4%����?����?-��)8����+&Q}��������/��s!�����B���d<I����|{�4Q�=g���|�!)U���!� m_�W�����A -^���?}��|y^��	l,��7��F���T�DDDFM����oDDDDd�DBW���!DF�DG��(�WLQ����(��0������|~����� C��gsw����m�~E��)��C
�a'2�j���S�Nk$���3\��d�K
C�gCQ��3;�>R��c�lS�@�K����t-�h�@%Ci��o��i��1�v��7�a/=$.������0b���;�b�`8�g�	����';U�����>����B�a]GU�C�z���\����:�N'���-A���chz�-�7���%���n�������-���cDz�m%�#�1 �����m6����~�~ok��E3��W
�n�
�����{~�����I��Y���X����X�~^@&�m�gE��E���`X�c�CV3��
��~oA��m�y����;����1��v��0=~)���i�(����3���k��j�sg<��0����!�>4h�����F�)���i$�'����?�(�����������+��[}=k�rQZ�_g���7��I���h4�-5�t������)6 ��^��������o��-�
��uK@��)�
����	}&�.Bb	#6���
�	;_��k�D\c�4:`��j0u�U���,��N��z�D�k�g��Q�mEsi����CR��s��9f���:K��y����A�N��}{k�>����<���)G&��!����]&��#�Fn�M�BD���+�VW$��HK��PR���4qBV����1�J�������ov����h�V�l��&�u<�Z'TS���T�&�	J�D��*D�N`FL9�MI��N������8X0�!�U���?�������aN:~�Y����av���x������5��yc
xt	��%������K��������w�O�4����@�e��|�B�5A��`���=�����o��>�`��)<��gugv��+�������t��9�RHm���v���7���,��5��h%����2�Q�������V����Y�A���z:t|�=���v�/q��O�%>G��>��
g���7?�I��2����������������{),T��h�4��Y+&�Mi2%�e,IM�!�fc��4��3SQ��[e�,��Y]hf1!k
,�p��bF`�LR"�l��I`���Z�6��s�(����m�������Y�V-P�U�����>��}�H�$��$b"+"&*�	��� ��*�%PR�w�����T:M(��(H,��1 @H�(B �,, 4$@��0K*�;qUG�]���5������UU��p5#������V��+p\�`�)L��|�������Qf�#BI&��I!})�1�]�_��A��N�
�K�g����?u���*MX��o���u�|jI	E���Di����~�#h�Q2']Z�w��H��*��QZ9����e����T�EX�H0!
1����h
u�E�T^��0 B�2"L��%�wTG���;��Z���*�,W�mR�C�s�4|j+H1$E$�n��s =��A�9�.$H=�x�RI�!+��t�����C�7����c&q�"m B���F�\�*o 6��zl�d�{>g��r���+��~?,e����}J���c+}1#m4�Y��8����[i����-;�����~>����"�P����a�_��<�~G��}�f��L�|������:B����`#�P��N��0��'G��C��N��f�U�A
$A��x���+&��m���������#>�Bz��'���)"z"0bIl����*�}�'!&Y�&[��:�����"�D��H�U"���
B��`�]��P(R<�"|�4@#`�EC(q��GW1�H�e�j��� Q!���P
~~'���#���#�Y�&d�N��D���"�27�#��#�b5d&��B��'^,O*�G"���(60� ����W��t?C��NyU�}��� �H���o��<��1��F�"���w;�2����Mi�!`�V�<�������t��`�>p*)�(^A�����<���*���O�@G�Q�)T��;���vU��@S���*-
�",
=&�vt�x�T
�Pq{��;��l�il=C���js��!��C���X���5�f~�E�����>��)��#�G�t��k� 4C���\b�I�m���c��#�R�b_d�����r�N8����z�h��u�d,����:�[���������o��T���3rG.4)>�0�DRD2M�,lVg1�+2*J%;���`V>���{l+�����Z���>��(WI@T���i\	����"M�����p��\6� 05�0-b��*�?sLO��Q�w������w���L6�����r����
�0������_�c���&t��q*�,�`cRd��KIef����6�L?��):�Y#���2�a�p�@����n� �Y)�K�mf�*�[�eK�����1/	��/���)`����F6-3�a+����!����S�|)���^���;��/����5�_�����kZ�d������>��N�xL*���}mv��V����
���|��T���E��h�ZL$P��f,!�8���E��o���Y�I.7��������`I�����+�Y�;�%�.
����c��AG+�]����-��e,��6
|��g��,,-�`�JR�`�Y�k?������Pa�<aJ�`�Hj�[��:�Z�����E��ANY���#k
E�
��nQ��^kj�jq�.4
����k�Kt�;������S�&�J7���sF��.N9�Q
���Q�s��]u�
��IP�!E+��o�N8��N��I���S�~�t�	����������������_ ����g$1�H�l1t���6��[�F�|���N�m����K���y���n��?q����I�$t�51���.���~�`��1#���$[�/���l��:!Dv)^w����������*d`�x�_K����]��h��,�����
��?����Q#���N!��`�x�RY4d6�"�*��J�����L|��z����>�dd��@[�?���;l���}!��z�+y;6�#��U���
�&7� �!
�J6���Uc���`J8�!�z8�#����3p�cz]�0�~�(zK�,7�g�}����Ja���0m��.����������?_��i��[%�������D����o6K���" �Kc 6�m�n;��)��u��%��a������p|�Gpt������TI>8�_zG���!�P��mW�����S�>�C��}�?t\w*!�t�����p0F�yb5
������Y`o�^�~�!�1����O�����g�b�~���Z���O�QLN��qN������W�u�7J�_L����N�V5H���M� �l4Mjs:I����Z�
�v��-���6?�>��:�tA�����l]�m�3������Q^���UUZ�Z���5��o�~(6��'����Z�PDo��e-�+m��#��~��w�'�G/Q���z}��BX���/j9�9��	�`�������{��(�]+{S�>�3�OKp��#pt��m�Y#n�&��(Q���r�x;c��g��Y�)s��`�������&���j�<���7������e+���zc�B�$�cA����}����?�h^+���WI�C��"{$�#��f�vKQ���D���?1!���XuJ��s�:r��'�������R���'���%P(�X������s���+�����������$	��|f��l�����N[��RT)�?������j���
��$�V39�~�pt�U��2�l\��[
Q�h��<%�e+������]V1v"M}���-������^).�Li��	D;�0r\�
��R���J]3�&���^���R}���|�h���Q��T��qzu,���o����o�����&Km@2Hd�A����kT��X��d��%�ZbDJ�@��.��
�����������R����o�GV��� � �& �[���������������<���w���1��&UM����� �BI	$ �Ll�Z�$� �Z|i%R��eLt����N�U�F�����*^��y�	������?��<������U�U}WK�uUUe�Ue��z���=|�������9�s���9��9�s��s�e�YeYg���c?+��w����<�T����?N.�>0 ?P��������3	2�&��~����qPq>k��l�s�� kV�������^^��)ta1����	�"��nkk&�7^�t�)�B!�dc��>*^���f.��O!���&��x��L�T�5�n�JM�� �w)H��@��cu��)��,!������`�{5��'�S�O��*J+*�����y�@�&!aj�R�f"�"�QO�'���IU�2X[+FKm��x(
���v���[2[���c�0c29G���$�"���R$�H���LwY&��W*���J����{C>��_������t�b��5#$I3p.�g�j���3�g�������8i���*���f�'�M7��jpZ{�����!yji0���}]��A��tB�^'�/x��G^��(���
�G����w�b����zhc��Z"w���I@do�{g?PpK�=\�:��-%�7h�l�S3p�M���/������+��MWF�F�}����*q��)x���5���58��$�Xe��/�L����E��3nyW���������r��N=8X���h=>�RP�����g��D���:I��R�t@�z��$�@#}�u,)q�y�?�H\A�$�lkJ������V���t�{xR��G_^l">B^�]6&������tx���&b-E�MG���g���"�	P���E>S24�57����:��w1���B@� 1��0%~��a�/DWY��4���;4�7P#00
�XY�}[�}W�x��.���]e�����������6]��/y������7��_���|���� I�;�����$����H����bH�(����]$ 'wG.�8r�����IDD@	wu�H�w8�]3&������ID���\Q�wtN�@'u��tw'quW��?!!��&���m��9�~t���Q�����'���3TI)�+�Q���4�S��L�;��O���=9H1|�!K�g��0�onBK+�=�����������+���w;����-��{��4HS�I(�'�� �>�������c���4��l�����6=%����|n!�yp���E��0�x.:m:}���m�&g#�9o1!��H�)�=��RD�SoU�/���������07�GD�����n��|x��x�%�jxJ�������g=w���,�{4��D������%�"G8�A�����	x����zo����f��k�#�����N�����v������(C�\7b���������_�'������~}a}�'��4��E��x�>q(|��G�
h_$�R����\`��x�p�~��[Gx���'8P������>�I��E]f���y�����g�dX�=r%&e�������xy������)]�\��������R��m��I#��2!�a����s�������.��HcLa���4bcF�����b��*R�*�2�olw|��nO	���`UI
��4���������C�T�Z(B	�>�v���Zy��B�As��_�������5(!A	B�PQO;�E4s�k�����,_�_����/�O��A���o�,�j|n7�z�������0`�����IH�8p/-����j���������V��i ^�n{�glQ�[Yhc�ez�}����l���'F�(��]J���2
�h����`EJ�v�������K��c.6C��O������P��0Hm	�8FX#��P�
��.� >c���q�g��Z��m����U����������i� y��AB��B}px�w�0Au�h�� �  ����#�#`EU=�&�~��S�f�������uu�[~/�{�����xo�$	w��mJ�����%�����o0�F}�k������#s�~o�4_(�����O{h�(U�{������~���mv%�����'N�I��d�~=�d)��������F�����H
/�����8;��o��{�to����ExZ�0�����Z��^QS�T��4�(L
Dj�_,}X
�$$a�+0%�/�P`
c�����c��
g�>��n���V�H��|���+-q�WtS>�~��	=��x ������#����~
S
�i���L��9 K���\u�=����(�=��A�Vs�4|#�a|\L^L��&��Y{�|�:�6�h�?��z`��GT��
�	h�8�%�I�Bt���zz|y��cJ
�BE(��������Z�����p�`���U1�M��������Q�Z���D��1���K�J�	X���:����k���?��"�}+]���,��I�iP��R�h��(yp_8��<�8�������E+q�t� I��*�i$b)�a�d�q��?[�l�~`~��f�/+�y�H���o)�3�o=b������DK��[n	D;P��D�z����2X�����pHD ��b�m�Vh�),�����KV�lcX���14�K�)LBTQ���K��S@��QT�P4�,EJ�P�����#���<�ZH
8��O����=��*Kx� 	��*`����Vw�Lwp���_QUT�UI���|*{Z��;��:�on�u++����~�36s���������D�UV�zZ=��-�b�	X�9�t��d>���'S���x���x���I�DqI�XY%��e�j�*�Wv������A �����U ���>�Ud�������&�E�Cg�����!��������
r�9�p�i��i���m���f�h���d?��G���W���jjYV>���m��7�i�i����p�AAAAC�W+U�s��m����f"g��,��.���j���<�b������:Ej�m�c6�lc�1�m��^9W-����������9���a��J(������s2L�v����X���8e����>d|}	|�F�� �H�,��� 6����g��*�_���B���������������.���(2��e��5M���Dxt#���� <	'd+(����o'�"����m�����)����P�x��G�1��>��O�):^���+@��`��_�����U-�ZHZ���]��7�H'�)�W�������u�Z�C������� O�0�����/������7���8^��������d��=�?v�m�-�����>�?s��N?c���y��m�Z�-J��jN��Q+�����FEt��5o��t=�������)�;q����D��s�Z���8������	���9V	s�N����[Z����W��v�W��
�����=_�&z�w����jdC�������m����52�W
�G��6������;kR
`8`1"�>8��tP�����q(�gl�o���%^X��X�5^��k�+��3������'X�������]7��tf96�Y�&�*h;��/#�9m���,�i�%�2*����8�	L�J
9(5l�|
S�DF5���y���F�+��3�������+��������F����� �<T�(�[&f5���y�[�5�����E��w�jP����j��`��
l�����J+�����o9�t��Ey�������s=����������Pu���Q��������=n��d����J	��#$9�F�kx0��ED��dV��Qu�zio�:�*+���Bq���*����
�p�06��e1"���f*��y���IJ��11R�58oV�0�I�&���\&B�����-��������f�A��%��M[%&���-��}���s|wr��8T����q�U�`JA��1��S(�y�F�U\)���,C%*��;[-5������	�%5I!	�MQEQJ��&��>��C��`�8b����	1��z�7������JU*�BOE!@��L��-�m-����P�����	����ER;L��; u�X�Y��6��6�
����U`����V8�����QZA7�b����������/"����<��/M���z�iV���u�����w��@m$�qb�(�vf�E�Zp"YX8C�'X�" y���
P0�������"�Ad��5��U[���B�.�nA!����f	H���I���DCy�z����,��P��X�5N%XUAO;�z�=/2��y�u�{���p��Fpj-������Y^"(kecp�9x�J3�"M6���:�Rs�8��~�%"�rg��:d[���<��w�2����
���8���O��Y�,������i�������o�'=m���i���O���������k������e�X��^S��$N�-���x���ye�Z�Q�i�F�������^���]���+tu���(+6?��L
��[L9��OV�P<�)��"$d%��TP�D�{`1P%�fR��i:�(~�.����j������}
z���&/d'���������l�����m�V�%L�&LKej��2��Q����,�Q�6YYke��,��ee�R��$AK0SDo�����5�fu��N�BR(��0��|�R��M�^g=�����d�w�Ne���OA>�V�5�in��@�j#�$p�gF��x�1�H�(�h��1�T��0`������Mj�vL
tO
%BO����v�7k�Z���m�c��y�`@��x�>��!�
��<5��3�}������FRSx4�8�h<�����I���)H�#��Og�?o����p��(�9�iJp����16�����w{33/�_n�330��c4*�P*�UUNsndDDRT��������xd�$y9������=ls��f�|>�)g�5��.Q��[�{����/�c����<�r�����z��=18�
�SRj4)eJ,�+��7w^��z!��1+J�N/m�)��}�S��&1� ��cWP������""�aaFV�j��6��h����}*
������������$J��[���[���me���>d������"�z�N[uC�o�5g�N������Ck</�q7�M�}a���$�{#�!���{>����#�����;I��P�xw�A��"<���$T�>=1�FmdX/)������)����
!t%B����ui�s�!�Rdg:�j���f��D���9@W���O�uO�����/��n���Ya���>�<W�6��8�����&���!����/�����'�.�4N}A
����k�2
��{x%e���%���XA�g��X�s���	t*��q&��D�!I�7�������.����_c��k-�Q�N���N0�P
gX�?A`���G_��$�L5�V�x�y��Yj�������g�P�G:�R���^\9#VM���5+�A/mw�(�C�Q�������9��qW�W���/�\���n����iQ�W~���G��o�W�}�����_����������|{��<��(fk�<3�+��H��z����c^�$��Y�3����:pJOn������n�/�w<�J�I��hd��S����4����8�WE\'�R���
'��9Db�
��Y��������Q=����U��>n+�+r�9���q�������C-�u��u�)���)]���ese
=|��p������+n����X�{*��J&��I:Y�8����(Q����7��YZw�t��9Z1�B}L����I�)_����*c��<�#i�>[q���D�_\�k�T�2��&>ldpF�$0�&�9�R��o�3u
���8�
�h��y����]�)R��*TE%DJ�W�M�����0�ya������p�A|�~F���C�9�$tHf��	���*1����c�w���v�6�����\f&����������������){�H|G�-��R��C9�\e�-ZK�����	�0�?��?	���,�Ya�]sl��R&1/H?z$�(K�����z�����cM�B�'1�Z�M�C�r�?��~�$�������ya%�!���>�\y�Z]�I���{��ZN���v��wq��	�U6H�2�b���+0��E��wWRJRNU�5i�B�UMf�n�L�R�G����Y���!n�nG*���wu_dKC��
[��W���eP0F�i4�O��{�����R�b�o7���G��d����D�K�C`"$!_PxJ�n���������h�K9�Lk�Q/Q��U�%b]�y4N���	��(��I\L��}���-~�]^}Q�:?��-�9A��z���hD�GI3��
��J�_�%�J,��R���m�������a���>0+�����������w<�,k����MR|>^l�h;��������
(
������M�79�I%
ir�3���7��-�|L~|;=�^�Y��0N�����GG���3�>�E��8c�_�9Iq(og��q�W�cm���:e������0�i�<`�l�aO�0�#���dq��/������;�#(MNQf�����+Q}����0�hDFzgA������z`�?�:� 	"li�����;�8�]w��%�V[���{$N,d�RZ���l[�F���������X
�JP�UTn�-�T���`+A!�=��B����#���M��V���x�_�����;�<��1mRp��.���3:���>��7vK/�Yh���"��nn���E!yJ%� �a"	�	������%%4Q��<=�;/t�&(Nda��!2�XauY@4k6������^*�\)M��"���i1�T""��&��u>n�f�2���������h��w�m��kSZ�I&�����5*���Z��[�O�tA,�(��\�t���k�Ib��2"�����M)��%3e$�%)4�DQ$Y��I������T��[/����c	�����J$�����J
�p������bLIi10�Hq3���"(��������yH/,�H�M��X  O���!w��'J�f`����A�)E�����7Y��!�������>$��������0,�?��C�}��{O�?�{���|�?������WG.E:������S�����{��%>��_����3?[O�VY~=#4_���K��8�e��?�1.�����}��u�~��j�1^0N����]!XI#��w���q��;H���l��K�"~�hY�\���?]"@<�E��������&Z��e{�P�����?��A����
~��p�drsX���d8�#��*k5?���������sM�y�E�,�;�je���-��"B�>�jb&(W �������8��_YaT�U"���4�Q����{�7���/�I$P@�[B"gl�	d�A
�zu�o)M7���m��cK��*~F_���,;Y}:"9���[�.�����g�y����Z.#��7F��J�0�B�@P%-MH�I���767�%����6��Wx�9Vc*��x�k���[A�����5B �B�8z6��T�W_6�H��5�w�5�����U&�i�D�yR�����:R���ph�b��hcJhh�hi��{�q ���/(.J�I�h��V�i��Iw���.@m3c�m#�G��U�tE��H�I�z	he�5��P��O������_'�15e+�������#������zl`wX��LW�����c^H����H�����5��	�
B�� u�@jcSx1)�Ut�(��&D�*?S�S��j��Yn�����o�$;�WTc��*I!�N"�vx�������B��Lg�Z�/�G����9r���Q�2};p��4�s��%5i�,��(�	'���4�l�U��~':���E")%�����'�����	��	J	�=�����$+ `�3�J@��4!��$��T������_�s>&�o�[�u���
4��K	�������%E���&L/5A����8���0�g�O+�E3�m{�����-�E�?�������xT����WF��e�<��BM{��:�
3���Qu����7�0:�
t/66g�9L��_�|>��`a'}��@P����;yg����������%�I�(�(f����X�wi�0�6����n����n����
,bN���&RR�^[f����!�n%��	�e�o��jSv��4��M���n�3����K-w��|�_����{�.�����
`A�au]v�P�z��'_zb_��J7�oh���W3�7c]�m��Q������AY�1��/5�$�j~�U,P%h(�#!`
�K����c�}�����p���)A���� �=�y��-~�P.,B��lH�s%B:�>��^��9uxl�
N7!+��4m�@l�$�����X�o4�2�a�3Br
�APj���3�o�^Y~�:�n���0.D��c��JR^��<TP�,�>�%��a~j�H�ci�-e����V-�]��^Wo��I*TL0a�XS\9+�T��N�Zx���9)�k��E���[������h/��+�)%D�W����'/��j _�N���AD�D�]T�{�����x�3��~D��#�a{<�h�JX2d��1,�E��A9H/����V^;��U](0Q�W��\�@"�q���v��"O��"� �;�#��[
%n�z�3�����7�XH�4ZdwJ��������
O��^4�p.�J�
�}Pz%�L�g��@�0]:S�z��K�/Q%=�G]������&�64Q��@�F!��6�+u(dx�[�����T��l8�T$>��<%��t��C��3zt�8*K��k��Z�&v�+�P����q�6Y���\s���������k�>w����6k(���y�3���ubZI�-��_V
�\��d03d���' ���I�D_�v�M��3��j���%�g	W�����q�]�8�}.��J�)-�C�p}!�'+�f��K��&�$�^�Kt�d�����������,�n�����\{'wg���_{%X��)m��u�V_d����e�����A���eN�DD\�sG
^|��!��}	�RPPQICKHU��W�����{#���q����S���S���B���3]+Ub�+t��(�$��c���M�5��H�[K)�8����u�m���P���K�Y��!��BZ�����(�Q�}��QxBN"��p�b�ih�Y�e~��_Wp��hQ�E/���Z��h��T�6)YT�[Qh�L�(���L����S�"��Pk����CLj�F�R�i6M�5(T�U�ME�[L�����f��F�R���5�����E:�!@���@�&�)=m8{�]Zr����P[�lVY���&��X��x��������+�:��|��,kX�u5p�@����������B!V�$*�"G��$�W�������7�$3��#���d�D~����3��c@��@�dLEA�T_�*d<}~oy�����Pr��������q���)uF��]���(��x)��&����@jtm��`�%X�QIN#������4���W1g����E:T*���T1����,�P���T�r"B�Q��*\61:k��,Lg�����)~��*(��)$���`��z���i����c
����T��!��Y����#$J�4��1���c	6I�1b�Jj!�y��������R��O�g�0���H|Pw9 %1hH���B�N�|+���S�N�L��40BKaA�=���3�8�HT8)��{�����o�1�H��� ���
i ���w�:=(��''	0d�^9,��THPH3�K9�UE8S����_�o�������P��gK������`w�&4��p�'wZ��rJE+����i`��j<]#�Q7
��-��o��p0(P���'��Y"���!�"D��l�`H
��;V�`�+(K($C�o,� |���aiaiB����VH�e��v I@������/K��@y�q*����1>��
*KR�J�bJ�h�:��$��:4����Mr#�� ����)�nd|���tO<�wX��QB�^zhG������UA1To{��8sURHBI$�I"7�AUU@�������}��@
a��N|||y�$�{��������J���"�l#LX��F��*+��L�R(1���X��6G+T\p�T	,2^����ab��m��*�k^��������ZJ=���?C������I�\S�wo2+K4�r����P�!r.Jk��E����3�"
�� PF�:����k��G/X��F��H�D��$�W�!���d��Y��:����J�1��O�����U��fp@���,�J��6ZS�s|�f;�	C�l��@�,}<�+g�������J����iz��s]�b)��$�I���L������
y����M�����D(��!�Z5f���#��Z�f�kX	!��",�j�A�Q�%��M��� $l��IH�����\�S��
*E���"gHK�(�d�N]�=�0
W���(%���G��)���l��5�W�Q���o@}!2�>|i��E���x��_����y����(�L��������+�>���x�:�����I����A0��%7��k��AX,��An�a�t�1�{�l�f��t�`�K���q�X�x��0��7�h��P?�aS��4�@!���I-��!�zL9P����m<�"
��@���"C���?LDl�s(@C2�:��z��;Jk`<�
����}�j	�&���k{;g?_��Q����;8T�5������6�n��A�#o��v(��|.��@��1 ���
�J��{!�s�'d���R�Um|ZQLt��4���/�������R�/�/��d���zR*���<wm��W�v��qK�t���]��++����n���rv��{����>#���m���7Cn��<����{j�v�ssg.v��.3����s�����NI+&.
��IS:��{�m9�k'7V�S������Tf�_V��n*��|s���%��Q�3,�g-_n���u�z<��3e)��b�����g�e���J{{%J�9WS���j6903��kx����������&�:�V��8����"i���*��[�rsG���{��q�����<��n���gRGc1�������y�2�����f9�vur�gv����S9��{K�{��;2�������DT�I����/9�u���^>o*�V�d�u���+�];o�=�^�M����`,l}c��?X�[$����*G�0��T>���
"K��E�fKt����"�?!�B������9��8�����z����j�-����X��C�I����8�erA:B����~�D��.R-"���?���n�pJ{�idF5��I4'���'��~�g:c��}p��!��'W=���
S������7������{��+���<Y3&�\
����@����kL(9���*�m����"!��97G���GJs=�ZN��1G_�}�����$�}�O��gc$�{h8iN�T@��B62�{���#0����|����tg����K�|��
W�a)�*.����>�4��J88^�dYQ��Dp�"}��0�M��\y�_O������33���)$_�%�S����Y�Q����u���?�RY�T},��Z�W���'"�I��WU+�I�M��p%
?�R9�_��{t�����$:B���h���`�9��?}����?��y��������.9?����_��e��M^r1��2�Z�<�5��a�b�n6�0j�k��HcH�\�$���������{+�`H=;�^�|�����K��}�?g���}����{�|�U��=���u����hh�U��|��}W�������U�����}�=\{y��4�I��+Fz�}@���s�w�L���"S��9�Lm�I��Zh���>`�������#q��������T h�t��J�ad���E�BP�Q��g��.nL�S,�E{*"�E�M�l���W4E����$$���Q1C����}���\
Y��U�����vpa�ZN�i�h���s#p����L)9��M04dfi]9�0�� ���?�?������Ev�������\H�#�V�z���L�<9�S�7t�����>�����RHs�?7��sb�_�����D�}�x*�)�<����'RpR|bH)����A�
?xB���z����`�C6}I	����L�����a$�~I��p�n������D�$�I$�I9�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�DN����i=D�h`?Z�*����H�e2R���3�1���T���E
6�	�U\���f��0��}/�+�M��D��u�`u�R�*��T\vkO�[*����W��t@��{q������|��S��B	��D�bd�L���)"2�l�h�2Y��xH �YX�]Hg�(����9H��?��!!?�,�%��R��{�5��k,�C�2L�g��k� �!�~���u:�S�R��+%:�G	y�V�e�g�f�#r���7{��V�:�}�{�� W��#��8AsN�#�BIh�V�R�r���1���T6�����
���H��	������=7P�Wc�1;�`���H%��>d��..&�>��
��'KBo�dE�\gSwRc��#.�S�+e����zkye�(��G��k��K�3��^�.:f��MR�R�D�)�K	��-fl�h���s��8t�].V��J%�,�
�|������U��y38EZH�KI^O�����*R���K���������)���8��9����$�;����w&�T�%b�H�����8SN{���Y�8��dQ*�:���@~����FK$�l�����\���H���W,Qr�������G7-y�����N�$Aj�3��V�F$`�e���}a("�U�����ZJ��4@^��I��`��wlvQ@�|��2�t��9����JV��g�k�x��x��*Z�4���-)����L������(��IqL��J�w��Ew�
��Bd5��R9�\���M�N�����P"	�e��!���)2,�U�RT�1kUx5�mII�����AJ��:��j�Fe"�J�<}@j�-#�

��G��B����������E�R�1�$}��Ec�H����z�1��u�)'��#L�6�$�M(4�![�05w���9��C��k��"���N"'�bb�T�t�$�S�L����`�x#���]]��)*W�)��n�aI�tJ��C(����U�Nu��@ ����{G��tm8��SY�\�������X�����/?��u���:�PA��M(z =O�>���.��aS?^�M����b�`	����}'�/��!��S�xn�L*
���n�R�"8}R+�)��h"Y����(&�����g���|����B��z�C�k��N�\8Jk4�h���i�����d������=7K�k<5�l�%�zO�t��2��C	("&4�u���1$eR�d����R�K���~��w�j�t�+�W��,� JmLJ���P�����(Q��P��G'�pd���9i$�'�@lF�}>����u"ToD`�W����&��C ����'�0��)���
m���m��]n-��1����M���cM4�l�?	D���|jH������z�x����p�y�]v������y�y�]��)#����*���9$�:*�NM��N���(���<�����<W�k���u
B�����DU}&�YVG��P������a�|���mxu��#�n��!�NF�4��\���4Q��i.@�H!��6K�=�\�G�V�z/�q��p�H2O�9n���r��P�4h��"6@�@�RC��3�������h,V����=_�YA�-�\|.��C���kZ��f��T~?q|�?o�V~���y����_��[��SeK�����Z�+YZX�k}{u����m�Kp�7BR@�k���DnH(]�-��d
!��n��4�!L~C����Z����yV�ni p�p�1�,m(�)�-�[�9FyT}���
1\2�=xkh�E
����eQ��)$�-bt�l
n�.�	/�������z��P��m,�����
�)J��W�L���omc
���S"�
��(N�-�!q?.|��l���!!@�a�B���lw��"�����LE�{e�g�]�����v�F��
13S�A���6���c��a����-7��+���0$��#��+����+��V
K)B[@�%��~�}:�G{+4��U�]l1��{s���2��yN;ls~��x�������r�F�p��d@L��H�u�8a�b3�&�?q�
�x�P
~�O����3�����U���7$"�	����r'�Z�����W�v���-Z�����(;\1V���3Co����~�������U�B]�?���J��t�B@�A9xr1I�)Y���|�lF���a��sN7����������\��;����jB�Kr�s�Z�M�W�w;{�R
���pj6rr�^�uF�:�$H�@�K����yZH������a�D�di�u"1���q����<�x�������-�j��p��1�Lhf#��(-k����v�����"`OXW�gLH�X��p��e�h��f�'��C�:�����N}���V�u�� �	O�N\����W��:YR!���@JF�����NS@���Y������
�U��+p�P��a#��I��2@O��!?��'������$�%F��"m����g�rr\���+z�fB��P�snZ�q-�*�����}O<�<1hB��8��q��h���7g(V,;��Izvr�x��Nu����������P��
���|��9���3M���@���!J	'���U�U;s�[�{�g��&�;�������wE&��s��(���+��<�tF�B�P�"�,�e��w�6��0��m�Q��h��9��RW�1�,��(�$��$H�	�o������[C�W��?DK���*g��fb�
������cv���mko����MJ����w��Y
�_��o���`�
h�fQ���xw�IVH6�����|�e�2V����x�H�{�������n���A�*" b�;[��������l@]�	`l���o}K� qbH*4��7���J�
�-�H��h�4����c�G�����c���"��w�>���P���Q$�%(	^�W���u��:����R-@G�mj[eZR�FU���B�2��>������>��^�����K9y���8��� �Zd����������c�K���l  ��($���N[8���9�bv%�wZ��"d6�C.4��J�NeNh�i��c�]r�+r�����)���A�i1��n������I_B������<^�������w�t*5���yUvx�>��5�3�v��d���K ��r(b�Z���zG�e��6����s������_�=�v��s��.*�e�y��V��YN��Jx�8V#����Xe������U�f<�n��/@*����\���zm*����r�iT�r?7��{�S�\��  �")#BW���Z����S��'c�D��&q��KY�~�k�O�|z�#1�D	D����;%I�K�O�i�D���X�w{6l�L:h����j��beF�&�)(�MD4���=�}����3.������9����eZ�2����EH���($�)A�6���(a��ld&���0���i�&�jG�I�19��m�TU\���:��m��|Zs��2:�&������>6�mL��!�mJR����D��@��\P��=$�i���N%F(�Qn ��2&U��Q��p��1��4����`��!X*��I�
�F�n����BS:��Z��2���}�����>]<������R]��
��������x��H������JL�]����u��o���v��6�������� �#~R*ai���H�~ ����h�K�>N<�<���^j�p�������������^��(�����_q/�u�hn��|G��������W���(�v������`5zW+��_M�o�B+&�t�=Dd��� �5� �	�t7�7��B��[B�04��:
m5KGBm�F�q,{N��my�OVn�aSL�'�
�vo�����U�@��L����*eE�Q]mo���K����l�*K�ka�w)m�#���-#��p-�#m>x���8DKJ�R����5����]c�wRX��^W[��1�R�X��3�g.I�2`���;P_*n��q1!���Wp����V��T�DM]A��]S��Xgie���F����rg~�QJ�V�(@"eU-6[$ru���o`u�
���(�FB�I��=��u4nC���<jvdh�����z�&u��D�K!`��(�-�j�����$E~�l~{�
|�S�y���������{�;SsZ��;�r|~L��'��������~_�}?'��]������LH�4�����&���=W�� �u�����b�a�!#-��Lz�"�gL@�1cq}wwh��E�U���<' �Q@m����+��jo�x%�d�����d��h��j��u�e��V�I��g�o��H�����{o��z$	)�_��m�]�����H��s�yu�K����.�����f��J
��SFX�3K(�v�p��|�;�K����j8���Q���Z5]j�ML�U����.�Z��Z�m�e��9-Dy��l�9r���C���E1`��`$��)����/(	07M�K��k�~s�Ka,_*�<���6�^Q������&�a�y��l�Q����r��v>��rNp�#]v�9h�.h��k&��M	�!4�C��@�������>��_���������`��~��g��o��<��L������#n��������5�����{������/U��������e/>�tQ��oRa��e�j�L�v�9��i�$�vq��,���	B��I1��F`����vCu��#}�Q�4��	��p��UH�����(� ��g�US~�}����D_bvbfz4p�>b`�i+�A��ruc���<�N�����3�)�S�#�k~�>E��s�����Ze��WZ�6�NM�\-(�����(�/s�����Dz�3K�Y����
)\,<��z�{�8���vMx�^'~�J��r�g���9�������f��7���s�C6�"�c@�e�*�8�xg�[��4�9j�x��E�b��HV����'����y���D[,��F�-�#<p�Y�#�E��^�J���cLq�8ZmZ�T��Y��-���B�i����leYUS3m�(����c6�6�����m���C�C��:c�)�lcn���{��km��n�'Xt�C��;m��{����rp����P��M1K/P�,, ���}�|F�:���H��X��Us�Ys38�3
��V+.�d�le
�6M��i
�����(�z6�6����K����Ni����v���'6�,/v�1�n1��������%O<;�Z_6��v�z�P�:s98�}�1�B�����m����,,775�R8���+�s�B:8����N>m�d�I�'/����b`��2a�P?�����7����_e{0�����h9(M6�4���/��El1��'��D��R]��Jy
q0Y'Q�H��Hc��/�
#���DI$�d�$�j }���!����I����������m������%`I@�	(P�9�A���[ws{M			$$���"a�5)���x~�el��.eK9s��������
����r��}7������ywY��&���U��GR�%8�M�V����T���8�,����{��1 ��y)�`�o3RK�)�8>�V����.eK9s��5�R��s�������������v������N�$v\�&R@U�$0d��F:p����i�Ep����(A�i`�:X���.�I���!��JqX>�����Jq��9��n[{[�.J�.q�&�*X�.q��Z�����=�v���������2Ge��e$J�����k�8C�Ydp���Z��cc�'�����$���Y��p���$` ���if������YSd��*a��s�����s�q0Q0�0�coY�\Ja�q0�d9x<�g����C�oG����W�N�q�qqP�Pdr4�Y��\;�92.�!��CP�[�M�A�� ��2cH�F�#46������$�R��I%,��2L31kb������sHB[�
��[��$�-����S�~����3^��7����e�}L��;�u�d��i���/��rw�2�����o9F�����r�.�y�V^El������;q}3y}�*����j9��;k����5��,a�l,��nN������31 �.P�9��q���;�x{'�G��|���c�^��y����J�����q�M��3�*\�%Wf6�����6��9�H���]����U��d	sm�(s����2��OuR%5�����g��F�ID�9���l���vht�te�i��9i����m���O=��|'W<';J�y�'u7b��t<��gp{f���bbAY���\��M�9����%��N�\$��!��n\��������UX����ywS�8[��7�W*����h��=�����)�=�������J�J��c�\����=c�7���3��r)?6=��}����ZI$�n[�L6F����V'��I�-��X9<�_%p����Yy����{��J���5�������}��M��\D�7���s�B��������z�����qQ�\����~'�c��Jg���������qs*X���v�*�����%3&��+G82U�2rF�:Dl�����s��V��B���������V�M��.�8�<�"��'r����� @��4�@�,��^M��!Hz��x7����IA�0��iw���s�$�BI||�9Go��!��>t�^�vM�H�G48p��f��J5qI��V����E��)�,�u)F�*�%������vCM4ZiE�/��0C�$�B,��D8Q���"��(`sf�	n�-�����R[���t���$fZ2ap��~�W*�1j+�N����y��M4c��9��BTNJJR�.�[�(����{�=��Y�b���]��Nd�s�=��s����2�i
~�Y;����(�R.HQ���v���\w�g*[�
�����L������)H����6��1BIi%�RQ�32A��1����������\I-��
8�%���B���JJK�E��LH�s���g�����y�_�lOI��9y�����{]p�����r��OoI`(�����n����F��SGR��{��8��V�z��E�+aB�`L�`���T�+���{�U�J:Y�o[�9�vw+�����
�����4�]��A�o�$Y$�[������}�]���O��=���O�n�����p�����D��`��IJ���Bf�h��������k�k�\�Y����:�C�zv:w�;�zv#��������p�w��fs0�;��|]�qnm�d�w�s���dv��[]��aja[��y7�D��y�WW���^��$���*/�|�-
w	/�<�t�>W����#�����{��4�=��������}�=�_"���=��N������4h3���$t�U�����������
�a5,]X�4F1��&��f�C�/~��zl��E����j;U���|�1�*r4��e6�
�����@d��&���'7#b>\c�71t�0��M���� ���`S;�W�W&�kyd��p�q2Rj���j�(�#8�(P1#����by�O�Q��O�����E��Li(�(�Q�������i�Xz�?��8bb6�cI�F��t��I$��p��~(���SyO`�D��5�.Q�����D�|��sWiH�B0��9�%d��DFq)V�*�|
<���2
��O��������W(-���
sN��S:dG�<���v��H��Y�0k��!(bm��yCe�<��I��9Q��pzG<���4�E�;�g9�4�x���;�bF�5��>;���U=��]�2v\��T�1����95V���r��S��9^��p`��(5�L����>G���l|�#�{*rG*�	���$�����1Q�X8CyA�1���uF����t��f\J>$�t��6�L��7�|-��dEr���&;n�iB{n�S�	s���o�9a`���I���W�(HF����f�n�U��
QJ�rw�(�����w��}ZS�xv�3���D�1����������g�S�Gp�0�)suh�!��a����S�����/P:hA�4ix����Y4�8"ptaf.�\������)�)��#�oSe�X&��L�~��%w�3�{�-C�,4� �o�Y�����.��lpl�j<�t����}���R���I`:�e{N��n���n���k���G���v�^��g]pz�;��
��,3���0@
^5�?G�:�Z�*@�RG�{����������l��[�����Z����Jyi='6LZ�z]_vO$�������^�wj��)G8��`��QT��<��}���d���#�����r��p= _�c�CH��l�t�Y<�����r~q�'7�d�l���	S7$��Lp�*�]�- ��K�agZ�?������idf`�"���A��g%H��0	2�;H��-�����]rD�O������������R��Sr���rTN��v��
���/����Hy��t���^]<���I~��/��
QD9Tu��R���)^���y�;<k#)JR�x���g������
��*���ok�b���@e�+��*��D���
4#�;�b� ��@�	v�N�
�h��I#j�rx�H���������(����r�
!��7�>����%�ORB�C4�������1������F������fP���B~�m�H�����z%=*��bIa�Q�z��;#���7��y�&/P\a�����CI�V�;��*I'��c���C�N���G��z��}��A�������I���^�Y�I?�$=���G�������,��c������Kpo��2�q�CF�	`}�K$&i]g��H�#p��S)(��gf����CSZP�#s�����FuR������8,q�������x������5a�5��D����}i�'��;���PP�I�LA�Q/���p��Cio�$����3�$���� D���������_���J� ��(K��mu���u���I�O����m)e-=�d���7���H�����bH���DAq� j?���\�1�!�9�b�����U&K~y���$@{�������<������{��bKk(�[am"��s���Id*��$L�D�^!y>X��d'�B��uXb*�E�"ZB@� R���
����k k�C#J�
��o���@���.��Zv��tC�t��ks�*�
��CLJ!$�$@0�9 �(������GS�����O�i���tGH�B��i,UJ������e��X��8"W�BIBJiF�Xf����UF)*=�6������H�3�����?C�z��I;�����qFaM'4q��C\�C���=N����d�:Op'��x2������GX��Q=� G����2�m�u��~��m��!�DI6���>��D�=a_��zM��/EOqi1��4�������R@^��"
��jP��! ��D�G�MMD���,���kO��O���(���Uz��<�@@9E�;�{�R���&V�l��Y�$��B?�8�}�z(����^�\=o�C�C�A��Df����F(��a��J
v�?b�I��'�~�?N���T�}l�����S�G����t�&A�5�W�?��������F�C}��4����E�RI# "�?,���������
��~$v�T{�J�h��k��I8%QD���j�f���<@���-�$��%�,KD��	P%`�X9"��cZH��xP�C�!��,��R��dm�a�(����z���bt��'��iu�@���n��r��v'��;�r���`���� !��.W�\�]�������=��nU�P9q�����
V����M ������P���y�Myi^d����va��.���B�>"@�$r��!�Q5)"}�T�c��������!����>2 �/�w���z/����D��-]�g��J:b${-��S�/!E1���0j ����~��S�R�T? �
��zO!Mh���j�z��>����$�����YZ�2�h#F$��+f]
����>QT��&���n�'=�A�rhS�7���1a�$4r�����w��H�:~QeS���S����W�I�G��?$���$��h�a,�C��AI�y�Q^x��Qp�Lq#�4��J��<O���
������w��I�����f,�R4v0?�H��a���������Hp�	��"���&�I��;�Q������^���$���"|�����"�+H
��E��b��@�(�i[L #�����/q{��E�[G�Ay+�'N>��,��	NU��H��q�gS�Q�yH1'�$uN�=q��B����A��9��4��l�,_l�L�(.�?;��h"
g������T��
�b]Z�c���&����$ ���o��J�od�kD{^�?7���0�o���_��wZ-<���>e���������� ���)*��O)���M{ XT'�$�����/ 	.( X���]f�5u��X7�n��=`���?���^o�����&� �A�R$�t��R���+(���<*.����y:\6�?`8+�@@��e���������Y�#��i�t�N>N�������'L��I$��L$;��p;Z ��E��!�C4Yb�$��:��N:�.=>&�c�t�T�����d
@��=	#jFj�c�cB�]��I&DV�d���=��� z-��Y(����pTm����@U�@�D�g`�=��W����~������Cj��Q\���N�y�^5��?��&tg$����?~]�v�	P ���7$��������2s�G����)����=G�/nOhB�MRg�� ��(��>����Vj���MIX�H�g�|��_��n��`��9n_J((\]Z>��7�0(��U���x��$,���vLM�����%���j��?���h�V�oM?�8���>d�J��}��	�_q!1��E�-#��ukUk�\-����aw\ �$.���p��������J].��\$������wv��N������4������&l�����n�;n�n�Je.����)Rfeu+�M��\�3dL��M]L������\.��2�me�E���D�)�J��%�����Z�#K��g7u��(���������!���w�p����JH�B��[B�B��l���v�,�:� m�q�q5�����T'X��0�R� &�B���Pa�{sbH�'Q<�$���
^��U������-(�"uR�O�>H_���i��?��~��m�����������-ex������X(~�D�-[
iY����i�b�Y�����y�4�:�<f`���,�7��z�����_���s��Ck8O���l�W���7�a��I��w�L$��@��</��5�����`�Fk�$?O�����C����*�jU&�4�S�A�B>_|+���Jt���T;T���s�H9NF�q����Y�3��*�0���'
N��p8�R��z\�M]I9^,�XD�n���Q���]
{��"@��Lx4�Z�| ���Z
�� �I3�E�R���3��wq��]G���_��(�!(������:�*��*�����}�^0�Ah*d,m63Qj5Z�i�-Z�a�P��G%Kj�H�~w�O�y�j�������������O�u`��"^�x?V('~"'^��]��C`����I�%I��0���D�,���H��`���3�����q(IZfD���[P�..�{���BH�vh��!}~�L�&�YR����)�)��H�H�3J��e6�jE-"��F�H�3FF�E,�B)H�R325j�4����R������D��$��J��		�$�JK&Y���T�j��VT��f��(�$�iYM��f�E"�FQ��E3B�0"���:"��#m6����R:���("A(������#��B��lC�8���[�62��<���)j(�W�dx�DU��cgj�`�j��f�I��wB?#��
�Z^�<�E��*Z�:���GnnB�B�K�����<%O9��bbH� ��t�M��U M�J�8�1@�J�Z%QMn��/�eaW{U�t��EcQ���J��U*RDC��A�8�IPc��L8Y��&��4���2�\`a�J�=}PGy�'2�JD���WU2Y_it)�&�K����m���r�s$��T��[e�e-E"�J!$�-�PL�
�,(�!AA��Y�2Q
T��IQ��%PbF@�)%�)�E( �&LL�����_yy$����2FUZ����wZ7rE���n��/����4�u��!�:e�OAy
���q�G8�j5V�l����!2���iq��twU�o�@���a�fBe�D����0y��;����{�;�<�*�0�`l�Ml1��#�^]�k���m�|gIS�����Fa�����1��P���l�����s2=Q��xC���Z4�aZ���V�8@�	"Pb�H�:�w^=_�ScV���LB;��3X=�BL�$
*�!+��|4���8(�f�#�kvF���"�b����HD�-8I�t�u�/�#�7%�%XYFx�����?���R�#vHb�� �|�vO���������G�����r�[F�k�(U{��~dC��#
Jz�&�(��o�����>�{����$iB	Y��|3iZ�����U5p*���"a�7��������Z���
M��QQh�kjZ !P��	�]~h�M����fi&D�c�y�A$G���-Xg��� E��t�9(��@�I���%dM������v�S�Ap�:�=c���B2����A��"�^������,C��� IK���G��t$-�u�^H�jk�:��AG�I������%��Q�S5�l��I��a�2�,~��T=~��zT�������m�5�f��D%��gW�$hy:t���E3���v�O�����3������1�a�����W�����M%��@���[y�n6L@O QC�/��P��T5X��yC�����ZU�BK�1����;���5*�:H����8�K>�CMm����'��o����Q�y��<?�r� N��8��4`���_g�8Us��@�����
.�?�N�6��ZJ��]�a�M��G����~�?��(�<N��S�0�
�	���$<�N��C(�/xf>���
���3B%B��%�\��B�UVE�TA��R������*���[[%�TT�6���$��f"�>�U��  �( >Y���'f@�qBIt(�.e���j1rH����{���]��!�[�t��|���k32|�=A��Hx�3�5�/�/�$���Hv��k�[OE�q�y��f�����/��{�����$�iO�0��g(W��7��A�2��VSh������%��S0�?N��^�Q�"H�*��5����C�o
	�ITHI��i�}�n�j��������o�~pG����������9Mu��p�:�D5�_o����������5$�$���[
�C2� � J@�#1	+8��*�68����`��I����4ST�L��NO�L�y����y��)��p��-����L�����:���?N�v<3X�Z �H8ID��=K�����=by��*�:DEqUG@�E�]-*Q]��\4�T�~5p��P���#�&f
�4����0�����h<P������A��%f�6��y���'A��"?P�J��(<-����>�����E��E�*����Aa��0~���%�;~��O���������Le��b�J����/RJ�m�
 M�������>�O��@����#
?:��,��\�HMV$���[����/8b���Sg6��D0� i��'�x��L����Q1�a������C_3@c��#�Js���;_{O{{ ��_�����~1��T��/t��N~��\K�B/�!<49E@D@�v��D9 *����!�9(�p����r�V�����[�2=���M���
A��t�n�y�`&�����"�<G�%����HI b��� ���6�'9���������'�{�DB��������T�5(�z�OY������.��M�'��W|p�??�5����6b����"���u�u��'��(��_8e��Q����D�?�����O�����}��B�
\�\qq�_<~n�{�v���~N��R�v�G�����I�P��������8�E���$F�����y�bBI$�w�� ~~�0��2JG�����@��=O<04�l$7?��	��=I�?iKJ_�������a�jv/��	�����Z�	��JD���\s���J�D��)�33(��5��6��� i��9�yv�Us���H��5�}���a�D��&� C @{�SP��z����y	�B4(���l!Y{�;W��r��f�@��m��D�|�qI
IKf`��kt�D����MT#&%��!q��Y?����>B�GL�B�i�"z=����T�0�0)�Re`&IPA*( E�l����/���}\��������"f!����M�R�RH���9p���#&���a�{��Q�P�	�uA@���w�����H6**�zD!	B����F7#�f�{���>��B`��w.%���VQ����p�������-((�Y%/��>�7dU�%3	�s���?�y��W��o�x3q�xP;��>3n�dID��	��
�J���Au�{s���'D���S�������������hi��j�i#"���I�f��7	�wr�����(�
����|=��ZzFynx;
�2����'���8u��`�$����I�_�$�u��2*�lR�da�D�Xp��p TL���@�$E >�0����Kl��mN��I����Qs�����H�D��F��WJ���Ij*���\7m��KY�,����������d�
�����Z����������v�3-����Zl?t�Mh���h��@a����$.{���BV^]�d�'�Bi �c�pQ(�gag�O<Nh�J����Hj�
fAA�'��=9��s�3f��w�����������i"�f��CE%�e�h�ai�� �����������2��E���XXYb��Gtq��\l+$)��&?M���{�C�B�
�GX���mH�Y+�y"���g�p�(�I�,����>��()����]�� �nF�`�S����n���H�(�DDB_�t0�_�Y��ZY�<�~�D�>�S�������(�n����9`SS��)�w�JEc�x��~�W�'�<��"m&��3��WYj�QU(%ED @IUIH31�C�,I��;	�7�L�����$�������Pi���!�����Xh,t�br�������Sz��`2{��Q��t����X�.�v;e�@�T_��L���p���LisH�]��{3�I(^�j�:87���g��8$q1-a3���I,;��a���`v� �"�W��o{�I�ix���	+Fs
��)WX����MH�39��3�eF.B�+s�$����%A�K`�D�d
��"�IR!��;���R�o�����B�^R��S��(���G�j�P��������a�^�@��Tq�v�$\�-7Mm�V�qf��x�F������7��~���]���@����o�S4M
Z�)+����q_��^y���X�����������1J9p��)���b���t����y��9N%��\��#y��?�K�9I�B��q������$( N}����	��6���e5&K��LY��J
e���t��MSj�V����� �H�,��"��2�DB����J2��*�,����!#4�4e�%6�����3M,�i(���evcF�1L����h=�
�����H@_�� ��Yt�,�%�d�~���g���|�������e�����jnO�2�Ad�[�9sk��������iS9�iU]P��??z��|�+���K^&I%%�P��1N�����0/�C�|�K�%���O�pL����F�/}�����="j����Fluhf��2ak�U�w��T�sn���<��f�������h���[b&;O� �=�� �fU��X�	9"������O��~����)k���$<v=��������n�<$�d��J�m�
���r(����I���h��� �9��;	�����_T'��z���p�������lH�m"b���B�Al�o��l<Z*�SQ�Av���0|���dUU0kU���I���>�=��v@����?�a�}n6j�H��?0F����F��$z�A�%$	�<���|,_<:&�f�1�wZ��nY�BY]P.a
�����V����08H)�'U��w�Bf�-�N��V���&E�b��='���24hVV�,��Ll�.HE�P��oYU ��?��p��tBEbD�� d F a��RR!e�UH�P����� ���$G���r��b�5�����;v���c�HbD�I����0n��dp."c%C8�����t������]eV�"#�����L6�����k�>���}�D��@h`��KG�Q�#��8���^F
��I��-�\ *���I���i���UH��H����,��1h(�v���!�������	=H������H<���������t��}��"��n������.��&���CJ�6�T�d���������$�X	�������7�<1�������r�uLt���SCP�����,�V���*M��(JZ�gC�a~7	�DD�@5�������UUUUUU5�Gn;������~�EiJ���Ep�%��
0�GHi��6��i#�!�K
��C1$6��I�I�T�M�ei���In[������M�M�i4��dM]4�&����M%�M�1$BzI�&BJ��A�A ��P 	R�XX�!FP��B`aP����X�!e$R`��A�bBRU���!J�"X��"%�C��[��yo8���q+m��I��!"��J�&��9F����VV�"�N�w+�)���1���Au�����=��;���FNC�2\�J�b
8�1��!d2�(�kg7=�}
���
��2�f��'Ur�Wn�!��+�4[I$IJ&��L^�)�^Tys�1����
O�k�aO��+��1�^eO�r8H�w.�E�X��o�+������������N�:�I��3��,��;����i+2#~��h�O\e7�EZ%`�WM�CT�7Ku8���/�b�I�L[|�&3g�D0bP(b�z�b�v��r��������p�A��#p�K����<:�q�j, �b��B�nE�NAq"��d�����LlP
'� 4�QA�^�"�����=+�H���Xk��.�s����p��O��=�.�I^�}r������vJ���������e'9Lq)���>�,���j}����zC#�)�������������S
�I-�aD
^<�����i�?����o�v�o��S����:���z� I%D����t�����MZp�C#�2��l��`���51U1s��w�ke�}��u���
UGDnL����X�-%�JM��;�7kY��i(Z�A�\h"C���k5������H�@��'�
X`��-e,�H�6��yi��q���%�FJ�Z�~:vw�w�:���\�Tu�"���w��:��"k[��z�4&D()����y<�M���`BHR��1����N"hc��J��6#��O���y4�HB	4(����T��h����	����a�BC��@�������	 ~�QI?�C��C����-��5�����rJ���V�:��M1��9��$$k�@M�B�}�HH�y��g���t5�$�2����U�uR�U--%�t�jw�-t�A��;��1�O���	R3>_�
4���ofF�{� �����BV�b�6�K����
"&Dk&���O*9<�I�Z�&{_W�~���@>�3�@b@����lI��U8�XD�����%%E����el�KX�,� ���	�N��#�����i:��?�Q-g�;����PQ�2��������X&�k=�m.�3�w��aq��A1ZPh����#��'y��P�j� �"
U��~�����@R�V�;�X�%�^�B	A"��)�0�3���y��������6]��o$7�A�9���P�����z�"��jO����G{���md,��">+�Tc_K��������A���Z@�KrG�E����3����lG�nD��VI=}�G�9~J������0���F�@s�_T�5�V&H�GZ��P'#�M"����dc�pf&�:{#���;A���Sp���:J����@�02L��8���>eL'C�!{A�e��`@�������"��T�8�8��@iH�!�-��S3��}��eT8��|��FY@`f�T^(��w�uI@X����!jR&�PaE�@X�HdEaAaa�*����U��X�J?���m�FnP�p����$u���H8(|��@�&�I��>���=�y��fP�-!9���`+�0!Q��_<#�:�^E�_v�t?o��W�N����{����S��d�������$��E_wr���Bad�H]��B�WU�����/dVPRA��S %$ ��-|3�t��vB@.�@����Y�"���F�������gc��D�[�
S���z0��x�"MG`���8�c�d���	b�����V"����v�Nl����H�O����W��QAF	�I1��0(��y��,���^p��<E�wx���zm�{zp�~�P�"��(�e[b�!'�A��v	�t�N�Iww�Y1���H��m� ���)H���,+�7��l#k���d�6-�1�0���&�ni�O)e�IB�u�P�+>G|I�H�VffaEeD�;���V�<#�������q��2]���B'��X�%��?J5��k'���N8�$�,�B2Y	�����&Fxb~��!�?�
���K��P����n�"�� *��`HeT]����s�
�s>!�OD
3��}-P�U������Q���=T�H�����2% u�����((�"}R�BvT�s���+���T�1����I|��TK�C���
���i�T��eZ���?l��|~���zk�q*�'�����������?���������#�-��9hMK�Iq@6������M���a���5���<�vB�
� !"�%<c�������G7��[�r�<7e�jR:?\��J����H
P$zh	�����d���}9��*�������A+���D�IYI-+{��$��Y)UpH����R�BK)KIHe����l��m���&�L����)������2��l�R��l����L���������iT����&PPm��YRIAjYK(e4U,�k�3!���9$�����Hp��g�O����N?���p��!"
9�:;�q�M�t����*��o��������V��)�H���%HI�
E+M�sC�$���?���)�	����so�Z������yb�H���������mbG��������z*Br�9����<"������ �"�5 H�0�	A�����6�������c�b��bM_,��e;^)�3 �?K�}o���^Q���|�E�y)�)��PR����=�q��w�(��/����F�y �j
��w9'��!>���yB"����+Q����X��\�!��L�� D}~�,I�H:��6��>d����N��a]1��u4r��zy����D�H�����7j4��q�$�L�h����B\����4�� Iu�����Z7�4�S\���3��X��"t��O���3!kbd
RY)*$�(��H�-�#*�V,��:�QE*�`f�OHkk�4�L@L�2�N,�`t)������`�p{8BB�����?}��}�{��mQr�#
Bj
���-b��Y�2e�Y�X������'{��u$.@��b%4�T���H�C�A��T�B�H��x}\��
��}%������9��XB�����[�Ny�GQ�4�}�iej7��JIL��[o��_��bt�Yx+?���gb�����}�Q-J�+���)�6�%�YB��t��"w$��R�O�_�md��&�Fg�)�?�b�m�&�b��~���5-`X���G;"D
_�^�ai'Z��1���1OK�
�>�
��O��a�If���C�<=jT��f����q�<�� )��Xg���G� ����8J��irO�~|T�d����f�Zh��Fh�!]K
d3m%��
����10���X� �#�$����6M��/n����\����U���!���i�k�|�t�Q����Q�����$yRhG���������#�BYL}��!]������I���AQ\%�oKa]��4��@��
e��0��B�D���k_��b�~�D�+����[2����^YAD��4v3��w�D�//����P����o��n>�yI�6��{3EHv������K@CK��N��QB�!ofb��������c�q�\�?Dz%A3����Ag�Js��/k����P������9�z:G��������w]nC
x$��4eb[�[(����(�w]�E(��n	2��F	rG!�\P��jtJ�8h"T)C������~R��?��W���~����x�������1SVH�	BC?}�
rb�����U43�D�N\Z�-��f�[Z��������`I����>���p�(�+����{�$n0�='��=��W��
�bE�D)A�QhAH��W����H_
���J��DC�������:J���r6�,�2E~�s[mKie��dKi�����5���������=�M%�G��������@v�2V�"�����]@��A��
�p*��W��8�r�"N�T:jB��p��Pe������X}�A.�p�n���`C�?�b
�Ox�/�Z��BX�#�G��j��@1�r��$��Hx,���o��$;;���2hUK���=Z����"��b���[yX;�����I 6<8���H�)���p�����)4�^��X�,�]#�\*%"Dv�$��/�/��U�U~�s*��l��5���4���$AXe���V"[���!���<��*�=np�F=C!�B���2F)%$��m����$����|���N��N!�E8M�X�i@�] �$�i��PE���j��:�l�MASp',��2h������4\2Q���	���A��y��H�eO��}��*$r�5$������$=	���z��z�����c������n�FjP��Z�?L@3*Q$:�Kep�aU�59$I�8���;[�f�fW�q�9,�D�<��}X
�;�hO��w���}]a_��}[Gm�������,h�b�aU%*J�%C�l�1##',#��+��9
��G�=0#�dz��yY�����[	�txG��>����������${��4E���KU)T�cE(�
T���ixZ7��
����|awR*D8Lu������]�&.��#���2GZA��kWc������G�Z�)��P�B%YT�"h���Lj�2��U�m�+h���e,j��$����-Y6�J�VJ,Z(�T�
�R�T	��BIa�IeZ�U��J�SR��(��K	�J�$�H(3*$��,�3,BL�����R�(S	@��,��P��2��*���$E�e5���f��f�e����y�����H�r�:�,����]k��he�a =�@�Ga1�8��}�}���&������W���11��LD��a �b�F����W�KuD�6M�-(�yU�x�"�� ��4SE���E���0S���$����	��C��!�=�}��p�0����������(dS���w��B�P/�X��HE�$_v�'�Q%��o��1�@�Iz��$�RHA!%����Y����y���J�$P��!����3�p-$IJ�m� �~�B�?�����3�q��^SS�T����B^JINPCw���j@����q���z3��<^v!H������\�b"y����`��8,IT�Jy4	���p�����W���;��A���Al`��x%��<�	 �h3������a�p;����#2E��H-�R���3�������IU�,D�K`j�n�c��C�p�������&n�o�>~�t�S�e�JX�$>�!�AUd!P�b���k�(��Y%�|�Y��+���T1}(I�y?�Q��{��`�s�����[|��!C/�Fv�Lt�BBFe!!�P��C�(8�N�E1� �<t�D���t<��;��F���fH���8�0��&8B}5$"�L�z�����6�N��{�}ZS��_�/�	0�������������=��
���R<����~xO�f��b��,�u��	�vG2���Q5��\���9����_|���9=�����)O�/^���d�3N�q��F(�������!��h�=9!�@����g��Y=�k��N7�5 �k����1@Cpu�m��rk�ZFNW#����or���{�����DD�N`�8<���
��ACR������6����[�6b2����A_�0%*�x5fjH���"�}ng&��c���uq��}[:g�6����l\`]�������Tt�������7KIhU������.0N��wS����vlkJN_���|Rp��^�X�H�,:�`��y6��92�X�LY#��_(�k��������Y-x3���B�Z���YS����/f����S��f��(�]�a��%]TSG���T���� �IaY�yRNP����
CqD�l_t��wzC�BX9�#W�|�3��]We��4f���
a(@�yY��"k4
HH���b�St�E38���soL'(�.:�q���R�'p9^T�V�Wi0�j�m�\��v���F������$�FD1
UJIM8���Tn6h�#���$V������_�C������Z3��a^�u5K��N$��JNS����y���4�g�����5��%�vEqR$1"���'}8*�1�if����3L��R(/�����Y����rH�M���f����Xi�������BGGj�])���c�o>��4������2���&	�C�$	
���$JD�����B�-T��YQ���#I�]{w�y5�
���U�$LO�Y����Q�T�Xp���d��!�u��	D�90,&��B����M�Q}�`y$��DS��?v�{����6|S!���T��t��>������MZ���.g'h��6j�ka��X������tl����A����a �
��6��uT����mEZ�m�H��2���[����RRS7]�F�j�jZ��#P��b���B�BE��FJ!�H��,�R�c��+��C���B+���"f�1�826��	EC�(����6�8�"l������}��1��Yz��@35����h'�$�C�>�~J����d= fyY_���������/B���<��F)�{������j������kq�g^��'�z���H���F:�����B�����RKo��k[�<B�gh��D�6!vw����BPA�����p�����z�9UN�)��<��z\���Pl`.���n���D��|	����O���~���0!�����I��HQUY�:����wDxXH���;�)0X�����*?kJ����_�31�����5'���l
'^��Ob �hb���t�R�~ry����r�A�	
�������`��= ��|���W��""j��y�^������+��'�����Q��#�!-�ofE�@<�@)M��e�S��)	0��J�"d� W�1W��u���HU�XI(}��E�
����?DuO�}��{���!('�L����X�M������	lR"ef�j���+n�Z�X6(����+&t�(�z	-��TP!����\:���t�b%)U�J*��:>�bX�>D�<��'Nda;�M��=��oLI+�k�wH,��1j[ ae�r���j�����v����������o�?��iU��?H�>j[i<}'C�4e����,n��F��M@fIB4KMc�6��L7��#��$pP�-��r7s����5��6�!H.�����
�Z%��kX��`YHfx�������nvj2��,��jMEJUM,���]�P����[m�lm4d���bTFx�"*���d!&P�
RM �{�Q)����k#-[�5t�j9a����""T��c��Y�W���G��@��1N�olNrN�	>��D ��%QT�W�'XL��;�
������.�F�O�*B��V�k���7�~g��z��{'����'4	G����Q��J(������^J�N��������UX<�N�����?"�����&=��y��I�?��X�����D8��5��/�n���~�
��_9
UT�O�ICP���9�\a��n����~��O����������b?�)�7PU@?��J�a�]<����/��'�����qg��E
BE'v8�4�N��� >F�
;
t��wv��N��_c�W��������X���=�b-�1�*@��D��r`tU��8�S���������,*������w��OR����"[*�`��:����p����4z:���U6�������v��	�=~RH���$��<�P}0'�I*�z��LS�s}��PP�=�'����fp�	�W��aP(mT�3�
%a����
�������KM�����W�� "@$����fP�MLmF���kZ���	�2R�Qch��F�l�����i�	Bf	Ba)�i%)PJI)f�P�L%	Bf��eE \����Tb��h�$RL)��1P@�J0J��	Bi%6$��%	���m+H��
b��2�D%$0���-	e12LB�����U����U&��M	�(��4�%,�P��8�����1A3RF��m�M��R���%S:�Wj�v�*I�Sa%.��U�B�����ABgm+]�F�2�����HIK���M4o�Rj�F4|s[d�\.�*�kZ[-q��UA�P�,��^-J��(����!�d��
Bit�x����SC��<�g���k���E[�% �� PWd;�n}�Io\�dH�!��#r�"��$�g�Z6��)����P���{�������:������h�gC�NR��Q����*~I��'��0PQ�N@���If4H���Z	������:~��E��`����Lm�Z��6��W�����}����'���)�Od�#0B�:/jpH��R��u��U�O��> DG��i����,s�jOm"�q��5�����u{�?~�V]L���x���a�����t{�X�����p
�Q<l��))iZ��(���*8A���9���m*nW1T�Em�E����d�6�v�o�1�'v��G�a-v��L�����0aA���bpk�88�.� �ec&B��BP�J��Rl��u6��R�)�2��Q\A�a�������>�Y�$���Re3#&dh��.�j���m����� ���:��K.��\uiN�U��N�fk{�+���A�f7��\@g�@;qzr��9!<�,)pi0s4�[T2DQIQ�fYi	��E�&B@��il�Z�������Z�I =
JT1�P4�U*D�LZp5��L�8�
��Lj��TBD�Rd������:���n�������'����`%Q
DI:�h}}��$Htk������y��7	H2�U���������T0 �Nt�s1B����7C�E���}Zm��iD�E�6��e�4`�M-�
�3��7�,n�=
��r}>j�)���������W�3��9��b������L}67Q�{�BI|�r%C�����R����}��)���?�������~kr&�N>�����T���ZiR:���G?G�>��>�"�JH�W���P�T$f!^/�hz����H\���68C�������
�����ce5�5� �M��I$"�����X<�7������9��.��������NW&Bt�GP�ar�I�*�C1-o����+��I��3Z�w}Q�6�y��[*�
�H<��)�^��I�T��b����,m,��b$��;�O��������}����!�#��K>A���_���^G2��&��7���8H��t�?��\�P�LD�u�%&�%�"X��~�v����B	�F��!BS,1��$�Y-�3�d����<E8����-Y!�t�<#�I ���=:;��F���t�$��������~��s=�s��#�|�	������Qa
����~�L��.��V����9�$���mEP���>^�"��
(S�d% ��I�L*��eI�BXB���(A,���8�o���8i0�z����I��tt���jG-4�cd���eR�jA���<�\B���2��������r��?B���9[�v��j0���t*e\}��?��N{�k�?�i"�%�4����W�Y�r����K-^,�N���d�C�J
�H	U��$A�Q!$���T�(8PJ)�1D���z�1,����a���|����
8h
ID�B)A��*D|W?�.���GO�?�(���F|{_v�p�d��W��Q�����
����Y�W!���������s(	�f�I����3��v�;^��'�:���/a�"������qp"Y=I�Z��aF��h��\cKdo%�\����,�����n��Ai-DF3b�X-%��%��$c�K0	��H��*��Rc	�Z�ZA�%TH�L�e�2�B�=uqr��{(@d���?����3}zN���Y�bH�9���9����-��z9�H�=�����:���*n��$}]��a;�	X-G�E�-�&O)�-�t�1m1��@������Fe�\H���P!���C�C�%�0
8`L�D�u$�jL�n�.Ofg�3���v��`���L.{�����9�h��NQ��������fUT���$H�PF�:�!+�c�����=��xy����O��MB�L���6(M%�I%!���Y�aB�L��8�%��2p\U �f�-6Q0�,I� �*%l/Y#��&��^�O2FZ�P�!0����
L��.:7Y��&��_o����
*�2v��/k/qRWSr���UR,3q��i�����166HV��,��%�M�	@���B��sV��q�@1��|�Gg*~��Q���E:�|�CX�h���}��dN�E��}#��78�X��=Xn��$���"�	��&S1f�=I��#8	�(�Hn���GzI!�G	n������16!�{vkD���G�q$�%�%��������r��M���hq����&L�#�����:���0� ����h&����'����P8���%+9LQ0@���0������8@1�M"�U��K'Z���y��&��1^��
ZT���I�F���%�=���x���T�� ;��K��0m�f�P&���C����~�EtY�I��D�	���
v��$""y����g4���"��y(F����(���O����	H��}�'�8�	!�pP�>���xOJFz���z�pJ�d��D1���N��B{%TGa���4@�|�����)��4��?C4��|X��Y�=u$j�	�8#��HG@���XJ�(�S��F'��j���T�$�ZQ��Z���6���ttc������^o��q8Tx<�)2���5-n����L)J�����B=���!} zT=�������NH`T�i" ����	%1����,��M@���'����G��5� �6��
�!����y�6����7u�{X�����M�o04���ok<�����sj7-��_��a����<�K�}L��iJ+�4�b����
�&���`���d�)�Y$TJ�2�Z��Y���,��(`���I�8�a�.�����Ux�
	�gH	o�"���_q>vLU,��z�t��w���r��o����)��s�j�����J$@�&&���
������,.����<�d�'�3�$�:4����03L&O>�X�������w���������O�p����5a��%
6�_�yh,���(�N,�B�TSd|�;&"O�������s\Z��}�����I�}�w�Q��q��N�1�}!/I �("��PXz���X�b������3�a���[�Mlv�\���t���y������z!B(#Y�Z���h8 ||n"Ih�y��x�����
���� Id�J%�HJ������/y<R�B8�I������J0�r���1t���'`*	����+��\]�`n���Q&��d�t)D���Ra�$(��'��x�e�����"�X�"0>{\w[�_�N������M���<i��:$�J0�m����R%/��Y�X���T{�DVD�'b���1'H����J�L��J:	
	q�q����"��N�S�E@�Diu��6�C(\!������)�P��qf�"�l�l(QEI�(K+%��I�"-�T�
#
H3��(�y����"��|�w��wYO��{�Kf�o�}x��vU/�[��"�j����$6"��\����0�"^a�j�*��P�
� �~Byy������B9��EP��;�Fke�#���W�}�<�9��PB��xVW���u�kfky�4@�*�4�ws�8��to|���
 S���Y$��3F������zB�z,���CY�s�k��������h�~K�N���;���=��W��d{D���(a�pD)�z��sl
"�����7�?�����J�A*B����%�&Ii�G�^�qp�����v!�����L-$��d�����d���f<W�{�X�,��K�F��j��������DG�MIk��6��* M�f,K�\�S�	�@%�+X��8L��J��v��X���>��;&C�*7��.�$���*a�%����=����}z��V�&��JI�Chg[
l����t���2&�5#�6������K#�ds�:*I;��#�Y�Q�����9�/����;�q����;ej6�^����,���0Cd���j�)3�1XP��"��82Xe�>�aH���e)v���Un����������l��}y��#�|E�ne�-�~6-:%)% ��g�c���T%)���8��>�8��x �+h���\C���|�_�����D�Xh�	�E���dN6�0�m������7��d2rp��;��N�	����uK#���$t��F�o�G{�1'r!�H�UmyU�|���������������0�V��Z��2��jV�JSbSL�),D��B�����L�mZ�n��������N��q8^�h��bL��x	�����!�v�P���3����|dpD��"'��^��Q`��M��G�n����\�BR��(�����$��X��J0��C�w)�	>>jfP#3a��cB"��
�;0��2��)����U���2���
j�e��QU��p�����������9�t
k���k��t�Q�TH�"(t����A�;
�T��sI���;��$�"��
�H�F�dHX��s�d�A�O�=o��R�p�&�A�%�9BI�H=�	i�$��4!��HT�Y
���C�L6��)�{�OD?fuS���_{������* ������i�aZ��"Z��~�z��������� N�~e�uf���]c����?�� U+�kk&��o�J���N�`��qd��s�.��j���Q���M`��$�b+A#Ir���T��h��R�u�T������[R2%K*,-�@����k�n:��N����6��*���������V��z,u��c��*�]8)�*�Om������2�����HkA�.�&�=9��zu�[$mPL���
���a{w��Ap��Ba'uZ��������P*RR*��IT�0=���f��W�v���A�Yy�v��JH�$0J1��@c���l�=��:Q�A��U0������EDLJR�0�8�eL��FQ4�%eJd�e�?c����~��8��v���%B�V[�
B����iZ�4HV n� T��_�'��e�,�g���M�>j��":���}�)�u�
���A�����$d�'���w���u�������MX����E�aBw���y8����� �zH���+�K\$f}(�N�3��(R*&"E��<��BIP�+�����/S�S�T�n@#��FZ\d�C���M��P��L9�F���/�|�o������XD�����$�C��96���K��m�=!�wFb��r'����x���������� �$�v�5�U������li����4d����\geT\Ut+���O�84#[}>4����iO�����D�����K����&�L�GxyZ$�7�b4��	�A	�Q���_!}�" :�8��%��3�n�����&��Y�
v�(�i@Q����p=�*��U� �2������#"��B>����!�{F"���0�T�O����?D(��S���aG��SE"�_��bb�oA���sE�QL�H�H�3Tm�Akj
��V��i���c[X+Ym�[� �I"Q	�������l��T��Q,���W����?4���-���fG��?82*}��.�>i�M�3��mJ�=9���H|%�L�<m�nT������{P���?���v�|�������I�0��>��?;G��q���Q@�$��m�+2�1t�>'�� �W�F�J�c����Gos��>�e�����0��q�V,bT�f�p�;u)IJFV+"��J1�If��V�>&�5[#P��)�J=<r5�i���Jt��V*��(R�4�66�S����L���:Gq%Z-�Y� TIFO��"�e
U��?��KOFFov��8�<���
��A�YX���$��$����6T�hm�[Z��)�F���)�D�IL����4�)������\?3O�4��H�1���J0x>����}��8�\d�����sP�w��Y$!�Cl���@��y�o�0
�B���gX����|�JMy����>f�)V���!G���<ZO�R��*�,�P���q�����L���"�����
���L<�������G"$�����9Ee	��
/��,��2w���l��l�f]���Ss��BL�Lr5��������{N�AA� �M=aw$��{p%�*���S�RT�}�ix�y��5V{��H���]��[KOI`�*�>��mY�U+F:�C���
�yV�z����S��X �KMa&�I�@���%�(�[�	`fb.�$l
4%����S^�G���
��0��`����/�N�(��z���,=OA���@nyu�q�����i�r����(��)�����[�n�5���0`%8�J�L����4�������s{�[�e�c3�����:&����E.s(�(���(P�k��N
��F�:NW4(bE�c@��:�h��S��l����0R����'�!�4�J�Hyl�3?���4l�b��L����?��`������������D=�z|��u���W��:V�JU�O8��*�}�}Z+>�L�����������@������sG�O��>m�.�����������,:n}�{�����
�
�&����S�7w;�������`gy�}@[�>����
]l�N�����g�<�g6����]B�	�������
�c��R��
:>��F���*����������9���stk#�we�^4p\!%��oA�P����X:) z��(Q��
��(�EP	h�(���4t4����D����l��
�����=iZ�2f��a"@ ���Df���dM�hz&�@LFiS		E*z��M�h4�d�JBH�h��� z���OT�B���S��	��� 5)Bd�L����m&�P��II  �&��M�<S�����F�@��/����{��Z���+0k���1�i%�U�a�s�P�s����1�{���`F��,���`��%������~�`�FP(Q��b�LT������_?;�/����x[�6��D��}��������g�;�������K,~��������#�Q����pk��.H44X�G�	�iQ�Bd�
O�je"��3�����>�����3�� <�$�:�$z������z?v��^�o�L6��s>f�i�w��j�����������.g��-7����H@I6� 2n�#�)X����������0�H_u�I �����}iN&y|9��Y���}+���G�~~=����1� �;m��m������������=���x���6����|�e���Z�,9��U�E����4�U�X��V!-����I���9��q�qs�_����l*k�
[�Y����� *�
��3����$�-��3*�������sD��i>ct^��yD��	����!��g�1��L
��JJ����p���1"H�l)BHK������j���I8�����,�K��m��
e�R���W�s� ���aK|��SY�(Ap����7K�JH.Yf��P��P��`�ZZ�F�*�e
�2D�]Y���)�h �A����A��g]"l���A�aT�M25�MdY��,��9b�S)�TH%D��^��������.r�2���&r�2:���=q��-,J���0�]_R�j$6A7:iK*�X��������c������������pHe��������O;&9�^*b�T�2�d�^�@��u�w���c�}''�p�������@���:�G�d�%`*Zm�P�%@%�����`,���i��@b(��(��������d�v�<���K���T�)� 
���%�Y�e���(�(C���^�f~?�������DFL�B�PP�2H�K
U��$!
�5�0�1�%u��	�R��B�+
bLKH�xd�
b*2��n����z������k������tl|�|���Q�1�c���|�����%�3?������f����C��r���:��/��q�S��By�!���@4X��I������n����x�PU�L�-�Iq(�pd4��>�~O��%_���fB�^r�E�����n��AA9'RB�����R�Q|���%�d����(������yy��|��Z�~�O�#�8O�����2���T�R���$����K'|RB��e�A"���eM*�<xg�����
�/�Y�{d������$�t����P��}�����p�����L� M~"T�"iu����|rC��
�/�n~^a��
��1�������Km�Z~p�?xs����s�y�$"��55��&��5�/52�-���4��-�����1��O�o9���O��q��W��N�,f<eh���U��i�5H�����B3�a$����?5y����|�����#B}f2� M��~Ly��Z���I1V�������������I%������I$i�4LM��7��U���
�����1�����c��9�?�z����SMy��-4�~������$��2� �-KP�<�e}I$�C��-�C41w-_������K�N���j�������afF/��:���(R5��N
B:,(����f\���	h���fWqs�*��C��I&��?H|p�����?���W���z^��@���	&,���*T2,%a,�0�w�R
�(��K��M�����1�Aw<���H�I����3=�z���
�S��"IL2��S��b��&��J�J�#-b#9$��*�:R4`�|��^j��"��$�W��nyArJZ�@*��[�������cc����[���`1&�6�M6i��&�*T��R��E����6�4X�e�6�|�=���������Y��z���X������S1m&Jp��?G>�=-�W��e�&���f@f�66�z��m��\�y�'Z�C������C�?#������jhhh`�������cC�7N��Bm9 ����Ci9Y{+Y���m!�o�5���KC��?�Kn�0��ADm�l����T@�����
����N	��T�|'JDO��Y^����^�{�����R���[�������|����x���Ih�Hb��!�����?��~�/������z��+�|8~�BL��?���,nO~�.�|M�8��VzPHK�+���a����I	�.�kN0i,����P	q	]�2jyIj
�
��*yE�,*�t9G��t;�;�{`K�h����q<�����`G���4��{;;�H���g<�":,�����f��E�C�Y��DBAc�R��4GEYg�x����Q���AM�9:�������y��|�������h�{w�c�:���Jf���������P�����qF�m��O\��������y��{��<�s���{���E�6n]��x����.��j�&s���GA����`#0c�d!\5�I{/Cm��^I1��i�i�����J����~�~��������O�Y�g��V+,�;�����U_G����k��&�L�%�$��$��Y��$�)2Y�RJIi+%%���$����d���%��d�f�`�o����-���i
0D,fjPi6���o��:����h��r,�ver�3J��N�'"Y����+�K�5�s���i]0.5e:���bt~�A�;��T�'���tYUi�kX<�B��q:��)5�q��4��0�D�+���u�n��g��AD�����my�D\.�o�z�Y=�����G]�]Z�;[]T��r�&�l�[�m��o<��R�����nS�:Z�Yw���Ze�:T��7&mY��3�s��%�g���CXk���y=j�F�fmRX�Vl�b2S�v���Ki
��%-��?�E�L`,���i�M�
�kp�p���3[���/;t������[sj����������nIcVMQ&�PQe�+2���LL�M��T���^W���C���{�RxR��
�T�'e���t�����<R�e��1��dV�)�����bVd���bQyA�_|���u���^����������n�t�{�){���6��X��7�������89*5�N���!����Y�x�T@\�%���p���:��$�P2�'�����M��Rd��%�IRi�	&�I,��%��RI���&J��$���31��fY������v�Y��lk�G��k�[~���f��m�F�h��B(��$CD��Z������,����4�"%j��*X��r���^iu:����P�S�S�������e�NR���8��N��L���GL+X:MN�����qq1�Q����6��Tt��.N�$k������lV�mtiF�]&W��:)2�t��I�%K..������#���;:����y�g����>n�d#t/Ek�8|�C����9T�+���ru��jt[E���Ve�Y\�S.��[Cd�b�I��a�]b���W
�'I�����+�U���[d��(����M�.�K1]i�p�v�S��)G-��9�~�E<���{�D	@+����U�5�����^Mr`���]pr�]iJ�/x�N��6����Z�np��s�<*��[��[~�[�3�����A�f���m�uSWLY[������q{~� �~������y7��]T5^�je���\��R�t^���Ew|�����zS��9*�V�ut�c��;(�v�����W����YWN��Q{����<kj�
\�meJ�+}�P U����U��M�l�>G#�U`��o�����~�#x���^q��������p��uNb�y�K�X�!v��	�}�
h�,��>���D����H�I$�=!$��`j�&�*��N\?A�t�1*dv�r�'��~��������v��}b���O�"~�d�g����B����IM�P4�����"?�����m^
 4xLZ�!oQ!H��>O�8�o��j�������26LQ�H���FK&fI���MU������I!cd�KmTQmE��&M��"�Q�������o�w3������n�M�d������,��Q[����$�C�HOH�$����ym��&�q���I.���m��]���)���w���w}�p�9�����"��$p�����l�$�R-�O�-_�>I!�lp�9'�-I���m���v�%J��_m�p�6�^6���M��.l��:���H�Wlc���8��v��q���'�I](���DH�����*?G���"�����%���:������I$�1����U&�����m����*[�s��;��+W��|�g�I����m��;��9�p�99�y�z���B�ElG�}#�J�(��-��i���s�$�� �N����#�F�$r�����s�'q����H��I%|-���j�$�
q$���	cqi'�n���!]�����m3�	��lI(�|��$p���-����I����cX������T<chIs�6I+��g�~��2��\���%���%�d����������,J$��N�9����"��S[m��w�QR�s�%���~�^[���.9�C���}�K~����������i2I���ll��z{}�E���^���G����$S��4%��EM��@A�@!N�����v
��~X����Tj#Su��|���^���1
(��H�E"2��_�/:�	Zp��^�+��[ZhK�����y-���Y���S6D�1E�%�d����o����}��V�ke��na��]f`���#�f������R������m/����'}��M���  q�Fpu.�^�b���	�e'�o���:F����.�����5��x�j�������4Z�7��!���S�G�bjdZ�V����k)�����-Jm��LTjX�)$��M"��m"��(eE5���Smf��Z�5����5��cJY�0�ef��H�$�$�
1,m�o���t2�+KZ�(�DB�2�0��Z*�DX����o�E����d�ww����337���pfY\�%�I�9��~������E�3u�T�����tB�wf�Z����;��6�rI$J6���$�H��A�d!��1����F���rI&L�2H��F�nI$�I������:1�y���
!!����&�k��<�X�>���#��Pid�i�w���ewu��D ������4�!*�D$��G�|��m4�h�.z�mm�m�KC���s�m�9�Q�Y?>q5^��Np����p�F�E������L����I��l�o�{�s8�/~J���������������N�
�6�t��MX�lu��PYbN�T��Lu.B��@�����w	
�!��$��.��7�w�9���N��;+��B�T�[����}�����7oV�G�����KO|�����N[��*d&����+�����O��U~�,���B��3*���B*�J���*�#E�F"��N�����9:����������u����������uv����:����������t;�����C������A�U"�F�VF�D�UUYej�����w"�b"��\��I"�(��wZ�9��U:��v��p�9�����@�����db*+B�*�2����L��/�>y�
��DZ�(�U�(�Z!tD��.�`C���v����N���C���C��������*(�U�TJ!r��m�oX���@(��Q�x����m#��JM�\a
�<8JR�7Q!e��{��N))��^�w��]���|8xw��@�8bu�H��G|
]��C+UT5����yU��	x�����/.cJ�����<���=fx��-r��()���1�W�$4�2���*{=��0��cc�����|DF���6���Z�*�D1�(D��������;{">���^����O�m��U�w�aw�DY�����s��[��B�(�a=�������VX���y���P���������"#k>>\�����O+J3�x�|/;)_*������'b�T�}�DM�;8��a"d����*���6j��"	Z��EWR�p5&l_�O/��f�y��p������dh����O���I�{��l�W_����6�
������[p%v�x�2	������_�p�O����������x��3�����r]o|8��In~tT�}�������*�����0��`1�/�B?���Z����m�7�Wd�Y�r����1'cy������@	I^��=n�{<�}��6�m���Y���T����W^C��v��]n}���`l�i,��Y�1�5T�)���!I���SJ�b����lS2Y��,3)�R��X�J,�&Ye,���)3,�Z��Jj�J[$�l��j*
m�+MZ#Y�rv7���nk�2C�J����`��f�h�5ZR5MbE&�QV�M�b���m���Ri6�%�T�IR���L�����(�m
Yi�
�-����Z���j�b+Y(�2��-����&��f�Y�f�.�������*Y(�m!%O���fz�F��t�i������j��4��mZi�L�2�h�f�a���4��Lj���<U[�FhmU��Y�fL�M�mk��-���Z�ci$����������}w]u����s�K���N(��{uo7���}��?	^Y���_|}}����^��k�{��o�����	_����o��~K�|��X��s�����u�wy�H��������{�����������u���Jwy~���[��=����w��������I(&���7u�S�	���PMR!$t�~m��}qO�I,���1��=�s��!�u�I�J���9�B�!���Y5�$�J�|C|<�x{�����O���^����_���{��I	o�m�����]HX����j�������l���r��|��+lVF��HI1v��u'�d�����|���������k�'jI
�]��|��p���B�9�����[��H���[��j��m���|��,0I���!�c{9s78���X r
�k�(�nDr������������9�k��
E����8�k�H}>w��}o��r��}|���64�
���T���t�)Uw\�E��d�c
*o0\��s���Zj��"���)v��r����L��%S��y�o#����g���q�:yg�~�m��&�-��O���t�N�g|e����~������-�e���o����������jl��4�)=�8g����wn�����/�t�/�>���o���|%���<k�%?
ioo_n������d�9���1:��;�������wg�w
<9����������n����:Z~yV�~QZ����<��|�;t����x���?m����>y���j��\���������wN�3�����������	�Yn�Z����k���������yyv������>����yc�z��}t��\6�������n�����m�����v�n�v��v���&���.����|�����4�CM�1���kZ���f��9��M4����JSeyr���.9��zh�����m�������m���l��q���:����d�9�ml>�B�����c�y��+1��7
��gb�X5v�J~��^Y^�����+z���lW]�����-YZ�Wv<e�����V�^VDb4F�����m2v��Zd�ri���s���T�wOw���m�d�������oK���e��DEw�U���l����]��<����u��6l��b�����tv��J8���9,�����������Db"5���� �k��0�a��K��	��cf��AE�y�1� n���9��6u��^2���.��-K�kz�K����[���;�r�yd�-t8�<�t�����������6����n�����*QE
��oa�vr	�d���.��m����@>�TD�z9:���*
�6�&'r�ukZwXpi�f����nF���O��y���<�EP�1|�C{'5����i�mm��w�tK�Q�����%DO���C�*
���SlXC�F;9�=QE6�g�7�I���G�����J�����*
bB�h��k��@�#�pu�a��`�m�6�@k{��uU��WeL��Q�.��3]��5��]W~�f�
5�>�:}$����=�8�V
��<��&0��X��p����J��]�"(����yf��"4e3��OC�7��t@*�h�w�A�aQvpx����N��i�)���;MG��:��3^SNQ@�o��3��(�\������t��5g�`� �d1�u:��0�f��'g�'KU��$�g���Bo��� \'5r��1'�/"�����`����[����QE(�=�3����8I(******kd6�m�r7��]�DE��k���M[���?s�^��<�'~/
�p���Z�l��eVj��5���F�S11�������d-d��i�46)�V��e�&Z��1�j�Z�TcU�V4����A�L�1�sD��k%�F�5�k�K�V�|eQ�����}V��t��#I��""#&��I��L��)0d�i4Rb1IbLS4��"���T�f�YJjd�M�JMi�)�M1M6�k4Ri�#1i�)4Q��1�Dd�I�1F�$����$h�MYM&,m���i����$���jLQI��DE&Mi1DQI�%�I��iL�DE3L��,bM���f��&$�l�jSY������)-��L�(�L�F"M3E&�M3h�I�)4��I)52�$��>�o���G����0�JRz��\�Rx}R���&U�4=�������}���_�8���7�>�,2mX���?]�tx%�	K�H���c1A��=������dB�'�wY
<��34�@��O��3�o����mDp��I���yS�N�X������Rl4�6Hf)!�4�Y�kc5�Zyt;��8�Dyz�5�M5&�Qc%&��Y���*4d�1�d53"I�)�������)��a�d�5%�h�Ff�&��E���CL�)&�L��LJd���-3���_�|����%>��D�?����^�.�t�):A�m�egQ����6�8��y�v{y����������Nsw|����>�������Uz��������\��A(�e�D3e�e���!��J�U;Za�J����L�a����uC
�hm�iN-��{�R/\��xy����Y�uv��_�lI�pv/O�?K�^�w,40������^i
���b�]��9�C�qM� �`0{���($N-����#N��/]���b���[!">���[F��������F\�q��s\�v��H�Q���S�5��)~�~*����2":��,X�5~��-�^4��m��r�3�I�S����F��)�U`-!l���F�������kdG$��r���$�� �Q�$QB�rl�*�����h4blgH
�( q����M)@����i�b���uM�A�qX��
Y���gh2ND[	$";���0�5�Dh��Q��������HN�����[gv���}>k��'������A�<������j�}n*��m�\sm���Z%Q���~���^��k�q�4k�]�����Nq9�"I#�����K�N��}�A�2bw�V�b���{���lq�7��d��>��Xlf2e�a�����~or_t?r��;���'��>c�p>s�|����|������.
���	�����H#�A���|*;W�R;1~�y@���x�1�_�ZOPfbS�H�%v�����r~�����{?��yk������r��_tU���l`��6����eu�:��]+���s-�6�jv������d���!(LM&�Z���i��X2>��QRmu�}���l����������	�w1E&=�_��-�6�,,���l0������W\�r���.GI�[�".�C��?����_>��O���[���P���$�����DYY�#��o�vN��;��r��^��a�W��g�j�f��%���J	�����
��b��d������1���O|BS������������^u�r}�Q�W��40���9~��v����/*������3*�+5B�u�����3$L�M��F������#��0�f���/x�*?�vYC��HB>ck���%&)��>���*�9t��7�o�/�}m��IM2�i-��
Q��.������������e��>����#�G�#�T�������~l��f���J��h�A�T�1m�K��s�i6�j���-���l���8���q����2S�
�J��.���
.6�C"b"0(�
Sl��B���i�!�?��D��J������T�1TU�����n�Y����Z���*����'VZ��A�EF�M�+�Q9�D��NZ�sUTZ�%�8���g;�6�����O���q�8�����z��u�:X��%"Tl�d������LD�k^Umw�&���],��L+&�"�����)�VJ��<I����`���y\N�u����)�m}��5���������KwbQ�)���\����(�;����=��4��l������6�0��c�����32z��V��+�����W�R�KW%l��q��@�Mv�	����������w�o�*��#�T�h�#�m�m�^wc
��.
*4MF�	���M��+0������d���K�
Hh�K(���d��(�����$i
4�����dT��Q�&BPfRH���LFSEIIi���T�i$l�[&��$�k-#RRY�����$���%�&�����,��z��f`a3s��)�n��U����9����%�7V��u�lsE��&��::���������4"*��%��@��OZn�]�o��T��oJ��Bu�w:"
�4z�E\�yK��	q!ap���y�I2BE��y!U����Dc�W��\�93����Lx@B��'����t���"�!F����-�!�cs�C�!����*�(�~�`o=��Dp��{�/���W��w�t���NI$�n�4�^�"�:x][__�FM�h�c�m������"���h"(�m�+&��b
��F�cj�lTkU������OWg�����6f31��6���f#$��,�%�(
���k�����,�c�p�KY)$���IYf)�c)����?oQ_�(W���������]����Z[,�6eL�i$�����M.Z�fY�x�(��:q\W4f��M����cT���m�j���ff�A$����Ia&i�YCS��������,�X�]nEZZ�i$�T�����$�L�i����I����[[o�����-]SI&�i$���l�)Af�2Fi3d�e�]m��j���b����R��1UB�ZN��l�d�$$�����l�LY�JdY�O��fl�5W��vuY��;vv��i�w�f�5\d����.0����������7�&���z��RKI�
�i���f��\�s4���km�-���m�	U��I�hhkh�m'-���m�'�����w������3kK�V%��������1��`�U�I�*�����!�o9G��<x��������w�{[-��@�?A����\3�=
�!�fe�e��qp4���'��"Yq����*�a��K���h"
����2	"b��sQky��-���>�I#n�����;k�\:1��a�Us��c!�r~m�9��^��w�.=p����C��y�����	��wKTU
�EJ���x+�=��y���Z�yP!e	3K �1����Z�
�Y�E(H��H�*T�HC_�ZUt�g���-)M�bL�R���J�������&kZ��G�S���F�f&3�R��_���F�fj�1����]���I1���"��MJM3(�I�����T��d�l�H�J�JZ��$����R�)m�IUy��8�����e&��Uf��Sm3Ai	�l��Y�Y�`-��^wB����	�$�d��[f����mT�����)-�J0��ml����C�a�[Df�+Na��L�hml�#b�Sa�|�G����z5��p��H#���������@�j���	�R�1�1��h&D�"	$�$��K_��i1�Dd��m���^�n��vU�8���<Q���OD�""D�]t�E�*�;��^8!��$	k�i��EP]��Hpw����z/�	$�$���=��QX�Dm���9AW�����U��6Q�63,cb2�ZYM"%@&b�31��Y�f��i���I���6���$l����o�-�m[F����l���$�.5�Kf����=�<���F�G69��u���cq�c�#$�&�$�I$@�4�4�HJ���n������$$$������?������A�3R
Nd�D���R
H5?=v<�*�^9��PjU`d\�Xx�V����qr��v�oVv�����y�a$�'<miUUn{Hrg�0��������9s�th����������q�;�&x���o{C���DpAKXpM��spy�&����9�������'�U�7�C�M�q9Wcp�Y�=����Fz�,�q
0���e�h$����,T��}����#�-���n�&��w	w	81�jq.�e���e�L��9F#�(���nV��N��c!�DU�@�J�hc$d�"K��Z�I$�I%$�D��$\��y)��.�=����u�m�'ht�T�L"�&�DV��^78���=�����[�d]5J^��X�w����S��i��m{�Q��ZNs�i���J)2fT�����(�E(��(���x���-uHAv��T��v�����i�dh0y��ov�;p�88DA��^v���fC4?���a�		=EY
&�	�e)B�D0X�	���d���8B:�����=���o:�����K[BmQQ��t:;��|��z��;	�eP��
L��8m6�n�a����u�W]]^dL�\9!&(�E������P`4��D"���$�RMB���wT��
�AL��':��\4��G����g��QE(�(������h2\u��3��NJ�������I=B������v���bN���i�����t����Tv��lf,b���ffXRI%(J�M4�S�r9��r��G2g�
U�d'��<��Q�Ux:�0��,s���������g9�q��O���IU�:r�������w��M( ���u��w��������y��f���	�fVl�����6��+�i�%�B��IV5��K�����,V��kW�h�t����#��k+is*�3g���J���cc66���r����3��kE��#����w�y]�e�q�&A��E��t;������4�3�<Q��D�dj���y����z��J��K�%�nuU��9��^ z��TUEQQR��J�*�l.��]W%���W���^tz<��~p
t�:z�w��	w���k��x
��
s'0s������Se"�������(��QEo��y�� 6 �
��������fn����������\�^A�c���2��8�������v��iDcU��y!G33����<�������g��@&���V^j�o[KZp�H�,��m�[ZM�o.-��,.N`'��'�C�$"!��aEp����������=uI��G�������_>�#��w�n�v�����mo����zD(��&||�#	�F
N��euRV�K1#�K2VE��isq.���������������	�)��A�tC��!97�����G�����oRFIt��4I���{R�r�q�6�p�I$�l�$�f��I*��d��I$��;]A��� ����������N$����]���6�\W���a�����~�/Vl�Va���5M��,�JTk2*M�6��6�61FKF�lTZf,[Q��Y��6�f��	��*�����#����@S:�KaQ��l��F~V8�Ez�SCy�����}��~�������D��i�������)��Zi�d�f�JR�Ul����	����a���dX�iz����W����t��#`).��:�n�\���{�������cBkmx}�>`����v)��$�II$�I$HE���i����Qr9�G#�F��Gz��Sq���Q�YTR���J��m���\yn���(�I%��nj������L�f�����i$��E�%2���o^�o~��I�I��n��f����~��I$�K�	�"�Hb[�4&/Hf�&Bf�aD!-�����m��y�H������2o����UE8��-{p��N'2�Ya�L�e��Y1eb���,�2d��+�,�X���N-,�2i��G������V�[�������/�����1]$��iyV�����W����<�{��|+�W��=�����3���r�f�A��C��Xr��FO���2���*k@����z�E8=�s��s.�!���SM
�1H�����I-�)c�cwP�	3������#�$�{��pFw�<e�����<�1�X�"������q��������k&rg !���^�=��w�������N���sr��������,732V�
h� ����c�w��C��{���b1�Y�q6��V�}}�m���1�C=�w�4��9�2����0���8s@�x!h#E�M�

��d2�{��<�:A���X6��I��q�&H�r���{�7��
8A��!3N�6�b�!$*6\���Syiy��t4
�8����Q�s�c��J" N.�(|1DB��d�!�dAC�!��BQ4���
���L�73R���xGoX�=z�������zH�O�����	>-��){�2��Rd�])%q��q�x@��@�"D$q��{���W����[v���6��m�BZ���u�6K�����\�s�����;���]e�q��GR��xw^*��a���������<S<xcD*p�9KFQBx��D��w,��C�i���!7N1������D�F860�	��$���p�Lx�R�B�iiM!4�T����������3�e(�"�:#*Rn����{�,�;j�}������N���8�wW{�sl��v�Ow������/<-���u��l��xuw�����>syOo#�9M[����gx��9�����|^{�}�=|{�������zU������~��}y����k�9�����;�.�;%�����/w���y��������gg����}����{��������yn�W���77]vm����f�����U���.�ox�x�/k��{'y��:�����w{w��9����s����,�!E�7t�w�s���� ���������9�M�{�B<�.g�w}�K;��4��{�q���H�~�{��_P�_�v�y�]���^�7����L���C�3�������m�+�X��]���*���cD���K>��8�QR)G��s��I-$�8��oI����~�~������������)b��se����9
����]zm������iA��=��Y��<e ��^Y`�� ��/�V���,��ATX@L��	��:�;s!�!�����l�9b���ZK*������j�J6l�����]NL_oW�/ONs���R	���t�B>�*�������4����B6	h����X��s�)-+H��Q�J���"��V���j^u"���`�B��	 D	@���m\K(�SJ���W��'d�[mJI-�G%�g9���'�ki6�fnf��j�\:��s��}l���}�gG����h�WK�!nB�4�QW�T������F�*��Y%�J�*&�
@�	�<��`�Nq�7�#FZ:U�\��v�g�<=�����
�X�H�BE)H�Hh�q���I�6<dn�
�V��"�[oQ�9�f��Hv�"9pG8i ���j�8����&�=]�7x3���WN��8�=�1�2d������������4�?sv^�n��q_��0�3��s��?|���Y]�����Q�i%��$���u��~C���>{�Q�"K���8����Z^rY%k�WycVK��fydDX6�G�V}>�8��V����yVV�V45���*������7�0��qCPsY�3Pn���8����f�����������v
�	�����	),��J�d���58L�w���_7V�����pe�����p��hnnj��l^���<��CB������q;�e���@s3������g������MFn��������������B%t4�KjH�#�$��BF/��P����Wb�P��W�o9�%���C�������(��T�w..�Co�
�_�g�����<P��2�@`�G��X:\bT��|fx3����a?�\������fn\�0��r�^t;3�;��lX��gp���[����H�)R����`��#��������������&�/�W��}���i���tA�������}g��a�m=�
�{���79W*�C�7g�{:��U�5?���z|��\rUs����.���o�?�����?��+��������x�T��
a����<�����i��%�<�����*�@{B���iR������E��"��Tx|
���`��A��"��]��S���y;G��~�(��uW��=*?�>�H�����{6�����?z%H�t)z�|k�a�:�����
�z��@��%Hz�OD})'u>Txw������K�w�>�����>��D�|��H;�=����vOZ'tA�����T�5�����3������5)�R�����?��]�x?^;��(�L~�
�?�~*BS��:�y�E���9\R��G�����"`L�D�%�/���%�O�A*�JUu��`���+�Z�M1X����1��	���&5dh�f�S
���e��I�6��i��5Y���0�1Lh��b�k#Fh�0��f�af�������C����@��D�WX�*!iqN�(��`�;v�J����dN��#KA�Z��5j�b���,��X4Fj���1�S#C4h��-Z��k�&��VViR��lZX�b��m,��,-���b������u�AS2�+K[WYZZmM�mV�(�L���Zk���\V��,a�*ji�X�+0�e-ij�
5�3	�'.r�eZjh������"�L��N4iq�����������KK���9���SF\�������h828����2+,ceH�*��y�W�0����U]��r������9,�>����Tv_�r���G�y>�0�����*5%d��6��Q�(�4Q���TQT�(�(��F�E�h�Q/������cs��u��|}az����p�R2'�w���[��(���/�@<OT�W���y�]�Yj��0�EOzc�v"\��R�x���$�u*C����yD��4�^�W������>��(��!��{�G�OaMe4���mb��k%�D�c-AkYakj��I����kD�fS5,��eZ��I�V�Z�`��d�5M��Y�VY'	R���r00�5�G!.+��������5%m/%�A/�pR�Q\��y)g��p��_��/�~��:"+�XJ��SH8`�T�&5
���>Z*��oa*������V$c�^�%�����#���(xK���)O5�O�����B���S�\G�@�x�������:U�c��\U}>���YK�Q�������������N��$��v+�h�
F�
��+QaW����%Vj�5�^�����J?��eZ5u*�u�!���g���J]�FCB�"L���jYP�
hKT��9�9�qq���z*u�L���ff`��8�rC�nD�r=WA��������>����)�>G{��I��V�S��&i�b�mM��Z��j�jf�[U�Yh����cVje���&Xe�	h3�,���4��-�����1cSDb���MQ�LV�l4�600������K	���Z�&C&��,�����F�h�F�&Zh&�4�df�IjkF-���m14��K&cYG����g����D������)�/�l�F��^I��}/�?���
�Z�������
�oc��E'n'Y�����T���C�J�}y�/���J-�X�^�'�H��-�Um��M����Kj�l�H-�mII%bT!fk6���e�{N��%�,h�S5��iG&HMaJ��i��H��M+m�ynkD
�rd�-*V�&����88���h���p��"����G����S�n����R�xo�x��z����z�6�6���.�vHm0!�� ��||������Q���6L��Q��2f����2���FV���`�e4YL����)��`���K1�����f3�K*�I����j����1L�,ll���f�c�1b��
���j"T��,��f��1b��[6LZZXYXYX�5<�����&�;�����h��6��j4�cb5$�T�F�ZK�j*f�BP�6��e���e�6���:8��g:\�������/�:U����q����}��
TSD%4��-�N#"�����N���O���w~h���:������h�|G{��Q�����3����{�^��������E=�+��)���)W��u�IS������c�/o�??�(���0����h6I�i�3�����5,d�Q�1
)kUcblF��1[VZXM+2Y��&/���J�Oj�U�+�"���">4�H|w���l��>GOr��>4��=�$y/!������n�}>��v��$.������zv+����|R�~T��R��}cDW���I��F���q��C�}����R�/��c��pr���������@�S�!��A��\����Z��MM4�1�2cLeXj�!��Z�
Xd0��V�j������[6f��S-(5M0��-j����cS&�h*��J�3e
6e�Zm�Ye��4r��he`������T��J��/�{Q��l�.�nN�RuJ���[Q��XkjY�$��-%��UX�aC�~���i�����rB��Q��+��wGL�I����~d�b �Dw����zB;DY~i��'*T��R�LIW�{]J/��r@vwE���|P�����u���:n��v��8}7����?i�k� �	>�L�l�31�1�1�1���L����5��C[6��)�!������7��SQ�����}>>��(���O��v?�z���w��/�I?6S�|9+�Rl���~
g���$�H7�A$Dh�#�������U8�����"�/J�]���/����������/�I>����'*���}���?I/JA.�Q��*8�9_	�}�&�����It�r.������UD,����%�'�S�����������\?�x���}O�����i,���6c5R3fE���jf�VdQ���m��*6�S6��������Y�
�f�����T�"3i�j3,lc5U333������W4��k�����������J��r=e;G�Aw}b���z���I}�
�y��_U/YI����9H%�a���~������n����O�T��v-���>��`BA8#
���;)_�������a{*��N>(��>?��$���tt(]a�RE���k�	v���� ���������y���%�pq^}������;%��Pv
�|b�u����c�y9�VP��	C����D�8�"�J�G�~B�\Q������&�A���GI���U��B�P�(��){���p�"}q=�N��\����f������/�h���X�W���_��7p\��p��U��bU���bK0)&EG�"?��Wc���/
v��k/�-y�j�w��4V&�bb�	U��M���S�����VT]S��*����;����'t#��	T{IuC���yPW/n��\��G/��
O���G��]��H��@X�~5Po{����TM�%iZQ�R��1F���&RcU�YMB�L,&0��d�&#$�iLU�&*��*��51-+QhX����[��R��L�2���L�V��f$�&q�[��i�3f�����jr�T�SQF�ZU��Ue���S�G���-�i��+E���e8l����,���# �d�jF1���l��a� �\L�A���1��������5-K[��J��L�&r���Z�2lMZ&j�.��J6�lB�Mj�dkQ�KZ�p��E��X��r�l5um+n�S3R��!+[q	���erS��SJq[+M[I�,���f���JJ5$�Y-6�kD���\��f���������j�$T?[����"�Q?�)T|�C���B�����IU9<y��7U��QX����/_K�:��q*��d���N])�\rI���/G)'{��E�����T�:pG~�	t��~�+�WjI���W�Ez�u"��U���q�h;��#�s��hG�uT���6|�HiP���j��[+
J[5M+,��EW���J�������/��)�����|�N�:)�{��e�uA_�k�$=�~4�+��@�^��
J{��*\��H|������8�T��?/)���C��R����d��+�����i�V#D��&,��4�&
��=E����m�J���^;��x�<��e6V�Sb-�DT-����KjY3$m)n��+����S��~���U�RM��=�D.vJ�����!{*!}<�Q��td~�(v�U�����e��B|�:���&�3���q���D���w<B�w��_����xb�]������+�))�$�&�I���>1|qd��{���R��T�l_qHD�kZ����h��l����4��M�L�3"�4��R���Sd��[,��&M3kV����c/tp�"�������qx:K$d�_�r��/a_bN��}������i��xG�PK����O�w]z	.�E1N�.��4dp8Y��;`�$AF��L)�)��)pLR2;���2`��W!�
��*�=�O�K�}>��R�y�v$����w1�����T]�L�?GVV1���c.���2l���t��J���)R�&Z��s���%��=�����jv.���Z���4��L��i�Z0����2�-LL�+V�4e���icL,�d��ZY�Z�����F,5Zb����)ce�MJ�����0J�%�����|�Q*�"��"���y%
�aL�5!)����r�8��Q��T�N������9�h�m�������:<A�TO�?^�m�g���_�A��s�K�ES��������j�4�"��in����F���*|�r�����@}��H��
��#�T�u/��/��)��s���
�
/%U��������c{������Q,hP���U:O5B�P���j�SY
�j�i�U��d��4�L���&�i�3������2kPkRh��&Mj
RZ�4�X�������]�{/l���|�QwEJ�fF`������B��5%yj��������u�pq�=�N�v�&A\^����?��5K�d0�X�eC@�����V��iL��f�)� ��l�,��4���% \�����������5�q<�QIN���>����H���e�L�����~��p��������;{8:��+]��d�Mg�M
&�~�����������������=��G����w.��}��L�%z�i��n����7���������h���������3^������"}�����������=>5����Y���[��
w��k�X�vO�^w��R�I����a<���8���7��{N�����r����O;�=[���{j�|��������h��u��j��qk����w�[i/;x@����j�EM�(�$
H�Wo�<� j���
-;�r�x��Up�����������3����*@PV���C����PjQ���N����@/`���$	��4di���z�&�T��0@4=F�=Cz�S �@��'�i���A���QST�SS�4����L#�0�	�$�JHI�S�4�=O����Hhh4�����L@M4�2S454�d<��zOT��d�P TI &M�	���4$���h�G��h������R9d}
=#(a�1�+T��p�V}���8*���<tU��64��5��������|���E�T��F4�[��c
��1bLXu�p�������]��r��4��y�f&f��MT�Z�T����MU�������j��6���=>i]�'^D��V��	[��^�Cc��8	� ��KE A.*��dTJ�������.�'���]8�$&�n0JM c�k��K�?����~��U��?^H�~���g��������l��DxX�i��9��5
C��Y$�I��88���A��"�J�RP��%�p�H%��Jb�5��C�-����L�Sx�V;�U�2?� ��P C�G
OR�
�g����?��v>5Z����*eI�S2z���-�D��h�����'��6�g���������qHh,$�R$��y���n_�"����h]"v�]%
�v'��	��T�y��4X"�HF�J����+�T�����<@�mx�mB@f���_���-$�H����j����*��)q88))*�,�i)d�Ya�6B����s��^������2��O�[V������%��������
oBF��ORH�=0�{=���aj�Me6�����u]��e�$w5�36-mq �t�C��L�%*-g�F�tv�h��������
�5b�6���M���,�[Yw���]t�2��mMV5��kt�R�P����m�7?"0<0� ���������}a���d���LMWU������}0���~�ht�b=o���:z�������^�������<������b�y���+��"h�9�'�NW����oP��z�}up��5�&�|�5~��p�������NTO��_�m��&�Rcm�4��h�-y�4h����V?e������-���Y	h[	�����k�1e	�^���!@1(bU�Ij�Z�yS��a�l����r�\*���M�I�d��uyb+����w�����hc.I�R��	&�7-�a4y������F�����<��U��#h�AFg�,�Z�)G	�8nx<�D�%���or������|T6���1z?������Q���F�AM[P(w>�G���:�q	o�����.�����d�UD��<���0����������DX)Y5K��#���CC�D���9X���2\7$�m�����*���=�7���K����-V�@�)��dML��m'��d���L��'�LNm�NF����,m��Mt�hK�^�
P�������Cr�nT��=���z���6�u��3���"l$�FD� J�K��X�a���H\�!!N��*T�$��D�%ICS���W.r�9�s��^�z�:t��YiZV��
�K�!iZ�O%?)N��%2�YL�nRBI!a����th��(�����$J�k������$�u�a&pUL��8JJ68@��fj�*T�Q&�"-+J�����J����w8�{^U���3.r�s���{�������x�������M������DEc�Z����L�=_j��JJR��}�ML�����qx��qq@��"Lm�k��,T�^�Gf^)��f������{�	��B)2�i^�Y��%!�RF{�_�Zo��"���:�w<�M�HA_1@.
H�������c��l��l���y�4�a3
"a4�
'#��LT��\SoI�R)�(9������C^�m4��Iqt]JU"R
��t@z�o� L�����������b�/��`�T�}�Q�\u��)��C I}��������XT����`2	�!���#$RD�o����k�U�4Bk�%2�3$��s�}_u_��T����*I�f����?<j�i����.����������I�^���vJ~�y������wS�V��]sW�NiL��w���7�����*��s�����k�DC���������*��_+&�a�t��5�uw4����l��l$YY\�����1]�������I/���<��6kM����7��:�sQ%����"d
��m���&�q���f[]��f�����{R~	$�oI|��{�Z�B�m4�����y�O�0�R=��I��*����{+��[�8��#�t����d��>�W9���������K$����XNjW���+�1vK��X����
W�v-����F�����I��*����6�W�\�w_�[q������<@Z������F���{���{9����Qb"""��r9�(����E��B������;�
�s$�����l�#��y�'��,��Wo���nx�o6�)��� ���G����������KP�7Uoa���(�W&���Vq��V�!�Z�~���
��E ����H�����w_�_�Z������~\s����ti6�a��������'9�#��x��H^�N�qf����6p����mn����>���>W�_r�[dZ��#,g�m�#md��%V�Rc��.��
V4����=����_.t3�yA��ot���9:��V�Ou0�
����*X�x|�s�����W�����)�'���~/�~�26��v=���t.;���W��d\P������eUZ�d�*�W��4��Cm[-�l���?s�y�w��$������.658�������s�N���n�Q��JB^r�UV��s��r�!�q�o�&�H�(�F	[.�Q�IQ'M&��y��~g��$�c�[��f�J4��,�Q9�)��#Z�X��m��3�G����Z�W9�����G�8���<���	�R�����m5N(V��������H�K�z��i��4���hi��*1*�~��������{J~�A<��t4�G����ZWj����)�������E�&�/]e�a��_�{�C�������FZ��o��bU�_m=������+�e�d�R�~����^*�h;�D;��CSM���`d�A���_D�;��wUz�3f����1��q{)-Z������vb����v�j�B���]��7������9��<��}��������>_|��o)��y{+,�Ts
���������KbmO����}��}�i��Z�m�����>h�B7�_���_�W����'NK�����C,$�D�m��;�������G.p�j��}�'�6����[5��M�OQRw���R&'L>�6$I�{�<�o � �Y*G��1����5x|����=���%��51vs��6x�&����b���@��c�|���>��@w�BmT_�wOd��v���|%��n��4j��o�xW�IS�f����G�j�K��,�����Q<|	��6*��H���=���-2�^=���Ww��8����F�4^�ym�J�}�p���i�H�"/��������I��[���_A��
@$%�$.����
�$�� [�����A������KX����������cl�\`���������_�f�{Z�E�����N����W"�}�m
kJ�S���6���Z�����K�������C�B�n���H����m��R�/gI.w]t��%��/���'Qe"8�&�/$���B��Q�D�������>���,�4�U��A�X,}������g���o[b��?��%�����?��j�E3�����`W�����"D&�'�.���������~���l������_�~yA���*�_��R�����%��#�5�X���J�*!w�~�Z�@��C�o��W�\��Q]8�M��k�(���^"��w�@�#�{N�5���zHF�ecD�K�y�E�����4�2�)��u~�
O����>���}^�iR�Xb��A`w$e	%��B��(e���
�3�%���~�����MR�����	�������J[�X����]v��Elm���� ��j�5�Gcmz7��P�?���U*�9����i%K�><�2��w9r�]�de�E��<x�UUUt��*���j^��A��nT���WD���/o��.�u�]v���������W]LN�c��Z�S	�b$01������{����������3+33333��9��>���xxc�{����/������6�d����}�Qv�E�9Q�� �M'�u�%lm�b�kf
���x�|+����Z��o#�����dv��0��H���L2d�F2��JR��)o0�@�c��?M�S���u_�����I��Z�Tb,��+��4�cX��S�'�W��Q�W+��^��z�}����(F����DPI��d�k
a(�
'�[-���K�mK)_Q��no����yO��������'����j�V���0�!�IM�f��z:9A�))
�`��2�����;L�����>��Cy��B��J�o�N�fffk>��y��A�	�-��@$�V XW@�g�#���e���r�<((��%D����H�����u�Dwn�9:����nN��;���k�`��[�" ���]n��������.�	rn��Gw\�m��)c�����(�D��|�w�N_>����>A��p>@{O����:O2�hG���-�8�k��'����=�Lp���48=�`A|��	}�#z�P�$ ���CT���L7�x�����cT��1*yJj[��FJ����0`����~��$5=d(�����P������v���������/����'�O�}���"�^^�}R2Y��Ygi����	�����Kc�h�������:�K�����e�}�:�����f���}j&�,yra��e"	Q�z�b�T3��e\{�q�"!^�G���|��mz�gK�b��-�Q67����!^��������N������Xh�H}N�O��A������c)���z��.��5�
��I�q>�iBRP��o�d�����e_���y����&��}�)�)5?o)q/c����{�tj���w�>�����C��)���F�b��/��
�5�fm�a�C��
�u��uc�����+I���������D��g�����7��x*��]@��q#���&���\QR<�����������4=�l��}��P�'�����t7���J�I��N����g�tI���"�8G��I7��Mt��"����<�5��s�(�����-b���#J�2�E4�Te���k�k+e[R[,)�m��6JMS,��je�,�S�V��I�Zb�T��$dM�}�z����j�~�[��jI��lz�5{W;�}�dj�-,����S�1�g���]����j�+��qK�R��A$}�s$�L�L���(����_1��6M���1�UU1��>!FU)$d��ZBK3TQEAb�1����m;�������B/I4��!�������m����L�VM�r�=F�$DG��*�`\���GwIko�55_w���k|xB��d�?R	}���qG��7$P(���c�65R��7&:�g�]Y����<�N�
�0�m�!��������_��R���t|���^�^r����>��d������o<��lH�N��A���Q�E�������Gz�&���)��LTL�m�H����������Z��\����>P����1��8"�p�k����nd�.����������s))(H����j-�-�"b��sR���=9=Hp���wy�lQ��9����Q{���n� �u����Z����9���C��z�$�rs��-�1d�Ug�V����
K��:���k���5�-�-������K[����u��H��jZ��������1����O;��z����^���%�z���#��z���\����m�9�q�Z�k,�,��������Y]��')�l��M$&��f�o6����`���*���L�m�l���&
U'&�F���L�p����iV�m�X�bX*p����K�6���^��^YU��(�[���L�)��1��)Z��:���k���5�-�T��j��8��$j]���C���R�k��Lb�*�UU�9)��A"�kNny:���V������xn���R-|/&��]*=I�v�{���)�����Zsw�q����P�Ny��:.���1+i��h��)HoN�`��H�����|=���>
��e_,mW2�6)��������N�����Ki3U����1�5�����F��<]K��)����%��Ffh�kLlfVfe�b���Z���K+J�)�YX��e����L���k4�LL����~�_�}IG��yx<�������I��A&?[$3�H<v����=�c���Im��Ql��@nL����{<McW8�!�fd�"**�fg���Ian����;������8a����p��q$M#4�>�I[1����!G����)�05!oa����	j�B�@�*�������y}{��]����j�������I�5������������T����G���R?
����p�C�=9��=��X�L<����t��������2=F�jVq�-�Rs��n30d�k���c�j�9���H�U�c�r����z�_����)e���'6=��x���P�������=q�'�z'��=V#����1J}�>�&��vt�A1�������E~H�d&�i1�|��G']F���	cV������yr�BZ�6����n3��+��kI}�2���e(k��~(fU>u4�6�]djfk�k���H�f��d�]��<6z,���v�L�'.�-�m|��=�w����R?[.�s���m,���N������\,�Y��r��K�����G�S��z�� "!L5a����hH��4��b��s���O��.P���`�E���<�����fY|7i����9��I6�������p1q�S��VT�JJ�8sw7��Gwj_
������c�(�Zb��q1�I���N���,�l^����BJ��h�
����ss_������6U��">�=��"=��A����_�������I9���4���7��"_|�eH����
��������d����224���>z�"��
�B����BCl`C;t�.���LP��f))d���>c�����Kfe%�V��������$�,t^f?K>[��MJI��Z�������;����gx���	$n(�#�4/ri���D>Y����ki���s$��$y�}Z�b\jG�Y��1�&4�,���8�LL�Q����Zep\��8���.+U��]%��m2H�����"�Y��,�$���������R��n��v��	i2%K�r���8R�q�dl������T�)��6]�Wk���������+�yx&U&��P����~�?�}{�����]��N?T����w��M����Q���;(��G����9��v�'�?����;�����x���~����u���?��������?q�{��F0�
a�5-<�������ff��+�a�<��:�%�U���,����j�=��U�6���i#���;��V'�Gl�+������F�M4�I�!���� ���q`�<dVmx"���p����|�'g�dnZ��|�3��C:����lQG�!����?�������G����Y��b������/��~*xUw��wW%'������W����]��?-�-�����
�i�����������g��P��wi+��A�
3�%���x?���11Tgh\C�v������q����~r?(n&�/N�y[�[�_}u��V���u2m�s��x�J���k)���r��a�*���CP�S�w]u�$�N ��.���R������tw}�JTi�c��dh�����c)
go8y�L��X)n&�����j�I�fQ����_��)�����:_G��V��,��%F�KHl�Oy����r.1�6l�_������$���7}D}�;���q��������H����~��|�2�Ej�
V�2H��
L��^��p�j�}���b�[�sms����|�=�����Q�ej�F�7��&1���5����'��k���������W��y������:�ffffgkfB6� d�4�|�
M��0E���5&�";Y�*�@Vcxn)Ld�=R�-,�'|��|8$���c�Eq�n}r��UW��S2�,��y]�����AfZ�dS}�~h�	EF����������n�1�tA����1�����go���q�m=���^�d:.���?s���}P���G���=0��}����������z�GTR�����,.��
��X���h��M�����,}�J���3�(�M1����=;e]���WJy�v�b���L+�����.�f�}�{m������X�ZJ'HS�*%L���CP�2N�H�e���x�@�5&��Y}��g(�Ta���OYY;�z��|�eV����-�(�	Z��.*��j��w��6�iO
���Y�n�a5�8Uj��-M�Zm�=^q��)8(����(��IL�n��?�J~�iO��%�>_��/��g���d�=G��N��9��G�C�����������S�%_��m�^�~u^\
�9�}�4N$d��r`��g���"���5��FK�-����?'�O���y�N_�����y�������#	��V=�p����p#+���K�?T�:6nyJ=g����_.�+ia+[��X>W%��Vf��P��u�O'�������Z��a���w}����e����k���k(s��9Nn�ODzt���S4z�$��!.��,�>�i!�X
�#�I���I�"����C}��e�Bt�kyo�6�������Uz\L�|��U�=��Q�4�3���zay`�w���>K�`{F�bm
�"��q=F���������*�����(t{�O����������[m�m���$�I$�I$�I$�I$�I$�I$�I$�I$�I$����U_�R��3M_
~nn�_��P��o��N�k���j���|""8l�`z���{2�����x��iSS��*�Z5���r�R���)��R9�~(��������M�������L�:�H��i�m���.G
�����tx�]dy�R3����*�i�	&;����(:����y,YL�I�<�0n��$$SM�1�y�	r��X/o�|����������D���vI��S��N���O)$���!
�l�����.��\������'h�L�z�R�[~�O�@�
�uV��������_�h���3)"&li�b$�I��Vj�������w�&�Be�'�T�[|����EQ��Ko�w��s���v��^��8�F!�%�lF�A/))�$9;,t�I������/������;�$x�D���LW�Y9Ym/�������V�D���U�5^M�d�,�9�jW�i��}����hxYZ�������)���/�^��p���.T�I��r^�-UV���i���/F�u���m6��6��J9C�<�t�����!�y�o�D��+�L��o������i�������XN���Q�D��W%^��h�nA��#7n�	F
�"e��4��x���,6�N}�������qd��EF$���c���Iu(�LHM�kR��}l|l�Sv���ekR�����nn����H��b0�����d�iI
�c/�l�R����^�����w]wK��Iu�Pwp��n�i�uB��VKY���b���;���#��`�W���/
�E�W= #s2��������H�"*$��T�W9�������0�:"1 �G:�w��.�S���zS���"$�~{�|�6PSf����wt:K�,�jR���F�m�B�4���YD���Rd-�F�[�d2�����������*"�����e�h������=;5��s��v���0�G�{?C��>���I�������DzB����g������{}���|������R��,\���{9��'���A����H�)y`PWhHj�Y�
�� X/%$!c�I�b�8���jW5�Rb��	��0 /x��n"� *�t3Aw�r���!�IGD�g�f%���n�+�$!	
!(K������)@b������ c-BrB0uc���D��R8nmDCj"���I%BeI�JYe���p�1zw�����de��*��&8�pp�9��tb�-�����Otv���-��;N�9�[�X��+$�M,kV���eV����#q�p������l��L�G
�F��kI�w&oO���@#d_N{�+��7�����h\X���hM�@��!o����m��!rj���*�Y�C�Q`��j�n�b����*R����i�'$���W7l3N!f�f�h<g29�R��*U��`Tl���m�tJUZI"��)*�K�t��jH�1%��
��&]C��*�
A���Au�*X�( �K��$	c� 16qn`�9�&_�-����q!8+�
����������r��c������d{3G�Y!(��]*�Q�^V/3[���[e��;^�
6���)��$�wm��$�I&�]k�3�E�K^+���]_�����oo%F�[������Q`����\���dTT`��$)Q����h�J"F���I Je�X�	�_�W�3�������!A`�����J�1E(eT�
�h�b�!��@c�BQ�A�IFeG�<�~�<�F7�8��s�)�1t���"q*
�4`�E��y�O^��d�z�|�S-$I�V��7r��m�.}[�$�|c�"�������Dz��&��I$�q7�D����)��
�lxd%�m$���I&�(�+&�������'��*��q�y����U�w��.��K�4L���1!#f�l��k7�����G)$!��B0E|�#���s@s`l�IH��M�ZmJ��������ZZU%RU%���T�:6��k1�bi��vW��it�.%�J��pf�1��)��EJ1Q&�3l������ko�e����C�zL�
�U4�[h�JjN�pBIo��'Y0���m&�)A	,,���m�>�}M;Z��k�5�1�1���)L�Js�=5�%eU�e[S�<6Y�
�dg����qIU����������B\��"-l��+�])\/���zlM �o"�������m[*\"J�X\���I@�1���8k9sx{1������*��X��S�<�n%)i���*JO��h�����"����F��8���~$�w��:���1��mm
0m�f P�|�K��2_]�\�����xN����b���I$���If! L�1�=���k� F;��S|�	��2�����t���r��<<��J���vN��Y����vL#��%[���^�K��~��G��4-|8J%-&c���Oc�����������+YU� �Qm�������v</���%s]��&�����4f��Z��>��e�r#>{��I��v��*e����
���r�D�
 �_�������70z��YmwI�J�(�����H���4h�oB�S�?s6��9Og�)^{+{o�5����)i�w�M��Qrla.Xm�����q�m	�-3��9v�o^���G����E������0fz�G>�����l�Z��b�����B�q�WKl���gN�;v�w�^$���D�S1��#�a�!
&��D8������k���?��W�m����v}Q������>���+R��JF�;_>�����������'+����'�"��j3$�mV��X��{>���������X�hA9FJ�YR�5��%'(�Y+*T�������e�*�]`���N\�M4�ZP�Kh��M4P�,��P����"�-��9*���W*�B�v�9r�4�Ii	��!F���`��)f�0P8�A���`���ab1�$�Z���U�,*�XZ���C�Q�j&,j*j.&(qP�cn$F�T7B�&916���n��E�6�rh�?�$<�`���.Z\�����Y:�I�'Z��ea������:�h���of�[5���Sv;*�qU$�����32�^^:�R��=���s�����8J����6_3�6p8s��o{��5�P&,�-ToC�o��5��Z����ie�7#�tr��b�L�}I���p�������s�vTS��K�eis5��-��:�WN�����:ng�N���9{(�>m4���j�r�V���g0�U���I�Ig�W+u�R���p�p��q[f�jV�e�V&������;e�/� ��������Y�-�������-iH���������
�c������U�m��%���	$�''�\��JSMp�bK���"@:�e.����I(���c}v3��g8u:�$B�"M��+/!c���D;�:i$dW�A�61�(���&�%�a$��DY[%��!��eY�mMUs�d��5��)NC#E���9�'����:bP��N����H���I c�D{���N�!�2b0BHgI.p})j��)M=1�E������[m)�����7��9����I�A�I��w}ffj�6eB�i.��%��l��*	
��;�\�M��l�rt����]s|������*����^V��$���ad"�p���
�b�rE@�F�#&q�s����8V^�X���s�[��b�N��[�-�]b��y��DM!$��ce�de%
����""�#��Qa�0%<��O]����wP�p�\,�����..�/p��$3����]������k��Z`=C�S����k[��#����{��oP�G���������������`����3���X�8�����fp����m�j�;�����jx���[���1o������n<6�G�RGs�H��������M���N]�u�?��f��3x2hBx�9j������6o��;���I��D:|��ff�	��Fg�<��+�y�8�Pe���JVS���y�A6h�1�>n�"|�9|"�'��
����S�;-"��-��v��\Y���:�N�@d���=����D~�h�6`��������D���p��n��H��~���S���������#a#���Y�Uv��p��t��p3�s���>?��N��������1��|j��7�5s�\�n���.���{�Q��8qx-Md���fY������G�#��l�Jr��i;������?K�x��</zT�������_�5������5��K6���K!�e��$wss�6��$tr/�L"_��Q����,�<���{)�>O���|��_�:�N��B{�����6D�z�G��Hj$&Oj��jO
;�q�v�Z�����?9��.�R��x{<�����\�=��������p����=��*�
���g��O��TL������N;�Z����_uQ�Ey����t�v:5v��K�����eo�q�%IVJ���|�������`^�Y��*Tt%�������f�����uR�7�Y���f�D����9@h�����K��LDI$<A���g	�;���D�iR��v�\7�#|1}P���[l�c�e`�Ye�(��H�O����7�������6:%�)	�v}��r�'_|��j����t�����a	�~a�R�?��9Ey�W�����N��:��s���ch#O��+�5U����> �hi�u'*�7��*`L:t���6��ls'�<�G�+���_��W�B�he�KP�����F�O�m���o#o��������
qG���+K����F��������k|hZ2e���+���V��-�����r��C�2�T��n����a�]uv���v�P�]���Y�j5���M4�e�6dJi���h�P��&���h"�����kt��#CJ�	�-��u���I��D�[�����&�ZU]+u�����v�i]d�t���j���A��	cimml���Fj1���v��.����������<zt�#�;�s�e���`�0�d������
O4���ai��F�M���^�1ao?��WZ��Ct�*�<����oS�4*)d�[��j���pP�~�y�G��#D���fI2d�V�ch0��Y��D�������K.d���lHOt|�R�	#�^2����T������{%�?������{`�HI�' �i���]�����TS�U��&��55����M�Ydj�&�L�eFli�,���4Y&-&�cK62i���V3-���ZKdR�SH5���+��JL��d^2�����w�^���i��Q�^C�C��]�ck5i����5`���5a[�����$ib�G�����
����5��R3C#%������
W��hFR&�=�/R�?���E�:r�YWi��w�3����J:�������_�G��C�1&I��bVf�t��c���Kb��L:�|�O��{,*���q������Y�
�_���IY!$��j[7��$%�5��i3��NFNx��McE��5���*�[o�?��,���w���>0�|����K����vS��9���O;};�MR����u/Z+�����\S���'����|?�|��0CRn�j#^'P-_{�y���u=�yD�K�a'���]��V����A��i/7O���Gx����/��Uw����;ty�y���$�"��q�vv��PC �z��j�f�;���:�)]��JI�T�{�N��c�^�~_mN b����$�����@tv\�^��|[�R��u��#�����e'��J�ZR���d��2�F��������rB��z������zzp��ar�-�I�R���z8��p���]����=�]����Va����vYz
����������4��=����u�_N)\^�����I$Bbn��r�S�������������o��H��,�E�?�AH�zT������8�3�K���=��K�z�~7����9u��~G��5�72Zc��>������+UB)�$(��>�.|������r�y��y:���.\+�6 ����f�&�PF��7K!������Wi��c�������_���z�H��*���=Y8�b���$b�����'��#�\+g�C8��x I��e'dC���UoX���z�~���6�(?=\4i�����8*>�8��3�K��*�?��T�6�f�1�sp��m^�W��mU[���QG�Ur=�W�����^w"�Q�<������}^7uO��;��j�\�O��	���G�jpK �4�F�|[����(���MO�-m�����tj��5f���|��=�uH�������71��ss_�{E:��n��/�S���~�������|s���O�+��@�L���mSQ�B��	�,�����Fwdt�&��eks)aS��T��3���d7��G����&C~Y����L�$����
�i91
��n�����8���������
8VL�
��F>�����(G��s�w\���������e����3�����f(K�h@���Bl�m��'���xVyk��Sb�h����6��,���Q�V��V*�cKU5���3SKSeM,� �
9�I�����;�	1Wa#G�n����-���=��H��2�kf�����1��Q�����s����A��x���n_=���P����I:c�ux���>�I�J?����a�7z����Oz2Y	v�E�h���N8�i���t`�x���z��1�N�0���_�":���vq8D�}����TxH�*Dm�&s��9��8��#tmV�V�}
1U10�U�9�����������R���ViQ�����$�.5�s��m�Q3E����_a����!U�n���*�&����\.����M��RC\���DM����Jd�)g>-�5��������L�A�	%�e"���F�v�At�������5�|���^��||�Q���V#�r��`���C1�U�J��M���3A�j,,)�S&K�r�Z��a��5-&51�fY��4����RY,�M�+�<�$7I.�;�:��U�vYA��xfcV5��y^J{���,ky������n����I��6�����m���IL�y�l`��I� hM&&$��d��b�lTe������������8z�Ecpq�EZ��{���uO����~1����}:�-�v��X�I����#U)5W������8����{����C�!��_�������W�Q�VWVS���~G����{;�����^%�j<��a�_�������u����V[[��y]�%M���"$�������X��M���E���
�DV*{�K������N�'�;�2Q�;/A���0�b#���R���������y��$����C�!�z�w�RN�4u��rt����)�����N��~��ikJ�CT�jL1,�ija�����{h��S�MO�?�+��;����Q��������&$7����]w��ib$w#S��8�#����tx��w�e�)Rp58'f6I�7�64C���d���L��*��|�OjG��E��s4�����*�
^�y��<%��E��*��U���*��"�W�%G�r�{)�U;Ju�������)�\�6����;#��
���?���W�FC�_!������>���w������>���|�8T�h���YzF�� $*y��>g�l�l/\�)�	hBY���g�S�����[�|����5fK1?,��t��ffN�p4��f33(�W��)AAA�4��
���S)�2�2�-Y�P��T��L�AA-����UY�1�5�|mU����/���_|�������n��7G�G�}���W��������,�2Mb�l�V�-im��w� @*��U�������%/y�������DM\�2�dT��m~���"����);x���Q����|;)Wb�]�f��{�_\��R�i<e���Od��b���zN��%��H\��,3�aj����B���a�\|Z���git"�x����4~�,34���F�\��Om/}��F��)�K��s�k����D�T1��O�<[��mI����z������^5�d�O��G�O�v�S��;I6�OdgAE%Dj��bL�n;�X>�q�$}�$;����8�?J"�a3	��=��uw����h������Xj.���M��6���,�&�>��e���^N-IH����O������o����G�hS���	
����>��bBcf��x���[�D�m�&������^���=�c+��y���6vp�_V]+���l�*�C����_���`���|��d��!6Uc�W�=���R�+f5^r�����*����
�)�du���v��c+���E��g��"K�����r���$Cd���z0���J�c���Dy�C�����"{��������d_D�F3K/��3���;u8sXXQ��1����u��y�(^��b�.�<{��:������%U�Q��P�x�^U ]��^���v'��B�W�,��,g���#������G���PvW�q���+�z�����w�]��	#m�&�H�!��Y&I�Ifmb�4������Ij�Y-�J2kJ,���f�Mf�&�f�#5V�Y��M2�����Mf���ZU��4�����2cf��c�F5fP�F��K,�*#d��~E��| �/I�=�9��U)�I1���'S����@����o�C�N�W�I��E�z�ug�\���/�Op�|T]��R�n�w�����{��<�NQ�	"j��A�.���'
E�����u�JpJ^����R�_�ziH���k[�O:��K���Y��H���W�?�7�������S�m2�k*������4�<g2]wq������:�����:�����s���JM��*�j��WerT���nWE
Bu��FM;5�n�G��k�9t�*���y<.��i�<W���c$w��LE����^�4�icSU�2_��jM
h�RJ���8Mby�<����9�\z����]2u\���4��Y��MANGN�p�n�QE2e�:*�N�O7�f����\M_�2��VI'�='��f�3���P�y�N��������O�H\^�#�/�UG��v���H�(5X�*������v��1�����SYiU�C�24����&��/��������%��Jm|�|w�����c�+��_���SCU�4(?/w���<8�I�OB��d�8v�h����T���U�,��M#j-�q�G����Q�K��_��,{�	*��*^����������OM[6����2DL����U�W���C���/F�����	�}��"�b��^��o�����"_H<��g���������+��{�]�%,��G�Yp�3r�':�]+*�rv���
����\�����������U8����]�y^I��\J��i#.``3a�_���������=�F�����&4��5�����C�S7���g_K�X��)�_���v��j~�}�_��US������/���{����<��I�����G�M--,�V-VR��M��6�J����$)E�m��5����&+��h�l��a2��Be�P�L$�m�+U�m-����%S]������j�I���u���u��Q3PIP�%.����j*�L������1Y�2�rG%61��!�C��p�9#�
Z��p!u�5��~���|O�����2G�����%D�]�a�%{�O���*8���>�� U��r���@�3�|������~H|:O���C!�������]��w�.���u#R�U�-�����k98�8���{�v����I�Gk��(r,w�����<k$v�Z�=	��������)��u�y��t�9(x�WU��|
Og�;�R���I���*����]�su��8���/�lST���=a�e�<�������J<���������U�2�.�����z����W����:H�?�����
2�R^����V���;�S��<����'B��Wd��]�}�����4U��[��d��y|R��,���e>��
����S=��W�~\��=�c
�5C��%N�,'D�}$�	&���lU3���r ����;:���T1��5��Lt�Z.������:Q�p��F�|�J+�aR�i$�"ZM*�������B8����z�d��(�Y`e"���bBWY@{����:c��S�y��-�f��L�$�W0p��F0��f,���1v�:�o���~L'�Mrl��e<^3�#���):'�}$��l��vw�����A3����{=�xA����J�P<�{*���?&6��kFY��#�WI�
p�A����U�[M��~rN��#���r�.�Jp�
7��ir�^��Q��Z�����f3���t?�u<F�����J�K�U���������Q�(/8��7�}���������������$K��W�qR~���r��� �Ujj���O�)Y/����q}w7��w�j#R^���I_y�M��0������|86���J�ZB���M����~v�;.�I3j��&�I%il����+MLf�E)T�G���G��'�~�%�6���T��������y4t��n�O�%�/���m;#���e��MT�������!��M$l�0t�?q���sr+R�I�b�<K������
������1cLc�)���3�8q�5���EI7���;y���7>�p�f$�h��R:��w�������&�
`���BWKY�S4�"��J6���2�T�QS�UtZ+�
0�>1q��+6%(H�u��������Y��v�$�*��#h:�K9t�[0x�Y�>���+�^Z������2[�-V�)=��v�Xs�������g{�"'������O���r6-�c�]�kq���]�w�!z�G�U���)�y��K�k�M2�ke�l2�1h����)��������67����$<I�R$�(���D�)�G�����ZbmK���*���s���	M2�F��mmcZf�6����������Ez%��Eq]�}���yJI�B�)����w[�:�������z����g�����%]�R�	(��$��J�������m�t�UQ}z���[l��0���N�+�w���v�;	�z�9�3�|�����GfG%�%�I7��
�//6�v��fL�n��F��t*��\<ME0ei�5->S?�W���*�������;S���;�>�^���;��Dw��!�������4/:Sx�����O�����'����u������G�r\E���O^�f�G�����+����
�y���@�mO����"NM=�����Z�.�����xA_�<G�!�f�=��Q���iMZ�d�f�C��U�B�&�T�CtO3�t<���=��6�
��Y�����s@�u�3d,��CT-L,�������>���Tjvx������v��!1�]n�b�Bx����eV!�l�X#$���Zk
)�J�JQ��Q�������j�e5Ol58Z$�A>�.-�C�0���;^���-�$��wx^��,o���U�Q$��#SV%�c�]������X�o��������2$���$��7�3��uz$�b�����L��3,fcf�����\��$�2�)SV��jc
?����5v�����Zs�5/Qu�����_���"�(H]_�T�
#63Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#57)
Proposal: UPDATE/DELETE ... WHERE OFFSET n OF cursor_name, was: Re: New ECPG idea, was: Re: ECPG FETCH readahead

Hi,

2013-08-17 13:02 keltezéssel, Boszormenyi Zoltan írta:
[snip, discussion of WHERE CURRENT OF in the ECPG client lib]

I had a second thought about it and the client side caching and
parser behind the application's back seems to be an overkill.

Instead, I propose a different solution, which is a logical extension of
FETCH { FORWARD | BACKWARD } N, which is a PostgreSQL extension.

The proposed solution would be:

UPDATE / DELETE ... WHERE OFFSET SignedIconst OF cursor_name

I imagine that FETCH would keep the array of TIDs/ItemPointerDatas
of the last FETCH statement.

The argument to OFFSET would be mostly in negative terms,
with 0 being equivalent of WHERE CURRENT OF.

E.g.:

FETCH 2 FROM mycur; -- fetches two rows
UPDATE mytab SET ... WHERE OFFSET -1 OF mycur; -- updates the first row
UPDATE mytab SET ... WHERE OFFSET 0 OF mycur; -- updates current row

or

FETCH 3 FROM mycur; -- fetches two rows, reaches end of the cursor
UPDATE mytab SET ... WHERE OFFSET -2 OF mycur; -- updates the first row
UPDATE mytab SET ... WHERE OFFSET -1 OF mycur; -- updates the second row
UPDATE mytab SET ... WHERE OFFSET 0 OF mycur; -- throws an error like WHERE CURRENT OF

or

FETCH 3 FROM mycur; -- fetches two rows, reaches end of the cursor
MOVE BACKWARD 2 IN mycur;
UPDATE mytab SET ... WHERE OFFSET 0 OF mycur; -- updates the first row (now current)
UPDATE mytab SET ... WHERE OFFSET 1 OF mycur; -- updates the second row

The cached array can be kept valid until the next FETCH statement,
even if moves out of the interval of the array, except in case the
application changes the sign of the cursor position, e.g. previously it used
MOVE ABSOLUTE with positive numbers and suddenly it switches to
backward scanning with MOVE ABSOLUTE <negative number> or vice-versa.

This would solve the only source of slowdown in the client side cursor caching
in ECPG present in my current ECPG cursor readahead patch, there would be
no more MOVE + UPDATE/DELETE WHERE CURRENT OF. On the other hand,
exploiting this proposed feature in ECPG would make it incompatible with older
servers unless it detects the server version it connects to and uses the current
method.

Comments?

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#64Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Boszormenyi Zoltan (#62)
Re: ECPG FETCH readahead

Boszormenyi Zoltan escribi�:

2013-09-10 03:04 keltez�ssel, Peter Eisentraut �rta:

You need to update the dblink regression tests.

Done.

Dude, this is an humongous patch. I was shocked by it initially, but on
further reading, I observed that it's only a huge patch which also does
some mechanical changes to test output. I think it'd be better to split
the part that's responsible for the changed lines in test output
mentioning "ecpg_process_output". That should be a reasonably small
patch which changes ecpg_execute slightly and adds the new function, is
followed by the enormous resulting mechanical changes in test output.
It should be possible to commit that relatively quickly. Then there's
the rest of the patch, which would adds a huge pile of new code.

I think there are some very minor changes to backend code as well --
would it make sense to post that as a separate piece?

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

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

#65Boszormenyi Zoltan
zb@cybertec.at
In reply to: Alvaro Herrera (#64)
Re: ECPG FETCH readahead

2013-10-11 00:16 keltez�ssel, Alvaro Herrera �rta:

Boszormenyi Zoltan escribi�:

2013-09-10 03:04 keltez�ssel, Peter Eisentraut �rta:

You need to update the dblink regression tests.

Done.

Dude, this is an humongous patch.

You *know* that the patch is available in pieces at https://github.com/zboszor/ecpg-readahead
right? You must have read the new "initial" announcement at
http://archives.postgresql.org/message-id/520F4B90.2010800@cybertec.at

You can review and merge them one by one.
The transformation of ecpg_execute() and friends starts at
2d04ff83984c63c34e55175317e3e431eb58e00c

I was shocked by it initially, but on
further reading, I observed that it's only a huge patch which also does
some mechanical changes to test output. I think it'd be better to split
the part that's responsible for the changed lines in test output
mentioning "ecpg_process_output".

It's 1e0747576e96aae3ec8c60c46baea130aaf8916e in the above repository.

Also, another huge regression test patch is where the cursor readahead
is enabled unconditionally: 27e43069082b29cb6fa4d3414e6484ec7fb80cbe

That should be a reasonably small
patch which changes ecpg_execute slightly and adds the new function, is
followed by the enormous resulting mechanical changes in test output.
It should be possible to commit that relatively quickly. Then there's
the rest of the patch, which would adds a huge pile of new code.

I think there are some very minor changes to backend code as well --
would it make sense to post that as a separate piece?

It's 2ad207e6371a33d6a985c76ac066dd51ed5681cb
Also, cd881f0363b1aff1508cfa347e8df6b4981f0ee7 to fix the dblink regression test.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#66Boszormenyi Zoltan
zb@cybertec.at
In reply to: Alvaro Herrera (#64)
Re: ECPG FETCH readahead

2013-10-11 00:16 keltez�ssel, Alvaro Herrera �rta:

Boszormenyi Zoltan escribi�:

2013-09-10 03:04 keltez�ssel, Peter Eisentraut �rta:

You need to update the dblink regression tests.

Done.

Dude, this is an humongous patch. I was shocked by it initially, but on
further reading, I observed that it's only a huge patch which also does
some mechanical changes to test output. I think it'd be better to split
the part that's responsible for the changed lines in test output
mentioning "ecpg_process_output". That should be a reasonably small
patch which changes ecpg_execute slightly and adds the new function, is
followed by the enormous resulting mechanical changes in test output.
It should be possible to commit that relatively quickly. Then there's
the rest of the patch, which would adds a huge pile of new code.

I think there are some very minor changes to backend code as well --
would it make sense to post that as a separate piece?

I had to rebase the patch against current (today morning's) GIT, since
there were a few changes against ECPG in the meantime.

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude. You can pull
the commits individually from the above repository. For the same
reason, I won't add the DECLARE CURSOR command tag change
separately since this is also part of this big feature.

I have reordered some patches, like some independent bug fixes
against the ECPG parser and regression tests. The backend change
is also added early.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#67Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#66)
Re: ECPG FETCH readahead

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

--
Noah Misch
EnterpriseDB http://www.enterprisedb.com

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

#68Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#67)
1 attachment(s)
Re: ECPG FETCH readahead

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

ecpg-cursor-readahead-9.4-v20.patch.bz2application/x-bzip2; name=ecpg-cursor-readahead-9.4-v20.patch.bz2Download
BZh91AY&SY�:�M�`��������������aU��K�,j5���y�w�X��g��l�j����noo����������/���>�y[��w�������{���#,�N}a�m_G�{��J���z��!o8�|��(�������-�����^����7Km_5k�N�i�S���0����_}�MP���o@7�&������w�k�W�Cm�}������`7�^��|{��w��U��{���>u%<���g;a����<�����=�${��r}�C��������
Z�7u>}�O
����R�t�:�i��@������{�nkX=�>�}^�}���lp�:�b<�|����������o��{u������x������e����<����{��m��;m�������Yj����/������{����q���Q*�a��4�}�(UHz
4
"O�����U6��������hZ�W���������{�m�wl`�Zfz��+Vf�WZEw^�M�Y�m�-�2/F�L��r�����WX�m���z�B����=�1������>}��TG���w����������v���=����UcKK}���>��v�<�F�����{�pw���S�S]�SB��6v�^��J'wn���6���.�+��N��6/d������wf����M�o"��
���e7�:��@�c�`.=��}���U��{]�I>�K�eM
��5{c�K���S����/v5JW�����������(P�������c�u4�Y�sZ�i���D}t����]�{g|u��j;�]�K��$J]�z��������w}m��N������p�*�}�=�����hh
2i3D��
2���z�'�%1QI�'�b�D�)�OM2O)�M3PP��I�����O���'��I�OS�@hz�h����))�5=�4�S@<�CF 4B��@&@5=�	���M(����)7�==SF�H"& 4"z��(�I�����5=5�i��L�1���>��4� ((������
�&�f���V2�0&B�PkbM�X����f��!(jP��"4L+H	�\ C4�JZ�c[&����R�i\3`��R �� U����$H8�����G9F������Tp��uu�� J7M��iV�CF������ 4f������UQ�J'-ZL�`\#��E���H�)F5��
a*��Fk����JJ��m�&���
��$M�!�Fn2���\����M���[��n��'K&�%�n�7$��P�(D�����������IQDm_0���y,>�k��m-����7!����Xjpi�8r���ShB�L���;�,tag������v4J��R��� �DA��#�����Y7��Qh���RX��:�$)���J�������?��Y�:����`&H�U�$P�����^���\��_���-x��a����p!�6�*��y�������$�������iu3.�Gv$q���g�3�&��P'����(���6;�r�������T\�<�;�>|����������ld��"b�p�r����X����A;����_q��a�A/.�II���s�����$���&C�8��ar�B����I�����L��m7ISF
��M���,K��l�%MqP�	���h�(7	�[��+�(�e��������m��N��]�w}��-��QL9�	�']o$o��<�8)����+-\���d�0��"Tr����wa�\�)m�*��	����S�@��k���}��n�*�������[��)�fAN�����QZi��M��X�=����C~�L�J`�Y���Sx�����������v�G
�-�#�'�������1He`,!)I,I(�RK!I1��s�Vf��\M�B-[$z�8�S���	;��� �#��3�'�GCG=�u�||����=y`����[cZ����)X,��zX�2��)[��%��u�t�x��1P�o;��)Z���1��)����w��yC�w�|N'F���q���q���������g.8r5���0�J;��:���00���4b.W@���]uKB�%�'����j�H�T1�&�	�~<ts����bq$�U5N���)b��M�#�7��h
�!�;}t�2r���i�l����tNM/ol�D�p1��,�!lBt�%�cwC�K��@�C�@����a�d[�g�����a�x��Y�lHP��s�*����Ws����@p�\"���TEDJ��)��P.3������l#���	�f)�J�#Y�����'���#�_������Ur�8�P����Cm��F�������9��$%��"�Tu�^4f1������LX���$7]} y �q���AgD*�g*XoPF��K4K?^:7�����'��j����x��E������m��A0�T��t{"3+�~��n��Z8���n�z�P��1���}>_3��Ps�����n��7���i�	�gt��A�FM8�b
���\cK
l��Wc�����|%#�x�p����l4kg%��6����u�v�,W�����D4��_���QCU@h�*^N;x ���������l�7"#[y��P�P}V�E���?����P��E��_�}[���A�(;����UUT�o�e����\��L����r��5�p�����U/����B���� �a�|yv�����1�;��]�wO_BW������������B�)��c$�"���������x����{S�Gwg�~�=Y���-=��r��]/�������7���3|�J�5d�MS�$��rN�_���>R5��oC%4��M��0n-_�����u$?���b���O���cI�#�a0F��r�?�cE3kHR�Bd/������ou��""�p��y�6�o}x8=�����m;��HuD>"?c����V�M�Dm;	�6bhF�)��7�_�;����i�f��p
bb������:�>�!�����_�a����]����}���K�2)���~gw�<�yf2�S���{Y{��|kTm��)II��*9>#FG��e�������3!&1+�6�Mo��3�F#�� ���	oP�?���p}|� E��;���.(�D�HLe;�@d���zR*z�Z���,7��o8B	[i!�s�Y;�y����!1�[C-��2�
�NJ�wH�0�-��~������
_����>��v����������4������m����p�A*NM���{�s����S��/;���4�8���<�$M�e�/���QE9�er�� �;���������h^gF�Kfx3����@��>>�?���T	e���,�x����k^�64�����d�����T1�X<CN��Aq-:x��;�i���������d@�3�ktN��0�"6���v������9Mz�@�`�zS"5
BI��.�����<�QQY�61�CE���+�<O��l����YP4����x�|M�����le�� �V#e��2�4]3fV�c���q��L�E��h���������5)�G3�/��l/&��=�&=������9N9��q��y���K�����ZZ��j�<�IH����~x�r�qG�[���o����u�kHJ�l
���+rJq�F4IQ	5I}��V$�V��������WVT��I'9��/�����6�;��J��m'(�V�r�(O���������H'_�����Mt��>&��z`��6����-_-�<
������K�V^�w�����M��/���z���5f��]z2��NG�[�o'��� �����o��N~����!IY�����}�����\�46�m�$<G�-\U�Z��]��
���ar�B�QC��)�Xz'���o�������0��ZK�\A]�s��mS��0V$��9%7<L��t��������E��I�����O�wq�[l^�������o����J�K�z~��!w1�v�P��g��K
�B���)��P��}l;y��Mu���jb�'�����Cl}e�1�*�C����SsXTo�#����.�Bn�8����H�#\bj�����w �jb�gI:����a���i��R�`;�@�u�0w�
:�i!4��F)	��BuMS[Q�����@��/�����!��������!0��o�^V����I�mu��r���������iD+����T�K&L�,��DD�G!��e���)���J{~X�����*�nK�������~�[�I%�����������V��vyy��v��"�_V���cp�!z�kJ��"?�r<�����O�t{z=	�e��3�tI�6r8i���{p�+�{,E���W�R��p��Mg�>l�H��=������������(����'���6��.q�����.�23�E�`C�<�3{�FS|�3�������������2~3>�MY9����"W�������<���=���s�������~��O�
�����������������P�UQ��>0���O	��3������Gm�������.�
����|m����������:�������E_��N���?Y��
��:d�K&�@R������>�>��^A*�;z���q���S)��%�����@�$��Z�YZ��J�~�^-��P���Q�f��r������P(<Y���@��9���b�i1�[fm55��k%F!
VaC3Y�5���8�M\����GynX�M��&�*�_�d��(ZH�XW�1��;��$'�fJ�D����"�%�'�;;?_,Vy���(=2���i���=�<��FUc�^�I�9+��"I$C%�@h��	�l$Q���w�l�}��P3��EV�&��O�IV��if{
H������V��J�n�_4���@��]�z|�^i�wo�N�C�kXi]X���,Wh�
]����x����Uwn�����&c��_M��8p������������o�%�u�E�6x��X}(��I%j�T�,W�0W��+QZ��jk[�e�I$��J�J�%���u���[��5G���(��I%B�V�{s�������4�)A�g�X
���)JRR����m����#<��,��#�1�c.\�s31R�J��,����~9��0.�Q�^7����c��t����[��������G�ke�I^�`����w�g��n�Qu��������;��������=-Z�=�����s����o���W�^�TR;Q
<S�����Y_�2�C@:��S	�7kB���HE)}�����3@�d0����@3A��7,Lo��M�!��RP�x��tn����7�8ST����4%����u����6|��<d1��#g+{�tsy���
����#3V�a�sb�Rb��5�������v�;������l8v&9��Z�!Mk�����&��=5�.�*�7���F6�s����P�0�����*dT�^'9�9�g�9����hu��Qk{�^�������/�����3.fs�w�3���9�g�9����hu��Qkz[n��B�����A�B�Z2!�% �Ei'i�u��g�z�&�����z��QD�h�����*m�5�w��9�s�����������#�0`���K
��xo
��7�������B�Kb,B,,, t0*�B0B0B0B+�~1�4i���5��
����p3D�
��,�L���	�/.I�W.r�����w��b��a�Y�T��ZKIi*�O��#K/���~�s��������^d�|k,JgK*�+I�U�I$�L��Q�nrRS��L��
*��'dD�lt��^,��QA(��D$I��F?��5sQ�������%�����8p���N<���]s[�oMI����J�[���������f�������m�\�Ds\����oU�6*4�T�d)8j2�kb�g���]|������!���/���������M����JV���.�X�g���$�X�Zv��iBU����V���B)�-.bf=����h��W6253�������q��MM��\^t���Y�bl	���r���"Q8�.�G�W���87b�\m���bva���t��WpF���[B��J�����������
-�iq�����_�����������	��\-k]�1@��+����&H��Llih�#-q�N�U���&1�k����}BdjX=;W�R50QfB��<�������{�w!�w2K_�N}�<�^m����F��T��s$_.��Y^�������1|q���8F���kPv.������zk����-�(�_�7�{��f���|W��j��Y���}����~��I��RS�����]��S%�#77}�+�����[��T��;s���wm�8:19p�����$�e�R���"�����Wl������������f���Le8����Jg�v>��g��zo���6����k��79��~�}��>�'�NF~N�l��?��9
~b����$���F}^%$HO�� � �Hy���Hz��g�fITJH��i����>]��������b�0��b$�x�Q� ��EL�;��������bU5o�L<nS�f��?����
�e��r?���������Tu87������Ny��N�A�+9u���{��F��/B�:A(� ��j��7�K�k��{��I>T��T�iTCt����&�m�����M]oU^�A����������9:����sS��t�K���A'
�0�d����D8�}�vC�/�.S�#��Rd!����n3&f���fK����d�Q�0{=a�UU�����������:H �zp��i���T�|�l�� ��	@_�b$~��~�?������������v�s��+b��e��kgz���w��`#,��J�4�$�< 'Kn�7Sui��������}|w3M�`��/z�\�{�]�woP��f���roW4��sy��f^���z�gy������wu��Z��
����w�Ty�P���R�����-��������������9��5BNV�������	#q�n�4������H@��s��ye�v��o��;������H^�����{�������
��9/�h�*����\���9-\I$�W6���\k
30���s����������X>�dd`��j'/A���[q�����5�=��/^�k����d�&�,���h���E�W��F�V`�%�LI�i���0��������A�A�A�P�N�`��tp�o{�J�1�S���_�����R;S*H=���J�k�\�~�P��w��	�qk�M i�k\>X�f:i#��@��f�E���4�N��UU���*�z�"a�����o}q�"�y)����S 2t�820�/Q����^D
/�wi��|�@������d;I����~��r(��s���7�~��-��j�h�d	
�������A -^�u{���y�����������7��������������#&"""+��s^"""""2b"!+���W���Dd��\�����(�zr��>���>\����ZR���s?��o�~����'�]����XV�C	8`��.��	������I��Ff�O�F��F�#Q���:�=���c�LS�@�K�����[����J���!�o��i��1��J���0���Ws��d��1s�B:�b�`8�g�	�'l�0:��U�. }k!GP�<J!�u�v��/C}�����Yl�9�^����chz�-�8��%���v�����-����������y�u!�H/��G����"���S���Q��f2����(�@W�
e����9(�sv2��b��m�����,��/
9Z�N��f��ar�D^|�����
�w�U�q��l������F9����`��<o�����/>��Gq�����Y:����RY���m�N�/���l���v�������O��)�S���{���[��=��sqb�_g������C�I���h5�-v��P�X�s���A
�)��x����z\6.91�����z���j��?{�����5����S�%Ed��bL�EH�Jb��t�sP��������GV�J��[�\��zo@W(�M`YL���T�+i(��L�7Z��#�FzK5gI�\d��$��J�p<�����}�6|�/������&�G����%>f���3��[a�F��fC�!��=;i��qw*���q
 �>@��CX�#s[��J+�7+�4������a.V�*�4���3;�1����![4��I�-h�-�X��MA����ZlHZ���Cw+�h��
����������S�n���C��MAI0�zY���7�x��b+ye
x���%�1����K�����������q]��Y��#��OR���}waG��{�Z
�p��>�a��E��<!�aY�?]Q���c�`a�{Cn����d��XoQ�8�X�`��-�@��c����rA���M@��f�d�����6Ec��@R��p��X� �)�����/Wn��0m�(�3�� ��%>g�d}�7�C�?}|}����*����$���B
�R��IH�K&��k&�mJkI�,�&������Z��t��9r�Z�VU�e�����F���F,m@A�!�
d
�Z�`(�V
��Zz��V���g
5��^)7W��R�[Z-�E�*
+�����}q�xDHN� ���$���"b�X��v��T;a��J_����`7���C��� ����YR���[MR���R��%L���� �<h����tG$����������j�id�&
�.V0D��a�>��j,�l}tY��2��	$�2N�I#��!�u���p���'DN%���;g����?[������_3�6�����n�(o��bH�����;t�Z�}9kB&����4�o���P�B
IRPUbJ��R�"<��S�= )���Qy����
���`�6����=����ZB����"�}6�-ie)� ��4&�uEiI T���9�M���$��8���q rA�����������>���:��L�����F��Oe8{�_�lr���2�X���������~��/:��V%�}9S�k�����_��WZ}U�G���Z�hm��N��W#7��j�=�����}r��Hz�!$��}��S��a(HF�N�����u��KC�J0�(p��3e1dwY�	��YQ(��O����8���1L>�����oY��^�"�����V�����]���>QI�F�GTt�?���\/�� ���C���4WMHG[��2&�ZFIS���*���`����jH���#���!���D0����P������j�
Y�������	(��oI
T
o������QH�,�y�2	��W����eB��{�6�>�1<$MJ��
�4�s����(����a��Gd��������H���Z�����P����]Zx��c��4��*���Gwz���� ��B��Z$�,�;Z�x��O�l�I��N��OW|�o����u^���'������A��zy���+B�H� A���i�N�&�C~�L���t��;�R--��x7�mCn{���:��
����@�����3���9r�2����L)�(��u�m�05C�c�fX.eW�8n�����^��7��D�A��_�����i"�*��w�����G���������x��C?�
3zG>T)>�;� ����f��������1_�HX���,F~�
�4��a-���Hx�+��0*_}qi\	���	"M��������4�F����>�#�G$������_�*�B34A�
t���r
���j�2���'|]h��������AL�$UsgS.�"��"�f�L��$��qvl��"�`��������Oa�z���%�`x��,�>�_��HG�T-z�Do.�r~�nQ����4����k6�?�'A��n�����v�%q�-��d�bTa��a$Dsy�llY	�r���6�o����kZ��� ����>��N�!x�B��$��%�<��`H�03����i���)�e�0c�lVx@���u�yr�?D����C��@IQ[An�n�H��K+M0��������_����Ny�u�>�4�6U*��8�\����)d(��|��g��*+�-
����A*�%J�g��vpc(yB�&�l��L��uUM���6/H�?����~��rj�j�Q����6�V�-KI2��~���&-i�����[������lJ��8Z9�-j5��7%��E�	������j���W%94�Y�lm%4��kR�)kZE&�!N���&����[���m���g���_a����i$1�H�l2t���6��[�F�}E�Y���D�Q�D����������������Fa���GB�����C�������?��#��H���$��{���gU���L(��g"Q)A���B?����(	�������{�V���/��������H�(�����O��^�A$q
����,�Ca� 8�M+�#J�C�i1���*�����
	)+���$F��!HIxL�8�+w�;=@��Uz�H��@�!
��n���$Ue���`J8��A�zyi#����.S������c><��,/i�|�������O1~�]|"���a����>1�����xl0��}!`�����J"\���G�5���" �Kq��[w�����2�o�����0g�A����Tw�P~�?�����������=��������EG����]^,|��!��������`]:����7�'��Cf��	��Y�B f.���b��������I3��w��*��������7��{x�A�����d����j�_\��\=�U#���xrl�KpH�5��u�?���
�b���~�:�� �n{�O�.�;<�����c�y�3��3��m LQ0��M�������bz?E�7������^�)Z	�PLI������+6~�s������d�1�%�G@3��xM|B�.��o=��'���u
P�y��=t���������v��F��6��8Q���s�������+�i��I��e�D�]iq/���/�����UUT��n�	����>���6�z��v���+�����O��=R�1�=�%$�i����0���N������zX���[
�wR%8����j�#��:��m��:uf_�O��R_���_7L�g��DP!���G��z����+�������@k%u��%��g��>'9or�y�P�!��'������wi`7���l�X���������{`��s����v����_)]������]��]��_{5��S�[�w���K��{�Q���?�����)K�rd��_�������'�<�i�v��{u��Z���e���t_'~;�XsW��
�Q5EH  � A�LA��m�+Z���X������b�DJ�@���.��w��z�I��w?���-����7rzTQ��d�|�����W�dum| ��`�-�T�I$�@e!rs$I-ZE��4�bM�J��j���e�2Z���T$��PAd�[.���I0AT��9QT�nS�*yk���Ui���{��b��g ��r��"A�_W������\n}\��}�����r�����-�S�������'�������s��9�UY�������U��8p���
�q��#��'��5���P@�����U>1@;m���|�B]��t1�&f�&	����f����|p��s�� ko�����-��]�r)ra2z�u��(��k$r��M�n����W�AcRX����h'�#�Z�A�S�c�u�m�r��#��j��%�2�{z�7�!�TQ��p����9���v�vi7b ID��4�3��EIEe@�UG�`6��Bjd�[��)IGR$}$}$��E���3�c1�f	0Vb&(���"5�'f��V�����6c��v,����u����D~�����'�+�N].5��h���:]���QwUqd�`&i ;��	�!v~I~��4{�9gn���`$� �Ll/u�>�U�&I��=��M��y����qU������6���t���o���������l���O��%��6����
iyT�U������P��J����9N>����>O%����de��6D���d�����3��+���i�1-"�\�hD�U�*���I6�
}_?�����W�n�.�s��tn���U���?���D������r#c���$$����}�R����i�Rf�������N�S��,�!��V,h���	(�����g��� ;?
�t�����3U��Ou�u�	��.�!��'�'�J>��Z(��6��~n��!+u](��R��������� �bz������|y3��&b-y�F��}���=����*��IO�d��5
 68vq��]]S;��tq� }�u��%~��c�]��d0��H;Dv��p�%�&4���G���zK+=��k�$J:m�>�����8p��9���7r}�_jX����~��������"U$5�4��Q�����	@ ^���Xl���"$����w2�"H@J���Y!D���(������$�;��$N;��n���I��[�""$�@uv�J ����Dw]�*�(���[����p���Y�����?O�=���7~�8spb�/�l�%0���E(��A�G����&O.�������>��0�s�a2�@��L�
:���)����O�t�bQ��{b�<����A�5B'xB�>��'��A�}a9��Ig�c���5_Ov�(����Y����|2��������l�A�!�+����O�u�n�"f�:����~�����|+D�
#G�����<��@����~�����t�:�M�`F����8Ii��]�c�W�V�$\0 "���������-(��_��N0�I�����'�q��=w�CRt��'f��k������N��C���I��'8C�\w���().
Wk����dO���������~
'��4��E�Oy�@�$%�O�>�)�}I4�3���|#O�������#�����h��Co,��*�D��d{��u�dO����o������bH�����;�s�q+�g�`�46�`��+���A� m
����(�sv%"I��
�
�~�%�'�����W����*Jh�JH�a����f����*`��Ju��q����	��UI
�5dh>u?�r���������}y���)�+H�3�����V��UB�s���]��o;/]�"��'��QMo��x�z�d��k�����Q�����_)�Y��3�B|��	,��5��(��b0�q�s������"�7���m�5a�{S���|�y�th����wE����]�W���KJl���^�)Btna�7R�z%�����>�R�D<;b����h��s�\������w����	*R5���~!
� ��k��(�7���~�m����(
�4���F�)_9�4��������4G���J���������<�m�H�InUS��7������@�\5�(��_fu���G�G|gL����K�,3t+k
��h���?u$�0zl3��^�/�'��k��FQ7+��O�h�(U�{���JJG���G�����h��)^_�����EA,�!DS�55i8�_Og�d�g^�}���<2�1a��m[������b��~qS�T����&#T���B+��������\�-��
��4\m������Z�5���������w�Z�"/��gL�aYm�����w�7���+7�~�"c��v���T��:���S7��4#�������z_W������Ol�g1_n���u/k����@�$����'y�������x:p��H�d~�"�@������P��.�WCB{�~j:Y��	������l�QH@
�P��wb���[<���Y�i����U2�V����6?�������-���t����=��<Z�����aJ�?E��P��>:9��;P&/l2�R�M(	f������f����]��������Fe+q�t����Pp`�H�Q
�@����a�:��xh��C4��y\���
D� `���FCy�r�����L(�����Z"\�J�xJ!���2'�_�F5�,uVw�	�=SJ��$��C)2����m���#�����,�d����@Q���%�����)@�� �
������ WH�x����$�����Iq��=1�,q�.��$�������"��w�{?7��:�����J�����=5[Q\c�G-�Ia�446A8��������)=����u��Tm
�����=0InI��X��T����g	����������)$(	p�M	���[-�iR������*��2�z���Wh%<:G�|R��R[E���&�EmQ���	U@J�F��?��J������*T��/u��q�u�n��/DGq������g��W�v�v�xN�p�$�k��;��N�:t���:t��������_/k3\�wrI�|�1�����0�3��;��o[�B]�����V�u�wz�2��I!BT�IA����$���X�r���F�o]�{����{�8p�e�X��I2�lo/������I*T&f�i�������4=��M)��h�����	�$A�/_s�v�����������!$�#�<�\��x���d0T~e���~��������{�����x�=�p#�%ha[q��of�G���([TC�.����� pL��� F��G�r�S	�}���R��~���wX��E����r���[b�e�����m �{��m�I�#��R6��0�+:����c�����Ro��BjS�G��Y^�\�Ly��/�*��r����|����be�^��]�#��0���3�k������q�=&��_�)Y���wMkJR����/�����-�7R��<yJLo���S�s��<��w��l�/��t���>�V��>~������=�?��^��Oo�y�xw�S�����*"��!����|��SR
d��H��go�u�-��B�9�'�p���Zsx<��4��(ui����H.<��Zs��<��
$��Pz�����[B�Zs��<����C����;0UX��4��)�E�����)�IA'����?A�y$�<(ui����NxP�N|'�Aq;��V��:|���y�(=e���<�����(ui����������r���PXP�i���:p��:���O� ��B�9���H(B(v��D(z���O� ��Eg�2��\��O:w��P�N|t���'"e��r�$	�4����������{���v�vV���D^���}�nT�x0��������ceq&�nX�����i9����<2�s9��R���LT��N�	�4 q�
�U���9	_����TTTTTTT���{�k��������!:(�f�#r�39%�)fD���&�yn��|mu6���Wf���"+|+����R^�q.�+��]�V�pb,$�	���M!)�BM������_�������N%�G��������$�RJ����#b�b�b�AD6�#�>�PT
(���_[d��S"�)��4�������J,�V�o&����Q��,�W�_�"��Nx�|z��Hq[r#����]����%z�U�
p�����<�����}F, oJ��`#8�����d��$�r(���c40����@�cBd����9P�vGo��������(}V��xy�]���QQPTTl@�UUt�:X!M$)p.��Z�*k\�A�w���lMd6�KX:������`F�$��Tz��DQ<�vI�we�\���;�w�@�
���������Zsp�-�-
T)4Q%G�������;���My������)n/@��^D�������������r�0��%������-px	|��[�#�ki(�������DCNOp 5[}�v�-�3��)�����y
���G�I�J��Pha�U4�H%P�-
�_��^yqY����n����
�������V���������OZ�`�	B��) �b*�*"�b�z`1P%�fR��i�������B�4�A*e�Z�,6[z*����^����e(#�d�&-�+X����R���m�V�%L�&L-��5�e�*�I�fY��ZY��TJ%%%�e4�i(��d�^�s�>���3J����X�b(��1O?	����.�~�v��F6~[IH���r���~�"(m���-.�"�G�8�C�n��@2 �M����6���;��
���]�w3�A>o@�������0���x�
z����n�������\��OM,	!l�e�O@���������������3���M��6���<:0qZ��_��Y���b>��������D����DDe�$m�b�T�������m��y����s��9�8p�!
��J�w���s�s""�)D�(b]�����\�C�^��<�o��<s�R�����������SYqr����+��4XS�u>u��7��(�����65��>$���4RQMI��h�a�����k������gQ3��������{n�����1N����X�O����5?
nn)�!B h[b����66���x���t�)�P�S��U��iR>���������ph�y��tt(�FpC���y�n�
���j�����i(:CkL_�r8Nn��$�$I$�G���>����{����F�Xh�&%C!�=����$����J��E��H���F�Z��^RI����{�9�����&���
W��^��vk����T�i,�l�6vA�(��/�p"�����~_���e%9�U|�������#���>y/8n��:��u �B�O���P�\_���$%���>�CD��0G����_|���������V^9�$��$��2b����|~i.��Zo$���H�)?��t}>���{|�(��=yh����n�*q�������pj#��+�zL�
\�+�pC���YSg�.E��<h���8� �:�JZ���yq���7�AxjW��^���Q��l��b\/K�����_�����^���4|x�������g��3�������������}����S{����B
���i���jOm��e$o�=��ZJ2�v"Tz����f�gN	3��/|U��P����#ibV�N.mC7��;�;;�M/�x/�Zl�����O��D�Fz���>��+u�����Wnrk8�	m���U��'>�������uYb�j�'���c-�}��v�)���)]�^�����
=�O/��q���������Y�*��J&�'u}.:��+�(�wuW+��.v���]�)Z2�B}l��[qy�W���%L�R���n�O����V��6}���Sh�����H��V��,���IJ+��M�7%�<� J�1�m�"����s��eY�*"��%]��a?�70����2������o���*����V&���V��j*��F+��c���?��w���7��������_\T����8�y�_\����/c�	��g�z�S��i9m����Iz�o�t��H�������?��L�Y��m�l���&1/X?�d�(��`�~��KMo:�4���!�d�?�k	�pNV'�pp���RA���r����g�Q�"�
#���������_�'�i9R��M�]Gm����G�0��m�cI�����Ald��J�W(�am�P���f!�>�2���N9��z#���7��|����w��jqrc��z[:����u�#�4�O�|��Y���E��8-?�w$}a++T@�Ib,$QRE�3H+��F{�%{{>Ne{�q�{���&5�8���W���/��'�`�����I+���_`i:o�_�d{N��/[m�Pj�^�6�'�+��L��A� o��_��IA����M�u�V5@�J�"_��7�(^}�_��(��g�/�P��#bD���B�$�&��0@j��I6^��T
!M.=�1j�7��-��2�q��kz�K����~�!���YB��6$FH�7�_�������rD�J����B�J��m��P��GT�����7������0�l�b��a@=�@�$4�LZ%��k�zc��e77��������}�j ����B��F1������4�O,s�a��h����hc�i��,l��[��@~a�%�!P;������B������??�?��z��x���j�%�W�L���
�m��B�o{�n2V�;R�����i}�Q%��@I4Gs>���i1���|%����_�gb2���\�y�l��+-RIw��0*:����z�ONSP����~���2�)��	BRSE�������E�����eb��8Q���b�J�5����CU"��Q��0E!���1�T"�i*���I������2���������-6�]���m�����o���F�-E�����M
��\�t���k�Ib��2"�����M)��%3e$�%)4�DQ%L��Xi��Q���c�YG�e~���= ����:���T&#��%���ZLL*L��a%��(�������w�/�@M��X��G�����{�S�4�L�E0�q��=�(���b;T�?��<C�b�.G����
������������0X�O��C��Y�y�<���C�>C��?�������N��|�vS�_����kgy�w����>�����C������?����z�����%�n���P����f%�u8z���B?������g��
��p�����
�I�Pt_a�]��q��:H���������Q�x0Zd\���?u"@=E���p�$2�?�2�d d������?��� ��B���O�M�[����!#��*k5?��r��(���s�
����R�{�R�7�i5���6�:�7W��uv�}y�J�����P�E��4�Qh1����"ow��?W��$�(@h-������d�A
�z���9M7���&~�A%�?�*�f���,�Y}:�:	Ml.
r_��I���!���-W!�^�;�^u�H�M!QA��jjF��H�
������h;�4h-Ew���f2�����K�4�Z
��T"H^�V��������D�k�[�q\P��j�����P1"j���L'�/�F](�JR~` X�G�=CSCD�CL�i4�;�hidAyArU*L�EDR�SN��K���0r��������b�VA�Nq#���^�Z���cU(Rr'�����	u/��Q5e+�����X���TE�A�Z���2)2��C�!|^���%��*H�����E�
>4��@��r��NuD�U���8Ch�`:u�T���G�T���wO��Na�DC����z=C	$9)�^.�&p�UV���X�����X���l�0�%R�E���!wL��`��[���Qf���������yvm�����WI���/���7n�@��6����R�&������I������$_�.�kWYQ��X�U��>]��G/J���[�)~�����3�/"�s��d�����:X�O�&}���i*-�N���b�Pt�|��D����f�;����SJ���Nm}�o���^����rv?���N�{5tm-A���Bh��i��i�`��w������y���SmK���e�s5������L� ��0����+Cip�*�W!�(�F�Gp�Z^��
0A��~������~�Ra��[�fW�85H��zX���$�?�e������k��z�������3��c��M��1�^�n'_����O��7��{p���y??����^}�����
`�+��IvZ]c���8�|���~����tv=�O������o���n�k8������ �����������E6?i��H��4L���
�K����2��4�L}
�d�3JPn�Js��K��X�����Q���'�L#�J�u<����4�������IU�-
[r��4Ye�,���z!"��<���h��7APj��3X����F��\Z���AK����t�2���)�����e���[+�"��S*��a�Y��e���ue� ���m��m��c��m��0a�X�����R"�:�i�f(.S�����R.���hl	Y����~��3���������'/�� �(@��^f�2�������v�6��&�Y�Z�����a��zh�D�2$���>��<���aA9H/����V^[��U]H0$�z�!n]	 ~Y]`�~���'�X����z�s�KcY[�n�L�6����A���$r�-2;�~�ym@�p
O���5�q.�J�
��pz��l�4�����{�.�i�=�{�����IOR/���l�s�b�W��@�F4R�����,�k��R�G�%��-�]�H��p���H}�'hx�-��Y�������M �\�{���d���n<��<�����r���p7m���c�$�|�m`������#sY���#����}A��i'��n������Vm�����|19�[�M��"�{��*o9n��:V��x�Q-�8����g�1��*r�������z����Q:��rrr�vkk�$��Ba��H6���Q�Lm�)�Otp�3����|�I���wvx9����d�;e-�|�^E`��'=�P�c,7%��P���eK@�1����Q6�V��=�vT�RP��ocq����^��sf������H���}S���B���3mkUb�;t��8�$��e����;zm�k-��q�\r�s���~�i�y���K�{u6R�E�hi�@@������B���w���A�yn�n���`��0b��2��_.�6�hQ��_�$���@��0lR��&������Qa���Z+b�%@E�������CLj�F�R�i6M�5(&�>Uu�Qh���-��?�8���Z���K33�]����"7ND�HP4)���P�E���i����������``�X>�n��tyI������Y�#�#�B���G3Q�
�f��Bc���"
B�����2�X��PI����o�>p�7�T3���l������������{
.��1T$}��*|=)�����ps�������q����}�������?��9�.��|.�C�
S��nE�*���>h�>� ���yl���Z����P�%��*W��S��(V�#:A9"�G��q�d����d�2�2��Z���e��9QE=�I$u�[
�����+n��(��?���C�I��,C�r'��HFH���M5&3��`la&�2,[)MD:OGy3n�J|)�)C�_C_�b��T;�!�
����,���1#$S-��N��$��I#���1#��D �	-�
d�C��y�C��
�"��o�t6�1���#��$_r��]A�$1���G������a&��m�5��*�
	��d�1���~����_�p��������@��gSma�OJ�@fLi�R�$��NSp2��R��nc�H��#a���<J" �[Z�UU��� �
���'�p�Id�$�0L����I(TQF�=���l�,��-A.���C�v��&a���1��������_G@O��BI����������!�HzD�J���3h4[Kh�md�d�������=k���.�7=��i��z������l���f��'��j;���QB}�}g�q�z*�&"����Ou�H��|{�^�z��������.��4�I$����Y�+�z���������jm@a6�,BV���*+�-n�$�Pc#Lcc{���,s��3_�����`�)A�y��_G�s�J���+��_@'�y|��2	0k���|�)�!�Z%S�M&�	�2���D\N�mg�<����:��:��j~x��qr��y��ilT�a4K�RIU{�kM���������>N��V���Rya���u��/��t�4���	`T���r���7��71�����@s�?o�q6�	2�:���	+��y��K�]��H�Q��g>�#�8�6�����=���Q���{Q�4�=p�"��8a�v���+"������].$�m��F�`��JF�=��tX�M�(���/�M�����V�/w��G�(q�����;�/6�Cf�C;�B�x��K�j(t"r�i4��I���]�o[����L�����.#i��n�O~����]��~���~����w�������j����O_.~�9B��Y#�An�c��)0c��������D���}P�c�������^}�<2@����En���*��a		$��t���1��n~�
�X��8
C2���N����#r��P�
���u����Tv����<�
�j����lHL���k{;i?o���������	���/:zCw~���p��=;�,Q��|n��@��1 ���
����{��s�'d���R�Uh��QLt��4���/��`j��C���/��s���l�Z/Y����Z���W�����k�8��u9��g8v�|X_\��,h�>L;1��y���M#:�����&�E�]S9�rD>���M�[������z{�pI����;"�u�5���G,�6f��1��^v����}�]C3�[������K����:�!F;�����%e�s
�s4���8f��L9�;���7�&l��poO;}�q�m���3z6�z�sy�[]D9�����F���vN������{�w������-�[bI���C�R��������3[\�S����s����>w8I�\��5��������oO�}��B��g7:kQ��{\�a��t������z�>�����Rw.��|\�f��;�^M�No��Ym)
k�ys7������5TXU*W�L���?���J�_.2���S�P��f�c4p�Y/�a��-�r��$R$�~��4��T?���A����D�'�=O�*}0���*�H��U_0��T����1�%E�UO�>2����}`K�%P�>_��D����$���kUl�hO�M�O�����t����!{D�*+��WG�!F��`�b�k���� ���63�u�����,�F��m����8���:8��w����G�����$OP����)�������� ���;����Gwd���������;Q�5�nB�|�����64�*_:��x��t��������+�)_)�����{��)�z&M�Q����e��s�u#YJyTB���N�5��o��O�����<�Zc������/��Zw^733��|x^��j��=]���w�np��g4=U/��������-������H�/Z������#��L�!�y4/��<V?�
�`�G�|�Gw���Q�}�[�k:�IU�L��>��.]kk�J��?Me�^V�vs���n�����Q�����h�"G��b���bv�.|�}��t	/UOg�/9�D��iz|�h��Y<�
e,�|��mNz)��z�7'��z���#jmB�{5�zzzO\���4�Y�����)��Zed�5�Y�Ewc�P��*����?��-�v���Ww�n#��-}<`|�������l���Fy�h����2]]H������Efs��j�
���������Y�2n�C$T��!��t��x����;���a��D�(4��w�w��`����^�u������g���pZ(O��#bFW�zk*Nv4���5dhk]y�@�0�����}��?���6�
��x���^}[XE$���C������w�J��������������)$?���f�s�lU+�t>��:�^M����U�8)>t�
}C��$�N�DO��dp�o��)*I���T����y�{�$�o��9��v������]$�D�$�I$�I9�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$�I$��V�p99*uBE���O���(�/|a	����o
!����4��[$dkUt(�R$D�P�]�����G�z�+N����T����H��%�*����Z����m���4�4r���*�)T*�d&��"Bi&�Hd&L�TD;D�PB�hB�t�TpoI���Ei��"8I"���O�7�����HrQ���%)�cY1i��$9��(q2I�JI�(���������}����������_�p���ewy�g6��[��[����o[����},�UUUU�B���A(oM���U{�:A��T�S�3I*@t+��m���\I�n�{r%�����O���WXo;��p�����ssi��{�P�gMJ����9l�����a�����6$�[���W�K�<t6�k��z4u7fi���+if4�io��1���-M���b�b�IQ�[L��|�����XHHIXt�"7N� i��|7Xi)4��Z0g��!���y��i���7e������4=�D�p�m�K)�.������h�jJ���%��@�j��7^���un�������%m���6��	B@.D�������LI�"�H��"�����N�)��^�����.G��3;ap�@HE,�El`��D���N�"��A��;��������D
 R}E���F��������k�{����'�}R��\4���,(�c#;K��#=�$6"M�����	.I��������7�>�7�`��k~������������H��O[(�"���edE�P\��O�]�n�1����j5�����Xr�Kbj��aW�fR*`$���c��#�

X�t���/
�T��,�KKeh���A����n3�g]����S)j�|.��mh���H+E4��(�wd��c�P}Iv�!�������� ������A�C�)$2�2g?����#��t�>��Y���\��v�*O��W/J�&�\E';Vr�Je���.��i��Al��B:wN�{������$v�A\:!e�R�H!������!>!#��"���=G�(==�n��~���U��)G;�q&1�n;��b��������������1C@����&��Pl�w3�eJ�H"8_f�k��6b�����U*�j�zy����UC����������
�|H�@X��u��l�q���R%�uT\�HI7���@|�@P\�(kk��L�Wj��N��))4���~���V�d(kV]0��%"��x&��1lw22Aj[>=[kW������|�6����>�e$0��9���f���)(b�N���U�����kl��,U38@� UGVa��3��8��j��
��"�A����/w��\YB
����V3�i4�_Y(�	�UT�$	�}�9$rG�p�d$ln
��D$��J�H���47��IB���io����5��f^F��8hV���M����c*I�D����6tC&8��[�{{]^,�k�<tZ�����Z������{�)��CQ��xh��B��/q���h���u�����������7������4Q�Cb-�qB2����Rmd�-{ak�4�6�m��E	0l�J�$�������:����+�F#d
�	D�b|0X��;
����F���(hQ���NP�o���D��q����&����-���
>���M�:x�s�
��x����r�N�c*�vt��X�/M	<�sF�eo97���c=+��~_o��UV�Rx�Y.�)CC<�����Dl �V�����	
!�$+*�$�&&�������zX���Y������A��d�����n:�R]�h�������I��Vh���`��g����]-�i!��7��(�NR��p�����������6�M��4.s�
R�S��s��@����g2����=��I14��}T�Y���S��H�r���H�h�cB5@�B�oM�Gq�%�b"�������2�*�sn�E�m4�_�\6Y���T��9>�:r�*���=�'����HL�T����+�5�
PMd
��0�_�_/�#C���*B8�����1����[l�����t��q$���G
�B�P7�B*���G
Uo�v�=>`��de������g��I�}�xe�.�t{�H��!Pb�!1��N2�-��^'h��R����:2A���ZB����d�N9�WN���/z��Yb$Z��:�_�Z�VM���%I,���6g������/a���}q�Q��u5�|��9�5�k����6����[�)*�RJu��E���']V;��ZQ:YgS�m�������f�:%(��	��4�����k��xv �+(S�Bg�L��Y������tVz1��>��.�9�3��]�g��$��T�����1����y�-k���.�s"
9�9bJ�6��u��������d
���`I�j��b�R�<m*���%[��I �M�:�i�����������T5M����v}>7����m����)��'!��r���!4!�BT4��0BN	�2��&w�Qk�x��o��kN�qZ�D�o�n^\q;�����<o[j�(C�y��t�J&�	��t���3Zv-h�
���,���B��HV�7g(,X&v���Y~K������+#��n�P2�#vT�S��I��`����4+B� �
U����}�ox�fMd�������	" ce4���D�~����f��+C�
�Bl*$ ���	0��w�6��0��������t9��6�+����V�|��$\�$H�5��9h�J[e-�����J����;|���Im�|��7sU����T5�<O[���������_zY���7[����!R-�#!�8��8�!x0I(��G�������y�>;�_������'���l�>$��QYU@����i��	L�js"�2v���fm�*��\���JP!R^]U�k~�3<n�,1@���&&�4��s��6���Fiu�
��?&1�����,S���c�
�2��t^����pq*r"�h?/�d�K	��BAV�(�0q����~o��	�����hC�w3*�<�t%Q�!�GiKJ��xa!��C��iWh��RC��z���<Y=���)�!��S1Xb�n�D2�h�Y�()����4�ttvK;g�N|�).��B��InI�G��xz��D���S�,����/��J��R�9�������^���(e�j-���3�W:��"��J��z7�~����s�������=}�����x�~&��;�r��|��'���V��YN��Jy�5���.v}��c|�J(>��������|X���r��b��;6��G��X��C�Du��F����gy/J��*�$����n����r9�+��D��&s�����m��'��t��F�6�� ���$RE����
��*
+���]U�������:��Z(��"0h�beF���)(�%�(������|��3�|�j��SE�8�����]i�Ih"��)J	1H����HD0���HD#(���	*S*R($`Dy�C���y������0��sCy$m��e�"*!FDT��
������	h�U#����H�@r`�i(0b�LXUT���W��J�d�3U�'��6z���������Y��S-/�����!`,���������
:�QQ0	��j���������,��\�=?<���5A�������g=�K�Q�(�FY�Sd-k �Da�E��1I�gq�3k[7-6r�OM�)Dm*^����w3ZC��|�g�F�^|{����h��~
.9-^���������|zg�����y�}��i�1�7�nd�9�X{���-|�JRw��4��6V�m2h�|��M�krR�uA����!�<���9�"H#+Vv��z����������MM4�c��+E[��'�z�q��<�)��������j���a����P����nWIblA"�j(,��S*4���b���v�����5�A|CU�+3Z��K���<�|�Q��M�x*��������(�d�~:3�F#.\	P"e8#�4"!� E���a�P��r���,3v���������Xn�Z���h�P�t�'�8O��ye��=4��lkM�b��j�&�W;
4X�CCf���nA���E���P��cV��5��*�M^�]�w]M8�bsm*���KIKn��kGi��zW��@1�1e��B�����x�������������������3�5�Uuw55y���c"�Ek�61�t���"�J�|�s��v��$�nI&$R����m6��t���y{������b)�������6b#-����Ih��|�����9��D(J
h���
�1�7�DQ{e�a����Z���r����P����+ki�m�I#����N����=���^f9��I �A��vj�.�^���Qx�zi8�DN"Qx����kvN8�*������9����E�~�����FX������&����(�5�R�����Ods���j�_�N���$��k���[j&�4K�:��U@Q��v��d���
���:X����R���b|s�~:Om��{��8�7� !��	��p�Z�M���Y�d�ZbD�7^��
�9n���d\2m�����ID-���05!����������g���/|���/5a�L>��:^��q�.���Z9��*b�)[�����5�����ISbP���f�l��E�e]�X�����i
|{YA�EI���y~�;��I D�v�M�m�+Vxr��$r�BPC��$�{<�F���pEpWVQ��tLci��<N�c
Y;o�W��mSDU~��n�Ot�^���b3�����#���;�Zi\1�Z�'7O����ZMU*T��"-'�`H�[��h�I�����<��[���=Q�ZY������7q���jn�%v|Q��i�����+����P	� cQ�\H����5{������U����D��L��?L�y5���q~�R�em�������Q�9��H��@�g�;L8���e���FZ��u���|�����<�_L�8�K=)����"x�=���xv�(�UV�L�wN�q�U��ie5�t-�n�y��.)��UP�|����G��.���T,�.G��HBL.F��$�6�af�X�3Bc,�����I$����XXXLT`�`aXU��u�0���������LeJ�:a(P(�,�q�lXV��J������7[M�������$5���+A��.���Y&\��#v�&��{m����T����e��B66�$���
�BF!���t<��#p�q�\!�)�5�.�����{��2�\��q����`ti�
��b��H���X�o|sj�w9�����~�\��]�W�g�����G�S�z�l��������P?��)*'@�2%�s��^�`���dj9(M6�4����w�Ele�����������S���d�GzG2C4I}D��wU�\l�rT6 $C�,BI_� �SI���R�H���)JekU�J�4�$�R�+����S�����BBBI	%32�dI��W�~�4~�5{x���[��1�f��xo���6$��r85W�t�5#�z�K&�/l���7���:�8�Uz'M�W��\\��Ns�o����|��bAgy���:o���4�U��9���$Z����s��2�Z��Mk�f�7��sH�{7������\����Zd�ci ,�4A���A��!��Y���6p���q�����l��G]�6B1
�wZq���o��-����'sW���&��/��������kX�2��xM�4����{�\�]�e���n��L1�6���=�33��qT*aD�0��o���sy���2�eV�a�8Cd)�YA�8(�t�[0�;��N_��z�5fI��=?u������E�`��4x�o77\"�R�B�*
V
J�������)�+���+�))�J���t�g	D�V�
�������vn�U�!P%:B��0���|��x�s��i�r59r���:q���NN����)RI$��MJ�[Ab�,B""$D��Q�
�8(	�I�������7n�;{���a�sj���a����9gN����&�o�wFg{�NqE���wz�7�9������cOiv��)������mh�j!�u�5�gHl����#���w����ws{�o(K�Y�S a}��.9]��{��s���1	���
�c��%�s4z��'��|VQ4]�95�W��L�I�Ws�,��oP��#N�O0���-���7��w��] ��W|���u�\�����J�&��[����pk�{��As#���m��b31��p������9R7�Xr����/�Q�����<Q��{�����k�/��8s�L�Y,����z��o�0lH5�H�pj�D��j>	"W��9K�������F�������t��Q�J�P[���k2���C���~o�0lr��A�_�[����(j����J��I���xs��'5�S��.z7�f��f�6�����"RX�-,����K���2����������������M���3���om%y���{k��n�������|y��������������j�s\�@��R��+��\��YBSMB'<
��D`�f#��!e�"P��3'��Z�'�\\��Ns�&��z&�M�g8�lm�^�\�&�CC���z�U�@{x���/}2Y5�m���M�����#�w��'���!���Uh�9t�;��m��
D��%�4�H"BHrA�������8��F�����wd�C �W68h���1�mqI�r,���eY�4X���OX�14!$��lH����F�v0��f����g/Z����3|Up�����y<�H:<�����'�'�����W�b|��K8��p�����3)����93���{�z35�>G�������������S�R�����1{t������k\���K&�-�(���z&�a�^^�\�V[H��yF��3��(�����&���l�B��m/*e�b�J����p��������fcm�{��
A*�����#I���=6�!Q�P�$�P�M+m�����c�!$�8���)^2�)�R��W���9o�^�^�����d���g0���z}j���w��rn�(&�7�n���y���
PYJ�Y[
W�f�Z(���*Q.����9�N+�w;��2��9a��B4�A{�j;��[{����R�5|�����y��w3u���J�x��JEg��
�8��<�D�HI%���K��_/��K&�-�D���,�[�����=�f��
���S���
>_uT�9\��E
t�ff;`1��7Mm7j`��y���\*�X���01�1���!aa#�X�����WJ�U
`J��oY�W��D�y��;���Z���+�s'fi����������Ow��-W�]gw�u�E�*e#*3J�3���qg�1|�3P�H�t�g_IF�zF�a�b�=�=?h�������4�UV��m�s��<�����ti���o�t��ub$�F����M�4Dt<��)��E���3�'��b��������������A�2�'"m4����ZI�����>Q����t�@��M���� �������:��U�������	'd��LM��H��j�a�Ab�	�� kb�����*�Ml���f��b��(D�S,mV�a�s��K����Y�=����j�����18���$��T}������:������+��+j��U�:���bK^��|*�����������1��������5b=H�a'�Wb�(����:��n��0I�(0���(�!V�;�U�����o���\��r���d|3����T��9�����W�g�����"�����U{N�D8���[���������On0afg�%�pC�W����!MV�%���:�=���fs�	��k"�Y���W�
��B�XY����C��T@�W%	zeQ�Xp���&U����s,�`��W�CYM�������_�,������8�E^l0��
���o�s����^p�m�|	^�"HE�o�~@yU^V����w;�*�j�6���}e��N���$~��[���Jqm�I�2.���6�-Z[�n��nl����0!��w���C�F�=L�^+9�:��:R���f�"/2rk6��N�E��<����44JhI
�	�=V�2T��I�A���'��:����+%h���G����9���X��N	t�-��3����-�����	?�Y����o��@��V��\?U�\{�,`e
���*-:��k���������^�X J�#�~_��?����������M��{���b��)�����1k�Z�����iD�o��K�n^�����#��QU��4O�WU���MZ
#�3oq�O�#�[~oQ�����������E���Y*4��x�

��#"M�n�9����D�l���
��R��@�����Y��O�����.ZC��"�bc������R4�"�f&T��I� Ci�����:H��$L�,>��A8��H&�jT9�m n)���R%��}hyj_6Z9�� I�2���zW���e��)�!�F����Z�&b��I�fB�?�Qj�UJ��1���Zn���!��'��i����pm�f��c�2����B�V�D���,�GF\-b�0��@�	b):X�6�I��U$��A����I�_� ��@?�rL:8�HA�~�AO��!�%�'�!FA�Fi}h�SRF_�BR�?�h���q�F�
�?�!?X6���[�������
��bIa�#P�I�tGg�~7���L^`�����M������9���I����������s���}���W�S��u�wc���I����^������B���3O�����A�e�^H�s}WV�|�����e��#���	`{�$�HL�����o�$��F�<�RQ����H%�Q�^���9!TF��m���Vu�����#�,q��+�����y�����5!�
kh�������i��f
y�9$I�'TA���/���������I%9��'.&�q8�9������2Gv����:#�e	rz���}^���6�?M�m����JYKOvGX�m^o���)�fE���"EJ>�*�����*���s�P��b�v,N�J �%Rd���C"~���I@�	�lC�>�?��+����$�,�2��Q����g���$4��?����+��/�0����T �.�EQ�C�!	0E��4.���v��5T�Z���������]b-�����:!�9p��5��
����P��I��(NH��#����C�z�����T��o��Du
A�/���"�_�0������K$c,"W����������Z	x�UFI*%�M�6�����@Ah�2��HK�R
�*���R��.H�)���[��b�A����b7��N���vd�9OP'gp�f[a�h}����|�����r�#��Up�p����k?�������=��&��2����h�K�7���6_��;	=D=$����|� �e=��@�J�0���P�U���	b�
���t���,lW�����#�U���w���p��u<u���%�L���=Z	$��BG��=hHn��`���w}
"���O�;�z��@BN��@�<g�X5�����M	=�����u�����>g���6�>v�/������ ��F�*��>�����Hz�	I��>�	�PN���E�J�b$���do�w�~���)�M����I�6	g�M��$)"���(�*�=�/������}����I&&J��%	�`4��f4�l�vkQV���C�="{r��I"b�3���,4���>����_�6+$�:�~���G����7�t��#yT�SY���<���6��*�!x���8b=�����K��C?h�^v��9VH����02���nJ�c�EG�)E]s�4*���A��:��"op���^��<!���P�O�T� _ �
���=#�'�	�A�O��+�$�����C� ?)"{�A�%�3QI���5��D��d���}�uG�0��������O�������5���?R?��
)+�
�����SD�cW�M%�pKE��
@`T�5-�`rrA&�8�s�8�d�C�4�� B�I
��16�q�H���=�G���c��<�b��Hh�eO	z��@8>�>���t_�_�.����F�`=���f�\��_��'�O����&8����x��$�RFL���5I+p��Y�����G�_���$�TH����R4t0?�L
~�����|�~�a�����?����������A�??���?������[������{�$V�bbiBB�|Q"��h�6e%����?C����/q|vXE�cG"�QnIB-D$���),�,�d���RjO���������������==��B����Dv3��j$��R;���8����(.�_3���D�]������_�(����o^�l���n��q�k6���*�� ����1�?'��lv3��=$�������hg��P^����6?��QO��{���l��=�x�� ������I
^���\�@�[�I����l���:�����#(����� P���6��u����f��U�Y����)C����`x����5�����pI�@��W���X��6l��f��(��� ��
�S���H&�������)�1��C�Lw����,��2
(���e�S�,s	�"�D%
�i4`����e�����A��37�$d
H�],��5)��x�dEk���d�i�=�����������8'���v�$gV�!\Q��d�lc�'��������v�!)��A�VT
��� $����"gN�I{
������H|bH�;�z7$���K��R�"��c�`6n�i�
WA���	b�AR-)e��}�8d8�p���~�N���<��?��5USHED��?���9�'�k�����O�.�_XB�?�yc�~~^J�0�v�]�E"�Wz��	t���u���D�ld�oM?�8���o�;��|k�K�����hVE2�*.��c��� �p��u��]ND.�R�t�"�;�8TP�J�
""�� �kB�If�XR��6p@�����hr�Aa�a�R���)�0���r	�a1`��#h�9��L�d�����I��XA�5��+QS�!E&vA �3�K���ME�b�Lq�n��[T�����Z��j����gk:���%-����������KU��d����
���J"#*�I;sN���N�y�I��p�����O�X�-BfG7��o� ���������O��w��n���y��s�? �x%���^^V�,��?-�������i��f(4����9X��yVu3(x���cY0@#����8��1Or��RnG?[�6��4��m�5}�\sx}T�z'�q��Oox��?�����a@|u��v$������>O��1�+��T����Ni����R��Jt��'�\��lt�\�R��E\z��y�K�5�V�F���8jx�m�SQ���6���B� �7I9^,�XMy[�d����d�����0?��4$�r�h(a7;n�M5��8������pld���;���]G�}`���{@�%RB@=���������-�WO�� �/������)L����j-F�l��CE$!Hq�c�p�@����<a����K��t;'s6�w�����lUK���������������i���
H~HR$���� ��a@@�T�,���$��d$���;�_G\J[L���8E \\;��^{B����h9}�>/kL�&�YR����)�)��H�H�3J��e6�jE-"��F�H�3FE��i�R6�H�f$dj�*i�Ze���U5��@$��$��J�(�����RQji�Yfk6KR)U�MeeMY��T���)[)�����)�2�,��o;�-IZu�]�U$Ed��1��R9���("A(������#��B��l!�@����s�<���)j(�W�dyDU��cgj�`�j�6�,�*
�����{�.���$
�D4Js�9	����#���1�j��Q���V&E�r'�]!�kbU�����G�� ����\$i&zd���9����F��-+`t1V��D�qN�=eA����8Y��&��4���Ya���?(#����Q�6�}|���,��]
d��%�Y-���,���M)��U�����M!`T�JT,X�"�jZ���,�E2�����[YV��E,��E0��!	�@I`Q%$d	R�Xh�kh�6�,��t��n�;����M�.��$a��
�R������l�g8�J�i2.�S`������j���C~�$��;��MF��������J$�7�8�f�����4�������a!B���G[�l�����CI���Q��UY�y����`|F����d����������{��T��y5���AnFb��mC��iZ�S�Z�O$�<��Z��R*�d����g�`D(1@�B��{y=���(����U
�e����i�{��8T����yQ����O=��	�F����J�.���	�KN~�$l	~`9'nK
J���;����������ZUn��I$�M	w���y�����r�^�ZW�����g{WK�!		$��C��bT�#��li2F���I����/���jAv�!&GH�4������U5p*���"a�����!�:W��5�� RZ�i����h����dJ?��L�P���o_���@�����	��P��l��Dd�)��d�9(�� ?�.����7Bo��G�����P{,��sy�k�c�T2���(h�=�)��HhAP�7�)������y�����'��{��G}�z�7=*��|J�o��x0}�j?^�9$�4����22d�9�?<��>��xe~:��rm6���j["��3��Ei9t���"����O<S��QT�L��<�����`��C��L�(�8=�=!�����'O[�����!����'�EV��f�������5{dD���B�D0�;<�?��e0��J���Z��~��y���v���mV�>�>�w�[����k`��Vime4��]xdR�~Z�T?pn���6��@������h�at������C(HP�AO��&jV%j�G��W�;�?�x �O'y<d|��
�	���w
t�x�����1�6Z!_��hD��U��;�#��H
�B�'���
F(/�)��"��2!)$m�EY4`T��_��78T��U)A����;KyT�*).����:L,BD����z�s|]�V!�[�t��&��ff?,���}!*�fz�`��/$_h~eC���������?��D�.���(�;�P}j��N��a#��P�3�o1��/���D���D��Z
p1�3��m���BF*��f�#l�&.��6�i*��4�Y-���k����>R$��pC^rz/T8H��6"Qj���I$��6�Y%@2��R�v��)N�	"[%����1����QCF�	T� `�)�eVAU�m+m)k%d���@�0a���a���m�4���;W����)�_�hk��m4��^ h���@%�obf�N����}��5������q�QJ�jA�J&
!����XL�N���H��U\@E�P1qL�h(3�*H(����[g��a�������6�)�]�!�P��|�F��7_q�?�(<�	G�o������r�����(i�}�c�������O��>fC���}��?����[���J%H������?�O�K[��?�-��wr|�7��=w{Um�i���!��}��d	F��D	
F��i2w�V*�� #lq�]V����O�"/x�����������H}$9�S|���/:����&>L;�z��u1%�4]�B<5�F��0��1	)�a�}�76�K�.�{�H>��N>�����B�a����H>��8U��G� ���V�&�	�0��D��{@7�����5LW^y��� �C�_���	��g���k	8�`$�	/������^�.|T��@ 7��J�O�=8R�l�f�����'��2�$'����i��
jH�H��8A����t��������<�x����6�V�J�	�q9�����������r�d0��|���Gg\j�pD�
>����������T����+�������}���wf:2���L^�'���r�\�9v��
E4�����o����#hT��=pT����O�Q����a��E*>���mC��^�H�Ru������a;�:I�?S1�����#�!�$#��*���=��f-H��6 �7�=>���x�����S�������O�o��r�p�.
6VSRd~��HBmg����q���D9�5�$&RH'�������b��������Z�}�]��
��E�3h�H���6�j���7m5x���T`@r�c�������4-P	��A}��_�/Z� br� 
���#��'C��������I���*mZT	A:�kj�������Z�d����;0%��Doz��C�T���.�H�Ic����S�G|aC&)���A�`��zA������!!d-,��(�������-|�>,z����\�/�����#�Gc�����.������&3����2n���Jf3������������o�x�q�+<�>���6�a�Ix�)���H��2�a���.w/V������(��RP����F�N�t�u�:��X�	�M&�LbI�f����<:>z~w{'�_t�'��k�Zz�y�x�
�1"$#$I�|�NQ�d���q�J��"�9�<�H��) �10P!R�PsQa�bA��1Q21�P�������v��m���u���"T�
�A�28�/����M�4h��t��HlT�����F��m���Y2���)0QXm�0q���b2*{����P�1`�����2��.�e�p���M����>�t�Z��F5.�&����[A�^��m����.��C��1A��:�}���r�(���i�������Y�T�t�:"������V3m4�'��`��rK�>����m#<M
e�4�I$�i�v���������p�aaa@����)UD�N��x��2T�V����x�3L�6�;4�$��]�>� 1L�wF�E��&g��p�,���\�.5$�o�E�E���Ik�j ���nF�d�	O��C��#�����H$�_xr0�G�Y�����w���&H"}h����oe��QT�eoz�OX#����}����A�vW9�u����-V��6���@tQd�2r�J�-�e$�
H(�!H"��)fh���RH�����f�A��t�k�U�L�1�(j�����(1��hC��qj�X�.{V�z>Z��>=������d�K��5�0�H��Jis{`��{a2�\�IY���ri��-��.iiq���6��Z5�P�����N����S,�Cicy\LKXL��O����Cz7�M*m��%6�Z/��UP(F�v��@X�gm��
U��4�
�+��IQF���(���.R&��������gZQ�[8:#�H�n��ixQ J-��!6=)��x�u?B$
�����c)i$hW$U�����Q���U7�!��b���
p�s�������!�1'��o��Tw��s�69����������	$�!/���j����5vAn<�O���4������Z����nq��k��o��
�������*�&G(������p��J�'��0|;&�����'��D n���ZH�"B����������#d
����.�(���0Mi�Mi�&�U�%���!@�$P��bdI��XQ��i%�+2cj��+!H�U�V"F������d���YT�&i���%��d��LS4"�nwh<�G�����*7���|�h�f?��W���=x�yww��NhK���*H����xD06���fI
��N�))iS9b�"���X��~��13�362��LDQDAQ$D3���#���=�J�����WC�k��A?0��C���	o�����yq��vq�`��t9y�B�p��^���#2�Z����~J��c��V�������	����hv��r�f"c����'�>*`se�iK%z9U��5�3��i�?���Jo���H6�A�T����K����7�4t	U��}���[c�F��D�Im�o���*I���0�'��'�}�����$v;����Oi�����K�;�E)Z������,�����A�5Af �����e�.Y����m�
j�Z�C�:�]'��G���Y�!$fG/���6o���������N�?djHG�p���R@���ex�o}�����Y����wZ����I,��1���-U��u�!�`n�S�Nj�	P�&bo����	�j��35I��v����Y��'��Z�U���),��
�Er�9��Nfn����\�����l�!dIU���!(� +�D*����- �G( 1�����,TDx� �4P
6���HL��c(S
�J��3��T��{����P���q�'F�p��$�z�:s�Y@��F�U��UQ~
�[�0��/�x����+`����t��R\*D�5���S�M�m��o���\�T��'���
,���|�9���e���{��7Y��E�V�M�^�8oP�8��d��kv[uC@��Z&�)����G
��1a!�n,�J���W�o�f|pv��^6��/�T�rI�ZBk�kB�����$#~
$g�k�t����Z�d���8��c�E�B���.�qi�[~���6���)lA��"���l
F1����F������Bi���a.��������V�p�M�JV���+�[�P��t����h��:�$��I�16M&��i6	6J�I�l�6V�i-�t�Y4��I�I�m&������d�Y4�I��I��$�Ou	������e�H$`�T�!@��eQ� P�%�X$�$�b$!�YI��H! �"X��!B�X�+h-&�i4�&��}��z���=#jm]���I���!!"��J�&����5N���F����qW�	�5%)��KI$����^<��@e*�����"}��K$���jP���#|�[���`|(pu�8�q��j������\K4_|����YH�UJ&�gL��8�yMeH��h�d1��������*`'Pi�LcW�S�\�2&]��y��{�Rn&��q��I�.��h���_n�t���4�I30�(��D�`(�L���-
��+la;�����\�h�CG5�B�\��hBUK�A��U]��`�����-�+C�m��Eh���B�z�b�v��r����*\;tV���[��/6k�T��%��rgn� �A]q!P���������K4t��[�%9��SU��#
��������Q*��i*����6�z�*����m�~Y~V���6\�#�����7�����S�z��[����������?E��*R:>�
���J%(�J��6����5|�Ip�(������ ��
����?�v5����~{O������;#��.�UwEV�^�Y��������3�N�?���1��<�E�!i�LA��X�~l�*}l�I����5����E�"�L*#�����u�����\(4���Z��D����ku(*O�^{�;t�m�*��xm����mSK
�^7�/$TU����!q\K0,��\�P����0^��rd�^d#��H�K�u�63%)N1�)�A0�� �AN���a'^��h
yf@� d� ����e@����d�o�d����y�m���o��������9�o��*����;OG���_4XG�U(d$=
r���EC��/��6�'���m�l���.���(j�*�b��T'<wws����v�lcw\�����s6P�TCA���r��N��kW:��T�d*���o����V*�����H5<����U����l����v�D�H����9���K��F�F�:� 
�b���+�2hc%�@P��f1������try��h��Bg������(T���
b�9�����#8�eDs,L�(,P�Q�D(IX(���F��R@$��=��Tx,�>��/��A����0?������5��9���G�^�������x�����������W���XlY(���������}B��'TMD����_��[�K���|]������X��b��B�N����(a�]&�B>�!� J���M�4h�g��T'�������H�kZ���c�����?q�BQM�Q=��a���������A���Z@�KzG�E����#�H��I6#�7"nH
=>��{z�O^p��8��M/Xb��F��t���D7�����v.��p?q�C�T�4�VF1�a�n���t��N�;���*m�')R����I��p����������� a�u� Y�{S����"��T�����y��4�C��@e����_F/8E@M�k����P�7f�_(�dM���-!�t*HZ���Z�T$X��	�DV� �"F$B	X�|LD���'e���t}��3����C����8>����F����}�U��4��1�NA4"�ZBsY���WcTa��W�����}�xF�������q���"d��NC����j��0��~!U:�<�Q�	�	E}]I$@�Bad�H]:!_���t��Q��h��$e��aKC�E�s�*W�n��TX�*�c_���P��oK��t���U�|fU�(����2feK�����0��%�b���<]��������A?�N��=��dR�]����EhD�D;�@��;�����QAF	�cj`6w�U�B�p}��-�P�e�'���nS���H$�q
�x�}��hm$O��zX'��M{$�����A=��)�V�0�'�B�=���zx�.h�7X'�$cqm2���K`��@@�)�\��M���h-��\Da������$��$^+330��Q4��
���H'�p���u_^;w�6�����o��&�|A?��t��R$O+��q�I����d�
x�)	zHL����
VC��o'N8�Z���W�$���*�|HD?����DI6�7c��������Hf#�H(�@���OBh�@{�"���V��]m���"�:�����p���I�;BxC�� |��` FE������J�Js�����~Hp=��
�2��v�e*��Sc��L��|�H����u���`��BA���H���~����� ��:����DI�d�J�3\@.�,@���w��YT�mjv���;���HJ�;(���n�g.���r�}����O����zs���zu���HH�TD=���yb4A�=%�%��m����AQ���I��
QJ��UE&�2I%YSe2v���ZMR��ZYJZJ@�-����e4�V���R�4h�h�jSF�M4h���������-JUe�������4h��ZM�i���N��YR��fCA�rH)��2���m������PtE?ugGE�I������_��i�.Y��j��
��}����!���4i�:�A�E��J�fE�����=sO��Z��C�� �t7�-X@��E�I$taM��{��mb?������+&����u��"OH��#�"�4�	D�F	
��E:c�'����&����m�9I	�.���6��:F�`�$��_;���/%�?L��|��G z�<��}�~���q��uz(��/�/O����D�AH��9!�$}ky�\��E��7DV�Uk�N�g��-�A&	��B"
�>�d��$�$\D����Y����:'��c�X�Z8a�yx����4*��#\<�G�a�oK�Q �f�]�H4[����@���^��/=�G������C��E�9	"�������������-bLL�JJ���2$
�4$#(��"����J�X�����
!�����)�����
q
&)%�c��R���p��a�i~�������mQr�#
Bj
���-b��Y�2e��\�i
9t�7��nJ���V�V�v�ck��`�#�E#���7�rF�:����P��@���`u����{�B�.[Gb��-���8��wM"�v�G�Z��DDA2�P+����x-���9Y�=�&���'��#�}�P���=��w;����>��������c�?��v5�� �c�)����~�PM��ev~q��� ��:��H�`�������p�1�jR�������T��6����v�mI�;#��(au��N��t	��*w()�Xg��\�� ���,p�5+�i���m�g).v�su1������a���Ypx�c��z���	�E�n{��e�X��IQ�7&�L�+T�
������#c��'�!����I��% ����Q��#�����4{>u�>W����)�v`��2g��B2>l7�Wl1�s#��j�3��N�jg�	n�)p_T� @����C��
�a��_�X����4Js����D�# (������ @?�������?X@�0i"�v~�>y��/��$�P9�"Cc����CWH����<�:�=�*�,�y�{��ooS�"z�e�r�d�~��J�$iq�@��Ag�Js��/k��H�P������*��G�J
�X"
<)e	��|Z��[���_e���t���\��2��F=)sG1����>i��&{���VAl�%���\#�~"�p}r�87I��*��������{��k=]��sFS	EE��g�u)�Y#���xUM��"���T�TT�����m��
��9e�A����-��c�$�W�?J�H��0"���?v��U������1+H*�	B"���@���?UO���������D��g����*�z��PHf��"�_��V2���A4��Rk�!���&X�A3����!$�&�
�6�?�\�h�%h#���O���1�F>�?J�Q�L���+�`���"NX�r��{q�jeA���-�J\@{}��q@�-���J���HA�/���:����j�b@z��uPv��E�2U]R��#�g�gv��C��
�|3*��E�~o��j���G��	�`��
��P`��H�A�� �����"h�H�~&�	��_>�C�r!�yT��k87!@��T�]�]�Z��#��H@�Lf��iM�4*	���N^���|>rc����Q��eR���{�$s�C�B��1���Sh�-���}���n��/;u�1���n�R�-<n�.{��h'v�c���-*���C5z��#���D�6�p��C&�l��M��������K�+��N�TW	R&���Q��<�$r�4O�Mv'�!��AdD=�w=��K��4���\o�� ��)��t��
qsI�1ca�,*�F�$�2bB� |'k�3Mf[�L�j�D"X��%�hMi�}�I_����Kn`��'�����`��p�8�r��d&�"�1
�1
�#',#��+<L�N[�,�����o0X�l�= !�]%�TX�?�������F�2�F�������r=j��!� [F4R���@-�CR�D���`��.������pfXHcW�k�t���i${������H]r���SH?IB�MC�H�P��,*L�������LZ��
11"�J%
�0TV�5�&�����M�+%�EJ�%��YR�d�S)T���-
���IC
$�!���@�����
$��L������"+,"0@D$�X�53Q���Kj+2U����aJEi��i6�e5VR�ek�����o�����O����b-#m��*D��R�k���,�1f�e�<{@$�;�B}���^��^b_R�4�v�Hj��
������#�4	��-+M*(i���v����=2�N��sd������
��U$!����,� ���9�H�H�E���U-���${y�	.���8Dq:����]���~?��4*��/���U$"�u���V���x���*�/�S�����W��!�vv���r�9D�}^8t����!"�,�M�o��\E�R��dH6��I���� ��N�@W��c����N�@>�T%��d�$�K�DoV������[���=���F����P!���kL;���%S)��'���� N���������&'ua������rC�'��>�9D���H�Dv�d����P��1����a����\�)*��%���l
Y��XL����G~l�������A����#�j�+(�R��!�q�%�����$5^��
���Q�K�,��������*�/�	=�7�z����6�C���a�1���I
x] b�� ���) �������BF�T� �2�Ij��O!����F��!�S��Uw<�C�p�
�+������\h��9���Jv�B�����L!0"vy����<#�8)�=�`���	H�8/��C����3"js�X�8'��%���D�Vss�`����;gy7��~�D���Z���T��KaN4���� %�1@Q
�&�l4��P��m���Pw�����4����v88�`�Dt��5�5P'B2I"H7N��������>�:.GE���orH����cc��DN�Op<>�f��vRAC�?$��r�'t!lCf�w��61@C{m���+��	J��59�NkH d7�����l~�u�2R�T���L��e�B�-�-���u<8�5^J��J����j
X�t����Z���J:����Wqm�T�����m-��������':�T���bOnN	V�nC�C.���1d��}Q����S]��KGa�	���@Lk�����U�������$��PDL��1�"��k, R��uex�����&>
�A+��~r(��G�y�4�U�_����w��$�0�BF����{������.4��#��X���d���Q5���R�X�Jt�.�L��)���\���`�8E	q�v�MA��o;Ut�ySM[���a4�4�P��U��r��]����]��B�PR�SN���Q%��#H�f������T!��>�&(���bD�7�W��MR�-��!�%'	���y�����4�g��^���,���qP#7��'�'��h�DGx�B�./���T_�����f��hI�*�6�������1a���C�O�H����Jq	����i7���m���R��z�H�* �a��"JB@D�AKU,)T{� �{H�|��N���Z �L�R�(�"b����2P��AXp����% >������$���a5�<B�����;t������Og��+G��O_3c�y���O��#�/������h�|���U�.'��������p!�I,D�������9/;�h����Q��F�n�n,�n�����u�m��R��9�93[h��*3l����k��mi5-x�#P��b���B�BE��"N��He�Z��!!)!�8J!� 9�B+���"f��w2@n�)$���6��.�n���X����/�w���x}:��m����-X�6(qA=i!�,��}2�J������z�3<����)������}�7��G���%[>>�������B"�����=-�^{�����b��}f��z	�����`�4���B��@���4Z%b��x�v9��9�%�g/�t�<E"q�P4M&�e����z��
��$���9��w�����`�.��a�RfHQb�|I�&
�������;�@"�(�&�` �UVbo���I�#��G��H�c�I��*��M*T~:Wo���������`	��jO�J�������T���T��=���E8H���T�����?�O���{
�"&��m�5��5\=^b������H#�D�jA-$��"�H�u��#��H���P�d�vB&L2zs{	�{�`�U�DY$���!Au����Q��"9��}�z���!(F'�L���n�,�e%������L�R��`\`Q��
P
�n�2VL�����X8nEx�&��@@�c��)H��J*Q�r}>i)��I$z<bG�'Nda;�&���>>�J���]�335-�F���^��Y�����s]�ED90�a�4����A}[�O�3��U|��O��G�KmGo����2�v������J5�*j2E
�v\��{'�����'���x �P�_=���^(wV!-K��M�ZVM]��R����pc��bG��.
�
�����N�s�Q��Ye.Rj*R�I���6���j6M��5�0�(!~�X�"3�DU�\$��I!�I����%29�D|���o�������L��R#����
�=D�)��;������ 1N�olNrN�>��!��$�%�@|�:�g���R$)D>�N�Rt��M:<?B�����?��?|x��D�1����[�y��1�������u  !FX`���N��LwK��v������VM����i����}�q����t=�aO�����LHD}6�����5A����E��r���]�J��%
��O����D;z�8�\a�wM�����~c��_�[l���q�����JnM�R@����`�.^=4}Ol�'�3�ko�o������CP�I��4�2S�2�����#�k����t��N������c�������X����<��=�3�b*��T�s���:����??Po��z���0�=�\���P�		X��~��$S�TN�u�?��c0y`��M%uc?������'�"F�c��A`�F'�
]}��1�J�hO�D=�&��I**v��!I&6��bxA��6&��!'J=t��T	����iP(n�aa
J� �
��:�}p��(��<��(�	$�$���$��� �	Edb,��&�SQ�kj���e ��	(�X��[�R[F����%	�%	��3�JR��&�R��0�J��h�Um�E \���������i[u+�*�K` �6�J0J��	Bi%6$��QD� �����)+)�@P�J���
(�)���0�*����ccl@j���J�4I�4��A(LI�n��*�]Z�a��6�	�A6�	��5	�J�:�Wj�v�6Ad4$��R��HP�����(L��k���&]T��X)	)v����Mb��MY��vkfN���b�&������P�
��&C8v���sm
"N���$��
Bit�v��Di����;3tVC��Ch@�I@��AU���|��=s����`����OT�����^��^���c,���q9��}�zH)6~�m��m�~�G-L�C�$J�7(t!�b�d#�/���{���Ts��G��q��I����t���E���#����)�������F��E~a���?�n8�1pv�������bFB�E�M�<������c�D�b���|_8��ph�}�)8�4��I�1�t����z
��\=3D�(�E-9��p}�����z=Z�D�����l*@|I�cvT���mk���KT��"�8�
�4��\�Ree�5[��4�!Jl������"v�
�7�`�Z�	�����
:BS�j���5�v��T�l&4m(D���M�g!(Z��I�^p�!�e@l���#�Z�5�Rb> �0�[XaL������g����o��
m!X�c���n�9jV��
8{V7O�a���������el�q�]�l�����h5���N����n3L������� db\�����6�'o`��6�U����Q�fYi	��Yv
�l�LV���T���b�nD�h\H��X��C�K5R�K��UCX���a���(;������LDT!�4A��\^�C{�����al]7����DxDs	��$�$�*�j:H!�(;C�������_A�^�DB&�"�BFX���=t��R
�Ya�����cU�*�$rv�����(0��<y#�bv]�����'gF�Z�~wx|G��F%tm`nx~>�~Ra���������5Z���
��g��O�t��&����QQ[���(Z�|}��~`K�OI'i*���pq���qX�.�w�k^�MI(�B�%�W^�������By��"�TJH�W����$�H�B���x���h
��U=;��0�����($2B���s�n=YEEE�{����{Id����?�R�OK�w������������������K�-[%�����G�I	#��������fTnE�#L������s=/���m�E�����_�I�T��b���\���p@FX���K��q�l�z��D}�"��JX�bW�~H�'�"jI8r��[����o{#,p���!��\�P�LD�u�%&�%�"X��~l��K%�&��`�3%�P��4�&�h%���$��Oy�)�x��j�"Z��G�y�_������F���t��I���_������y�g���=A��_<�vi%D<�U�PpSC"!�I2vZ "]��@�!)kNf�)�d[
���?A�g7�H�0���%&�����B&�)&E�Y�3
qm���4p8�*["BwN�~�#s$� ��1����F�*�;V��apkm�i8X`�o���%Q}S�����k��r�~T����ok{���QE`���=�xk|M�sXh��T��1	�$l�HB���~��6���g���$��c�!B������(�����$��A(�0�m\���1,�������ks��F���j�j�����Ts�J�^��?�fT�+��'�J��'����wy�TU�i6�^���v{�z���p&�}Y�y���B�dp���3s9hP,E��2�z*��g�����{���l����f�B�(����Oh�����B�p����E��h�IbJ�n�S��O��0�Y���/��+��Z��f��ZK�TK)H�&	��`&)0�R)U	$�"
@�CX���
��V\�)2��xv�o^'
4i�XEe�{�g(�bV'~H,��A$a�s2gD��JB�82�D&i�+���6uI����������\�6����	��rKq���-�Z��B�&t��!Q�z*�A|FQE)R{��YZ1�J�p�7<�"�[d�mQB�������L���'��r0D3{Il�3�b�F=%)�]Y	�CU�)�*$�H���4T���
=~h�!+�c����N
,<nY�����h\f�X�l�|[7$�<&��^�:_=�v��M����v
�����<k[M�L+�"lH9��[�}6d��Fy��y��^YWd�90��
\�IO4f�C�AUVP�|�?m�	%J�V?h��h��U��^uP���vA����
cd�j�����[4����G�m��"����*����=���d9(���
>��(��Gh"��>!��d��=w�t��#��:o�!�s���#���rp����"��T���c�-��5ZDi3�������jt�$�[���6M#x��TlC���kH����m�tp��Y����cG��1�$���u�P�����B�in��>�+fvBa��ss����M�v
 O�����r}��J<�@s��`���)�*>��=����_��(EZHQ��v���^���0��
Z��h�I���4���\>��y�HK���}=�t����3�hu��N�n��.��������E�uXP��#��k��sl_��)���m�~aD�R6�L% `n>F��A?{� ����_�����_'�
�����+>u@L~�����By�4�������h((�*�������l������)��=i-?}��C�R@����&"}�b�D�Y$�$�iP�Q��gu�����"�R,��iF}�j��0�RN����6�;+��z?6�������I�K
,+[����L)HD�S��O�c���=H�,$o�=�Y�vi��*�i�������RcO�>�&M�X3AN�\�Q?F:j'Am[n�C�)���m#�+[�n�M�J�����6d�04����;�������qj6����o�G��.
*���0t�;s3��<��_I�)m�����������)���6B��HF(f*��l��k6��&"C��D��x�%����4�����A0!���-��L�L��h c�D;��=d��������j���� ���~-S���C~�jAH,A�eYn=U�uW��1B���>n�����aD������K�+g���2���i!�(�m�Sa���	����;�������8��h;
{; ����4�P����� �M������=����_���B�����F�G�MC�hx��2�D��>�)��;���b�(%��1��l\;�M�A����""k[	����p�2�N�0�"bF=y9�n8���HU�k*c��{q�h8�|��"IY�E��A���R%���TH����n�.��}/��Z���K LM�v�9u��;|(����������,���'z��d���rvE��i�AD�x���^q,�.<�3�I"`s0o�G5���,,w�A�+�DF�k��}����|8pd&��r�i��:$�R1V��D��Q���<X�c�w��x!,'�8#�IpA���/+�3�Q�HhK}���Tv�mJT~.��#f^��S�B!b�P�^� �H
��R`9���E#z�d�7J�S���hKBkG��I�"-�T�
#� �TPH"�KJ�o��p������)f?s/W=yg�S����V������^+��	�Et� ?��\�PsuTk����<(����:Z�R4�F��$e�J�J����-rW=�t�C��n�O<��������P����;m����^�������[vAEbJ��g�f��7�����H�Hcx���&�"#m�]�mX��=5Z-���������0
������������q�Z��&�F���a���#-���XB.
$���!!+jaS}mM$�����g+,���J����NipIoI�Z�B;��W�<@&�wi��1�A&j$���P��D+.����+��u�g�7�`��azft�F-q-��=����cb�uM�*�H��h�M�fLK�\�S�&r���c+eE^�({l!� $ZT���=3~�L�7�*�
����dV�r���V�tf�7cM�R����VHm�a�m���8�sI�MH��uq�ok��%��29��$���#�Y$��t�'�Y��x��b�.&,�Rn�hM��d(��f
� ����������b�w�V�������P�������rIE����������$���;bD��&�)C����D�!�)cI� s�����q'�I5&;�8����p���T%E`�I���K)��T�u�&�\��@d����$�v���Dm���o�G�J�nT�*N$�4��n�d��58v;�M:�&:wuC�YRyD��OA��� ���u�m����I�:�6f�g���
����)�V��Z��2��jV�JSbSY[-R���M�����FE{��L�����u��*j�$89����z���K�3��'bn4�����x�T�.�;�s���~h���p��>E��#�6��G����|%AQfbB���-gn�'�*"Ab�(��-���y��I�x�A��	���[UD�@�60��2��)���"U���0�*��
j�b�d�UE���:������~���9�u	��������:X�tIWp���$�J*t�("'_�	&c�������F�7Q"���F�B������R}��|���s�O	,d;wu�=�$�$?Uj���HH�A��HT�c!_yh���
���g_����?�=��=~��d�I��C�����i�0�D�"Z�H����((&�@��n���/c�5�m�������?�� U+��k&����J���N��}��=	�
?B]}�Ui��]��M`;��IeZ	�Tm�)�J�?hZ�J!I`),��E,��(l��i- �%������{cq�V��.����h�s�C�C���z
����me�4�������	v�����z��8q�n��a!���\�������:UX�kA0#mDm����8;^�f��.����I�V��=~�ey��@��)A)Xd��*a��D�&RZ+�v�n�B����&j�)(�D��zn��u�B���)��7I������|*�BSL�F����>�N���
&�YFF��CHM,�,����@���H�����B@�X����v��L�D4HV n� T���/�G��e���<��9m���{��������(} ����)��`�-�X��|~^��u������Mx�O)L���@�S}�:�q����t>��Dz����+�K\$f}(�OC��(R)�pE($�DFV�V%'�������N�Pv��@#�lZ�\d��K]kJ0i�B�m{'��g�G	Z����E�L�?��]Q��8�IY�������avx��_F4�O����yO��������� ���5a��@��N�BaCU��M�%�p��%�~[8�DD\Q�4+�����8
h����Gs��iO��#�>>Z��UR�����Vj0.�"�n���3a����S���dz���!�������'���s�%��3�nb���M&����@�hBa�F�
����q��Tr
�� �
/���D�
�
�<����E��y�����|	��'�
k�����Q������o�������pp���PA"�(�r�$eY��R���k����k[Q���
�Z��V�5d$�"!!��Y~`����<.
B2���c�l��������|��?K�A�S�v)t���GA��!�-<1�|sQ���2A34��#vH�3�����B��m�����!�%�0C�V��V�N��b G��'�h������I	B����RJ�Uv���`�x}�;|�4:T�LD_����:���)�VR�P���#V*c���2	�=;u)IJFV+$�e�C%��Y��U�O��5n���E������r5�78����LN�X�#��K	�lm���zd�Li��I�h��l�QBJ2|L0(�P�����Q���<13m��=���������A�YX���$����l����H����0��Q $S���FSf�4��U��!�i"�_�y��@%�����C�H������>D`�{�iS�}5���.0�|
;��T;�MwY ���=r��b@�C�#b@��c�����&*��$�������~���h�T5�Q����'�I��DH�� �Y��<���
T'�.Kd$D}/�/�{5�����+��Y\��ei�Ei��^�R�����
�������h+!��o*��-~�W_�UU;*����c*�'�3w0��%�|y71�mT��P�p3�XW���4��AV(������U�*����}��p�}��8@U*U�Q��SYqp`�l�� �I^��.�� �K]�GI��@��K,�����������y5�a�$�����>�}�&�N,��X�S�8�9n���1�r��gn}t3�����c����F�dA�;i6���n�5�������^���3���vfyM!`�9ZSg6�0um`0��g���C�rM#�~J\fQ(Q)K4P����<�&��`�S��
�Q�h6]������7'���(t�$LT�&�0����K�e����N3�Rq����M���b��L������S��`������������A=��z|{�^�$��G��)@�F����=�RC���if���pWt�d����f�t|�Us���e����>v�e�>^;��$�r��Y���r({���8�_j�[�F��6��O��`����nxa����/���d�[�Oj������5}�n�����@;'���N@P�w�e*zpW�G�������b����wwd�l������������zid�����|��P� W�5�4)@� I&L�q�R�UP)B�Ztd�j��P����
�E)���u T��!"@A	�Fj �b�jdL�z�z�d�F�S���0�
4�e)	M��
�
��(�j�)��j
�i��4���=OQ6R(��Q��CCLF�4�h��RRBh&#)�F����������j<=����-||+0k���1�i%�U�a�s�P}���������~k�^�����z/A����z/A����z/A���Z��.���m���@�F�m�A1R�����r����y~��_��������A-������,r$`�i�L�������$}���?�B���?��(y��Ta��s�7��L���� ��������2D��5���%��.@s>�C
�r����3�.@yI,t+�H�}������~������=0m���\���	x{5�~��r������.e��9��h���m}`� i�n�����X�����������d
�/�h�H+�4cz�t�:����Y��������|��{���1� �u��m��c����������<��z��������+�~+�����|�W5clUE&�IV5��[kO����\�|*_�Db)H�r�"�FSG�E�����m��_���	�Y����s�}x7�9C4\�q�[�=�pZ�TY�wM����}6����i"H�\)BHo<�CT�9��T��'�\�+���%���	6�m�1�R���W�r� ���`��x���X%.Q����!d�x�	I���8U:���A��3�g7�~hm�iD%�u��^�AM`	�,���[cU
����!�$�`�g�x���@Y�&�eBF)��Y��h�2��7�x������[��U��h���P����������fw�TMk.gp&�B�SQu5 ��-��@Z�b���[&O^I�@\/�����|�J%_|me8$2���{�+�,���(����*�~�Npp�3�������Lx��9='NN��99(`�M�d��`*Zm�P�%@%��r�Y+r�m���Q+%	��WL��J��/.����{�:��2^x)�T|��L������S+�C*���Y�uD"�h�(�Ic����{��7��f��d��0����XHB�c��
�TT��	�:OM��P
5��H��?��"eYF�!�����w�y�}�������
��GF����x�}z���@]j��e�#�]��-Q�BTB��x�N�"���Oh�W�@�:����0��x�F/���j��B���0�.�X2�������<���wT���H��,�R��-J&2h�=,��?/%oJ��V�B�\�(���o����AA9'B��gO����[�����D��_$�I�eG>M�����C�.���������O���_F�xo{G�?W���U��i����_||�W����d1Z��-4��t���CH|�o����)J!�X~�^��T�E�*����������n�%y��e��
�&�"�$��\lp��<l0��}��e��t���)�P��#HhhJ�i$������O�7Ct��.�N��	�����M}�O>5�^�e�,�ib.����(��������N�}�����8��x+��N���N�awb��
�"�����U���I@�Ez�� �Ju���N�r+�O��q�bO�������n|�N�m,i���'�p����'�=�j�@�B�����0�I$.p��=�/�$�I8Y��*����9�24���KB����,�D��& r��m��P������I$���4�J�U\���F�(��|X�h|�y��+��������[���]!����2����)��og�������coqV]!�!v�*1|�����%#_��A�GE���};o6C���(��M7����Zi�e�t{ZcE�-Y�����	����Q��J�%��%�&�T���2�`�i�;4������X~���Uw��]�{a��Z�jS��R������YBWN�IJ������}����*�|�^i0b<��/qm$�2U��=NM������f�~��Ye�X�(�1����1�1�l�b�Y�T���e���b��i�b��i��M4�F���$�UJ��t��$��Wk�������$��Z����S1m&J��?�o��n��-�>w��������~Dz�]q�\Hx�'Z�~�#������~bGs�<���������f\�������C�0l!6��M���������U������p���5GaZ������	i��'�DQX�R���`�v�M%��������N���	������z���gLK�q,M������=����'������K���3�\�'L�5/�W���}��W��1���e�r�o�M��6��A`���Q~����h_��Wx
*��-��b(��k�I	��jJh|�IP��Z,BR�1:�$�F��E����U���@����(����zC�zol�d��[z�u:�����>8
�*rH��%���4$�V����A��>��>!����s��'���* -	�!V%|�0�%���DT	Z�C�:z0�Q�k@�VP��C���<G���zq���
>�s�����@�<�{YY1�bh�QBBV�k�����������4��>��~��U�|���e���Z:�oo���_3��E�:d�����N�N,/3�b���:B_Q�b���
z���20��!
���K�pD6�}��&6�m1�7��A�i"f�p�a77�x��N�_���?��/�5���S�M�+���{A�m�m��#����2%�M���ZL�d��i�I�Rd�4����ZI,�%�$���&�JR�$�Ye�������M����#FB�������b2R�^m�������r,�w�q��������f��t�]:\��G8�(��
sU�S����'G�)��v��8-b{2:�I�4�����x2��m��MiqpM2��8�� �cgms�~r���(�0���^x�(�]����{g%GF����+lM�H�,0DIl�um�j��t��0;�wt�,�r��t�����s��M1�H��"�A 5F��f�������5�k���4m�$j6M���e��N�;�Im!S5�D���#0�\�Y�E0	��T�nns�"6wo&���/;t�6��%d��N�&p��r��v�[�F�5D�J�E����.��be�n���~k�xWU����+����IE��*+�
i\��B�D�E:��d�)N2��f���ViF0��X��X��2j��&e4�&���W�������Q���u{b��B���.���I�|E�|�����������?�LdM_�s���Y����z9�!	������!�>	a:��)$8N��*��EW��kr}[�{RI�RjL��$�)*M"Ra$�d�I$��%��RI���&J��$���$��(������Gj����e�(N�4����|
Y{��q�"l��$ 	�!5��\1��{[R��*�I�"f��!�JeUb;I�,���+��v�k�NH�@�|j>\K�[�r�duX��i:�U:;kj��V�t���>�C�3����GN.���.�Q����.�.H�'CrW�Z�6������d�L�*Wft:Re���.�W�\]��1-��6GI��v<t>���d���3���>n�m��Z����vW[c]�*��tYc�NN��U�N�c�#�pt��psN*h�B���6*�.���dc�rX��gU����e1�]�N����E��KIb�-kY��������Ig
GwE�}�+�T��������c5/�|�4QBDP
�[g#D�o��C;�\iI���&�s	\����u���z����������u
�d~����C�[uR�o���L�����A��_��m�uSW6,��^����q���(���ysO,����&n��{mk���c����J�g��������;{�G��u��.��?���7a��]�4�aO5�����I��yy%=���x�66�:j��k*U�����@3l0�����2������c�ri���79�p�/D��\>�����/1��������p��u5n%W2�?_���y8��?,�����TaC�c�[���D������I$�<��P=���S�U
�C�W�����UL���Q���?���{|�������]��)��� �p�L�����!d�PX�=�P4��h�DDF��?eW�5H$4�@h�1j�$�D%�/��o��-�U���5Z�Q��b�F��1I[H��f����Z4��!���I�(���������QjL�[`4ED������_�������~�����<36��^���%��b���;��-�-$������Ki�wRIw� �����7�G��H�9����;���u�������8Kz]��{������z�C~��.9'U,I�!��]�I\��D�i^]�I{/c�i����$���B��8GidJZD���c��Yi]�Y!WN���zI-�c�0,��L��A
	!t�
����G���f6;N]f$�+I+zb���vw��Ne���Q{�m�o=�+.�w�l�/u]����8�^-$&!%C`���l�����&��72����I�B�X��=����KvKQU�g[H�����I���wi��sy�8�nG!�m.�y��&��.�gxE'���[���K�HIR���o�%��0�Oe�[��D+���M���6���m�%oF!fI#����Y��H�tV*j�4���C�6���=&I%�,rz���Lr^�K@���z��2�������lv���RQ$�Rv��n#{��J�r�P�I+{�'�W=���~n�lV]�����^�����Tv��5yS�����o��7M�t��*�kZ�������=~��y��5� �@4�!N����^�U�&�B
w�h�AA*�k@	������T0(�3����|����R�4�&�#l���xb�}�u+��%z<�C��']U�9tU>������*������S6D�1E�%�d����o���fUD�H��vW�.2�\o-������+������������&1 lE�vXue�Z���h��"I#
@���*��W8���[���s�P�"�'M�_x�5Da!SC�&Q�b�M�E��'{�suf7k�6����)��������������E��2��"��VR�MlH��l[j�1Q�bX���Y4�TQ�hL����b�aM��J�k��Rc4�H2��)f�����Lk�"D�h�D(��5��U��;�e��r�����J"Y�I����E��,md}�7�`��v�N�wx^��333xq�7-��er��i$H*���#�qun���De��[M��I#lEJ�gd����I$m����$�H��F1�� ��F1���6�:t��I*T�RF��6�rI$�I��U��Ba��]/���b�84�1��Lp��c��g�;$��$Y$k�����4�!*�'8��(1�
�D$��F���9)��z!om�hCm�hGbX�A���{����Q��O�8��F���{msF��F�E����],c%�{SM*��b�U�D��M�t��6���1s\�������x�^��k�z���i'Tt4���p��M6:
Q`�,$��L.a1�f��%C.$�B���9�%F	���)���=�-�^{��vz��^\�r��U�W-["����{����{/�#�����R��{���sz����R�� ��84��^B�${��%�c��A9s�������J�-
���e��������@C������\����D`�
��B�D(�(�Q�]�9s����� QE�B�Y�h�FHeaZ"��UY%Eh�NE�����N��T���"��UV��n��W,AdB������S�$QE���ZG"B�@:��v��p�9�����@�������TV�UVeU���U�_"|��UV���Qr�+DQ
�B��E.\;���u��t.��A��u�����h��!VE�QZ%UEV��D�*(�QT�wB]�F9�9�:�}~��8�Q�Q���P�C�M���jR�|��|7�R�6��� jP��4BIe�XmS^=�<6����V�2�����[���U�������i�fP�Z��/Yh�J(�������v=y�}F���-�1j��N\RQEA�t�08e9P�����<���4�
��n���"7&�$��S����4$�g��r���i���W�%�I�7GVu���Z��������Wi%%EGn�����c6�L��n�d�\n����T�P������"�DF[<q��<�Q$�Bk�BV;���-TU�n4�NEnZM>
@�$Gf��0�2u�����+���)2b3$`�����R��EWR�x������k��m���9��9���%��V2���O��������6y��}�c�?a[l�f�]����^��;�9��d:�����-Db}�Z���O��o�^
�Z7�N�[��%�):�ZBB
�Bq���F�<�l��9��$U�G&3����/�B1!$��#?~L��3B�#M�NQ�jLG���x���6�o�)J�xf���Z����������*�
`5�mf��[U���U��QN�vN�~{�U=�d3If�J��)�cF���&j6�SJ�b����lS2Y��,3�R��X�J,��,e��X�������"�PR�%1IE&)1IK-,�E�Rb����L��b�L���&(��l��1���~����$9��n0u����6��il�&�"��Q"�f���M�j��������AT�M��i�%RT��Eh�&�)56�4�B�Zj�E�Kf�ka��$��Z�X���J ��&*F�-$lI��&,���""1���Yd�U������e5R���F������n��n���H���z{&��V[6[2�e��Z-��4�3R�d�i���cV�d�Dz^���V�1f�3I6��Y�����-����jf&df���UA_����L����%�a8�s���f�3���O������;���������n1�:����;���w�6���s�w�}��^��g����b���H��,������E�s������{������m�F�qf�7�=�r.s��.E*!#.���j���nf<jrA!�J	�"G7�m�����%��fg.�����ww���C=������a�'��rH��V�
�v� xx�C6�2b�I���CznlL�n�z�o������w��I	<�n���kc�uq!R�y;�\�y���w.�Kj��_��O����r5��BI����NI��w333�.��HI�6����{��R���I!�-���S��[:$��[��&����zI �K�-���������������V$��V��s��
����X r
�k�4c�7#��AUp��p�����r��5�s"��s#���s�0H@x$ ��x
�
���k	� �KPn������6JR�V�����``��������d��"�Te�
�&\��s��(RR�2�P����7���>�����'Jt�����K[���_������"S�9_r�����"':?5�tJt���?�m0������p�iK�n���p��i����<�kY�t���7n��~��o�R��8��w)���w����z������d�9��a��^��R�V"0��������������N������}�KO�}kJ>�Z����<��\�������xzs������K�<���j��\���������gN�2�����^�:���y�\v���h�j�������������.�w��N�t�
�x����,���n��m�Z�j�m�������}2m���iM4�i��i��[og)l��g>|�����y�ffhx���kZ���z����ny��zQ������.\�r��<��9����Z����V�Z�c���M4��8����Y��e�skY�aO�������1��cF�7F}���`���)���ye|�k�DV��u��m��x�NL��]��;���,��m��F#Dm|�����!�6p�q��p�ap��\�������:Wz���rS���gc!����(����|�� ����9YZ�WyS���$�(���q�gm��{�`�%�a���a��K�������EW�������WmYk��0�a��K��	���(�������V�^���\�����`��7�G�K"]���c�es6l���`����hu��r����d0�%��c�hs((�M��m�;��{��
�QB����k��z��Eo
�����e���N����P�
���*���\N�kN�K��d�<:��e���N�w�
{���QE
��d7����9�������������e���N����P�
���*6T���\N�kN�G3f��g�7�s^<
=e���"�: �
���S@�T��|�5��6��k��Z�i�|�j���bf����t�r�A�
e��xN�V���\�������\
5�>�:}:DO������]e�okw[�{nE�f���/���.���N�;�9�6ll��9:Z��@Dh�g���I�gk�t��p��;g��<����i��gw�"y��e����k.��:�gkZ�.b��|���aF���O�H�p��K��aH)�0���GS&��66N�.N����h�I�@Bz&��������QN����Q���8}�@��og���!�EEEEB�A�l��
�;G|�S��f�a�y8�4]���?s�^�T�O8S���p�;Q�Z���d�U��2k6+5�3�	���B�XM25��Fh�QOQ����5F5�T�T��m�kli�5�6�2��c����Q�CL
i-s�s�����(�J�������M6(��b1�����M&4Rb(������I��&)�fMd�F,i�ie)��i6I)5���U4�m4�i��I�h�d�I�h����3h�cfM���Rb,��I5e4���R�m�kJS4�j6��1DE&��4I��E&�M&�M�2E�3&���6f�,i�����I�I�Mfb�Jb6�����2h�M3F��I�h���&��6Mi$��&�M&M$��II��X�#?�����$W�s�A~��|�K����TS��+,�eY�C�����Sci���i~�q����|6Xd�<��Xrg��]���%L�YubE�Q���`�
8r�D#"T��QUB�C��@s�,�.������w����j#x$��b���T�S�V0��:tl�
6M��Hl���j���m�<��{?%j����M5&�QbI4m3L�eF�,��2��$��F�3fd�`�%4dXA4�)MIf�6���I�&Qfd�#�4�I�S)4Y�S$��Z�l��}���!�?���)�T@���I�o���:Rt���`��������I#�{?e��ew���s��E��w33{o�������n1�I?[���%�A��"���l�[$:6�UZ�@����E�9����	3���P��R�0���_��6>�|���K��������d�!��a��Y��T�0���^K�!X?B�����9��C�qM� �0�0Yn5����ho�n��b0�p1�\�5��=py=��<��s���fS`��W�W$�JKrn�Q��,��H�3��&�}��[L����V�_�1����alS�js.h�y��{��c�q�B�5N�a���9+��,��V����( Aa��A��6,"8��q%���U�I�";b�IP�t���&���.!�!6�&X�a�A!d�`�BR��� '(@$���DvB5e��r"a�������I��e5�$D�:Ma�2��e�4�9(����l�.	�\�����7:������������:���YO����l�x��%�'Sx}��2bw�DB�bK��]8��(�'�ze�8��Ua����%�_�T�G�}����
��u`x���#�����������>��|��{}�Az�/N�b�����KD��H�-*;1~��������r����~�#�to:��:��TZGWg��W����;�X���O+5���l�$��r%���l�����j}��+�J�j�o#�����	l����/R��d��W+����Va{�4�;�6O��_�6�	X>BA�g���+��_����bwsRc���������a����a���E'���+��q�t�SpAH���d�����������0�od��!���%�<�j��+=�h���"�LEr�����a�uU���u��Y�l/�q���W�Y�=��L�}BB��b���4�� A=UO#�G�����O������r��'���=J����r�~��g��@���aR\��\�J��U'�x���]��,����t��4#�$��?�����c����O����M���)&�2�0�[R�?D?���=�4�me���t_5�G���G��W������6l��(�*�S��=���r�m��*�r�lj�d�f�il�j�6��2.jd3&�c����t�q���9���D`QpNVK]u��6���]��;������]�_�/��!�����^���z�����T���&7��V�~�I�w,'VZ��A�H���RG*��)6!q���H��Q6q��	+59�8� {�H�E�G���@
��L���m��XC��RAv[(���e�JD&&�T�D\�kk-�8���VLT�u��NTJ/��Ogz��Q�rO+�y������c��QqfsB������KwbQ�)���I��(�w�b����'<�wt�����c��i�����=�����J��oV������(�d���0IJ��e�����u�}�!��&���n��;@5�j
�]�W_�oV����aZ�e��F��5m	0M���YY����#t���\�k���*R�LRDd��(����Qd��E�ISIQ2*RQ(�!(3)$H��$�e4T��4�Q*m�I$��ZM2H��H���id���I#$�IZC; �������������m�a:��;�NS,�
N�5��%\�Lg�����90[�����W����6��4C�� ��,�-�K���v������y��c�Gm��`�^{��#%	O:���Z5�q%�q�Wh����)&HH�����-��c'�����<����Y�F)��l�u�[�E�^r�W��q���r��=<'qLZ;�"C���l8��j�h���Q�z=���  ���{�/���Wm��F
�����M��S����Z0X"��c(��h�F�*�Zd�`6��T`�F��Q��-��[M���QZ���-~;����m��h��R���2��d�Re�$��[^KU�[C1�\6��JI$���A�Y�a��Fk@�7k[���Bv��k�\W,��]lN��$��YJi�)3�MAW���U������f��Dr�q�q\���4�^�Y�`��CS"j��kSW3	3L �MT�L��0�4�,���kcj�m�L�M4K��F�-S4�I�Zd��Q�h��i��a$�J5�
�����Fh�5��I$�M���2M�l��d��4��d:�X�m�]k�]�2�[cQd)����V��JBBKKL�	��4��5����_ff��U}^���5�Gn����=����W3.f'�:x/�#b ������EI������RKI�
�i���f���I:g�/<�����������|s@���t���-�y��UW����}�\�j9}����e��(�*�����Jx��e7Ue%�N��IW�^�:N��$�Bi���M���	� u���KJ�����"�pY*�����]] .��w*P�T]�"S��MR����	o7�q��?,G���'�����9Y��h?{�E�d�.o"�F��P[%YG��\������#�����I��9DA��7��.=p����C�{��/���'I�-QT*�j�}���*���J�i�V�����B�f�b33+i�I���I�#J�R�Md�5������}�iiJlf$�
F�KL����kkl���5�11��R�����h�4[3TY�%�Z�T��I�e����jRi�FJL���A�JI�M����$����L2@)I(*R��6��8��9����j���Sm3Ai	�fbS11���o������NI���um����Y�ISge�R[$�a������v�j��Y�����s���0�m-hl+ZV��>"/���7�^��
��9����.���� k}�����9Jl�1��lbdI �"H�"H�	$�����-A��6��hG`�W��wF����O}���<�-*2$� ���C����Up�/�dH�f���QAw/68?.S�VI?I�Kmi�p$!�m�K��W�m����(���S`Z���R�H��ie4����$��f�f��l�R���`L�L�B�6L�������B[��a��C$�N6��w#j��U����<����Nu�:����[�����k��IM�I$�H� i(iP�����5�hTDTEDr(������_���~R
I��jp�&P'f��jA������W���"�P��"��z������UG������X�WW/#4�$�'<miUUn{Hrg�0�7��Q�%K��S)S�d@�A�U�p�	%"�\��x��}��7�h�~�ff��`/aQ&��nM�;r'I�G;&O
�
o����r���Y�=����Fz�8^�96��&}w�w�W�!4b��Uo��y�@y�����c`�����Y�rAn�.�'8��n�d�9����(�1�D]-�r��u�v� �
�"�7u��pI���I�����5\��$�I$��I%$�7wW#�o%:��U����s�-�n�-�D������QA�R�+`�/����A��,��Ex��/\��b�*�y��^��mF�qSZ�����K%�3*j����(�E(��(���x���-uHA|�x��HI4�24<�s7��Y�����"�\����y��*��X@���qU			<E�����je��%�t�(s�N������G^y��v �����s�:[�	%��j�c�8xc�tw�|��[�a2���p�p�s�q��8mL��& �Z;A�����U�g"��$�F�.���HDB-�����%��g�;������W���
en�9�U�+��yB������wqE��,Q�
�-�{?�O��p[������"zU1Wm�U:N�t���^�u�4��~*����F�����Ke����y$��RI%(J�M4�SI�&�������u�B��L4�L��y���R
2J��S��c�Uun;�b�s��8���'�xzG�B_,��<�����m|������g7i�\��~�7������y��f��g	�fVl������[�ckSfKB��j��kE
�+Iy5��*X�%����M��F�t��hs����B���p����x��}^{��]H�wn��� �d����0[mnN��pZq��[�2
,������t�*$T���Wt:Q���#����W��^���������b)8��WE��e�/��s-QUEEAD��
`��i2j7wu��61��/�=�GN_={���)x��}�e6�����'2s9�i�(�e6Q��K��](�Eh��(�~���R`�l� ���4�������.���� 3|��y����A
4�$�Qw*^�*(�����`U�C�\��������;v�����y������gE�&u��6���	�ifK���v��g;�rp�p�N��y!���	K�n�H�����5z�/mm~
�y}5~E�m�_?"/���E5��E��m����=�(QE
L�}��X�<�y-<����J�"��J�["��YuF�\���1H��>sxt�+JU_�E%I�
C�!	���<I�Wj������^�%���Lk+|����-W]�kWR��I&��I ��$�U-$�mJ�l�K^s��"����W;


C�:^��8x�J�*P��TQF�k�o���W�7�}��J������l�1fZR�Y�RmA�T����2Z4cb�1b���EI��-�����������W���f��@|0������Ev3�1������V�)������?�#]�/&�B�B-�Zi&���\�n��"�H$3$�6�R�l����	����a����be��O/[�yD�t��#`).����s:k�H����������k��}���+a(j,�czd��$�U|�4���D��\�Gh��tw�W������J7v�R���WrZ��_�]m��+�Iq�SP�������0���N�}^yz�{��^����S|��C>2��mRI-j��NY
K2VQd2��%IX@4�*���]�X����B�% �d���y�d$ @�@�	�2��WRq8�a�2�2d�,����,�X�2d��L�Z2�eb��8�YY�!���x��-�)�#\�I���JQ��U������>T�hN5��:������+�y��U�n���M��G�c�v8|�P�2V�9�������$/��
��\�n��#�FY��w\2�T^����0Zc��go#�����!"�C$��-1���1�.V����"�G
���-������@�'{X�DN�hC���
=�l'��Y3�9^&�zP����ot-�32�K���
��������'z&Tc1�����������fY�/X���G��(?[����L���wSi�(-]�	����m�t���p+��m��J�Q�*�TN�ZU4����Z(�0T���YFfd*
�g{����8A��IT6�II��kAR������N��n)���^\�3$������z������R�*b���S/r���y�`.��s��,g+�c��C�BDB$	��>/�o�<�Y� �1�B��1�C1!d�` 0A��16���5,=�y�y�c���kggg��ZH�O�����	>��U��}���i2y.��t�/!���' ��G�����W��{��n��Sf�Z���@�W��\m���wn�B�����Y\��9]��V]n����:�x����w.����G]���Yc������-HBe�d��	Db�1�\�HC�a����i3
c���c�i��cp��c�P�c*�"\$.��]��	S%r�n�(��{��9���>c��Q�2�7�o;��9i���;��������'wZ����7w.Z���'��f,�wx_x���y�v�,����8����g���������3��'5��n'�����{���t���{}�I��w���w��s�>�{����v�w���Y����\���&�;�n���o7�v���7���tg'{��^����>���{�����]�V�E|�kfU�����������q�$�]����k��.\]�o�k/uw]�&����9y���f^Y�{7w����X�&f���9��W���������nE3�!�B�!mv�3�������Oz������H�>�9�/����l��%��}x.������%xY������,\��e���[H�fZy����.����37$���&���VE"H��wV�$�$����y���^��(�Q���������qO�`��e�������9��f���j��u���$":���[�^X�NT�E�S��x!G����aPX����|��.���-�8��t�$��o��9f���m]���p���[��jE,l����7
v����^��vn�i�)���0�B>[��^�������J��5��%�K;aya9�8qEIgZEs�������C������c��c��+!-��!�(IIEm\%�c�R$g�f�Uj���[����ci""����k2K���������������B�A2��d�HX�v���fDh�P�mo;u�`���i����B�zpVAS��"�:�,�$�!����5&���#v�+�����U�m�0�j���VH>]Yv3r��2f�Wd�����j�W��"�T��Xtc4�x�B��� d>��H� ���������0�+>��/������O>UG��Q�������$�wm3-<�Q��$��&A&�^n^�x�|��x�����9]�M�Q���]��.H�.I���F�K��u�Qn�eDZ�Om���Wp-w������CCFr����iyts���=r�F ���q��1cq��Z�����*��s�����t�����1�0��I	��RX�TJ��D58f`*��c	_'6���aH�@���v���`�FVV(�6���u�n�`YXU�����q�X�U�w� 6�j���-y:����W:��Fd��j��b-�h�}T;Z��Y���Z$�>"@@����P�����������2���z�����8��6�"B�X���k���V��rz�_��a��t�!�e�@`���wF\�LJ�F�_J��rs�/�����
.D.��p.��VU�i����:�rWB���X����FV���7g;9�~��8�_B���aK*����S +�O`�����x8?���~�#[�8��O�G~�O{�?V[
�i��Xl��L���"���u��r����+�������c�O��u�s�����������������>���?E_�w\��Jv���W������{�����Z��76�}��W���}�
V������~{�*���������s�\�{+������x�^N��F/�e.�����G����a�����K��2�p�O�����B���Oi�5_����mD�{� {�"��)���)�O��A�>U{�)~�������;�jA���.������^�6N��)v�U�������1�=[}��{_���3R� H��o������m����H�L~�
�?���"���*=Oz/�uQ��$S���TZ�$�%-/<$D�I��M"R�t�U�#��5�-2����a1����0�ji�cQ�F���h�1���j�l�f�SZm�A��)��a�e,h��j�Mdh�f4c�[R�F��8�8�$^�G���� ����p����;v�@�0��$�i214����j���ad����T3L��52l1a3K)�e1�����������
�T��L
�&����6��Vc2�-M%����[u�AS2j��'&MF���2Q����%��M�iT�eh���,���cc4��������4�X�+SK�p�Zd�ce�Z����--s'4����d��L����+�L�F�FL��Eq����L�rekT�-+���&Ee�l��y@�`+�Uy�]�jZ�"r������rYH>����Tv_��GA"��'�'�<�e�lm6������Q�(�4Q���f��Ml�E�L�d���4lmf�3����F������G��(��Bv����{p���+{_)I|���%@y�r`���W�)�Wii�S#3��Z�gZ$�G�!*�~��*�+�UWk����z�A�T��:�o^���;�|�5R)����z�G�OiMe5�f
�������&�5�LU32����-ZC,+�kD�fS5,��eZ����6�0k��%Z�M��Y�-4�W%Q08SSZ�r�\W������dh@��+ix�)����D�Q8�8G�+=�_% ����~�p�l�+��W��i�qKp51���Z���R����$��_1�F�1��c��s��|��l���(z��O1�Q'�c����!O_�S�\G�!?�����Qt3��pTl���y=��_�	�=]��/�;:�;�u"����SE�j4h��d�����Y�5�e�i�%�+�h�J��/d�F���D:��#�����Q���������F�D���
K	ZiI�4L�����������:���5���fj.��U*�r'S��]z��w;XdN���>�jP���#��ZI��k
�E�2�d�lj1�6�b�1f�
�*���i���j����jf�4�a��%��Zd�����1Z��R�����j�S4FM-F���2�,��0�iXl`a�����6�K5��fL�M��Y��611�2�L���VL��MFii��FIh�20�12l�Y� ���VR���{$��~�>���[�q�H��y|�f�6m�xe'�����I�;IG���=�_������oU����@���=S��^����{P{h�O��������KA�V0�A��c(i�e�*`����h�[m~y��X���d�Q��VCl�2X�b�
���,�^��d�R���f���-qhEe`�)FlVYaIe`�Q%�s%���m�����M2��*V����46��(�8��33h���-U\#
���U�H�Gr�������dhI&�T�T1?��^"�ci�n�����{kTh���Z���}��������E)l���T��R�#&l�����+H��ej��FSE��l���`�2�,�,d���,��c0�XY��L�MCf��e�d�P�,�����ab�����b��L���(��-d��f�Y[)X���i������b8L�rG�<��vx���2l�bM	BBTi���jI���X��RX��QS5����[$���*5��X�u���.[f�5��qK����zv���G���~���C�����K\�n�rVe/���N��EO���:����	Mt�'������^�vp���b��w~�k>y�������xD��iRp��"����;^�P��
!w)^d�Et�|%���P:4~\vQ���1�3(�����YdY��iR�V���Y��I�CF�Z�X����Ei��V������i�fK0��VL_��B:{���4������J>4�T>;��r6R�fG���]yG���g���%�>�)��T��X��>���;z�)T������^��=�A�EQ��.���/mYR9>?���%$i~H��%R����wW���_S�c�<�����x&�?�*�����A�Z�	~���Z�F�V�VQ���(�D�CV����CV���M���f���M6Se��e�e�M��ZX?3�s���f�U�����l�:]�.���E�)f�������`�1mKIaK ���C���P��6��X��R.+!�?Z���gtt�����J$���X�������]����TY~t�}���R��*�L�.�{�I��NU���k���
H�P>�:����7z~���8}w���?q�c�R+�O���R����JKJZI���L��,�Va�
l>���|�Wa���z=V��������}~>��T|mO'�����;����B��� 4G���#HB[
M�=so��� �����:����sUTfB��>N=��=Z(������|_Y_�O�/�t?�_j�>���BNU�����y:~B�^�$�����TW)Js��cD�����������:�U��1e^���N�xIR��uD�?ZC���\?�xC��>o�����F4,���6c5��S5�d���Vh���6(������U�Sf�,�U�Y�Q�J��f*��23,lc4�6jUf?Q�_��G'2pJ�������#���G�7�����OJ�w}�G�n��D���%����[��G�E��h�I/^����fi�fm36
�,[a�|��tq8��?r�eU�o��z^&��Uyh�|$��>�@����t��N��"�px.���:�]bJ?8>o*��(���:T����y�HUZ���v�d����*S�QyO��G��7��s��PI��G���Vx)/:	w������\���iy�="���d�y����Z=��N��5<J��n��c����RpjFt9r~���]�B�)	�T��R�E�;��h�_]���*�NTs�z�yXf�)���'�)��Wc�I�)O��Ew�{g�;�����?�������\eWbn�<�9I]|.�*Y$Jv���(G���;����'xW�~0'���IW�����W/v��b���&_k."�_���j�/mS��c��*Cz��|�!��h�K����b4��R5Y2���h�S ���#�`���I�1Vh�
E�4��i1,�D�
K|�kcc-��3D�fPDe2�.����\T��12��D�i���mv������$����l��N�ph�5S���6�h�1p��
���EKCv�-U���R��qll-d�e�5#�j�0�r�$��p�1�#%�if,��,�����V���V�����36�m*6K0����Rf	��T��QbKa�)��p����X��3HJGmYj���c[�kH�+����Yild3Um3	����L�(��$Qd����j�����,�R��ZNM FUjD\����}���J�D�X<�O��z��ES�_7�(�r%<y��7U��IX����S���]���V�S$�v�9t.�\�')z9
w����^�8U;��Tw�r��������v�1I{�xRr;��TC�S�r��A�|
>�;�f�>����d�3��C"5MVY�ea�V��SJ�1`���U����#��x��������<T����]t�#��_4T�z;@��g�E^�~U�?��{�{�l}E�=��}!\�� �|�IP;; >8�HL:4J~�)����c�i]���%��J�,�(�L%jV��V,bj��I�Z"��S�|��S���^U0xw/4��ye�l����[B6�6�[Q-�K`�VikQ�&���W����S��?S�����M��=�I;T�{��B����"��@�{�FG�2}��ek��l����/��]���j��p�y��������-+���#��M{?5�O��=���W���:H(��M)ebY]��S�D��
���f���K���� � �&��$#R�f��ZYSKL��e)L�fi��K32�iM�2�l�3,�4��4�2M3l�#�IE��igK��<+�4V+��vnXS��+�I���~�.���4���*���<$�DK�yN�JU�PX�K���4�9j�V1��s���W.];�������X�R���;,�^ N*�PA4�[�WR,��b
�{������Q�����=�<�A�9ec�1�2�2�M�<0����a�X�0��X|�}�_�/% �J��t�"�N��&�2��M�-)d��,�2�if���S,���2�cU�Ze���Y5i5e�L�-h��cZ��2�����64i��������2���K��)4�<���Tvb��C�$���2��"�	{��*C�U���ByB�vG������F�m�m]76�Q��z�z����m�����w���,��9��������2i��4�m�b���TF�n��E��,,*�)\�������T���+�T�#�R�t���/��)�����)�~�K�G�w+x��'�}�-[������} %�,��]�K�U=��k(��T�Cj�Se�3 �l�5�&�i��Y��M5&j�52h#�&MjZM��k%m��`��B�R�����U;��|'���T]�V��a�df	��fB�I��jJ��qCeU���y:��8�^�N�v�&H�/c�R��1F
R��R���U��)��i��J����3j���j)��(i�f�@���b�����j��I�%d�kIq<�T%N���>�����Q������y;D���~q^r�*v��_3
���]?�V����
�2���A�n����������������z���r���WY����w�|J��q�����;=�����Wo������O}�.���pN����+O���-n-��z���wW�����j74�xv�|�#����������l��u!=���-��7x����{�{������/W��nT�w^7E��/sy�j={�{�==����O�[w���^��;;��i��j������}=�D��jE�P(S_}TCx:���
^� P-��k�hz9�Sl�_\>��Z
 1���(�a�GA@
�Tdpi@

(;S�@{d���A����A1a44LF�h�!�L����=!���@�MF�$j= =F�4@h
	2��4���S�Q�h�
z�(E=F������4& !��2zF@���T�z)�S�������3@��	��LML�S*~�y=�h~�= ?T�G����A#����2��b�L1a�1�D���O\K���$��RScMLcZ�+1����{��[���������a�cZ��a�����,I��n�4S������:�Mp������W8�4��1���Ut�_�?��\v���V@�����+������u�
�����F��������n�KE A.*��dTJ��9���]{����]8�$&�.0JM c�k��K����S�>k$���t�~5�~���������3}���}�����<���3	:HHC��dx��$:����G�xC�DE"�v��VKV���J=���T��j-���
4�C��d���J��:���F�P���IS�����B����/�S�]�j��|x�{�ZH�����+�t1X3@V�rm��l�D�}�/�3��R�O��$��Ql���1��V���N��"��mDr�O�L]����)���B5�����y�����f��:v}���U�$s�M����i$�@g�/�V�z�UQTR>�ppRRUUTY���I,��%e4���W_�aaR������b�yu��}���Xh�,��$p�)���OO6��0XZ���M������Wu;�x	]�
`���n(dz�Q���r��X��9h��F�-�D�v�V�X��V������aI���������$������C�������X���b��)����#��>�U$���Jh�K�����]�}��On�k���e��[���#����Nc��������W��_=����{��:��������B#��y�:�������c`��=��_8hlZ�&T�2+5O��/��W��*YD�����#��e[IZeY�i�����m6����C���}u����~zu��`��T8j-��Ea\��� i���0px�(��BlHB��
+D$�i-�����.?v����"��
�z���j\�J�W����A�aL0�g���F2���U,Mt�m�cr�6G���������5����^������PQ��r�Kt���N���/49�#��Dqs����~���s7�~�UU�v)���Vv���=�������+Z�32�X&�����WM�0����������`m���qcL� ��T$(Z�Vs�	X,Fv0�K�=3 �33
����21�y�=����k.^z[��t��)o��n��h��Z��a��i\�G~�����ZT���o<���jb\�A���)�."��O��*|��=�|[��6�u��3��y�p����!$JK�4�/�0�tzH\�!!N��T�JI�:c����Nj'9\����y�MR�J���$�DZV��i�R�$��J��);��R�� @�r��,4�+������j���x���Hk�I$�f*������
 yS35J�*J�(������|.��<D�*xZe��yW��\�1�c0��G����������T��R�������@�`�K*�DRe�s�����`���&����BB'�d��T@�F�������XU{��F~I��v����{H=������x�)��L���Mc(".l~��c2����V���z�/�C���	�a�����>��V��ev����
"�A������4���t4��g8����v�F���>�G��\���2�������x�8��?k��|�z_�F������|R������yV
�M���GMq�n�����'��'����7��R����)�fE)��Q���"a���������9#9�������>@?'�
�U���~���,b��`�}f����E
�
4$4����?�M=��{������G8^�U*��}��S-�]����s�3=u��w{��������7����R���nx�/��l���UUks���l$���2����Qm�A���s��/��g�7�Mv���S,q����	,���� P�$�l�7��f�����R�7�}6�LoZx��:������
S!h��O���yz���%�W���������k+��7�,��2O���<vH;pO���[k�Y�L�K�5������������N<�sA�O�>o��I�Cb����9$1�G<R����������/<@jo�y�b����x��(���Dx�s�4�g
U�I���
���F����"'6n���<���E,��������<���E� $);���l���������
$p���n,6����6���Z�������x��7~F6��[�eU������������2�z����sSm������9�cI�>:�;�=�R�+JR����B�"����|)��&���r��6����}�3���O�89�����xN���[�)�Zr�E�VbY)&�}�j�\s������������!_�>�|7�^QjVks�����c�Sn�z��K�*t�����~����]s7�z���:W>'2[���;9�#���~�����%,�_��j72M�l��m������=�p"h��r�����!������v�����'i���l*;�26$�I)���7*�56�6cd�F�I.��h,�	��C���&�Z����?q������z=s}��c1�l�2�d���"6�WZ�������m�v&���mDh�Z�V�FL��������?���J*xP���M���(�������.���V-D��i�i����!T�__������/�Rx|
�PO9:�'�i]���������E~����M��N��������{BC��_&��$f���V��
������=�]��<�s�P*��S�����W����C��Z�l��S*�qR����/�9��+;����m>�Z���Q���)Z�o).Z���Wy����_m.J�lqB��D=�33��#��=���g��g���u�c_��j�8[��Y�K pa�!'�Z������dy~�����2�����j���NOWGR|��8�oR'�����K���W#�%�����!�R����A�"�RKV��|! �
�6>�����j�I�����?�t�<��z�2X�|�m$$��7<No� �Y,G� �)�jp�$����l���6��M6����|#|�����;����D��,}o�7��=|TS���CjI����3���|���uS�z�7��yW��S�Moc�_.���7(�t�/�z��o%w1m�Vivq��gj1���zx��[w7���^y!��%�����''��jN�%�z�3NLG����_���,����|A?���M@$%�H],'!j�|[�?_H����a��N	i���%�t��L�Z�&���Um]2:l��>}���[����U����U2����a�))��l�����z��� �PDuT�+�]�a��'�t���z������RMi�)_��$���-UoqUYs�~*�Q����
�N�2U���I.��l�����5"0eJ?��W�]�hYh;T��|�rX,��������Y����7��
�$��~��Iy��s�m�)�#���Fn���_tmp���������1T
6����O�#�fl�����P��R����������xm��\�*t�5����������~�U�(�VU��ii��m�j�;B�ozh/!tg�;!�?���co�=��Dj��h���^aav/O������L��C+�]_�G�^�G��_g����JV[kg���?@��.F�};�H��o��T@{��?�8���g��J����M�[���8�����&�^\��)����M����5F�KZ[`� 6��Ypl^��x��MU�R���]�t�������E����U^��A���A����%�c�?F�����uU�Wy�Dr�(r���E���Q! :��/���a�?�C�?3�x�����������p�8��b��W��;_K*�~����6�e6�}���J.���G*9��9�3y[�5�[F����j6M���x�u�w��M��&{�s_4��o-<��1�)��_o�}�W���C�
�w���Z�H:�.i%��e��i$�!��6�	�
[mL����5��*|D�*����_ex��]����om�B0�a""�
4�6�E���[-���5%d���+�������Y���t�>��6�*���a����[���~3�G�=�*B�a����R�����A@g�����x
m�{�'����o�������{}c������HGL�wi	>��0���uM�b��d�X��T�B����>��Oo�c���"Z����=�2w5�����	y��@DA	uv�" �]���H��Ub!E����(��DA#�F�H>>�}��9~vf�[sm����#�=���u��������xv���0mzqAL���k\A���c��u���������
~����ps����$M
V�����s�4��P������R��N��:���|t��>'���fT�>Fa����d�������>�(�`?
�\����"�z)�O���&��f��,�o,����������'Ft�����a�T�!�UV��8;b�*{~�5�k����(�H�����%�
�Z�$�>�����
�b1 @B��C�^�]v���:^z��j���������I$������������i<j��a��!�p�|�Ia����~��}{���������1R���oW���R��E� �� 3H�x�U����G����I��'��~�iHP!by��_2bA�������o���X�*�e����	���O��(��e����(�������7L|�+��o�>���?��||~���{=/WL���Q��;Um�#��bq�y#�x���w!�������wx,{}�}b�$�����~���R����>���b�z�/gI��}���&����oExz���y'���]�{��MQO6�m*����T|d�;�����R4�3-$SLEFYH�������T2�qMj�f�,��l�EI%&�,V�&�1Ii$�.��_;��O3x�1r�Z��G��2�UaUV�������;}�dj�65�U��c;��v�}�^�R�H���$��"w�����f1����4QE�U��lI�o��qU3M�HG�
2jI$���$�6�(��,Av�7��M�s3137UUH[���J��UUUM�2����f^�:$�P��W 9��[l���
���4�{|��q�V���	9�]a���\�s($pH�UUs*��e��I��(}����jp8j��98��� �r����"F��=�yZ��������{���8��~����o�����
���"&������$�9��]�}@��o� �q]0J��`0�kl@�!��g���E��3����>!�Q3���@������u������:��k�{<�<9���C��]$��c����#)�K��P�Zs���j�ZJT��
���0����UHF�<P��j%^p�B��i�NORp��[��Ns�0�!���������c���n���O=jk�[�[r"-���������DE��&'�!@��.:�r����q�q8���OC�������Sb���'.T�&�1��������6���� ��M��k���`8���rUX�	�.��P�(`��P8�P#����[	��m�*L���
p,�Ni\�w��m����lC��p������!�J��m�[5��j��������N+"��s0���+f%T���	p�@��������E����\x���OnJ�@wx��M"��N9���9Zs�����=����B(x�9�������V���<t�t�VS�y�������9����H��H��������H��$oD46�����[U�������D��=�f�U�Y�L��Y
`�
iX��z��?�A���x?�����34i263-3�6�����YZT�M���&e����J2���Sl[%|_ig�|�I����9>�m:\�5?y�1��C>"I�������s��Go�mc
�y�_y�<"eT��^���m8�DA�����E)I��yEF��k4r�^��L�[��N��#�W3�%7&!�(,&P���@�
=�&D�MI��"w���O�$v�Z�!���L�@��4�)�C��Wu�A�Y��[2�G���_�����z����d�g�`'`��$��=��|����X�(Fa�t�Gw������TJdV�Q���mlN���D�S/��3O:���~s���O��>����[>,bsc����Z�!�Cq���w����<���'���v����>��}X��������gW�C�
.�|���M�d�U�c��:�C#����9�_�
\��z�%�c
�{W7d����;�W�S?�
(V������gc������v�t������A�� pQ�i�6M��n��g�����Y�f�9t��[^�s���'h����G���������-����[%�����k6�r��K�������Os��G���@��r�~T{�x�Q�7ct���>��1,�.!�������������7fsw;M$�SmJ������S��j����h���T��zi�Og�Oxw�C��Q�U�R�'N�_��?7��lR���G�IW���`��������i�*�w�]���D{V1��t�4OF��]�x��K���l���i�8S�]��/���~�|��}""34�!���;"��
���~��������@����%�b�����9��V<?���~��X`�3),j�tfd��7�N	1��X�����/�����n�c�*}~��r���7c|j��8]���5����1��F��>�A��������*��R\jG�,��V����Nb�N�N�&I������Zep\��8���.+U��]%��l��%"&m&����d��2(����-X��"	g��kY�Q=��.���4���,8b��A��Q�.�ox+������m��.�G[V-[
Q��Z��N����1�������4����Mr���
���i�H��AW�R=����a�,%����������<O�;��?S������.w��'������*?3��,)E�-���l���'�{wva��N�����r�����1V_��Y��Y�.��|�%W��P~�#����|8��/(�/���e�htC��M4�m&��O#�����c�a��"�h+�+�/w����O�D����g&��Lv��<��gN�+���{�
�8������C�(����Vc��+�Z_�����?��O*���.��8�zt���u�����	Q$�����\S�j�9m�~�.�4t��9���[�6�\	���(Q�D�>e���'��FJ��P�K���0��e�VY��zO�O�v�m����-��s'���61J��{�&��9�G{�U�7YLW���cIT�=�����Q�������
�WG�����������k�=Y�c���h��Qf�V���z����R�M�5��95����Kvc)J>(����������W�J��d�c0�P���d��Wi�]v��f��1��~0��E��7}D}�J��S8�vXv����t�E��|�\��o��3�'���u�9�����]�W������:���d\�M�2�1;��'���vYj2L�P�n#}$��U�5J���q1���������������b*Z�}��yUVg[fB6� d�4�|�
M��0E���5&�":��*�@Vcxn)Ld�<$496ZYPN$��$�pI��M�u�u
�w9����O;���	������
�
)�e�fE7���������3��Y�^S;����8|$
��	���������IF��m�����$�0��������<���E�����`�08��lh�>^?GDt<��H�px�(�g�t;�,.�����cO�����FOz��Y,m�4������H��=�����_[�=l�K��W���
��.��K�#
Q�A�����+n������A��!�Im�X�����L�	��l�U����gh�Ta���N�v��o���Mr������P���<wP��z�����}���zr��������]��V�9�����y�\
���������,>�����O�����)��R_3��>�~�U�A��n����5)���>YR{�i_��!�~�W��f���)G�MI�r�p�
�7'��M�Dy6&�����]�h��?�%�O��V�kZ~���y�b���~���Wh)�����yRe�f*��_� �]:�y�{���i�~]<9�<��vqn��k.��y���"��N�yJ�9�Sz^r�
�a���;��3���������-SM���uR|�Q����p�h��I�!/K�u,�?&4����c���t������I�������kd@Gj����q��gx�;W���o����������gch��c86�:�BG�I}lX�*[�Ec"�*x����w,�k5�|�OR�G����a��8�$�D�o
�j����$�I$�I$�I$�I$�I$�I$�I$�H��'����~t�=��W�_���S�h^�����S�L����V��{m\@K� ����x��+���P/��Sk��F)8?�9��db���� �`�jJ����z���`���\:<V����6��
�U��m�M�L���4��
�p���RD�$�^����jy�����o������'P����^���1n��(H�������xW�
�I������l�m�c%
&������������A�I�%$��!Bm���V[E��ou�Xd\����B�;�/9�b���"9������>��GrCc1���1��93cL�&JLl�����eoo��������U�X.j����2W�P��m[6�"%�G��������|�6��$�B��V�;��}z�6�iuy=j���8���7I9z��;z�����C�Y$%�)c%����m/������p��i�2��Uz�t�e���e��U9���u�j��{m�v�����|/�mMi��k���Yy����VNK��ff��|;\����p��q�����i:��s�HnL'JT�S�_	s�:1GB����3���qlAmc�}�k�������k�>6o�����ls[P���k�J.�	 !�I#'a${�
+-�����q�`�X��*+7���5����+�I�Q��i��j8��h�3�%,u���ZQ)A�*���b��J�w�*Q����������m�{��|�w;�����D��V�UR��6�R�
�k:��,PX�s�cpA�
��E�U(�*��nfUY�rUR�R"�Nf�J�s���^J��b����8��x9���e�]������{��i��*��rOU�5�=`w����S�wWV���������?�!�HZ]��%��L�#�/�oq�d:����#;RCLB
u{DC�������6*,�U��m�[X2���/I��^���Cq���M�X�������Oi���t5#==]7����sJA>�����1<%���{ �]�����

��i���P�y��hV�"
P�B�o
�p(�t%[�������9���Dw�`��~��X��D7	%�l/�y�z����]�zj��%&����b����
nG�W�~���d��W�W������y�m�{�T���"�I*��*Nr���U��������QX���U\`8�������1�]mJ�;<��������g"&����8;�P�=:'1|�xb1����se�&C#��-8������+�/��� ���9q�T�b�j�a��h\����hM�@���q�]T��WB�j���jj��z:���jL�=�9lX�F&&�`����@�bR�����w�����4f��*At����
��k7d*��$���F"��tD}AH���������^�������\n;�����j�����������*B�q>_���WF��	�]�T��75a�b	v���s���F]���9&(pD�e��u�ab�"��`��������*�mYq���$�Uun�����������N�}l=L
F2������
�%����*J(
"!z��b��2��[���yw�W�,��N|}}�w�E��P��2��D����A�$sL7��+��E���2�b�m���u����*"&�b����'h��B�c~���NwT�b��%��S�W����Q(.|=9���YLb�a�M�%�Z�� 8k\��
u�oH��������9l.K��T��&�m�l���s��HM�`�� ���p�g�q��3��j`xW�K�4P�����u�r�Y�����G2I)6�����Q
�n]���C%3y��jU���M��~���UEQTZ�E*K:L�Vv5���4��v6�����#�	n	� ���"���M
f�a������������D H��x�/~*�G�h�Ji&V1�xr�
��eS6���m6�A��)-}�}��>+���\@�m���Q�g��b�u��i[����u��~45b���T��Y��j���Hu�6]=[��)�:p�0��X�p�MFo��"��A��?$�Zi���.%���e��CX�*�a��K��g���	�IM/�[��3���sy���9��6�����x�^����v�d�$�
6�;m��,��IF,�HB5�Q���<�L�z�����|W����}}��w����$C1	�5�w�����}����
�e���%V�@�5�����S��������T$$��sr�3�|�����R�&���5�0�������1�c�)��he���^����,"���7��-���b�jO���h����~�oSy���hM7�+l0��l(^8fp��fy�������u�����p��3�$���J�_UYD5{=:��N�9
�N�������vR��$\
��4i'���}���w�>�m���5�o|0��o����&s�M�f+X��$�{���[���8Wg���)��x�����=�j�!��+AP��I<#]#��Z(|q-QE
�mfTu���\����/_����"��$@(������!	�Z���HKj+�]q�����_Hu/�$��~�`X��wpKR�� �k��8����Z�������*�>��ml�5W�k��G�W�+��Ji,t���2VJ��)�mT��d���*SIe$����{K/(�W*�V�Jr�Ji���	��Ha&�4�Y%�!��H��X��9*���W*�EV�Jr�Ji���&��`

�4�({�q1���9V
08#��&���e���Ae�,-]i��c����uD��T���J���(�����E.�
�
����%	�BH�f��>"���>O���d���d���p�1�Q���'a�o	�s�
�oG��M�����=�%N���ffZ���]�V�������#K����%s���8_L3�8t:w�8s��75@������<�t������:���Yn�H���*��&R��1��p:U04S����s"�+Wsq�q~��%x���]���L�d��;�o���&�\m[.U�����]$U���&IgY�W+���I�����D�6VJ����1�!����7�S���>��
�V���Y���f����t��z�AS�x���B\�n�B��Y�<�a�J�����.���)��cV��x��A���m�d�����d�Y��Q���B(HB��f����e4�� $��H�+��J�[�Q��%�(`����c)\������y����w���������"�����L����\x��$;�ClF	�%��-��JSW�B��J}�;�lHH���*o��Nm��P��r�9��S\�9i�]���n�k�DA����&�hR���0��������s}3��9��y
U;�n�����>p,��E����0s�+����0$FL���{wS�������U�kL%V��"YX��o�A�����4�B��,cX�Hn6��C���iIUhVR�����FD���T�WQTb&!�b��v�����t�CERC;�� ������Mw�������g9s[���(�K��\�����f�����u%vh�z� ��Q�0>�O����?�������x8,���>Q#*�CT�Kc
iw�?��:������]�����a�A��RI�`�3C9F�)@K��6�2�]9ua�(~�������2�YD!<���
%�����-2@B��B|=0DEF�O��G�}���������&n������0�%��0�tx���E�oO8�������^J�����ZuU"@e�'��s�Y�EKML����	� A�I�������rGR������f�md�����p��]����Z�\U��1G��G������4��$�q�?�3���{��"G�'�|��|�9�����G����^jY����:�|5/��p<� v��q
�$i���jk&�^�e��?��T�?�'��6�%9kc4��N��
�uG4'i*C�_���}J��5�������k���m�kYj9��s�(t�y����G�)��z��S����r@��
�=K��})�>�������_���������D�����y�Q!2z����������_��$����>�_@��>G�����p�4���v��(�Y��iC���VyU��������TL�������=��W���j��i���K��c�Wa�Z���>��>6V�g������no���:�mQ����	P�	������;���L�_b}��'U*�~������/��������#�[���"P������K�_w��S�%H{��
��o�/�"�'��+����2�Y,��TuzH�G��"}^��F�S�I����^�����+���]GYv\�3�/Go6�y�c���7�rR�>��%�����i}�����>��8q������K�5U����<2X,YI88�WY�t4��p����%v�M�9���d�����<�ax^�����;W���1R4��ol���3��)S��A���O�t���Z�6��6�����j��FBL�����������A�R+�)�I]v���i�U���jAR����	����k�u4��������FB��)�2h"�����kt��#CJ�	�-(����IE�����i5����[M�����[J�%�����V���j
����IF��V�M*��cs]���]S����O��{9i��:���9�\J�,�6K?��_��o��I�'����+F�M���^�1ao?��WZ��A�R�VB����"h8TR�58���T����#�'��~��d�Q[kZ�p�;��&efd?iD���~5�`�������_��C��g�H�O��E�7`�%Ha����%�?m��=�Q�U�U.T~d��>�����w;a�;�(���iR����-��&����e���i2�������ZY�X�5�4�c&�LX�c1*���f��["�"���C�0pE���2��b�%����wT�I����m�%!y����?�������m,�*i�4���?P������R9Z�Rs�l+�V���Fj�4��j��\�9K����C
z*��Q��ZG��3�;�N1X���}����#�C]4����?��u��]a�W+���fj��GX��%%R}i4�t�|�W��=,�aq=w�����&8m�c��SP���gW�6D�l��X��d�����#)�e���[4~�8F���~������)>O�Tg����T�y��vS��9�����o���D�_�t�r'\�����*G�>����6������S�$�jM�MDk��dI����;��w����N��|_K��R�3~�+�N�^���/\�����K
��'�UU��1C��������L��"_��gj�IJ��Ui�����O*�G��_���.��������p�:�wD��I��oC��RW#c��*W��s�{sU�n�Hz��=P�[�z�����V����d��4�mH�G�F���Q����|�O?o^5Z�������"��.$qR��}����y��s���7N_��?���|J~)�l4�XU�����>��k���8��K�,�g4��R����/�%��Z�&�`k��[?��B5��@.���F����c�'�qp���IVp��$�=�$���~��J����v��[�zo@��nhCi��d����UB&�j�>�.���d�����H�0A
DL����"'�!���r��
TD*��W��c�.���~&�?�z)�"������
A�I������b`�b�h���J�8S�G �-w�����?>��H�:�����%�Gz�$�._����U�F�<B4��G�'��uIt�$��?Z���l�f6nn������U��UV���*����������e���K�9�����BK��uPHA�"��m,��O�S�����jpK �4�F�}����Pdr�W�a����z��:]���Y�.��/��U�0F?��c�����L��P�Q�m����Jq{�R�mX���ut�)�q��O�>�^F���V��ha�j)��F�6�R3�U��]�j6���R��.5����g�s�oMp�	9$�a�����LICD8��4�������p�DJ�cr��z����$0��(��HA��x��0�@}��]�"�2��ekOo���=�u��x�.)��-�l�m��'�]��>��N�%�dl��d����eUj�eb�V4��F�2��j���5Z�e����T�K�y����ck�^]�>���m��=6�"@�����&fff��'��tO��=�����>���yg��t���������J|#Q���MN�#�A���?���hh}����4���#5����S�$��yg������_$SE�:��z����sS�������Q��>]���"M�]����`I���{��oC����u�u��)�0�S���Em����v���TVjQ��&e��q�x:��Z,�	�H��mN{����]�;�J��pba�i9�e��MK�����(��5WL���6�%�%YT����u�Hp�N���|s�F�8�b�*�&>�P�l!3��-�m�Sn�����i�JE�#�r��`���C1�U�J��M���3A��hiVZ2��\�Z0���h��h��Sk%��*�[nM&��2��U�[=����n^��;#DUuVF u��)f3X����]��M:�vx>�+�P"�#	C�KM����J�������u�Gb�-YeiG�0�Z�k����o�����1�bNR��
F�H�"DDA=nN*�U~�}?v�g\����"�O���uz���HA� ���d�yY��1�H���q�H��?�?����>�������~u��I����S��_?���!)�eI��z���{��s�=�����cu�"~c*�a�z���;��)���{�R��������V!�SG�n��D��<���x�����xy?m"����<G��(8�]�:��)����y������c�?0�{��Z�����@�>4]�t���:����N���Up�>�Q�BGek��l3R���h���Z�T�?������D�{i���g�J���&��Q���~�jUy#$����.�wn4��";��wf�	��W�t;���������+����a�J^{�c�p}�-�"F��;�;�_R�������v�����=���YU�R���w���\�?�dW�R�}�����.��<>����x�'iN������3)�\�6����;#�2Iv�����:�����(z��0��hd������'�$}�����7n�KFv���x��� $*�)����'��u���q�|!
Kp�o)�l|m�@[��x>�0c@��j�S2?D���������i���ff���i��mS-6K�T�i��4k3F�:���UVz��>6��H�_E�E?)O���y����w@��5��t^�i^�4�q5~��J�Y0����j[{z�xDm��EO3�%�	��o�����x��]U[���p��k���:Ei�����R�
=�6|��J�
����Fk�W�K����<�%���'�������w��S��J�%h,3�i5d\��[��L<��2��]�����x�I�vi��Xfi6i�5,�2s�J>�W��G�S��<�'B�F��4/����c�~���7u��~�6�E���'�&���o��I����H���fI�:�6�OH��E%Dj��bL�n;$X>�q�H�	#�7���G��h�\�|U?
<R�|N����F_T���MDK����p�F���;�\b#�[��>��]V'oUU��/�����-�o�bF��4)�����o�=�d�����6<���X��b&Hco�o�Q��RuD�R;h�I��y���r��	�SI7�eK]�Wh}��������&;5%�����Q
d��K
��y_`t����2�c�B����_��������#��S�tC]��]�3*'�A9����
�O�������b�X���/�z�*���
��P��kb��O�13K/��3���;u8sXZA��1��O��v{�O^R��b�.�<w] ugs�B�T+U�������)/2U'�>x�	����:���d�s��gd��^/^�xJ�����dz�Kd����������mU[V��e#L�f�d�Y&!%�k���f��L�&�5d�I(��0j�cA��5�4�Q����l+23)���2�Ei��FMj��R��M45hL�1�Vj�h�h����j*��d��2�$����4o�)":���SZ����q�;���<>�W����U;�>b���}$�]�]��Vx��>�����y��8���G���|	�����~!���$�,*� +|�P���!/+�a��S�J�����������R%�����K�[d�k1��;/������f)����S�m1Z�kT����|,i{x�H�u�u������S���Dv��L�*���������jC��eq*#�U�]
�Q�.�4��5�(8��]9���T�����SQ������;�����j������3K6�55_%��WU��F��U'ta�k�!�������1��Q���������v9f��2J9:!�1��!G���8�o�I^����|vkX�z����J=U�#��=����$�2+�V���u^���x�<�������2;���C���H�|�pR�X�U~/j'�Wj�(c1G}]���J�Q�c:5���5\v<���,�T"��(�7���<4���$�P��V�bh��o��z$��)�#�O2��d��9����)�y�*��G����F�������_������X��rU��I��J|w��{�}�O���S(�Q�"27��d�K'�o,I7��I���A��Gk��I^�R���������#���L%��G��N�3�r����p<{J���tp8���
S7 ��q��E��R�N�T��Lj��2'��J��d�����NJ����T��O���]�y��G�_����f1"3�����S�$�_��n�K<FE_sC�N��������j����<dH����*��
���Z;���6���}9��I?���������*�����%����7n�v���8G�MM,YYh����4X��Y�$����j�����&+X�h�l��a2�&��	��0�I��VmU�m-����%S]������j�I���u���u��D����	)v�Q9��H�pL���lf��8W��f9T\?�P�pj�*���l�i���[���b}!�2Gx����;Mv$�s�����>�?1�����bK��h��=������~w��u���P�Af�Td�-����F�������~#!�r�*����Mn����VL�r�N�;*M������%yJ�X��6�lk��Y#�����;u��e]��|��G�^�y�TE^*���I|�OO(w-E'����r�/,L���7\�������
�j�t?�=N����*�����Pz���Q�����#`�P�5TW���B�����)����_���4�_��OB�������m����^Ot���'B��Wd��]�~
�t�'����|�����>�z�kj�2�p��o�G����S>!���}y|�|��)Z���_2��SI�%O��K��6�3b&p��"S���s�����Q�7�V_�1�]d�W9G�'J?�+���_��5TX,I5�-V����
�
Iqu��X�{�w���]A�s�U�t;;
�N����~������w�Lbi��8\����i2dW��r!�,b��1f.\n�A��7A�����O�����R9<N����?Z��={���������b����NxyJ���^��DyA���U
��+�U^TzU�;2~|m�����1�G������N��Ke6�`��'��d�%�gw�����Jp�
7���r�_	�Q��z�����f3���:������
!.���������{B]I��$��#y�������������)>�o�%N��_q�I�qG����!*�S ���)Y/�G��_u���8]�Z����I�U/��&���iT������|�6�YZ������==���a���uBFm������eh��e�
Y���������;�2=���,��RJ�I)����?���&����G�"b	���x��#bd=|����k��rEm7)�����)t�dc����s�zU��gVyH�J�������*w�-�K�T��8��'r��M�M��a���l���$�c��l�]�:]-�s�N�(��1�:�)3��fBR��h$�(@Eq��8��>���s�q8�(����^*EDVuZ,e
��$��#�W=|:��������=�9)�����;+5u�;C�lk���C��D���0�~6fRd��
�Pq)�fmb�����j��=�q��X��u|��`����I�9�c��]�kq���]�w����������|�9T]�vB����ff�������F��Yhj�����J��>*W�G�����xE#���S��F��SL�%�x��Zm�.xm�SL����kV�f�d[
VC����CG�p�������g��$z�=�~���;��(���);���w��`�}J�>[+Zm��l����M��4�j���4O��D>V�WA���_n���kl�k�'}m^�WHv���u�:��:�dt���.����;28�p��s%F�S���U.�r26�L��������^���]vk����D�LZd��KO���+�N]TGx����a)�(��5PX������f��$x'��<��K����W��S�P
�������c�����g������*7��d���y*�34r<'�/�_>�p���q��H�!��P���Q��s�����V�.��)��y%/���UY�eY�Rx5Z�-�I�kJ[6��6&mQ�+�����}��C�z���:ti �nv��}=y7P�h��LmH�4hheI����8�$i�i9��Tjvx����3��S���0k��^�]
	�sE�XVR���C(�SB�P��
�JQ�$6��=i�v����|!���E���������4���:�h��C`������8�����^�<:dWUvN�����}���x�H��'��&i�35������z��
����s�W�����+�\���f���c3���,W5rI5L�JQ�mL�1����q�J�a��u��9�s��Qu�����_��"�(H*zX�
#69Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#68)
7 attachment(s)
ECPG fixes, was: Re: ECPG FETCH readahead

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

I have rebased the patchset after "ecpg: Split off mmfatal() from mmerror()"
since it caused merge conflicts.

It's at the usual place again, you need to clone it from scratch if you are
interested in looking at git diff/log

I have removed some previous ecpg_log() debug output and
the total patch size is not so huge any more but I am going to post
the split-up set in parts.

Attached is the first few patches that are strictly generic ECPG fixes.
They can be applied independently and obvious enough.

Subsequent patches will come as reply to this email.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

01.patchtext/x-patch; name=01.patchDownload
commit f167aaa9693305e08cd6b2946af8528dada799b4
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:31:21 2013 +0100

    ECPG: Make the preprocessor emit ';' if the variable type for
    a list of variables is varchar. This fixes this test case:
    
    int main(void)
    {
        exec sql begin declare section;
        varchar a[50], b[50];
        exec sql end declare section;
    
        return 0;
    }
    
    Since varchars are internally turned into custom structs and
    the type name is emitted for these variable declarations,
    the preprocessed code previously had:
    
    struct varchar_1  { ... }  a _,_  struct varchar_2  { ... }  b ;
    
    The comma in the generated C file was a syntax error.
    
    There are no regression test changes since it's not exercised.

diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 342b7bc..fd35dfc 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -837,7 +837,12 @@ opt_signed: SQL_SIGNED
 variable_list: variable
 			{ $$ = $1; }
 		| variable_list ',' variable
-			{ $$ = cat_str(3, $1, mm_strdup(","), $3); }
+		{
+			if (actual_type[struct_level].type_enum == ECPGt_varchar)
+				$$ = cat_str(3, $1, mm_strdup(";"), $3);
+			else
+				$$ = cat_str(3, $1, mm_strdup(","), $3);
+		}
 		;
 
 variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
02.patchtext/x-patch; name=02.patchDownload
commit b6d57b3fa709757769eb27083d7231602f2d806c
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:33:40 2013 +0100

    ECPG: Free the malloc()'ed variables in the test so it comes out
    clean on Valgrind runs.

diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 125d7d8..2438911 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -347,28 +347,31 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	close_cur1();
 
+	free(myvar);
+	free(mynullvar);
+
 	strcpy(msg, "drop");
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table a1", ECPGt_EOIT, ECPGt_EORT);
-#line 115 "outofscope.pgc"
+#line 118 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 115 "outofscope.pgc"
+#line 118 "outofscope.pgc"
 
 
 	strcpy(msg, "commit");
 	{ ECPGtrans(__LINE__, NULL, "commit");
-#line 118 "outofscope.pgc"
+#line 121 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 118 "outofscope.pgc"
+#line 121 "outofscope.pgc"
 
 
 	strcpy(msg, "disconnect");
 	{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 121 "outofscope.pgc"
+#line 124 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 121 "outofscope.pgc"
+#line 124 "outofscope.pgc"
 
 
 	return (0);
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr b/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
index 91d3505..c7f8771 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
@@ -102,13 +102,13 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 58: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 115: query: drop table a1; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 118: query: drop table a1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 115: using PQexec
+[NO_PID]: ecpg_execute on line 118: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 115: OK: DROP TABLE
+[NO_PID]: ecpg_execute on line 118: OK: DROP TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 118: action "commit"; connection "regress1"
+[NO_PID]: ECPGtrans on line 121: action "commit"; connection "regress1"
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/preproc/outofscope.pgc b/src/interfaces/ecpg/test/preproc/outofscope.pgc
index 25efe75..6b5d270 100644
--- a/src/interfaces/ecpg/test/preproc/outofscope.pgc
+++ b/src/interfaces/ecpg/test/preproc/outofscope.pgc
@@ -111,6 +111,9 @@ main (void)
 
 	close_cur1();
 
+	free(myvar);
+	free(mynullvar);
+
 	strcpy(msg, "drop");
 	exec sql drop table a1;
 
03.patchtext/x-patch; name=03.patchDownload
commit ed380002b153f97b8436dc4d8caa9fd638f63c2d
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:34:06 2013 +0100

    ECPG: Add EXEC SQL CLOSE C to the test.

diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c
index 64497b6..9aa11d6 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.c
+++ b/src/interfaces/ecpg/test/expected/sql-binary.c
@@ -133,15 +133,19 @@ main (void)
 
   printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);}
+#line 69 "binary.pgc"
+
+
   memset(empl.name, 0, 21L);
   ECPGset_var( 1, &( empl.idnum ), __LINE__);\
  /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
-#line 70 "binary.pgc"
+#line 72 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
-#line 71 "binary.pgc"
+#line 73 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch B", ECPGt_EOIT, 
 	ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
@@ -150,7 +154,7 @@ main (void)
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(empl.byte),(long)20,(long)1,(20)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 72 "binary.pgc"
+#line 74 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -159,7 +163,7 @@ main (void)
     }
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT);}
-#line 79 "binary.pgc"
+#line 81 "binary.pgc"
 
 
   /* do not print a.accs because big/little endian will have different outputs here */
@@ -170,17 +174,17 @@ main (void)
 
   ECPGset_var( 2, &( empl.idnum ), __LINE__);\
  /* declare A binary cursor for select byte from empl where idnum = $1  */
-#line 87 "binary.pgc"
+#line 89 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
-#line 88 "binary.pgc"
+#line 90 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch A", ECPGt_EOIT, 
 	ECPGt_char,&(pointer),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 89 "binary.pgc"
+#line 91 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -189,7 +193,7 @@ main (void)
     }
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT);}
-#line 96 "binary.pgc"
+#line 98 "binary.pgc"
 
 
   printf ("pointer=");
@@ -199,7 +203,7 @@ main (void)
   free(pointer);
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 104 "binary.pgc"
+#line 106 "binary.pgc"
 
   exit (0);
 }
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.stderr b/src/interfaces/ecpg/test/expected/sql-binary.stderr
index e164a84..d6b4777 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-binary.stderr
@@ -42,55 +42,61 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 60: RESULT: \001m\000\212 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 71: query: declare B binary cursor for select name , accs , byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 69: query: close C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 71: using PQexecParams
+[NO_PID]: ecpg_execute on line 69: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 71: parameter 1 = 1
+[NO_PID]: ecpg_execute on line 69: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 71: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 73: query: declare B binary cursor for select name , accs , byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: query: fetch B; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 73: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: using PQexec
+[NO_PID]: free_params on line 73: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: correctly got 1 tuples with 3 fields
+[NO_PID]: ecpg_execute on line 73: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 72: RESULT: BINARY offset: -1; array: no
+[NO_PID]: ecpg_execute on line 74: query: fetch B; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 72: RESULT: BINARY offset: -1; array: no
+[NO_PID]: ecpg_execute on line 74: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 72: RESULT: BINARY offset: -1; array: no
+[NO_PID]: ecpg_execute on line 74: correctly got 1 tuples with 3 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 79: query: close B; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 74: RESULT: BINARY offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 79: using PQexec
+[NO_PID]: ecpg_get_data on line 74: RESULT: BINARY offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 79: OK: CLOSE CURSOR
+[NO_PID]: ecpg_get_data on line 74: RESULT: BINARY offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 88: query: declare A binary cursor for select byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 81: query: close B; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 88: using PQexecParams
+[NO_PID]: ecpg_execute on line 81: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 88: parameter 1 = 1
+[NO_PID]: ecpg_execute on line 81: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 88: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 90: query: declare A binary cursor for select byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 89: query: fetch A; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 90: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 89: using PQexec
+[NO_PID]: free_params on line 90: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 89: correctly got 1 tuples with 1 fields
+[NO_PID]: ecpg_execute on line 90: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 89: allocating memory for 1 tuples
+[NO_PID]: ecpg_execute on line 91: query: fetch A; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 89: RESULT: BINARY offset: -1; array: no
+[NO_PID]: ecpg_execute on line 91: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 96: query: close A; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 91: correctly got 1 tuples with 1 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 96: using PQexec
+[NO_PID]: ecpg_store_result on line 91: allocating memory for 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 96: OK: CLOSE CURSOR
+[NO_PID]: ecpg_get_data on line 91: RESULT: BINARY offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 98: query: close A; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 98: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 98: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/sql/binary.pgc b/src/interfaces/ecpg/test/sql/binary.pgc
index 723027d..7cc77d2 100644
--- a/src/interfaces/ecpg/test/sql/binary.pgc
+++ b/src/interfaces/ecpg/test/sql/binary.pgc
@@ -66,6 +66,8 @@ main (void)
 
   printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 
+  EXEC SQL CLOSE C;
+
   memset(empl.name, 0, 21L);
   EXEC SQL DECLARE B BINARY CURSOR FOR select name, accs, byte from empl where idnum =:empl.idnum;
   EXEC SQL OPEN B;
04.patchtext/x-patch; name=04.patchDownload
commit 9c94635d8e2313202cd8c218da7b04cb913fb5b4
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:34:48 2013 +0100

    ECPG: Add EXEC SQL CLOSE C to the test.

diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c
index db7a0c2..c6be49c 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.c
@@ -162,24 +162,34 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   printf("%d: %s\n", i, str);
 
-  /* declare D cursor for select * from My_Table where Item1 = $1 */
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
 #line 42 "fetch.pgc"
 
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 42 "fetch.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 42 "fetch.pgc"
+
+
+  /* declare D cursor for select * from My_Table where Item1 = $1 */
+#line 44 "fetch.pgc"
+
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 44 "fetch.pgc"
+#line 46 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 44 "fetch.pgc"
+#line 46 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 44 "fetch.pgc"
+#line 46 "fetch.pgc"
 
 
   /* exec sql whenever not found  break ; */
-#line 46 "fetch.pgc"
+#line 48 "fetch.pgc"
 
   while (1) {
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
@@ -187,47 +197,47 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 48 "fetch.pgc"
+#line 50 "fetch.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
-#line 48 "fetch.pgc"
+#line 50 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 48 "fetch.pgc"
+#line 50 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 48 "fetch.pgc"
+#line 50 "fetch.pgc"
 
 	printf("%d: %s\n", i, str);
   }
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT);
-#line 51 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 51 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 51 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table My_Table", ECPGt_EOIT, ECPGt_EORT);
-#line 53 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 53 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 
   { ECPGdisconnect(__LINE__, "ALL");
-#line 55 "fetch.pgc"
+#line 57 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 55 "fetch.pgc"
+#line 57 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 55 "fetch.pgc"
+#line 57 "fetch.pgc"
 
 
   return 0;
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.stderr b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
index 2284218..246139b 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
@@ -102,46 +102,49 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 39: RESULT: text4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: query: declare D cursor for select * from My_Table where Item1 = $1; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 42: query: close C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: using PQexecParams
+[NO_PID]: ecpg_execute on line 42: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 44: parameter 1 = 1
+[NO_PID]: ecpg_execute on line 42: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 46: query: declare D cursor for select * from My_Table where Item1 = $1; with 1 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 46: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: free_params on line 46: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 46: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 48: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 50: query: fetch 1 in D; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 48: RESULT: text1 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 50: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 50: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: ecpg_get_data on line 50: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: correctly got 0 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 50: RESULT: text1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode 100 on line 48: no data found on line 48
-[NO_PID]: sqlca: code: 100, state: 02000
-[NO_PID]: ecpg_execute on line 51: query: close D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 50: query: fetch 1 in D; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: using PQexec
+[NO_PID]: ecpg_execute on line 50: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: OK: CLOSE CURSOR
+[NO_PID]: ecpg_execute on line 50: correctly got 0 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 53: query: drop table My_Table; with 0 parameter(s) on connection regress1
+[NO_PID]: raising sqlcode 100 on line 50: no data found on line 50
+[NO_PID]: sqlca: code: 100, state: 02000
+[NO_PID]: ecpg_execute on line 53: query: close D; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_check_PQresult on line 53: bad response - ERROR:  cannot DROP TABLE "my_table" because it is being used by active queries in this session
+[NO_PID]: ecpg_execute on line 53: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: drop table My_Table; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: OK: DROP TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlstate 55006 (sqlcode -400): cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 53
-[NO_PID]: sqlca: code: -400, state: 55006
-SQL error: cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 53
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/sql/fetch.pgc b/src/interfaces/ecpg/test/sql/fetch.pgc
index e280d27..aade678 100644
--- a/src/interfaces/ecpg/test/sql/fetch.pgc
+++ b/src/interfaces/ecpg/test/sql/fetch.pgc
@@ -39,6 +39,8 @@ int main() {
   EXEC SQL FETCH :count IN C INTO :i, :str;
   printf("%d: %s\n", i, str);
 
+  EXEC SQL CLOSE C;
+
   EXEC SQL DECLARE D CURSOR FOR SELECT * FROM My_Table WHERE Item1 = $1;
 
   EXEC SQL OPEN D using 1;
05.patchtext/x-patch; name=05.patchDownload
commit bd94cc347e63ca0d69550d3a89eeed9990c1eb87
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:35:08 2013 +0100

    ECPG: Simplify free_variable()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1a7876e..e5ee8a9 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -87,16 +87,11 @@ free_variable(struct variable * var)
 {
 	struct variable *var_next;
 
-	if (var == NULL)
-		return;
-	var_next = var->next;
-	ecpg_free(var);
-
-	while (var_next)
+	while (var)
 	{
-		var = var_next;
 		var_next = var->next;
 		ecpg_free(var);
+		var = var_next;
 	}
 }
 
06.patchtext/x-patch; name=06.patchDownload
commit e87b71d8b02dbbdb20ed111efe178b3b85b33299
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:35:23 2013 +0100

    ECPG: Fix offset to NULL/size indicator array.

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index dcccd92..5f9a3d4 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -526,15 +526,15 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + offset * act_tuple)) = variable->len;
+										*((short *) (ind + ind_offset * act_tuple)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + offset * act_tuple)) = variable->len;
+										*((int *) (ind + ind_offset * act_tuple)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + offset * act_tuple)) = variable->len;
+										*((long *) (ind + ind_offset * act_tuple)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
07.patchtext/x-patch; name=07.patchDownload
commit 341eaafeed61dbffadf22350f6ebd7a7457f5690
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:36:07 2013 +0100

    ECPG: Fix searching for quoted cursor names case-sensitively.

diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index 0682287..b3b36cf 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -290,7 +290,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		struct cursor *ptr, *this;
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
 		char *comment, *c1, *c2;
-		int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
+		int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
 
 		for (ptr = cur; ptr != NULL; ptr = ptr->next)
 		{
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 71b11f4..64e7600 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -492,7 +492,7 @@ add_additional_variables(char *name, bool insert)
 {
 	struct cursor *ptr;
 	struct arguments *p;
-	int (* strcmp_fn)(const char *, const char *) = (name[0] == ':' ? strcmp : pg_strcasecmp);
+	int (* strcmp_fn)(const char *, const char *) = ((name[0] == ':' || name[0] == '"') ? strcmp : pg_strcasecmp);
 
 	for (ptr = cur; ptr != NULL; ptr=ptr->next)
 	{
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index fd35dfc..9c751d8 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -291,7 +291,7 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 		{
 			struct cursor *ptr, *this;
 			char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
-			int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
+			int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp);
 			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
 			const char *con = connection ? connection : "NULL";
 			char *comment;
#70Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
1 attachment(s)
Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Attached is the patch that modified the command tag returned by
the DECLARE CURSOR command. It returns "DECLARE SCROLL CURSOR"
or "DECLARE NO SCROLL CURSOR" depending on the cursor's
scrollable flag that can be determined internally even if neither is
asked explicitly.

It is expected by the ECPG cursor readahead code.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

08.patchtext/x-patch; name=08.patchDownload
commit a691e262f562debd4b8991728fddd1e0895cf907
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:50:31 2013 +0100

    The backend knows whether the cursor is scrollable if neither SCROLL
    nor NO SCROLL was specified. Inform the clients about this property
    in the command tag: "DECLARE SCROLL CURSOR" or "DECLARE NO SCROLL CURSOR".
    The upcoming ECPG cursor handling code uses it. One contrib and some
    ECPG regression tests have changed.

diff --git a/contrib/dblink/expected/dblink.out b/contrib/dblink/expected/dblink.out
index f237c43..d2b5d69 100644
--- a/contrib/dblink/expected/dblink.out
+++ b/contrib/dblink/expected/dblink.out
@@ -442,9 +442,9 @@ SELECT dblink_close('myconn','rmt_foo_cursor');
 
 -- this should succeed because we have an open transaction
 SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
-  dblink_exec   
-----------------
- DECLARE CURSOR
+      dblink_exec      
+-----------------------
+ DECLARE SCROLL CURSOR
 (1 row)
 
 -- commit remote transaction
@@ -477,9 +477,9 @@ SELECT dblink_close('myconn','rmt_foo_cursor2');
 
 -- this should succeed because we have an open transaction
 SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
-  dblink_exec   
-----------------
- DECLARE CURSOR
+      dblink_exec      
+-----------------------
+ DECLARE SCROLL CURSOR
 (1 row)
 
 -- this should commit the transaction
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 5c3f42c..ef36d78 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -42,7 +42,8 @@
  */
 void
 PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
-				  const char *queryString, bool isTopLevel)
+				  const char *queryString, bool isTopLevel,
+				  bool *scrollable)
 {
 	DeclareCursorStmt *cstmt = (DeclareCursorStmt *) stmt->utilityStmt;
 	Portal		portal;
@@ -118,6 +119,8 @@ PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
 			portal->cursorOptions |= CURSOR_OPT_NO_SCROLL;
 	}
 
+	*scrollable = !!(portal->cursorOptions & CURSOR_OPT_SCROLL);
+
 	/*
 	 * Start execution, inserting parameters if any.
 	 */
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 6a7bf0d..89665cc 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -505,11 +505,15 @@ standard_ProcessUtility(Node *parsetree,
 		case T_PlannedStmt:
 			{
 				PlannedStmt *stmt = (PlannedStmt *) parsetree;
+				bool		scrollable;
 
 				if (stmt->utilityStmt == NULL ||
 					!IsA(stmt->utilityStmt, DeclareCursorStmt))
 					elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
-				PerformCursorOpen(stmt, params, queryString, isTopLevel);
+				PerformCursorOpen(stmt, params, queryString, isTopLevel, &scrollable);
+				if (completionTag)
+					sprintf(completionTag, "DECLARE %s CURSOR",
+							   (scrollable ? "SCROLL" : "NO SCROLL"));
 			}
 			break;
 
diff --git a/src/include/commands/portalcmds.h b/src/include/commands/portalcmds.h
index b123bbd..8e756a8 100644
--- a/src/include/commands/portalcmds.h
+++ b/src/include/commands/portalcmds.h
@@ -19,7 +19,8 @@
 
 
 extern void PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
-				  const char *queryString, bool isTopLevel);
+				  const char *queryString, bool isTopLevel,
+				  bool *scrollable);
 
 extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest,
 				   char *completionTag);
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
index f463d03..fc36a14 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
@@ -28,7 +28,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 101: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 101: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 101: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 109: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -140,7 +140,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 138: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 138: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 138: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 146: query: fetch from mycur2; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
index fc909e5..304a3c1 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
@@ -61,7 +61,7 @@ DETAIL:  Key (i)=(7) already exists.
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 95: parameter 1 = 14
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 95: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 95: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 57: query: fetch forward c; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
index d04e426..60a31c7 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
@@ -18,7 +18,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 34: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 34: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 34: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 37: query: fetch from cur; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -134,7 +134,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 50: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 50: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 50: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: query: fetch from cur; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -302,7 +302,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 76: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 76: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 76: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 79: query: fetch from cur1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr b/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
index 16117be..b10a9e9 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
@@ -70,7 +70,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 37: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 37: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 37: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 39: query: fetch 1 in C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -92,7 +92,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 48: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 48: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -230,7 +230,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 37: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 37: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 37: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 39: query: fetch 1 in C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -252,7 +252,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 48: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 48: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.stderr b/src/interfaces/ecpg/test/expected/preproc-cursor.stderr
index 7af39db..f4ea79c 100644
--- a/src/interfaces/ecpg/test/expected/preproc-cursor.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor.stderr
@@ -60,7 +60,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 67: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 67: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 67: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 70: query: fetch forward from mycur; with 0 parameter(s) on connection test1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -138,7 +138,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 108: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 108: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 108: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 111: query: fetch from mycur; with 0 parameter(s) on connection test1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -220,13 +220,13 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 153: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 153: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 153: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 154: query: declare mycur cursor for SELECT id, t FROM t1; with 0 parameter(s) on connection test2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 154: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 154: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 154: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 157: query: fetch mycur; with 0 parameter(s) on connection test2
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -316,7 +316,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 206: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 206: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 206: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 209: query: fetch from mycur; with 0 parameter(s) on connection test1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr b/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
index c7f8771..95b1a98 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr
@@ -38,7 +38,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 40: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 40: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 40: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 49: query: fetch mycur; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.stderr b/src/interfaces/ecpg/test/expected/preproc-variable.stderr
index 3ec974d..262afa0 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.stderr
@@ -50,7 +50,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 63: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 63: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 63: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 72: query: fetch cur; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.stderr b/src/interfaces/ecpg/test/expected/sql-binary.stderr
index d6b4777..16a5736 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-binary.stderr
@@ -28,7 +28,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 59: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 59: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 59: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 60: query: fetch C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -54,7 +54,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 73: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 73: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 73: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 74: query: fetch B; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -80,7 +80,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 90: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 90: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 90: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 91: query: fetch A; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.stderr b/src/interfaces/ecpg/test/expected/sql-desc.stderr
index ef11383..601039f 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-desc.stderr
@@ -72,7 +72,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 58: parameter 2 = one
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 58: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 58: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 60: query: fetch next from c1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -96,7 +96,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 70: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 70: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 70: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 72: query: fetch next from c2; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.stderr b/src/interfaces/ecpg/test/expected/sql-dyntest.stderr
index 6afccb2..124b29e 100644
--- a/src/interfaces/ecpg/test/expected/sql-dyntest.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-dyntest.stderr
@@ -32,7 +32,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 60: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 60: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 60: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 64: query: fetch in MYCURS; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.stderr b/src/interfaces/ecpg/test/expected/sql-execute.stderr
index fa90672..7b39b5a 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-execute.stderr
@@ -46,7 +46,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 52: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 52: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: query: fetch 8 in CUR; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -118,7 +118,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 74: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 74: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 74: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 75: query: fetch in CUR2; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.stderr b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
index 246139b..ca192f0 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
@@ -36,7 +36,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 28: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 28: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 28: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -114,7 +114,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 46: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 46: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 46: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 50: query: fetch 1 in D; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.stderr b/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
index 451c2f6..6dc56ff 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
@@ -46,7 +46,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 52: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 52: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: query: fetch 8 in CUR; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -118,7 +118,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: free_params on line 73: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 73: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 73: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 74: query: fetch in CUR3; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.stderr b/src/interfaces/ecpg/test/expected/sql-quote.stderr
index 866774b..eb36f55 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-quote.stderr
@@ -73,7 +73,7 @@ SQL error: nonstandard use of \\ in a string literal
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 45: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 45: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index b3d771a..f9d412b 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -28,7 +28,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 103: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 103: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -136,7 +136,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 138: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 138: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 138: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 141: query: fetch all from mycur2; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
#71Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
8 attachment(s)
ECPG infrastructure changes part 1, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Infrastructure changes in ecpglib/execute.c to split up
ECPGdo and ecpg_execute() and expose the parts as
functions internal to ecpglib.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

09.patchtext/x-patch; name=09.patchDownload
commit 00261a77f0d4d802419708b716103a04743fc361
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:53:16 2013 +0100

    ECPG: Move allocating struct statement earlier in ECPGdo()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e5ee8a9..83acaf4 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1720,6 +1720,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
+	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+		return false;
+
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
@@ -1735,6 +1738,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
+		free_statement(stmt);
 		return (false);
 	}
 
@@ -1753,13 +1757,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
-	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
-		return false;
-	}
 
 	/*
 	 * If statement type is ECPGst_prepnormal we are supposed to prepare the
10.patchtext/x-patch; name=10.patchDownload
commit 34f2739761ccecf515e2a863695c0998dd899bdb
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:54:29 2013 +0100

    ECPG: Move char *oldlocale from ECPGdo() to struct statement.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 83acaf4..01e1a32 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -104,6 +104,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -1708,7 +1709,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
 	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
@@ -1725,7 +1725,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
 		free_statement(stmt);
 		return (false);
 	}
@@ -1766,8 +1765,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1798,8 +1796,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1828,8 +1825,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1886,8 +1882,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1909,10 +1904,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
@@ -1920,11 +1914,10 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	ecpg_clear_auto_mem();
 
 	status = ecpg_execute(stmt);
-	free_statement(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
 
 	return (status);
 }
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 835e70c..0e85ee9 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,7 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char	   *oldlocale;
 };
 
 /* structure to store prepared statements for a connection */
11.patchtext/x-patch; name=11.patchDownload
commit 63db7e1b2f33841044f2a0e375beaf6517a6a784
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:55:03 2013 +0100

    ECPG: Introduce ecpg_do_epilogue() to restore LC_NUMERIC and
    free the statement structure.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 01e1a32..e977a4e 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return (false);
 	}
 
@@ -1765,8 +1764,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1796,8 +1794,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1825,8 +1822,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1882,8 +1878,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1905,8 +1900,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	if (con == NULL || con->connection == NULL)
 	{
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return false;
 	}
 
@@ -1916,12 +1910,25 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	status = ecpg_execute(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, stmt->oldlocale);
-	free_statement(stmt);
+	ecpg_do_epilogue(stmt);
 
 	return (status);
 }
 
+/*
+ * ecpg_do_epilogue
+ *    Restore the application locale and free the statement structure.
+ */
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	if (stmt == NULL)
+		return;
+
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 0e85ee9..f9a861f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -165,6 +165,7 @@ struct prepared_statement *ecpg_find_prepared_statement(const char *,
 bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+void		ecpg_do_epilogue(struct statement *);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
12.patchtext/x-patch; name=12.patchDownload
commit 840a3777fa3efe0e620fe424858d1acc5c17e2e6
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:55:36 2013 +0100

    ECPG: Introduce ecpg_do(). The core function of ECPGdo() is
    separated out, so va_start and va_end are done centrally, and
    the function can be used elsewhere.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e977a4e..b97e241 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1702,10 +1702,14 @@ ecpg_execute(struct statement * stmt)
 	return status;
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
@@ -1740,9 +1744,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
-	/* construct statement in our own structure */
-	va_start(args, query);
-
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
@@ -1765,7 +1766,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 
@@ -1795,7 +1795,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 	}
@@ -1823,7 +1822,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1879,7 +1877,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1894,8 +1891,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
@@ -1929,6 +1924,24 @@ ecpg_do_epilogue(struct statement *stmt)
 	free_statement(stmt);
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters are passed as variable-length argument list.
+ */
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name,
+							questionmarks,
+							st, query, args);
+	va_end(args);
+	return ret;
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f9a861f..f0e9b3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -166,6 +166,7 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
13.patchtext/x-patch; name=13.patchDownload
commit 98e2bc382c0e714a213844612f7d640781e4048d
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:58:02 2013 +0100

    ECPG: Rename free_params() to ecpg_free_params(), move the nParams
    and paramValues arguments to struct statement and make the function
    non-static. The ecpg_log() message was modified in this function to
    reflect its new name. Some regression tests results have changed as
    a consequence.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index b97e241..551902d 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1078,18 +1078,18 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 	return true;
 }
 
-static void
-free_params(char **paramValues, int nParams, bool print, int lineno)
+void
+ecpg_free_params(struct statement *stmt, bool print)
 {
 	int			n;
 
-	for (n = 0; n < nParams; n++)
+	for (n = 0; n < stmt->nparams; n++)
 	{
 		if (print)
-			ecpg_log("free_params on line %d: parameter %d = %s\n", lineno, n + 1, paramValues[n] ? paramValues[n] : "null");
-		ecpg_free(paramValues[n]);
+			ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", stmt->lineno, n + 1, stmt->paramvalues[n] ? stmt->paramvalues[n] : "null");
+		ecpg_free(stmt->paramvalues[n]);
 	}
-	ecpg_free(paramValues);
+	ecpg_free(stmt->paramvalues);
 }
 
 
@@ -1134,8 +1134,6 @@ ecpg_execute(struct statement * stmt)
 	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
-	char	  **paramValues = NULL;
-	int			nParams = 0;
 	int			position = 0;
 	struct sqlca_t *sqlca = ECPGget_sqlca();
 	bool		clear_result = true;
@@ -1338,7 +1336,7 @@ ecpg_execute(struct statement * stmt)
 			ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS,
 					   ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS,
 					   NULL);
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false);
 			return false;
 		}
 
@@ -1353,7 +1351,7 @@ ecpg_execute(struct statement * stmt)
 
 			if (!insert_tobeinserted(position, ph_len, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false);
 				return false;
 			}
 			tobeinserted = NULL;
@@ -1368,21 +1366,24 @@ ecpg_execute(struct statement * stmt)
 		{
 			if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 			{
-				free_params(paramValues, nParams, false, stmt->lineno);
+				ecpg_free_params(stmt, false);
 				return false;
 			}
 			tobeinserted = NULL;
 		}
 		else
 		{
-			nParams++;
-			if (!(paramValues = (char **) ecpg_realloc(paramValues, sizeof(char *) * nParams, stmt->lineno)))
+			char	  **paramvalues;
+
+			if (!(paramvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno)))
 			{
-				ecpg_free(paramValues);
+				ecpg_free_params(stmt, false);
 				return false;
 			}
 
-			paramValues[nParams - 1] = tobeinserted;
+			stmt->nparams++;
+			stmt->paramvalues = paramvalues;
+			stmt->paramvalues[stmt->nparams - 1] = tobeinserted;
 
 			/* let's see if this was an old style placeholder */
 			if (stmt->command[position] == '?')
@@ -1393,7 +1394,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false);
 					return false;
 				}
 
@@ -1401,7 +1402,7 @@ ecpg_execute(struct statement * stmt)
 
 				if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 				{
-					free_params(paramValues, nParams, false, stmt->lineno);
+					ecpg_free_params(stmt, false);
 					return false;
 				}
 				tobeinserted = NULL;
@@ -1417,7 +1418,7 @@ ecpg_execute(struct statement * stmt)
 	{
 		ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
 				 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
-		free_params(paramValues, nParams, false, stmt->lineno);
+		ecpg_free_params(stmt, false);
 		return false;
 	}
 
@@ -1428,33 +1429,33 @@ ecpg_execute(struct statement * stmt)
 		results = PQexec(stmt->connection->connection, "begin transaction");
 		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
-			free_params(paramValues, nParams, false, stmt->lineno);
+			ecpg_free_params(stmt, false);
 			return false;
 		}
 		PQclear(results);
 	}
 
-	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, nParams, stmt->connection->name);
+	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, nParams, (const char *const *) paramValues, NULL, NULL, 0);
+		results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
-		if (nParams == 0)
+		if (stmt->nparams == 0)
 		{
 			results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, nParams, NULL, (const char *const *) paramValues, NULL, NULL, 0);
+			results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
-	free_params(paramValues, nParams, true, stmt->lineno);
+	ecpg_free_params(stmt, true);
 
 	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
@@ -1727,6 +1728,8 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
 		return false;
 
+	memset(stmt, 0, sizeof(struct statement));
+
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f0e9b3c..c469220 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -61,6 +61,8 @@ struct statement
 	struct variable *inlist;
 	struct variable *outlist;
 	char	   *oldlocale;
+	int		nparams;
+	char	  **paramvalues;
 };
 
 /* structure to store prepared statements for a connection */
@@ -165,6 +167,7 @@ struct prepared_statement *ecpg_find_prepared_statement(const char *,
 bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+void		ecpg_free_params(struct statement *stmt, bool print);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-rnull.stderr b/src/interfaces/ecpg/test/expected/compat_informix-rnull.stderr
index dc906c8..ef33456 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-rnull.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-rnull.stderr
@@ -14,19 +14,19 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 1 = abc
+[NO_PID]: ecpg_free_params on line 36: parameter 1 = abc
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 2 = 17
+[NO_PID]: ecpg_free_params on line 36: parameter 2 = 17
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 3 = -74874
+[NO_PID]: ecpg_free_params on line 36: parameter 3 = -74874
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 4 = t
+[NO_PID]: ecpg_free_params on line 36: parameter 4 = t
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 5 = 3.71000003814697
+[NO_PID]: ecpg_free_params on line 36: parameter 5 = 3.71000003814697
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 6 = 487444
+[NO_PID]: ecpg_free_params on line 36: parameter 6 = 487444
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 7 = 404.404
+[NO_PID]: ecpg_free_params on line 36: parameter 7 = 404.404
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -36,25 +36,25 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 1 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 1 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 2 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 2 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 3 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 3 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 4 = t
+[NO_PID]: ecpg_free_params on line 52: parameter 4 = t
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 5 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 5 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 6 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 6 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 7 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 7 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 8 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 8 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 9 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 9 = null
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 10 = null
+[NO_PID]: ecpg_free_params on line 52: parameter 10 = null
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
index fc36a14..31c88c9 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
@@ -252,7 +252,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 184: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 184: parameter 1 = 4
+[NO_PID]: ecpg_free_params on line 184: parameter 1 = 4
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 184: correctly got 1 tuples with 5 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -292,7 +292,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 221: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 221: parameter 1 = 4
+[NO_PID]: ecpg_free_params on line 221: parameter 1 = 4
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 221: correctly got 1 tuples with 5 fields
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
index 304a3c1..b6f6573 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
@@ -12,7 +12,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 28: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 28: parameter 1 = 0
+[NO_PID]: ecpg_free_params on line 28: parameter 1 = 0
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 28: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -33,7 +33,7 @@ DETAIL:  Key (i)=(7) already exists.
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 1 = 14
+[NO_PID]: ecpg_free_params on line 36: parameter 1 = 14
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -59,7 +59,7 @@ DETAIL:  Key (i)=(7) already exists.
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 95: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 95: parameter 1 = 14
+[NO_PID]: ecpg_free_params on line 95: parameter 1 = 14
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 95: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -99,7 +99,7 @@ DETAIL:  Key (i)=(7) already exists.
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 75: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 75: parameter 1 = 21.0
+[NO_PID]: ecpg_free_params on line 75: parameter 1 = 21.0
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 75: OK: DELETE 0
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.stderr b/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.stderr
index 0eb90e4..74d25ac 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.stderr
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.stderr
@@ -32,7 +32,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 81: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 81: parameter 1 = 2003-05-07 13:28:34
+[NO_PID]: ecpg_free_params on line 81: parameter 1 = 2003-05-07 13:28:34
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 81: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -44,9 +44,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 95: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 95: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 95: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 95: parameter 2 = 2003-05-08 15:53:39
+[NO_PID]: ecpg_free_params on line 95: parameter 2 = 2003-05-08 15:53:39
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 95: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr
index c1285f5..0ea9b84 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr
@@ -24,9 +24,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 1 = 1966-01-17
+[NO_PID]: ecpg_free_params on line 36: parameter 1 = 1966-01-17
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 36: parameter 2 = 2000-07-12 17:34:29
+[NO_PID]: ecpg_free_params on line 36: parameter 2 = 2000-07-12 17:34:29
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -34,7 +34,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 38: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 38: parameter 1 = 1966-01-17
+[NO_PID]: ecpg_free_params on line 38: parameter 1 = 1966-01-17
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 38: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
index 60a31c7..6d2a0e0 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.stderr
@@ -36,9 +36,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 45: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 2 = NaN
+[NO_PID]: ecpg_free_params on line 45: parameter 2 = NaN
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -46,9 +46,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 46: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 2 = NaN
+[NO_PID]: ecpg_free_params on line 46: parameter 2 = NaN
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -68,9 +68,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 45: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 2 = Infinity
+[NO_PID]: ecpg_free_params on line 45: parameter 2 = Infinity
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -78,9 +78,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 46: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 2 = Infinity
+[NO_PID]: ecpg_free_params on line 46: parameter 2 = Infinity
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -100,9 +100,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 1 = 3
+[NO_PID]: ecpg_free_params on line 45: parameter 1 = 3
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 2 = -Infinity
+[NO_PID]: ecpg_free_params on line 45: parameter 2 = -Infinity
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -110,9 +110,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 1 = 3
+[NO_PID]: ecpg_free_params on line 46: parameter 1 = 3
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 2 = -Infinity
+[NO_PID]: ecpg_free_params on line 46: parameter 2 = -Infinity
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -286,7 +286,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 72: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 72: parameter 1 = NaN
+[NO_PID]: ecpg_free_params on line 72: parameter 1 = NaN
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 72: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -294,7 +294,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 73: parameter 1 = NaN
+[NO_PID]: ecpg_free_params on line 73: parameter 1 = NaN
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr
index 9557da5..acc8194 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr
@@ -14,7 +14,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 60: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 60: parameter 1 = 2369.7
+[NO_PID]: ecpg_free_params on line 60: parameter 1 = 2369.7
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 60: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr b/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
index b10a9e9..d3bcd6c 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
@@ -26,7 +26,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 24: using PQexecPrepared for "insert into T values ( 1 , $1  )"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 24: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 24: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 24: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -36,7 +36,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecPrepared for "insert into T values ( 1 , $1  )"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -186,7 +186,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 24: using PQexecPrepared for "insert into T values ( 1 , $1  )"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 24: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 24: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 24: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -196,7 +196,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecPrepared for "insert into T values ( 1 , $1  )"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-type.stderr b/src/interfaces/ecpg/test/expected/preproc-type.stderr
index 3072da2..314db70 100644
--- a/src/interfaces/ecpg/test/expected/preproc-type.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-type.stderr
@@ -18,7 +18,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 65: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 65: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 65: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 65: correctly got 1 tuples with 6 fields
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-array.stderr b/src/interfaces/ecpg/test/expected/sql-array.stderr
index 7368559..c5247e3 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-array.stderr
@@ -22,9 +22,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 37: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 37: parameter 1 = {9,8,7,6,5,4,3,2,1,0}
+[NO_PID]: ecpg_free_params on line 37: parameter 1 = {9,8,7,6,5,4,3,2,1,0}
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 37: parameter 2 = klmnopqrst
+[NO_PID]: ecpg_free_params on line 37: parameter 2 = klmnopqrst
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 37: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -32,11 +32,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 39: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 39: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 39: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 39: parameter 2 = {9,8,7,6,5,4,3,2,1,0}
+[NO_PID]: ecpg_free_params on line 39: parameter 2 = {9,8,7,6,5,4,3,2,1,0}
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 39: parameter 3 = 0123456789
+[NO_PID]: ecpg_free_params on line 39: parameter 3 = 0123456789
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 39: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -58,7 +58,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 53: parameter 1 = 140787
+[NO_PID]: ecpg_free_params on line 53: parameter 1 = 140787
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -72,7 +72,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 63: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 63: parameter 1 = 140787
+[NO_PID]: ecpg_free_params on line 63: parameter 1 = 140787
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 63: correctly got 1 tuples with 1 fields
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.stderr b/src/interfaces/ecpg/test/expected/sql-binary.stderr
index 16a5736..a85ada4 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-binary.stderr
@@ -18,7 +18,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 51: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 51: parameter 1 = \001\155\000\212
+[NO_PID]: ecpg_free_params on line 51: parameter 1 = \001\155\000\212
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 51: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -26,7 +26,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 59: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 59: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 59: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 59: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -52,7 +52,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 73: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 73: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -78,7 +78,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 90: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 90: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 90: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 90: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-code100.stderr b/src/interfaces/ecpg/test/expected/sql-code100.stderr
index a928a89..5a3ab35 100644
--- a/src/interfaces/ecpg/test/expected/sql-code100.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-code100.stderr
@@ -14,7 +14,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 0
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 0
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -22,7 +22,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -30,7 +30,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -38,7 +38,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 3
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 3
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -46,7 +46,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 4
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 4
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -54,7 +54,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 5
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 5
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -62,7 +62,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 6
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 6
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -70,7 +70,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 7
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 7
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -78,7 +78,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 8
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 8
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -86,7 +86,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 26: parameter 1 = 9
+[NO_PID]: ecpg_free_params on line 26: parameter 1 = 9
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.stderr b/src/interfaces/ecpg/test/expected/sql-desc.stderr
index 601039f..cdd7bf7 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-desc.stderr
@@ -20,9 +20,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 35: using PQexecPrepared for "INSERT INTO test1 VALUES ($1, $2)"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 35: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 35: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 35: parameter 2 = one
+[NO_PID]: ecpg_free_params on line 35: parameter 2 = one
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 35: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -30,9 +30,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 40: using PQexecPrepared for "INSERT INTO test1 VALUES ($1, $2)"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 40: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 40: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 40: parameter 2 = null
+[NO_PID]: ecpg_free_params on line 40: parameter 2 = null
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 40: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -40,9 +40,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: using PQexecPrepared for "INSERT INTO test1 VALUES ($1, $2)"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 1 = 3
+[NO_PID]: ecpg_free_params on line 45: parameter 1 = 3
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 45: parameter 2 = this is a long test
+[NO_PID]: ecpg_free_params on line 45: parameter 2 = this is a long test
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 45: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -52,9 +52,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: using PQexecPrepared for "SELECT * from test1 where a = $1 and b = $2"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 52: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 52: parameter 2 = one
+[NO_PID]: ecpg_free_params on line 52: parameter 2 = one
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 52: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -68,9 +68,9 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 58: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 58: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 58: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 58: parameter 2 = one
+[NO_PID]: ecpg_free_params on line 58: parameter 2 = one
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 58: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -94,7 +94,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 70: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 70: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 70: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 70: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.stderr b/src/interfaces/ecpg/test/expected/sql-execute.stderr
index 7b39b5a..de02137 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-execute.stderr
@@ -34,7 +34,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: using PQexecPrepared for "insert into test (name, amount, letter) select name, amount+$1, letter from test"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 41: parameter 1 = 100
+[NO_PID]: ecpg_free_params on line 41: parameter 1 = 100
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: OK: INSERT 0 4
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -116,7 +116,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 74: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 74: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 74: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 74: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -146,7 +146,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 94: using PQexecPrepared for "select * from test where amount = $1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 94: parameter 1 = 2
+[NO_PID]: ecpg_free_params on line 94: parameter 1 = 2
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 94: correctly got 1 tuples with 3 fields
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.stderr b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
index ca192f0..42665cd 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.stderr
@@ -112,7 +112,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 46: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 46: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 46: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.stderr b/src/interfaces/ecpg/test/expected/sql-indicators.stderr
index 810623a..cff02d2 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.stderr
@@ -22,7 +22,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 27: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 27: parameter 1 = null
+[NO_PID]: ecpg_free_params on line 27: parameter 1 = null
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 27: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -30,7 +30,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 29: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 29: parameter 1 = 5
+[NO_PID]: ecpg_free_params on line 29: parameter 1 = 5
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 29: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -64,7 +64,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 41: parameter 1 = null
+[NO_PID]: ecpg_free_params on line 41: parameter 1 = null
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: OK: UPDATE 1
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.stderr b/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
index 6dc56ff..30c4833 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.stderr
@@ -34,7 +34,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: using PQexecPrepared for "insert into test (name, amount, letter) select name, amount+$1, letter from test"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 41: parameter 1 = 100
+[NO_PID]: ecpg_free_params on line 41: parameter 1 = 100
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 41: OK: INSERT 0 4
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -116,7 +116,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 73: parameter 1 = 1
+[NO_PID]: ecpg_free_params on line 73: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 73: OK: DECLARE SCROLL CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index f9d412b..1804c39 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -224,7 +224,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 185: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 185: parameter 1 = 4
+[NO_PID]: ecpg_free_params on line 185: parameter 1 = 4
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 185: correctly got 1 tuples with 5 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -262,7 +262,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 222: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 222: parameter 1 = 4
+[NO_PID]: ecpg_free_params on line 222: parameter 1 = 4
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 222: correctly got 1 tuples with 5 fields
 [NO_PID]: sqlca: code: 0, state: 00000
14.patchtext/x-patch; name=14.patchDownload
commit 36f14a7ab3a6f0328a3000e10a58e8e9f1e23fc1
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:58:48 2013 +0100

    ECPG: Split ecpg_do() further and introduce ecpg_do_prologue().
    Add an error path to return if ecpg_strdup(setlocale()) fails.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 551902d..c43b59c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1704,21 +1704,27 @@ ecpg_execute(struct statement * stmt)
 }
 
 /*
- * Execute SQL statements in the backend.
- * The input/output parameters (variable argument list) are passed
- * in a va_list, so other functions can use this interface.
+ * ecpg_do_prologue
+ * Initialize various infrastructure elements for executing the statement:
+ *	- create the statement structure
+ *	- set the C locale for communicating with the backend
+ *	- preprocess the variable list of input/output parameters into
+ *	  linked lists
  */
 bool
-ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		 const char *connection_name, const bool questionmarks,
+		 enum ECPG_statement_type statement_type, const char *query,
+		 va_list args, struct statement **stmt_out)
 {
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
 	char	   *prepname;
 
+	*stmt_out = NULL;
+
 	if (!query)
 	{
 		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
@@ -1733,6 +1739,11 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	if (stmt->oldlocale == NULL)
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1905,12 +1916,9 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
 
-	/* and reset locale value so our application is not affected */
-	ecpg_do_epilogue(stmt);
-
-	return (status);
+	return true;
 }
 
 /*
@@ -1929,6 +1937,34 @@ ecpg_do_epilogue(struct statement *stmt)
 
 /*
  * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement   *stmt;
+	bool		status;
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator,
+				connection_name, questionmarks,
+				(enum ECPG_statement_type) st,
+				query, args, &stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	status = ecpg_execute(stmt);
+
+	/* and reset locale value so our application is not affected */
+	ecpg_do_epilogue(stmt);
+
+	return (status);
+}
+
+/*
+ * Execute SQL statements in the backend.
  * The input/output parameters are passed as variable-length argument list.
  */
 bool
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index c469220..83ea011 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,7 +169,11 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 void		ecpg_do_epilogue(struct statement *);
-bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list,
+				  struct statement **);
+bool		ecpg_do(const int, const int, const int, const char *, const bool,
+				  const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
15.patchtext/x-patch; name=15.patchDownload
commit 0c964283592e03e64dfae8b01f03553450ae4332
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:59:19 2013 +0100

    ECPG: Move PGresult *results into struct statement from ecpg_execute()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index c43b59c..e3a44f7 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1130,7 +1130,6 @@ ecpg_execute(struct statement * stmt)
 {
 	bool		status = false;
 	char	   *cmdstat;
-	PGresult   *results;
 	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
@@ -1426,50 +1425,51 @@ ecpg_execute(struct statement * stmt)
 
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
 			ecpg_free_params(stmt, false);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
 		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
 	ecpg_free_params(stmt, true);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1493,10 +1493,10 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (desc->result)
 						PQclear(desc->result);
-					desc->result = results;
+					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1526,7 +1526,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1549,9 +1549,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1582,7 +1582,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1605,9 +1605,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1622,7 +1622,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, act_field, stmt, var);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1641,9 +1641,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1667,12 +1667,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1684,12 +1684,15 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
 	if (clear_result)
-		PQclear(results);
+	{
+		PQclear(stmt->results);
+		stmt->results = NULL;
+	}
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 83ea011..50fe87f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -63,6 +63,7 @@ struct statement
 	char	   *oldlocale;
 	int		nparams;
 	char	  **paramvalues;
+	PGresult   *results;
 };
 
 /* structure to store prepared statements for a connection */
16.patchtext/x-patch; name=16.patchDownload
commit 5a4939890a1de51f53ea6fbf87acaf094c4a08a6
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 10:59:42 2013 +0100

    ECPG: Split ecpg_execute() up into 4 pieces: ecpg_build_params(),
    ecpg_autostart_transaction(), a smaller ecpg_execute() and
    ecpg_process_output().

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e3a44f7..00327db 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1125,17 +1125,17 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+/*
+ * ecpg_build_params
+ *	Build statement parameters from user variables into
+ *	an array of strings for PQexecParams().
+ */
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1421,8 +1421,17 @@ ecpg_execute(struct statement * stmt)
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
 
+/*
+ * ecpg_autostart_transaction
+ *	If we are in non-autocommit mode, automatically start
+ *	a transaction.
+ */
+bool
+ecpg_autostart_transaction(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
 		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
@@ -1434,7 +1443,16 @@ ecpg_execute(struct statement * stmt)
 		PQclear(stmt->results);
 		stmt->results = NULL;
 	}
+	return true;
+}
 
+/*
+ * ecpg_execute
+ *	Execute the SQL statement.
+ */
+bool
+ecpg_execute(struct statement * stmt)
+{
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
@@ -1460,6 +1478,33 @@ ecpg_execute(struct statement * stmt)
 	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return true;
+}
+
+/*
+ * ecpg_process_output
+ *	Process the statement result and store it into application variables.
+ *	This function can be called repeatedly during the same statement
+ *	in case cursor readahed is used and the application does FETCH N which
+ *	overflows the readahead window.
+ *
+ * Parameters
+ *	stmt	statement structure holding the PGresult and
+ *		the list of output variables
+ *	clear_result
+ *		PQclear() the result upon returning from this function
+ *
+ * Returns success as boolean. Also an SQL error is raised in case of failure.
+ */
+bool
+ecpg_process_output(struct statement * stmt, bool clear_result)
+{
+	struct variable *var;
+	bool		status = false;
+	char	   *cmdstat;
+	PGnotify   *notify;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
 	switch (PQresultStatus(stmt->results))
 	{
@@ -1947,7 +1992,6 @@ bool
 ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
 	struct statement   *stmt;
-	bool		status;
 
 	if (!ecpg_do_prologue(lineno, compat, force_indicator,
 				connection_name, questionmarks,
@@ -1958,12 +2002,33 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	status = ecpg_execute(stmt);
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_autostart_transaction(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, true))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
 	ecpg_do_epilogue(stmt);
 
-	return (status);
+	return true;
 }
 
 /*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 50fe87f..1f96869 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,10 +169,14 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
-void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 				  enum ECPG_statement_type, const char *, va_list,
 				  struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_autostart_transaction(struct statement * stmt);
+bool		ecpg_execute(struct statement * stmt);
+bool		ecpg_process_output(struct statement *, bool);
+void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
 
#72Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
1 attachment(s)
ECPG infrastructure changes, part 2, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

ecpg_log() fixes after part 1 that produces a lot of regression test changes.
This patch is over 200K in itself so I send it separately and compressed.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

17.patch.gzapplication/x-tar; name=17.patch.gzDownload
#73Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
5 attachment(s)
ECPG infrastructure changes, part 3, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Further ecpglib/execute.c changes.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

18.patchtext/x-patch; name=18.patchDownload
commit c901afd59894f49001b743982d38a51b23bac8e1
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:05:34 2013 +0100

    ECPG: Explicitly decouple the tuple index from the array index
    in ecpg_get_data(). Document the function arguments.

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 5f9a3d4..7f3c7cb 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -119,8 +119,35 @@ check_special_value(char *ptr, double *retval, char **endptr)
 	return false;
 }
 
+/*
+ * ecpg_get_data
+ *   Store one field data from PQgetvalue(results, act_tuple, act_field)
+ *   into a target variable. If the field is NULL, store the indication or
+ *   emit an error about the fact that there is no NULL indicator given.
+ * Parameters:
+ *   results:     result set
+ *   act_tuple:   row index in the result set
+ *   act_field:   column index in the result set
+ *   var_index:   array index in the target variable
+ *   lineno:      line number in the ECPG source file for debugging
+ *   type:        type of target variable
+ *   ind_type:    type of NULL indicator variable
+ *   var:         target variable
+ *   ind:         NULL indicator variable
+ *   varcharsize: size of the variable if it's varchar
+ *   offset:      size of the target variable
+ *                (used for indexing in an array)
+ *   ind_offset:  size of the NULL indicator variable
+ *                (used for indexing in an array)
+ *   isarray:     array type
+ *   compat:      native PostgreSQL or Informix compatibility mode
+ *   force_indicator:
+ *                if Informix compatibility mode is set and no NULL indicator
+ *                is given, provide a way to indicate NULL value in the
+ *                target variable itself
+ */
 bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int var_index, int lineno,
 			  enum ECPGttype type, enum ECPGttype ind_type,
 			  char *var, char *ind, long varcharsize, long offset,
 			  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
@@ -167,20 +194,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	{
 		case ECPGt_short:
 		case ECPGt_unsigned_short:
-			*((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((short *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_int:
 		case ECPGt_unsigned_int:
-			*((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_long:
 		case ECPGt_unsigned_long:
-			*((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #ifdef HAVE_LONG_LONG_INT
 		case ECPGt_long_long:
 		case ECPGt_unsigned_long_long:
-			*((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long long int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #endif   /* HAVE_LONG_LONG_INT */
 		case ECPGt_NO_INDICATOR:
@@ -192,7 +219,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					 * Informix has an additional way to specify NULLs note
 					 * that this uses special values to denote NULL
 					 */
-					ECPGset_noind_null(type, var + offset * act_tuple);
+					ECPGset_noind_null(type, var + offset * var_index);
 				}
 				else
 				{
@@ -243,10 +270,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		if (binary)
 		{
 			if (varcharsize == 0 || varcharsize * offset >= size)
-				memcpy(var + offset * act_tuple, pval, size);
+				memcpy(var + offset * var_index, pval, size);
 			else
 			{
-				memcpy(var + offset * act_tuple, pval, varcharsize * offset);
+				memcpy(var + offset * var_index, pval, varcharsize * offset);
 
 				if (varcharsize * offset < size)
 				{
@@ -255,20 +282,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					{
 						case ECPGt_short:
 						case ECPGt_unsigned_short:
-							*((short *) (ind + ind_offset * act_tuple)) = size;
+							*((short *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_int:
 						case ECPGt_unsigned_int:
-							*((int *) (ind + ind_offset * act_tuple)) = size;
+							*((int *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_long:
 						case ECPGt_unsigned_long:
-							*((long *) (ind + ind_offset * act_tuple)) = size;
+							*((long *) (ind + ind_offset * var_index)) = size;
 							break;
 #ifdef HAVE_LONG_LONG_INT
 						case ECPGt_long_long:
 						case ECPGt_unsigned_long_long:
-							*((long long int *) (ind + ind_offset * act_tuple)) = size;
+							*((long long int *) (ind + ind_offset * var_index)) = size;
 							break;
 #endif   /* HAVE_LONG_LONG_INT */
 						default:
@@ -307,13 +334,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_short:
-							*((short *) (var + offset * act_tuple)) = (short) res;
+							*((short *) (var + offset * var_index)) = (short) res;
 							break;
 						case ECPGt_int:
-							*((int *) (var + offset * act_tuple)) = (int) res;
+							*((int *) (var + offset * var_index)) = (int) res;
 							break;
 						case ECPGt_long:
-							*((long *) (var + offset * act_tuple)) = (long) res;
+							*((long *) (var + offset * var_index)) = (long) res;
 							break;
 						default:
 							/* Cannot happen */
@@ -336,13 +363,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_unsigned_short:
-							*((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
+							*((unsigned short *) (var + offset * var_index)) = (unsigned short) ures;
 							break;
 						case ECPGt_unsigned_int:
-							*((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
+							*((unsigned int *) (var + offset * var_index)) = (unsigned int) ures;
 							break;
 						case ECPGt_unsigned_long:
-							*((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
+							*((unsigned long *) (var + offset * var_index)) = (unsigned long) ures;
 							break;
 						default:
 							/* Cannot happen */
@@ -353,7 +380,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #ifdef HAVE_LONG_LONG_INT
 #ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
-					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
+					*((long long int *) (var + offset * var_index)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, scan_length, compat))
 					{
 						ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -365,7 +392,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #endif   /* HAVE_STRTOLL */
 #ifdef HAVE_STRTOULL
 				case ECPGt_unsigned_long_long:
-					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
+					*((unsigned long long int *) (var + offset * var_index)) = strtoull(pval, &scan_length, 10);
 					if ((isarray && *scan_length != ',' && *scan_length != '}')
 						|| (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))		/* Garbage left */
 					{
@@ -400,10 +427,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_float:
-							*((float *) (var + offset * act_tuple)) = dres;
+							*((float *) (var + offset * var_index)) = dres;
 							break;
 						case ECPGt_double:
-							*((double *) (var + offset * act_tuple)) = dres;
+							*((double *) (var + offset * var_index)) = dres;
 							break;
 						default:
 							/* Cannot happen */
@@ -415,9 +442,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					if (pval[0] == 'f' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = false;
+							*((char *) (var + offset * var_index)) = false;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = false;
+							*((int *) (var + offset * var_index)) = false;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -428,9 +455,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					else if (pval[0] == 't' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = true;
+							*((char *) (var + offset * var_index)) = true;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = true;
+							*((int *) (var + offset * var_index)) = true;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -453,7 +480,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_unsigned_char:
 				case ECPGt_string:
 					{
-						char	   *str = (char *) (var + offset * act_tuple);
+						char	   *str = (char *) (var + offset * var_index);
 
 						if (varcharsize == 0 || varcharsize > size)
 						{
@@ -481,20 +508,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = size;
+										*((short *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = size;
+										*((int *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = size;
+										*((long *) (ind + ind_offset * var_index)) = size;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = size;
+										*((long long int *) (ind + ind_offset * var_index)) = size;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -510,7 +537,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_varchar:
 					{
 						struct ECPGgeneric_varchar *variable =
-						(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
+						(struct ECPGgeneric_varchar *) (var + offset * var_index);
 
 						variable->len = size;
 						if (varcharsize == 0)
@@ -526,20 +553,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((short *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long long int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -606,9 +633,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					if (type == ECPGt_numeric)
-						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
+						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * var_index));
 					else
-						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
+						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * var_index));
 
 					PGTYPESnumeric_free(nres);
 					break;
@@ -659,7 +686,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					pval = scan_length;
 
-					PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
+					PGTYPESinterval_copy(ires, (interval *) (var + offset * var_index));
 					free(ires);
 					break;
 
@@ -703,7 +730,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((date *) (var + offset * act_tuple)) = ddres;
+					*((date *) (var + offset * var_index)) = ddres;
 					pval = scan_length;
 					break;
 
@@ -747,7 +774,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((timestamp *) (var + offset * act_tuple)) = tres;
+					*((timestamp *) (var + offset * var_index)) = tres;
 					pval = scan_length;
 					break;
 
@@ -764,6 +791,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
 				/* set array to next entry */
 				++act_tuple;
+				++var_index;
 
 				/* set pval to the next entry */
 
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ca3e0ba..438d3ab 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -433,7 +433,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -452,7 +452,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 	{
 		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 1f96869..f91867c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -139,7 +139,7 @@ extern struct var_list *ivlist;
 /* Returns a pointer to a string containing a simple type name. */
 void		ecpg_add_mem(void *ptr, int lineno);
 
-bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
+bool ecpg_get_data(const PGresult *, int, int, int, int, enum ECPGttype type,
 			  enum ECPGttype, char *, char *, long, long, long,
 			  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index bc94f2f..9985a6c 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -393,7 +393,7 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
@@ -578,7 +578,7 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
19.patchtext/x-patch; name=19.patchDownload
commit 3021ae9aeea085ff6f60ef736fe58126afb4f96f
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:06:37 2013 +0100

    ECPG: Make SQLDA loops go forward. One regression test .stderr changed.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 438d3ab..1fcfebc 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1551,6 +1551,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
+					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
@@ -1564,8 +1565,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1592,14 +1593,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
@@ -1607,6 +1613,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
+					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
@@ -1620,8 +1627,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1648,14 +1655,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index a93ea07..d01aeea 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -148,23 +148,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -190,23 +190,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
20.patchtext/x-patch; name=20.patchDownload
commit 0e4077fd13266f9870ef620c4a81795ad86dbc82
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:07:50 2013 +0100

    ECPG: Allow returning partial results in any order from the result set
    into an arbitrary index if the user variable is an array.

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index b2990ca..5d86c53 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -481,7 +481,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desperate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), LOOP_FORWARD, index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1fcfebc..ace6c11 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -307,12 +307,14 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction,
+				  int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
-	int			act_tuple,
-				ntuples = PQntuples(results);
+	int			tuples_left, act_tuple, act_index;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -363,7 +365,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -372,7 +374,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -393,7 +395,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -429,11 +431,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -450,9 +452,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1489,15 +1491,18 @@ ecpg_execute(struct statement * stmt)
  *	overflows the readahead window.
  *
  * Parameters
- *	stmt	statement structure holding the PGresult and
- *		the list of output variables
- *	clear_result
- *		PQclear() the result upon returning from this function
+ *	stmt:		statement structure holding the PGresult and
+ *			the list of output variables
+ *	start:		start index in PGresult
+ *	ntuples:	number of tuples to process
+ *	direction:	in this direction
+ *	var_index:	start index in the user variable if it's an array
+ *	clear_result:	PQclear() the result upon returning from this function
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1509,12 +1514,11 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
-						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
 			nfields = PQnfields(stmt->results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
+			sqlca->sqlerrd[2] = ntuples;
 			ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1541,7 +1545,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
+							 stmt->lineno, ntuples, (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1566,7 +1570,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1628,7 +1632,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1679,7 +1683,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(stmt->results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, ntuples, direction, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -2032,7 +2036,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f91867c..e09e351 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -29,6 +29,9 @@ enum ARRAY_TYPE
 
 #define ECPG_IS_ARRAY(X) ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
 
+#define LOOP_FORWARD	(1)
+#define LOOP_BACKWARD	(-1)
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -165,8 +168,10 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction, int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
@@ -175,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
21.patchtext/x-patch; name=21.patchDownload
commit 762f9119ded05920771af083df336a76a15a746c
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:09:16 2013 +0100

    ECPG: Allow appending a new result set to descriptors.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ace6c11..b28ab9c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1498,11 +1498,13 @@ ecpg_execute(struct statement * stmt)
  *	direction:	in this direction
  *	var_index:	start index in the user variable if it's an array
  *	clear_result:	PQclear() the result upon returning from this function
+ *	append_result:	the user variable is an SQL or SQLDA descriptor,
+ *			may already contain data, append to it.
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result, bool append_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1514,6 +1516,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
+						tuples_left,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1540,12 +1543,35 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = stmt->results;
-					clear_result = false;
-					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, ntuples, (const char *) var->pointer);
+					if (append_result && desc->result)
+					{
+						int		tuples_left, act_tuple, col,
+								row = PQntuples(desc->result);
+
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
+							for (col = 0; col < nfields; col++)
+							{
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+
+								if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								{
+									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+									status = false;
+									break;
+								}
+							}
+					}
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = stmt->results;
+						clear_result = false;
+						ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
+					}
 				}
 				var = var->next;
 			}
@@ -1559,17 +1585,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
+					{
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -1621,17 +1656,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -2036,7 +2080,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true, false))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index e09e351..ff12acb 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -180,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
22.patchtext/x-patch; name=22.patchDownload
commit 2bb97fdf7ec4fcffec2767eb21f87e73db890503
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:10:13 2013 +0100

    ECPG: Use the more descriptive "act_tuple" variable name instead of "i".
    Use the variables declared for the function scope, don't alias them.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index b28ab9c..1326870 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1517,6 +1517,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	{
 			int			nfields,
 						tuples_left,
+						act_tuple,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1545,23 +1546,24 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 				{
 					if (append_result && desc->result)
 					{
-						int		tuples_left, act_tuple, col,
-								row = PQntuples(desc->result);
+						int		row = PQntuples(desc->result);
 
 						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
-							for (col = 0; col < nfields; col++)
+							for (act_field = 0; act_field < nfields; act_field++)
 							{
-								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, act_field);
 
-								if (!PQsetvalue(desc->result, row, col,
-										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
-										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								if (!PQsetvalue(desc->result, row, act_field,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, act_field),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, act_field)))
 								{
 									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 									status = false;
 									break;
 								}
 							}
+						ecpg_log("ecpg_process_output on line %d: appending result (%d tuples) to descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
 					}
 					else
 					{
@@ -1583,7 +1585,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda = *_sqlda;
 					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1605,13 +1606,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1642,7 +1643,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
@@ -1654,7 +1655,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda = *_sqlda;
 					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1676,13 +1676,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1713,7 +1713,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
#74Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
1 attachment(s)
ECPG infrastructure changes, part 4, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

This is another, semi independent subfeature of ECPG readahead.
It's about 150K by itself, so I send it compressed.

The purpose of this patch is to track (sub-)transactions and cursors
in ecpglib to reduce network turnaround and speed up the application
in certain cases. E.g. cursors are discarded upon ROLLBACK TO
SAVEPOINT and ecpglib needs to know about it. When an unknown
savepoint or cursor name is sent, ecpglib would not send the command
to the server in an open transaction after this patch. Instead, it flips
a "client-side error" flag and returns the same error the backend
would in this case.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

23.patch.gzapplication/x-tar; name=23.patch.gzDownload
#75Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
2 attachment(s)
ECPG infrastructure changes, part 5, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Patch 24 slightly speeds up ECPGsetcommit() at runtime, shifting
the strcmp() cost to the ecpg preprocessor. It also avoids the
confusion coming from a manually crafted C source that sends
a string different from "on" and "off".

Patch 25 is another subfeature of the ECPG readahead code.
ECPGopen() gets the user-specified (or unspecified) scrollable flag.
ECPGfetch() gets the amount of tuples to fetch separately as
a fixed value, which may or may not be also present in the variable
argument list. It makes it unnecessary to parse the FETCH/MOVE
query and extract the amount of tuples that way.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

24.patchtext/x-patch; name=24.patchDownload
commit 23d69755b6cb86a9a6b4a089ac9dd1ee11a51abf
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:30:04 2013 +0100

    ECPG: Modify the parameters of ECPGsetcommit() so it takes a bool
    instead of a string with the "on" / "off" values. This way the parser
    does slightly more work and the ECPG runtime does slightly less,
    which means slightly better performance. Also add a check to
    not execute BEGIN if the transaction has already failed. Extend
    the same check in ecpg_do_prologue() and match these two.

diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index bbe44ae..eb2d2be 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -162,7 +162,7 @@ ecpg_finish(struct connection * act)
 }
 
 bool
-ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
+ECPGsetcommit(int lineno, const bool turn_on, const char *connection_name)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
 	PGresult   *results;
@@ -170,10 +170,15 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return (false);
 
-	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
+	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, turn_on ? "on" : "off", con->name);
 
-	if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
+	if (con->autocommit && !turn_on)
 	{
+		if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
+		{
+			ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+			return false;
+		}
 		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "begin transaction");
@@ -183,7 +188,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 		}
 		con->autocommit = false;
 	}
-	else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
+	else if (!con->autocommit && turn_on)
 	{
 		if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
 		{
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index a60e209..3f5997c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1866,7 +1866,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return (false);
 	}
 
-	if (con->client_side_error)
+	if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
 	{
 		ecpg_do_epilogue(stmt);
 		ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 02f319d..1ac15d5 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -48,7 +48,7 @@ extern		"C"
 
 void		ECPGdebug(int, FILE *);
 bool		ECPGstatus(int, const char *);
-bool		ECPGsetcommit(int, const char *, const char *);
+bool		ECPGsetcommit(int, const bool, const char *);
 bool		ECPGsetconn(int, const char *);
 bool		ECPGconnect(int, int, const char *, const char *, const char *, const char *, int);
 bool		ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...);
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ebc9b16..df85424 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -222,7 +222,7 @@ ECPG: stmtViewStmt rule
 	}
 	| ECPGSetAutocommit
 	{
-		fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+		fprintf(yyout, "{ ECPGsetcommit(__LINE__, %d, %s);", (strcmp($1, "on") == 0), connection ? connection : "NULL");
 		whenever_action(2);
 		free($1);
 	}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index c139e41..5abbf4f 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -61,7 +61,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 32 "num_test.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);
+	{ ECPGsetcommit(__LINE__, 0, NULL);
 #line 34 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-array.c b/src/interfaces/ecpg/test/expected/sql-array.c
index f770c09..befa89f 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.c
+++ b/src/interfaces/ecpg/test/expected/sql-array.c
@@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 27 "array.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 29 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-func.c b/src/interfaces/ecpg/test/expected/sql-func.c
index 5d524b8..823c5b4 100644
--- a/src/interfaces/ecpg/test/expected/sql-func.c
+++ b/src/interfaces/ecpg/test/expected/sql-func.c
@@ -35,7 +35,7 @@ int main() {
 #line 11 "func.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 13 "func.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.c b/src/interfaces/ecpg/test/expected/sql-indicators.c
index 22aacc1..168ccd4 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.c
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.c
@@ -111,7 +111,7 @@ int main()
 	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
 #line 15 "indicators.pgc"
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);}
+	{ ECPGsetcommit(__LINE__, 0, NULL);}
 #line 16 "indicators.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-parser.c b/src/interfaces/ecpg/test/expected/sql-parser.c
index 616135d..1d6c0d3 100644
--- a/src/interfaces/ecpg/test/expected/sql-parser.c
+++ b/src/interfaces/ecpg/test/expected/sql-parser.c
@@ -38,7 +38,7 @@ int main() {
 #line 14 "parser.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "parser.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 6c4d84f..bfb75ca 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -41,7 +41,7 @@ int main() {
 #line 14 "quote.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "quote.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 199a77e..c74ea26 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "alloc.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index cd28c85..3a559ce 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -210,7 +210,7 @@ int main ()
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 69 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 70 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
25.patchtext/x-patch; name=25.patchDownload
commit a5cb7ed8d0c5dc131721f000c40b4586784ad4ad
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 11:35:45 2013 +0100

    ECPG: Pass the SCROLL/NO SCROLL/unspecified to ECPGopen() and pass
    the direction and the amount of tuples to ECPGfetch().
    Use this information to reduce network roundtrip to the backend
    in case a known-non-scrollable cursor and backward movement
    are used together. Use the recently exposed ecpg_prologue(), etc.

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index c6e1667..45ae1f6 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -5289,9 +5289,16 @@ while (1)
      <term>-231 (<symbol>ECPG_INVALID_CURSOR</symbol>)</term>
      <listitem>
       <para>
+       This error code may occur in the following conditions.
+      </para>
+      <para>
        The cursor name you are trying to use is invalid.
        (SQLSTATE 34000)
       </para>
+      <para>
+       The cursor was declared to be non-scrollable and you are
+       trying to move or fetch backward. (SQLSTATE 55000)
+      </para>
      </listitem>
     </varlistentry>
 
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index 44b6b37..b9b3500 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -97,7 +97,8 @@ static struct cursor_descriptor *
 add_cursor(int lineno, struct connection *con,
 					const char *name,
 					int subxact_level,
-					bool with_hold)
+					bool with_hold,
+					enum ECPG_cursor_scroll scrollable)
 {
 	struct cursor_descriptor *desc, *prev;
 
@@ -123,6 +124,7 @@ add_cursor(int lineno, struct connection *con,
 
 	desc->subxact_level = subxact_level;
 	desc->with_hold = with_hold;
+	desc->scrollable = scrollable;
 
 	if (prev)
 	{
@@ -243,7 +245,8 @@ ecpg_commit_cursors(int lineno, struct connection * conn,
 bool
 ECPGopen(const int lineno, const int compat, const int force_indicator,
 			const char *connection_name, const bool questionmarks,
-			const bool with_hold, const char *curname, const int st, const char *query, ...)
+			const bool with_hold, enum ECPG_cursor_scroll scrollable,
+			const char *curname, const int st, const char *query, ...)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
 	int		subxact_level;
@@ -270,26 +273,89 @@ ECPGopen(const int lineno, const int compat, const int force_indicator,
 		subxact_level =
 			(PQtransactionStatus(con->connection) != PQTRANS_IDLE ?
 										1 : 0);
-	add_cursor(lineno, con, curname, subxact_level, with_hold);
+	add_cursor(lineno, con, curname, subxact_level, with_hold, scrollable);
 
 	return true;
 }
 
 /*
+ * Canonicalize the amount of cursor movement.
+ */
+static bool
+ecpg_canonical_cursor_movement(enum ECPG_cursor_direction *direction, const char *amount,
+				bool *fetchall, int64 *amount_out)
+{
+	bool		negate = false;
+	int64		amount1;
+
+	/*
+	 * We might have got a constant string from the grammar.
+	 * We have to handle the negative and explicitely positive constants
+	 * here because e.g. '-2' arrives as '- 2' from the grammar.
+	 * strtoll() under Linux stops processing at the space.
+	 */
+	if (amount[0] == '-' || amount[0] == '+')
+	{
+		negate = (amount[0] == '-');
+		amount++;
+		while (*amount == ' ')
+			amount++;
+	}
+
+	/* FETCH/MOVE [ FORWARD | BACKWARD ] ALL */
+	if (strcmp(amount, "all") == 0)
+	{
+		*fetchall = true;
+		amount1 = 0;
+	}
+	else
+	{
+		char	   *endptr;
+
+		amount1 = strtoll(amount, &endptr, 10);
+
+		if (*endptr)
+			return false;
+
+		if (negate)
+			amount1 = -amount1;
+		*fetchall = false;
+	}
+
+	/*
+	 * Canonicalize ECPGc_backward but don't lose
+	 * FETCH BACKWARD ALL semantics.
+	 */
+	if ((*fetchall == false) && (*direction == ECPGc_backward))
+	{
+		amount1 = -amount1;
+		*direction = ECPGc_forward;
+	}
+
+	*amount_out = amount1;
+	return true;
+}
+
+/*
  * ECPGfetch
  * Execute a FETCH or MOVE statement for the application.
  *
  * This function maintains the internal cursor descriptor and
- * reduces the the network roundtrip by returning early for
- * an unknown cursor name.
+ * reduces the the network roundtrip by:
+ * - returning early for an unknown cursor name
+ * - checking whether the cursor is scrollable against the direction
  */
 bool
 ECPGfetch(const int lineno, const int compat, const int force_indicator,
 				const char *connection_name, const bool questionmarks,
+				enum ECPG_cursor_direction dir, const char *amount,
 				const char *curname, const int st, const char *query, ...)
 {
 	struct connection  *con = ecpg_get_connection(connection_name);
 	struct cursor_descriptor *cur;
+	struct statement   *stmt;
+	int64		amount1;
+	bool		fetchall;
 	bool		ret;
 	va_list		args;
 
@@ -297,12 +363,67 @@ ECPGfetch(const int lineno, const int compat, const int force_indicator,
 		return false;
 
 	va_start(args, query);
-	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks,
-									st,
-									query,
-									args);
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator,
+				connection_name, questionmarks,
+				(enum ECPG_statement_type) st,
+				query, args, &stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		va_end(args);
+		return false;
+	}
+
 	va_end(args);
 
+	if (!ecpg_build_params(stmt, (dir >= ECPGc_absolute_in_var)))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (dir >= ECPGc_absolute_in_var)
+	{
+		dir -= ECPGc_absolute_in_var;
+		amount = stmt->cursor_amount;
+	}
+
+	if (!ecpg_canonical_cursor_movement(&dir, amount, &fetchall, &amount1))
+	{
+		ecpg_do_epilogue(stmt);
+		ecpg_raise(lineno, ECPG_NUMERIC_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, amount);
+		con->client_side_error = true;
+		return false;
+	}
+
+	if (cur->scrollable == ECPGcs_no_scroll && (amount1 < 0 || dir == ECPGc_backward))
+	{
+		ecpg_do_epilogue(stmt);
+		ecpg_raise(lineno, ECPG_NUMERIC_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, amount);
+		con->client_side_error = true;
+		return false;
+	}
+
+	if (!ecpg_autostart_transaction(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true, false))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	ecpg_do_epilogue(stmt);
+
 	return ret;
 }
 
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index 70da2b9..b5b5550 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -218,6 +218,13 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
 			   translator: this string will be truncated at 149 characters expanded.  */
 					 ecpg_gettext("invalid cursorname \"%s\" on line %d"), str, line);
 			}
+			else if (strcmp(sqlstate, ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE) == 0)
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			/*
+			   translator: this string will be truncated at 149 characters expanded.  */
+					 ecpg_gettext("cursor \"%s\" can only scan forward on line %d"), str, line);
+			}
 			else
 			{
 				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 3f5997c..18e3461 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -105,6 +105,7 @@ free_statement(struct statement * stmt)
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
 	ecpg_free(stmt->oldlocale);
+	ecpg_free(stmt->cursor_amount);
 	ecpg_free(stmt);
 }
 
@@ -1133,7 +1134,7 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
  *	an array of strings for PQexecParams().
  */
 bool
-ecpg_build_params(struct statement * stmt)
+ecpg_build_params(struct statement * stmt, bool first_0_is_cursor_amount)
 {
 	struct variable *var;
 	int			desc_counter = 0;
@@ -1365,6 +1366,17 @@ ecpg_build_params(struct statement * stmt)
 		 */
 		else if (stmt->command[position] == '0')
 		{
+			if (first_0_is_cursor_amount)
+			{
+				stmt->cursor_amount = ecpg_strdup(tobeinserted, stmt->lineno);
+				if (stmt->cursor_amount == NULL)
+				{
+					ecpg_free_params(stmt, false);
+					return false;
+				}
+				first_0_is_cursor_amount = false;
+			}
+
 			if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
 			{
 				ecpg_free_params(stmt, false);
@@ -2069,7 +2081,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_build_params(stmt))
+	if (!ecpg_build_params(stmt, false))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 5bb7ecd..bc54a84 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -66,6 +66,7 @@ struct statement
 	char	   *oldlocale;
 	int		nparams;
 	char	  **paramvalues;
+	char	   *cursor_amount;
 	PGresult   *results;
 };
 
@@ -98,6 +99,7 @@ struct cursor_descriptor {
 	 */
 	int		subxact_level;
 	bool		with_hold;
+	enum ECPG_cursor_scroll scrollable;
 };
 
 /* structure to store connections */
@@ -202,7 +204,7 @@ void		ecpg_free_params(struct statement *stmt, bool print);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 				  enum ECPG_statement_type, const char *, va_list,
 				  struct statement **);
-bool		ecpg_build_params(struct statement *);
+bool		ecpg_build_params(struct statement *, bool);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
 bool		ecpg_process_output(struct statement *, int, int, int, int, bool, bool);
@@ -249,6 +251,7 @@ void		ecpg_commit_cursors(int lineno, struct connection * conn, bool rollback, i
 #define ECPG_SQLSTATE_SYNTAX_ERROR			"42601"
 #define ECPG_SQLSTATE_DATATYPE_MISMATCH		"42804"
 #define ECPG_SQLSTATE_DUPLICATE_CURSOR		"42P03"
+#define ECPG_SQLSTATE_OBJECT_NOT_IN_PREREQUISITE_STATE	"55000"
 
 /* implementation-defined internal errors of ecpg */
 #define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR	"YE000"
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 1ac15d5..ace2d2c 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -65,8 +65,10 @@ char	   *ECPGerrmsg(void);
 
 /* Cursor functions */
 bool		ECPGopen(const int, const int, const int, const char *, const bool, const bool,
+				enum ECPG_cursor_scroll,
 				const char *, const int, const char *, ...);
 bool		ECPGfetch(const int, const int, const int, const char *, const bool,
+				enum ECPG_cursor_direction, const char *,
 				const char *, const int, const char *, ...);
 bool		ECPGcursor_dml(const int, const int, const int, const char *, const bool,
 				const char *, const int, const char *, ...);
diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h
index 7cc47e9..72b8596 100644
--- a/src/interfaces/ecpg/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -99,6 +99,25 @@ enum ECPG_statement_type
 	ECPGst_prepnormal
 };
 
+enum ECPG_cursor_direction
+{
+	ECPGc_absolute,
+	ECPGc_relative,
+	ECPGc_forward,
+	ECPGc_backward,
+	ECPGc_absolute_in_var,
+	ECPGc_relative_in_var,
+	ECPGc_forward_in_var,
+	ECPGc_backward_in_var
+};
+
+enum ECPG_cursor_scroll
+{
+	ECPGcs_unspecified,
+	ECPGcs_no_scroll,
+	ECPGcs_scroll
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index df85424..a3bc1ad 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -130,6 +130,12 @@ ECPG: TransactionStmtROLLBACKPREPAREDSconst addon
 		transact_start = false;
 		transact_rollback = true;
 		transact_name = NULL;
+ECPG: cursor_options addon
+		current_cursor_scrollable = ECPGcs_unspecified;
+ECPG: cursor_optionscursor_optionsNOSCROLL addon
+		current_cursor_scrollable = ECPGcs_no_scroll;
+ECPG: cursor_optionscursor_optionsSCROLL addon
+		current_cursor_scrollable = ECPGcs_scroll;
 ECPG: stmtViewStmt rule
 	| ECPGAllocateDescr
 	{
@@ -303,6 +309,8 @@ ECPG: fetch_argscursor_name addon
 			free($1);
 			$1 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsfrom_incursor_name addon
 		add_additional_variables($2, false);
 		if ($2[0] == ':')
@@ -310,10 +318,44 @@ ECPG: fetch_argsfrom_incursor_name addon
 			free($2);
 			$2 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsNEXTopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsPRIORopt_from_incursor_name addon
+		add_additional_variables($3, false);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1"); 
 ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("1");
 ECPG: fetch_argsLAST_Popt_from_incursor_name addon
+		add_additional_variables($3, false);
+		if ($3[0] == ':')
+		{
+			free($3);
+			$3 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_absolute;
+		current_cursor_amount = mm_strdup("-1");
 ECPG: fetch_argsALLopt_from_incursor_name addon
 		add_additional_variables($3, false);
 		if ($3[0] == ':')
@@ -321,6 +363,8 @@ ECPG: fetch_argsALLopt_from_incursor_name addon
 			free($3);
 			$3 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 		add_additional_variables($3, false);
 		if ($3[0] == ':')
@@ -332,8 +376,23 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 		{
 			free($1);
 			$1 = mm_strdup("$0");
+			current_cursor_direction = ECPGc_forward_in_var;
+			current_cursor_amount = NULL;
+		}
+		else
+		{
+			current_cursor_direction = ECPGc_forward;
+			current_cursor_amount = mm_strdup($1);
 		}
 ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
 		add_additional_variables($4, false);
 		if ($4[0] == ':')
@@ -341,9 +400,65 @@ ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
 			free($4);
 			$4 = mm_strdup("$0");
 		}
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("all");
 ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+			current_cursor_direction = ECPGc_absolute_in_var;
+			current_cursor_amount = NULL;
+		}
+		else
+		{
+			current_cursor_direction = ECPGc_absolute;
+			current_cursor_amount = mm_strdup($2);
+		}
 ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+			current_cursor_direction = ECPGc_relative_in_var;
+			current_cursor_amount = NULL;
+		}
+		else
+		{
+			current_cursor_direction = ECPGc_relative;
+			current_cursor_amount = mm_strdup($2);
+		}
 ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
+		add_additional_variables($4, false);
+		if ($4[0] == ':')
+		{
+			free($4);
+			$4 = mm_strdup("$0");
+		}
+		if ($2[0] == '$')
+		{
+			free($2);
+			$2 = mm_strdup("$0");
+			current_cursor_direction = ECPGc_forward_in_var;
+			current_cursor_amount = NULL;
+		}
+		else
+		{
+			current_cursor_direction = ECPGc_forward;
+			current_cursor_amount = mm_strdup($2);
+		}
 ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 		add_additional_variables($4, false);
 		if ($4[0] == ':')
@@ -355,6 +470,13 @@ ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 		{
 			free($2);
 			$2 = mm_strdup("$0");
+			current_cursor_direction = ECPGc_backward_in_var;
+			current_cursor_amount = NULL;
+		}
+		else
+		{
+			current_cursor_direction = ECPGc_backward;
+			current_cursor_amount = mm_strdup($2);
 		}
 ECPG: cursor_namename block
 		{
@@ -411,6 +533,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		this->connection = connection;
 		this->opened = false;
 		this->with_hold = (strncmp($5, "with ", 5) == 0);
+		this->scrollable = current_cursor_scrollable;
 		this->vartype = current_cursor_vartype;
 		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7);
 		this->argsinsert = argsinsert;
@@ -518,48 +641,64 @@ ECPG: FetchStmtMOVEfetch_args rule
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker);
 	}
 	| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker);
 	}
 	| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker);
 	}
 	| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker);
 	}
 	| MOVE FORWARD cursor_name
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("move forward"), cursor_marker);
 	}
 	| MOVE FORWARD from_in cursor_name
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		current_cursor_direction = ECPGc_forward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("move forward from"), cursor_marker);
 	}
 	| MOVE BACKWARD cursor_name
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("move backward"), cursor_marker);
 	}
 	| MOVE BACKWARD from_in cursor_name
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		current_cursor_direction = ECPGc_backward;
+		current_cursor_amount = mm_strdup("1");
 		$$ = cat_str(2, mm_strdup("move backward from"), cursor_marker);
 	}
 ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index eb3511c..30dac39 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -36,6 +36,10 @@ int struct_level = 0;
 int braces_open; /* brace level counter */
 char *current_function;
 char *current_cursor = NULL;
+enum ECPGttype current_cursor_vartype;
+enum ECPG_cursor_direction current_cursor_direction;
+enum ECPG_cursor_scroll current_cursor_scrollable;
+char *current_cursor_amount = NULL;
 bool transact_prepared = false;
 bool transact_start = false;
 bool transact_rollback = false;
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 71a802f..276735a 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -317,6 +317,7 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			this->connection = connection;
 			this->opened = false;
 			this->with_hold = (strncmp($5, "with ", 5) == 0);
+			this->scrollable = current_cursor_scrollable;
 			this->vartype = current_cursor_vartype;
 			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
 			this->argsresult = NULL;
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index f3d39ce..134b581 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -31,7 +31,10 @@ extern int	braces_open,
 			ecpg_internal_var;
 extern char *current_function;
 extern char *current_cursor;
-enum ECPGttype current_cursor_vartype;
+extern enum ECPGttype current_cursor_vartype;
+extern enum ECPG_cursor_direction current_cursor_direction;
+extern enum ECPG_cursor_scroll current_cursor_scrollable;
+extern char *current_cursor_amount;
 extern char *descriptor_index;
 extern char *descriptor_name;
 extern char *connection;
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index a49b89c..22fb67e 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -125,6 +125,23 @@ static char *ecpg_statement_type_name[] = {
 	"ECPGst_prepnormal"
 };
 
+static char *ecpg_cursor_direction_name[] = {
+	"ECPGc_absolute",
+	"ECPGc_relative",
+	"ECPGc_forward",
+	"ECPGc_backward",
+	"ECPGc_absolute_in_var",
+	"ECPGc_relative_in_var",
+	"ECPGc_forward_in_var",
+	"ECPGc_backward_in_var"
+};
+
+static char *ecpg_cursor_scroll_name[] = {
+	"ECPGcs_unspecified",
+	"ECPGcs_no_scroll",
+	"ECPGcs_scroll"
+};
+
 static void output_cursor_name(struct cursor *ptr)
 {
 	if (current_cursor[0] == ':')
@@ -226,7 +243,9 @@ output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st
 {
 	struct cursor *ptr = get_cursor(current_cursor);
 
-	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks, ptr->with_hold);
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, %s, ",
+						compat, force_indicator, connection ? connection : "NULL", questionmarks,
+						ptr->with_hold, ecpg_cursor_scroll_name[ptr->scrollable]);
 	output_cursor_name(ptr);
 	output_statement_epilogue(stmt, whenever_mode, st);
 }
@@ -235,10 +254,24 @@ void
 output_fetch_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 {
 	struct cursor *ptr = get_cursor(current_cursor);
+	char	   *amount;
+
+	if (current_cursor_amount)
+	{
+		amount = mm_alloc(strlen(current_cursor_amount) + 3);
+		sprintf(amount, "\"%s\"", current_cursor_amount);
+		free(current_cursor_amount);
+	}
+	else
+		amount = mm_strdup("NULL");
 
-	fprintf(yyout, "{ ECPGfetch(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	fprintf(yyout, "{ ECPGfetch(__LINE__, %d, %d, %s, %d, %s, %s, ",
+						compat, force_indicator, connection ? connection : "NULL", questionmarks,
+						ecpg_cursor_direction_name[current_cursor_direction], amount);
 	output_cursor_name(ptr);
 	output_statement_epilogue(stmt, whenever_mode, st);
+	free(amount);
+	current_cursor_amount = NULL;
 }
 
 void
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index a293e9e..f0a26f5 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -131,6 +131,7 @@ struct cursor
 	bool		opened;
 	bool		with_hold;
 	enum ECPGttype	vartype;
+	enum ECPG_cursor_scroll scrollable;
 	struct arguments *argsinsert;
 	struct arguments *argsinsert_oos;
 	struct arguments *argsresult;
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index e47b373..ceb95c1 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 101 "sqlda.pgc"
@@ -258,7 +258,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, ECPGc_forward, "1", "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 109 "sqlda.pgc"
@@ -316,7 +316,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
@@ -333,7 +333,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "mycur2", ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, ECPGc_forward, "1", "mycur2", ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 146 "sqlda.pgc"
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
index f88f9f2..8258bcc 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
@@ -158,7 +158,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "c", ECPGst_normal, "fetch forward c", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, ECPGc_forward, "1", "c", ECPGst_normal, "fetch forward c", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), 
@@ -244,7 +244,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 static void openit(void)
 {
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
 	ECPGt_int,&(*( int  *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 95 "test_informix.pgc"
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
index 715f960..f055ae6 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
@@ -82,7 +82,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur cursor for select id , d , d from nantest1 */
 #line 33 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 34 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -90,7 +90,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_double,&(d),(long)1,(long)1,sizeof(double), 
@@ -137,7 +137,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 48 "nan_test.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 50 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_double,&(d),(long)1,(long)1,sizeof(double), 
@@ -221,7 +221,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur1 cursor for select id , d , d from nantest2 */
 #line 75 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
 #line 76 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -229,7 +229,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "fetch from cur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "cur1", ECPGst_normal, "fetch from cur1", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_numeric,&(num),(long)1,(long)0,sizeof(numeric), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
index 8872986..2a9d890 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
@@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 35 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -143,7 +143,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 37 "autoprep.pgc"
 
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 39 "autoprep.pgc"
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 46 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 48 "autoprep.pgc"
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
   i = 0;
   while (1)
   {
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "fetch cur1", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "cur1", ECPGst_normal, "fetch cur1", ECPGt_EOIT, 
 	ECPGt_int,&(item1),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), ECPGt_EORT);
 #line 55 "autoprep.pgc"
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.c b/src/interfaces/ecpg/test/expected/preproc-cursor.c
index 6f92797..8ba2987 100644
--- a/src/interfaces/ecpg/test/expected/preproc-cursor.c
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor.c
@@ -187,7 +187,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 67 "cursor.pgc"
@@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch forward from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname1, ECPGst_normal, "fetch forward from $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -212,7 +212,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch forward $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname1, ECPGst_normal, "fetch forward $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -227,7 +227,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname1, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -243,7 +243,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname1, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
@@ -260,7 +260,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move in");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "move absolute 0 in $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_absolute, "0", curname1, ECPGst_normal, "move absolute 0 in $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 87 "cursor.pgc"
@@ -270,7 +270,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname1, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -286,7 +286,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname1, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
@@ -323,7 +323,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -337,7 +337,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname2, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -352,7 +352,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname2, ECPGst_normal, "fetch $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -367,7 +367,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname2, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -383,7 +383,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname2, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
@@ -400,7 +400,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_absolute, "0", curname2, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -414,7 +414,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname2, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -430,7 +430,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname2, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
@@ -483,7 +483,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname3, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, curname3, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -493,7 +493,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 if (sqlca.sqlcode < 0) exit (1);}
 #line 153 "cursor.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, curname5, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, ECPGcs_unspecified, curname5, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test2", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -505,7 +505,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch");
-	{ ECPGfetch(__LINE__, 0, 1, "test2", 0, curname5, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test2", 0, ECPGc_forward, "1", curname5, ECPGst_normal, "fetch $0", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -520,7 +520,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname3, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -535,7 +535,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname3, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -551,7 +551,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname3, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
@@ -568,7 +568,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_absolute, "0", curname3, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 174 "cursor.pgc"
@@ -578,7 +578,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname3, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -594,7 +594,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname3, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
@@ -663,7 +663,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -675,7 +675,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname4.arr, ECPGst_normal, "fetch from $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -690,7 +690,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname4.arr, ECPGst_normal, "fetch $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -705,7 +705,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname4.arr, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -721,7 +721,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname4.arr, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
@@ -738,7 +738,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_absolute, "0", curname4.arr, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 226 "cursor.pgc"
@@ -748,7 +748,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward, "1", curname4.arr, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -764,7 +764,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, ECPGc_forward_in_var, NULL, curname4.arr, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 99d181e..36dbea7 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -201,7 +201,7 @@ get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
 static void
 open_cur1(void)
 {
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
@@ -225,7 +225,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 static void
 get_record1(void)
 {
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur", ECPGst_normal, "fetch mycur", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "mycur", ECPGst_normal, "fetch mycur", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c
index 67d66a5..b227d31 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.c
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.c
@@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -206,7 +206,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	memset(i, 0, sizeof(ind_personal));
 	while (1) {
 		strcpy(msg, "fetch");
-		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "cur", ECPGst_normal, "fetch cur", ECPGt_EOIT, 
 	ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)1,sizeof(struct varchar_1), 
 	ECPGt_int,&(i->ind_name),(long)1,(long)1,sizeof(int), 
 	ECPGt_long,&(p->birth.born),(long)1,(long)1,sizeof(long), 
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c
index 8826cca..26e9655 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.c
+++ b/src/interfaces/ecpg/test/expected/sql-binary.c
@@ -111,12 +111,12 @@ main (void)
  /* declare C cursor for select name , accs , byte from empl where idnum = $1  */
 #line 58 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 59 "binary.pgc"
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
 	ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), 
@@ -142,12 +142,12 @@ main (void)
  /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
 #line 72 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 73 "binary.pgc"
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "B", ECPGst_normal, "fetch B", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "B", ECPGst_normal, "fetch B", ECPGt_EOIT, 
 	ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), 
@@ -176,12 +176,12 @@ main (void)
  /* declare A binary cursor for select byte from empl where idnum = $1  */
 #line 89 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 90 "binary.pgc"
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "A", ECPGst_normal, "fetch A", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "A", ECPGst_normal, "fetch A", ECPGt_EOIT, 
 	ECPGt_char,&(pointer),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
 #line 91 "binary.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
index 25eaa02..6dca2e6 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
@@ -90,7 +90,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 37 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 39 "cursorsubxact.pgc"
@@ -122,7 +122,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	curname = QUOTED_CURNAME;
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 57 "cursorsubxact.pgc"
@@ -181,7 +181,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 83 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 85 "cursorsubxact.pgc"
@@ -232,7 +232,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("savepoint (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 107 "cursorsubxact.pgc"
@@ -288,7 +288,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("rollback to (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", curname, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id[0]),(long)1,(long)1,sizeof(int), 
@@ -351,7 +351,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("savepoint (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 158 "cursorsubxact.pgc"
@@ -362,7 +362,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("open 5 failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", curname, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id[0]),(long)1,(long)1,sizeof(int), 
@@ -388,7 +388,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("rollback to (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", curname, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id[1]),(long)1,(long)1,sizeof(int), 
@@ -405,7 +405,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("fetch result (2) %d '%s'\n", id[1], t[2].arr);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 178 "cursorsubxact.pgc"
@@ -425,7 +425,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("rollback to (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 186 "cursorsubxact.pgc"
@@ -445,7 +445,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	if (sqlca.sqlcode < 0)
 		printf("release savepoint (a) failed with SQLSTATE %5s\n", sqlca.sqlstate);
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", curname, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id[2]),(long)1,(long)1,sizeof(int), 
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.c b/src/interfaces/ecpg/test/expected/sql-desc.c
index 6999768..2007112 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.c
+++ b/src/interfaces/ecpg/test/expected/sql-desc.c
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c1 cursor for $1 */
 #line 57 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "c1", ECPGst_normal, "declare c1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "c1", ECPGst_normal, "declare c1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -256,7 +256,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 58 "desc.pgc"
 
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "c1", ECPGst_normal, "fetch next from c1", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "c1", ECPGst_normal, "fetch next from c1", ECPGt_EOIT, 
 	ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), 
@@ -295,7 +295,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c2 cursor for $1 */
 #line 69 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "c2", ECPGst_normal, "declare c2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "c2", ECPGst_normal, "declare c2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -306,7 +306,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 70 "desc.pgc"
 
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "c2", ECPGst_normal, "fetch next from c2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "c2", ECPGst_normal, "fetch next from c2", ECPGt_EOIT, 
 	ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.c b/src/interfaces/ecpg/test/expected/sql-dyntest.c
index 7856a51..4571aee 100644
--- a/src/interfaces/ecpg/test/expected/sql-dyntest.c
+++ b/src/interfaces/ecpg/test/expected/sql-dyntest.c
@@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) error ( );}
 #line 58 "dyntest.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "myquery", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 60 "dyntest.pgc"
@@ -272,7 +272,7 @@ if (sqlca.sqlcode < 0) error ( );}
 
   while (1)
     {
-      { ECPGfetch(__LINE__, 0, 1, NULL, 0, "MYCURS", ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, 
+      { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "MYCURS", ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, 
 	ECPGt_descriptor, "MYDESC", 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 64 "dyntest.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c
index 326a3c3..ef1e4dd 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.c
+++ b/src/interfaces/ecpg/test/expected/sql-execute.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "execute.pgc"
@@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 52 "execute.pgc"
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "8", "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 72 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
@@ -215,7 +215,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 74 "execute.pgc"
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "CUR2", ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "CUR2", ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c
index 48bdaaf..70a50ba 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.c
@@ -99,7 +99,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 26 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
 #line 28 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -113,7 +113,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 30 "fetch.pgc"
 
   while (1) {
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
@@ -135,7 +135,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
   /* exec sql whenever not found  continue ; */
 #line 36 "fetch.pgc"
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_backward, "2", "C", ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 37 "fetch.pgc"
 
 
-  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch $0 in C", 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward_in_var, NULL, "C", ECPGst_normal, "fetch $0 in C", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
@@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 44 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 46 "fetch.pgc"
@@ -192,7 +192,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 48 "fetch.pgc"
 
   while (1) {
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "D", ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "D", ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.c b/src/interfaces/ecpg/test/expected/sql-oldexec.c
index a3f8948..361091f 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.c
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "oldexec.pgc"
@@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 52 "oldexec.pgc"
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, ECPGc_forward, "8", "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 71 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
@@ -209,7 +209,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 73 "oldexec.pgc"
 
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, "CUR3", ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, ECPGc_forward, "1", "CUR3", ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index bfb75ca..eae10d4 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 43 "quote.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
 #line 45 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -178,7 +178,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   while (true)
   {
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index 83804f5..253ccc3 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -251,7 +251,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 103 "sqlda.pgc"
@@ -268,7 +268,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "1", "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 111 "sqlda.pgc"
@@ -324,7 +324,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
@@ -334,7 +334,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch");
-	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur2", ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, ECPGc_forward, "all", "mycur2", ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 141 "sqlda.pgc"
#76Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#69)
1 attachment(s)
ECPG FETCH readahead, was: Re: ECPG fixes

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

$SUBJECT, the real thing. Needs all previous patches.
Compared the the previous incarnation, a lot of debugging
ecpg_log() lines are removed. The newly introduced regression
tests have much smaller .stderr outputs because of this,
the patch is about 800K smaller in total.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

26.patch.gzapplication/x-tar; name=26.patch.gzDownload
#77Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#76)
5 attachment(s)
Followup patches for ECPG readahead, was: Re: ECPG FETCH readahead

2013-11-20 15:25 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Followup patches/subfeatures for the ECPG readahead code.

The last (31st) patch drives all cursors through the readahead code
and changes a lot of regression tests. It's over 100K so I send it compressed.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

27.patchtext/x-patch; name=27.patchDownload
commit c6ba221f6a83f193303aa40e55ff917ec57e6967
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 13:37:45 2013 +0100

    ECPG: Allow overriding the cursor readahead window size using
    an environment variable for cursors where READAHEAD N was not
    explicitly specified. Preprocessed C source of some regression
    tests have changed.

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index bdea033..1c8ebe9 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -463,7 +463,10 @@ EXEC SQL COMMIT;
    Option <option>-r readahead=number</option> on the ECPG command line modifies
    the default readahead window size for all cursors. Explicit
    <literal>READAHEAD number</literal> sets the readahead window size for
-   the specified cursor.
+   the specified cursor. If this clause is not explicitly specified for a cursor
+   (option <option>-r readahead=number</option> is considered implicit), then
+   setting the <literal>ECPGFETCHSZ</literal> environment variable overrides
+   the readahead window size for all such cursors.
   </para>
 
   <para>
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index 7084752..88f7d2c 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -15,6 +15,12 @@
 #include "ecpgerrno.h"
 #include "extern.h"
 
+static bool	envvars_read = false;	/* the variables below are already
+					   initialized */
+static int	default_fetch_size = -1;/* use this value instead of the
+					   passed-in per-cursor window size.
+					   -1 means unset. */
+
 static char *ecpg_cursor_direction_sql_name[] = {
 	"absolute",
 	"relative",
@@ -25,7 +31,7 @@ static char *ecpg_cursor_direction_sql_name[] = {
 	"forward",
 	"backward"
 };
- 
+
 static bool ecpg_cursor_do_move_all(struct statement *stmt,
 					struct cursor_descriptor *cur,
 					enum ECPG_cursor_direction direction,
@@ -291,7 +297,7 @@ bool
 ECPGopen(const int lineno, const int compat, const int force_indicator,
 			const char *connection_name, const bool questionmarks,
 			const bool with_hold, enum ECPG_cursor_scroll scrollable,
-			long readahead,
+			long readahead, const bool allow_ra_override,
 			const char *curname, const int st, const char *query, ...)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
@@ -371,6 +377,35 @@ ECPGopen(const int lineno, const int compat, const int force_indicator,
 
 	ecpg_do_epilogue(stmt);
 
+	/* Process the environment variables only once */
+	if (!envvars_read)
+	{
+		char	   *tmp, *endptr;
+		long		fetch_size_env;
+
+		/*
+		 * If ECPGFETCHSZ is set, interpret it.
+		 * - If invalid or unset, ignore. Leave default_fetch_size == -1
+		 * - If ECPGFETCHSZ <= 0, caching is disabled (readahead = 1)
+		 * - Otherwise use the actual number
+		 */
+		tmp = getenv("ECPGFETCHSZ");
+		if (tmp)
+		{
+			fetch_size_env = strtol(tmp, &endptr, 10);
+			if (*endptr)
+				fetch_size_env = -1;
+			else
+			{
+				/* Readahead disabled */
+				if (fetch_size_env <= 0)
+					fetch_size_env = 1;
+			}
+			default_fetch_size = fetch_size_env;
+		}
+		envvars_read = true;
+	}
+
 	/* Finally add the cursor to the connection. */
 	if (con->subxact_desc)
 		subxact_level = con->subxact_desc->level;
@@ -378,7 +413,9 @@ ECPGopen(const int lineno, const int compat, const int force_indicator,
 		subxact_level =
 			(PQtransactionStatus(con->connection) != PQTRANS_IDLE ?
 										1 : 0);
-	add_cursor(lineno, con, curname, subxact_level, with_hold, scrollable, readahead);
+	add_cursor(lineno, con, curname, subxact_level, with_hold, scrollable,
+					(allow_ra_override && default_fetch_size >= 1 ?
+						default_fetch_size : readahead));
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 76735a0..6fb7755 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -65,7 +65,7 @@ char	   *ECPGerrmsg(void);
 
 /* Cursor functions */
 bool		ECPGopen(const int, const int, const int, const char *, const bool, const bool,
-				enum ECPG_cursor_scroll, long readahead,
+				enum ECPG_cursor_scroll, long, const bool,
 				const char *, const int, const char *, ...);
 bool		ECPGfetch(const int, const int, const int, const char *, const bool,
 				enum ECPG_cursor_direction, const char *, bool,
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index d3f47aa..96d9c56 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -535,14 +535,18 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsopt_readaheadCURSORopt_ho
 		this->with_hold = (strncmp($6, "with ", 5) == 0);
 		this->scrollable = current_cursor_scrollable;
 		if (strcmp($4, "default") == 0)
+		{
+			this->allow_ra_override = true;
 			this->fetch_readahead = fetch_readahead;
+		}
 		else
 		{
 			int	this_readahead = atoi($4);
 
 			if (this_readahead < 1)
 				mmerror(PARSE_ERROR, ET_ERROR, "cursor readahead cannot be less than 1");
-			this->fetch_readahead = atoi($4);
+			this->allow_ra_override = false;
+			this->fetch_readahead = this_readahead;
 		}
 		this->vartype = current_cursor_vartype;
 		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $6, mm_strdup("for"), $8);
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index fa6b5e6..99dd117 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -319,13 +319,17 @@ ECPGCursorStmt:	DECLARE cursor_name cursor_options opt_readahead CURSOR opt_hold
 			this->with_hold = (strncmp($6, "with ", 5) == 0);
 			this->scrollable = current_cursor_scrollable;
 			if (strcmp($4, "default") == 0)
+			{
+				this->allow_ra_override = true;
 				this->fetch_readahead = fetch_readahead;
+			}
 			else
 			{
 				int	this_readahead = atoi($4);
 
 				if (this_readahead < 1)
 					mmerror(PARSE_ERROR, ET_ERROR, "cursor readahead cannot be less than 1");
+				this->allow_ra_override = false;
 				this->fetch_readahead = this_readahead;
 			}
 			this->vartype = current_cursor_vartype;
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 8d0c3a5..5a206cc 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -243,10 +243,10 @@ output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st
 {
 	struct cursor *ptr = get_cursor(current_cursor);
 
-	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, %s, %ld, ",
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, %s, %ld, %d, ",
 						compat, force_indicator, connection ? connection : "NULL", questionmarks,
 						ptr->with_hold, ecpg_cursor_scroll_name[ptr->scrollable],
-						ptr->fetch_readahead);
+						ptr->fetch_readahead, ptr->allow_ra_override);
 	output_cursor_name(ptr);
 	output_statement_epilogue(stmt, whenever_mode, st);
 }
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 50a6057..be93397 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -130,6 +130,7 @@ struct cursor
 	char	   *connection;
 	bool		opened;
 	bool		with_hold;
+	bool		allow_ra_override;
 	long		fetch_readahead;
 	enum ECPGttype	vartype;
 	enum ECPG_cursor_scroll scrollable;
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 61c1027..2650987 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 101 "sqlda.pgc"
@@ -316,7 +316,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
index 650c9b1..7085780 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
@@ -244,7 +244,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 static void openit(void)
 {
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
 	ECPGt_int,&(*( int  *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 95 "test_informix.pgc"
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
index 0cfa63a..f81edd2 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
@@ -82,7 +82,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur cursor for select id , d , d from nantest1 */
 #line 33 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 34 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -137,7 +137,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 48 "nan_test.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 50 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -221,7 +221,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur1 cursor for select id , d , d from nantest2 */
 #line 75 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
 #line 76 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
index 3e13351..8230135 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
@@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 35 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 46 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 48 "autoprep.pgc"
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.c b/src/interfaces/ecpg/test/expected/preproc-cursor.c
index ed07e09..18acd70 100644
--- a/src/interfaces/ecpg/test/expected/preproc-cursor.c
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor.c
@@ -187,7 +187,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 67 "cursor.pgc"
@@ -323,7 +323,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -483,7 +483,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, curname3, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname3, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -493,7 +493,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 if (sqlca.sqlcode < 0) exit (1);}
 #line 153 "cursor.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, ECPGcs_unspecified, 1, curname5, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, ECPGcs_unspecified, 1, 1, curname5, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test2", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -663,7 +663,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 59bb7de..8979c44 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -201,7 +201,7 @@ get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
 static void
 open_cur1(void)
 {
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c
index 81b4ac3..d0b921f 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.c
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.c
@@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c
index 94c2b05..8874e24 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.c
+++ b/src/interfaces/ecpg/test/expected/sql-binary.c
@@ -111,7 +111,7 @@ main (void)
  /* declare C cursor for select name , accs , byte from empl where idnum = $1  */
 #line 58 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 59 "binary.pgc"
@@ -142,7 +142,7 @@ main (void)
  /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
 #line 72 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 73 "binary.pgc"
@@ -176,7 +176,7 @@ main (void)
  /* declare A binary cursor for select byte from empl where idnum = $1  */
 #line 89 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 90 "binary.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
index 800da8f..47ded6b 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
@@ -83,7 +83,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move absolute n (every 4th tuple forward, positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 38 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -150,7 +150,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for move absolute n (every 4th tuple backward, negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 73 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -217,7 +217,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch relative 4 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 108 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -290,7 +290,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch relative -4 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 153 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -380,7 +380,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch forward 4 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 205 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -453,7 +453,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch forward -4 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 250 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -544,7 +544,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move absolute n (every 5th tuple forward, positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 303 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -655,7 +655,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move absolute n (every 5th tuple backward, negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 364 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -767,7 +767,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for fetch relative 5 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 426 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -889,7 +889,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move relative -5 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 497 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
index a8d01a3..47d71b1 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
@@ -76,7 +76,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 35 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -105,7 +105,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test noscroll_cur for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_no_scroll, 8, "noscroll_cur", ECPGst_normal, "declare noscroll_cur no scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_no_scroll, 8, 0, "noscroll_cur", ECPGst_normal, "declare noscroll_cur no scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 49 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -134,7 +134,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test unspec_cur1 for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, "unspec_cur1", ECPGst_normal, "declare unspec_cur1 cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, "unspec_cur1", ECPGst_normal, "declare unspec_cur1 cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -163,7 +163,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test unspec_cur2 for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, "unspec_cur2", ECPGst_normal, "declare unspec_cur2 cursor for select t1 . id , t1 . t , t2 . id , t2 . t from t1 join t1 as t2 on ( t1 . id = 27 - t2 . id ) order by t1 . id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, "unspec_cur2", ECPGst_normal, "declare unspec_cur2 cursor for select t1 . id , t1 . t , t2 . id , t2 . t from t1 join t1 as t2 on ( t1 . id = 27 - t2 . id ) order by t1 . id", ECPGt_EOIT, ECPGt_EORT);
 #line 77 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -194,7 +194,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move relative 8\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 93 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -248,7 +248,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move forward 8\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 127 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
index c2959ee..852fee0 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
@@ -157,7 +157,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 70 "cursor-ra-swdir.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 4, "mycur", ECPGst_normal, "declare mycur cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 4, 0, "mycur", ECPGst_normal, "declare mycur cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 72 "cursor-ra-swdir.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
index 4fce79b..a25348e 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
@@ -92,7 +92,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 39 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 41 "cursorsubxact.pgc"
@@ -129,7 +129,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	curname = QUOTED_CURNAME;
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 64 "cursorsubxact.pgc"
@@ -196,7 +196,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 98 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 100 "cursorsubxact.pgc"
@@ -255,7 +255,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"savepoint a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 130 "cursorsubxact.pgc"
@@ -413,7 +413,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"savepoint a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 220 "cursorsubxact.pgc"
@@ -473,7 +473,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("fetch from %s (case sensitive) unexpectedly succeeded (expected 34000)\n", curname);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 246 "cursorsubxact.pgc"
@@ -497,7 +497,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"rollback to a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 258 "cursorsubxact.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.c b/src/interfaces/ecpg/test/expected/sql-desc.c
index 5624774..de0ab8a 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.c
+++ b/src/interfaces/ecpg/test/expected/sql-desc.c
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c1 cursor for $1 */
 #line 57 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "c1", ECPGst_normal, "declare c1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c1", ECPGst_normal, "declare c1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -295,7 +295,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c2 cursor for $1 */
 #line 69 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "c2", ECPGst_normal, "declare c2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c2", ECPGst_normal, "declare c2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.c b/src/interfaces/ecpg/test/expected/sql-dyntest.c
index 1ca75a6..deb1bb2 100644
--- a/src/interfaces/ecpg/test/expected/sql-dyntest.c
+++ b/src/interfaces/ecpg/test/expected/sql-dyntest.c
@@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) error ( );}
 #line 58 "dyntest.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "myquery", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 60 "dyntest.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c
index d81dd77..638628d 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.c
+++ b/src/interfaces/ecpg/test/expected/sql-execute.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "execute.pgc"
@@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 72 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c
index 900d96e..8b6117d 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.c
@@ -99,7 +99,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 26 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
 #line 28 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 44 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 46 "fetch.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.c b/src/interfaces/ecpg/test/expected/sql-oldexec.c
index 69a6c57..ea5f4cc 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.c
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "oldexec.pgc"
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 71 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 91a7501..a2eba0d 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 43 "quote.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
 #line 45 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index 927540a..eb3384e 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -251,7 +251,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 103 "sqlda.pgc"
@@ -324,7 +324,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
28.patchtext/x-patch; name=28.patchDownload
commit 68c18b862f3aa1520cd1c82ed122c8e5a61daec0
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 13:42:43 2013 +0100

    ECPG: Allow returning the number of tuples in the cursor at the time
    of opening it if the user explicitly asked for it. This emulates
    the behaviour of Informix but can be useful natively, too.

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 1c8ebe9..2a481c4 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -477,6 +477,15 @@ EXEC SQL COMMIT;
    For this reason, <literal>READAHEAD 1</literal> is recommended.
   </para>
 
+  <para>
+   There is also a possibility to return the number of tuples returned by the cursor
+   in sqlca.sqlerrd[2] at <command>OPEN</command>. To turn this on, use the
+   <option>-r detect-cursor-resultset-size</option> ECPG command line parameter.
+   This may cause side effects if the cursor query contains calls to volatile
+   functions. See <xref linkend="xfunc-volatility">. Using this feature also
+   slows down opening the cursor.
+  </para>
+
    <note>
     <para>
      The ECPG <command>DECLARE</command> command does not actually
@@ -4904,6 +4913,12 @@ struct
     processed row, if applicable, and
     <literal>sqlca.sqlerrd[2]</literal> contains the number of
     processed or returned rows, if applicable to the command.
+    The <command>OPEN</command> statement may return the
+    result set size in <literal>sqlca.sqlerrd[2]</literal> if
+    option <literal>-r detect-cursor-resultset-size</literal> 
+    is specified on the ECPG command line. This may cause side effects
+    because of traversing the result set. See <xref linkend="xfunc-volatility">.
+    It will also slow down opening the cursor.
    </para>
 
    <para>
diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml
index ddbdbe5..27b6435 100644
--- a/doc/src/sgml/ref/ecpg-ref.sgml
+++ b/doc/src/sgml/ref/ecpg-ref.sgml
@@ -175,6 +175,15 @@ PostgreSQL documentation
           </para>
          </listitem>
         </varlistentry>
+        <varlistentry>
+         <term><option>detect-cursor-resultset-size</option></term>
+         <listitem>
+          <para>
+           Detect the cursor result set size during <command>OPEN</command> and
+           return it in sqlca.sqlerrd[2].
+          </para>
+         </listitem>
+        </varlistentry>
        </variablelist></para>
      </listitem>
     </varlistentry>
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index 88f7d2c..8979c32 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -48,6 +48,15 @@ static bool ecpg_cursor_next_pos(struct statement *stmt,
 					int64 *next_pos_out, bool *next_atstart_out,
 					bool *next_atend_out, bool *error, bool *beyond_known);
 
+static bool ecpg_cursor_do_move_absolute(struct statement *stmt,
+					struct cursor_descriptor *cur,
+					int64 amount, int64 *return_pos);
+
+static bool ecpg_cursor_do_move_all(struct statement *stmt,
+					struct cursor_descriptor *cur,
+					enum ECPG_cursor_direction direction,
+					int64 *return_pos);
+
 static void
 raise_cursor_error(struct connection *con, int lineno, const char *name)
 {
@@ -297,11 +306,13 @@ bool
 ECPGopen(const int lineno, const int compat, const int force_indicator,
 			const char *connection_name, const bool questionmarks,
 			const bool with_hold, enum ECPG_cursor_scroll scrollable,
-			long readahead, const bool allow_ra_override,
+			long readahead, const bool allow_ra_override, bool return_rssz,
 			const char *curname, const int st, const char *query, ...)
 {
+	struct sqlca_t *sqlca = ECPGget_sqlca();
 	struct connection *con = ecpg_get_connection(connection_name);
 	struct statement *stmt;
+	struct cursor_descriptor *cur;
 	char	   *cmdstatus;
 	int		subxact_level;
 	va_list		args;
@@ -375,8 +386,6 @@ ECPGopen(const int lineno, const int compat, const int force_indicator,
 		return false;
 	}
 
-	ecpg_do_epilogue(stmt);
-
 	/* Process the environment variables only once */
 	if (!envvars_read)
 	{
@@ -413,10 +422,50 @@ ECPGopen(const int lineno, const int compat, const int force_indicator,
 		subxact_level =
 			(PQtransactionStatus(con->connection) != PQTRANS_IDLE ?
 										1 : 0);
-	add_cursor(lineno, con, curname, subxact_level, with_hold, scrollable,
+
+	cur = add_cursor(lineno, con, curname, subxact_level, with_hold, scrollable,
 					(allow_ra_override && default_fetch_size >= 1 ?
 						default_fetch_size : readahead));
 
+	/*
+	 * Now discover the number of tuples in the result set only if:
+	 * - the cursor is known scrollable, and
+	 * - the user requested to return the number of tuples in
+	 *   the result set.
+	 * Although this slows down OPEN, for some loads caching
+	 * still overweights it.
+	 *
+	 * One downside is the multiple evaluation of volatile functions
+	 * and their possible side effects.
+	 */
+	if (scrollable == ECPGcs_scroll && return_rssz)
+	{
+		int64		return_pos;
+
+		/*
+		 * We are at the start of the result set,
+		 * MOVE ALL returns the number of tuples in it.
+		 */
+		if (!ecpg_cursor_do_move_all(stmt, cur, ECPGc_forward, &return_pos))
+		{
+			del_cursor(con, lineno, curname);
+			ecpg_do_epilogue(stmt);
+			return false;
+		}
+
+		/* Go back to the beginning of the result set. */
+		if (!ecpg_cursor_move(stmt, cur, ECPGc_absolute, 0, false, true))
+		{
+			del_cursor(con, lineno, curname);
+			ecpg_do_epilogue(stmt);
+			return false;
+		}
+
+		sqlca->sqlerrd[2] = (return_pos <= LONG_MAX ? return_pos : 0);
+	}
+
+	ecpg_do_epilogue(stmt);
+
 	return true;
 }
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 6fb7755..de78378 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -65,7 +65,7 @@ char	   *ECPGerrmsg(void);
 
 /* Cursor functions */
 bool		ECPGopen(const int, const int, const int, const char *, const bool, const bool,
-				enum ECPG_cursor_scroll, long, const bool,
+				enum ECPG_cursor_scroll, long, const bool, const bool,
 				const char *, const int, const char *, ...);
 bool		ECPGfetch(const int, const int, const int, const char *, const bool,
 				enum ECPG_cursor_direction, const char *, bool,
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 453fe24..eb070ec 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -18,7 +18,8 @@ bool		autocommit = false,
 			force_indicator = true,
 			questionmarks = false,
 			regression_mode = false,
-			auto_prepare = false;
+			auto_prepare = false,
+			cursor_rssz = false;
 long		fetch_readahead = 1; /* No readahead by default */
 
 char	   *output_filename;
@@ -53,7 +54,7 @@ help(const char *progname)
 	printf(_("  -o OUTFILE     write result to OUTFILE\n"));
 	printf(_("  -r OPTION      specify run-time behavior; OPTION can be:\n"
 	 "                 \"no_indicator\", \"prepare\", \"questionmarks\",\n"
-	 "                 \"readahead=number\"\n"));
+	 "                 \"readahead=number\", \"detect-cursor-resultset-size\"\n"));
 	printf(_("  --regression   run in regression testing mode\n"));
 	printf(_("  -t             turn on autocommit of transactions\n"));
 	printf(_("  --version      output version information, then exit\n"));
@@ -247,6 +248,8 @@ main(int argc, char *const argv[])
 						return ILLEGAL_OPTION;
 					}
 				}
+				else if (strcmp(optarg, "detect-cursor-resultset-size") == 0)
+					cursor_rssz = true;
 				else
 				{
 					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]);
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 891c768..ede2038 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -24,7 +24,8 @@ extern bool autocommit,
 			force_indicator,
 			questionmarks,
 			regression_mode,
-			auto_prepare;
+			auto_prepare,
+			cursor_rssz;
 extern long	fetch_readahead;
 extern int	braces_open,
 			ret_value,
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 5a206cc..98b2588 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -243,10 +243,10 @@ output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st
 {
 	struct cursor *ptr = get_cursor(current_cursor);
 
-	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, %s, %ld, %d, ",
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, %s, %ld, %d, %d, ",
 						compat, force_indicator, connection ? connection : "NULL", questionmarks,
 						ptr->with_hold, ecpg_cursor_scroll_name[ptr->scrollable],
-						ptr->fetch_readahead, ptr->allow_ra_override);
+						ptr->fetch_readahead, ptr->allow_ra_override, cursor_rssz);
 	output_cursor_name(ptr);
 	output_statement_epilogue(stmt, whenever_mode, st);
 }
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 2650987..8d39c95 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 101 "sqlda.pgc"
@@ -316,7 +316,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
index 7085780..390082d 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
@@ -244,7 +244,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 static void openit(void)
 {
-	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
 	ECPGt_int,&(*( int  *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 95 "test_informix.pgc"
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
index f81edd2..5f633c4 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
@@ -82,7 +82,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur cursor for select id , d , d from nantest1 */
 #line 33 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 34 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -137,7 +137,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 48 "nan_test.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 50 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -221,7 +221,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur1 cursor for select id , d , d from nantest2 */
 #line 75 "nan_test.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
 #line 76 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
index 8230135..475bdc6 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
@@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 35 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 46 "autoprep.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 48 "autoprep.pgc"
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.c b/src/interfaces/ecpg/test/expected/preproc-cursor.c
index 18acd70..3ff4e00 100644
--- a/src/interfaces/ecpg/test/expected/preproc-cursor.c
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor.c
@@ -187,7 +187,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, 0, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 67 "cursor.pgc"
@@ -323,7 +323,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, 0, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -483,7 +483,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname3, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, 0, curname3, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -493,7 +493,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 if (sqlca.sqlcode < 0) exit (1);}
 #line 153 "cursor.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, ECPGcs_unspecified, 1, 1, curname5, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, ECPGcs_unspecified, 1, 1, 0, curname5, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test2", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -663,7 +663,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, ECPGcs_unspecified, 1, 1, 0, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 8979c44..8b7e990 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -201,7 +201,7 @@ get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
 static void
 open_cur1(void)
 {
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c
index d0b921f..e028003 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.c
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.c
@@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c
index 8874e24..6e711b2 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.c
+++ b/src/interfaces/ecpg/test/expected/sql-binary.c
@@ -111,7 +111,7 @@ main (void)
  /* declare C cursor for select name , accs , byte from empl where idnum = $1  */
 #line 58 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 59 "binary.pgc"
@@ -142,7 +142,7 @@ main (void)
  /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
 #line 72 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 73 "binary.pgc"
@@ -176,7 +176,7 @@ main (void)
  /* declare A binary cursor for select byte from empl where idnum = $1  */
 #line 89 "binary.pgc"
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 90 "binary.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
index 47ded6b..fa51afa 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.c
@@ -83,7 +83,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move absolute n (every 4th tuple forward, positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 38 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -150,7 +150,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for move absolute n (every 4th tuple backward, negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 73 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -217,7 +217,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch relative 4 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 108 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -290,7 +290,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch relative -4 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 153 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -380,7 +380,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch forward 4 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 205 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -453,7 +453,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur for fetch forward -4 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 250 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -544,7 +544,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move absolute n (every 5th tuple forward, positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 303 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -655,7 +655,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move absolute n (every 5th tuple backward, negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 364 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -767,7 +767,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for fetch relative 5 (positive positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 426 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -889,7 +889,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("\ntest scroll_cur4 for move relative -5 (negative positions)\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 4, 0, 0, "scroll_cur4", ECPGst_normal, "declare scroll_cur4 scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 497 "cursor-ra-fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
index 47d71b1..77115b8 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-move.c
@@ -76,7 +76,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 35 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -105,7 +105,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test noscroll_cur for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_no_scroll, 8, 0, "noscroll_cur", ECPGst_normal, "declare noscroll_cur no scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_no_scroll, 8, 0, 0, "noscroll_cur", ECPGst_normal, "declare noscroll_cur no scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 49 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -134,7 +134,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test unspec_cur1 for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, "unspec_cur1", ECPGst_normal, "declare unspec_cur1 cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, 0, "unspec_cur1", ECPGst_normal, "declare unspec_cur1 cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -163,7 +163,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test unspec_cur2 for move absolute -1\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, "unspec_cur2", ECPGst_normal, "declare unspec_cur2 cursor for select t1 . id , t1 . t , t2 . id , t2 . t from t1 join t1 as t2 on ( t1 . id = 27 - t2 . id ) order by t1 . id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 8, 0, 0, "unspec_cur2", ECPGst_normal, "declare unspec_cur2 cursor for select t1 . id , t1 . t , t2 . id , t2 . t from t1 join t1 as t2 on ( t1 . id = 27 - t2 . id ) order by t1 . id", ECPGt_EOIT, ECPGt_EORT);
 #line 77 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -194,7 +194,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move relative 8\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 93 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -248,7 +248,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("test scroll_cur for move forward 8\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_scroll, 8, 0, 0, "scroll_cur", ECPGst_normal, "declare scroll_cur scroll cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 127 "cursor-ra-move.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c b/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
index 852fee0..c3ab5fc 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-swdir.c
@@ -157,7 +157,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 70 "cursor-ra-swdir.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 4, 0, "mycur", ECPGst_normal, "declare mycur cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 4, 0, 0, "mycur", ECPGst_normal, "declare mycur cursor for select id , t from t1 order by id", ECPGt_EOIT, ECPGt_EORT);
 #line 72 "cursor-ra-swdir.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
index a25348e..bce9d2c 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
@@ -92,7 +92,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 39 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 41 "cursorsubxact.pgc"
@@ -129,7 +129,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	curname = QUOTED_CURNAME;
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 64 "cursorsubxact.pgc"
@@ -196,7 +196,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 98 "cursorsubxact.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 100 "cursorsubxact.pgc"
@@ -255,7 +255,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"savepoint a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 130 "cursorsubxact.pgc"
@@ -413,7 +413,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"savepoint a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 220 "cursorsubxact.pgc"
@@ -473,7 +473,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("fetch from %s (case sensitive) unexpectedly succeeded (expected 34000)\n", curname);
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 246 "cursorsubxact.pgc"
@@ -497,7 +497,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	else
 		printf("\"rollback to a\" succeeded\n");
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 258 "cursorsubxact.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.c b/src/interfaces/ecpg/test/expected/sql-desc.c
index de0ab8a..c6e3a08 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.c
+++ b/src/interfaces/ecpg/test/expected/sql-desc.c
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c1 cursor for $1 */
 #line 57 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c1", ECPGst_normal, "declare c1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "c1", ECPGst_normal, "declare c1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -295,7 +295,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c2 cursor for $1 */
 #line 69 "desc.pgc"
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "c2", ECPGst_normal, "declare c2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "c2", ECPGst_normal, "declare c2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.c b/src/interfaces/ecpg/test/expected/sql-dyntest.c
index deb1bb2..82bd4af 100644
--- a/src/interfaces/ecpg/test/expected/sql-dyntest.c
+++ b/src/interfaces/ecpg/test/expected/sql-dyntest.c
@@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) error ( );}
 #line 58 "dyntest.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "myquery", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 60 "dyntest.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c
index 638628d..2e209b4 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.c
+++ b/src/interfaces/ecpg/test/expected/sql-execute.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "execute.pgc"
@@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 72 "execute.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c
index 8b6117d..bd7c38e 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.c
@@ -99,7 +99,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 26 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
 #line 28 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 44 "fetch.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 46 "fetch.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.c b/src/interfaces/ecpg/test/expected/sql-oldexec.c
index ea5f4cc..6e81082 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.c
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.c
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "oldexec.pgc"
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 71 "oldexec.pgc"
 
 
-	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, ECPGcs_unspecified, 1, 1, 0, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index a2eba0d..913ceb4 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 43 "quote.pgc"
 
 
-  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
 #line 45 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index eb3384e..a249ac5 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -251,7 +251,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 103 "sqlda.pgc"
@@ -324,7 +324,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, ECPGcs_unspecified, 1, 1, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
29.patchtext/x-patch; name=29.patchDownload
commit f14a730dae6c563f8507ec2eb5b873b748a8fc32
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 13:50:16 2013 +0100

    ECPG: Increase the readahead window permanently if the application
    ever sends us FETCH FORWARD/BACKWARD/RELATIVE with an argument
    larger than the current readahead window. This invalidates the points
    and corner cases tested by src/interfaces/ecpg/test/sql/cursor-ra-fetch.pgc
    but not its results. Leave this test in place for reference.

diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index 8979c32..f366a3e 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -1952,6 +1952,16 @@ ECPGfetch(const int lineno, const int compat, const int force_indicator,
 		}
 		else
 		{
+			if (dir == ECPGc_forward || dir == ECPGc_relative)
+			{
+				if (llabs(amount1) > cur->readahead)
+				{
+					cur->readahead = llabs(amount1);
+					ecpg_log("ECPGfetch on line %d: permanently raising readahead window size to %lld\n",
+									lineno, (long long)cur->readahead);
+				}
+			}
+
 			if (!ecpg_cursor_fetch(stmt, cur, dir, amount1, fetchall))
 			{
 				ecpg_do_epilogue(stmt);
diff --git a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.stderr b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.stderr
index a22a294..e80a1fb 100644
--- a/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-cursor-ra-fetch.stderr
@@ -1646,13 +1646,15 @@
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 325: query: fetch backward 8 from scroll_cur4; fetch all: 0 amount: -8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 325: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ECPGfetch on line 325: permanently raising readahead window size to 8
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 325: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 325: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 325: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 325: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 325: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 325: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: 26 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1662,22 +1664,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: 23 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 325: RESULT: z offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 325: RESULT: y offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 325: RESULT: x offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 325: RESULT: w offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 325: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 325: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 325: command fetch backward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 325: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: 22 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: 21 offset: -1; array: no
@@ -1686,6 +1672,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: 19 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 325: RESULT: z offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 325: RESULT: y offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 325: RESULT: x offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 325: RESULT: w offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: v offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 325: RESULT: u offset: -1; array: no
@@ -1720,11 +1714,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 333: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 333: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 4 from scroll_cur4; returned 1 tuples
+[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 8 from scroll_cur4; returned 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 333: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1738,11 +1732,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 333: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 333: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 8 from scroll_cur4; returned 6 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 333: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1756,11 +1750,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 333: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 333: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 333: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 333: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 333: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1806,13 +1800,13 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 350: query: fetch forward 8 from scroll_cur4; fetch all: 0 amount: 8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 350: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 350: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 350: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 350: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 350: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 350: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 350: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: 2 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1822,22 +1816,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: 5 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 350: RESULT: b offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 350: RESULT: c offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 350: RESULT: d offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 350: RESULT: e offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 350: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 350: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 350: command fetch forward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 350: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: 6 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: 7 offset: -1; array: no
@@ -1846,6 +1824,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: 9 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 350: RESULT: b offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 350: RESULT: c offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 350: RESULT: d offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 350: RESULT: e offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: f offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 350: RESULT: g offset: -1; array: no
@@ -1964,13 +1950,15 @@
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 387: query: fetch forward 8 from scroll_cur4; fetch all: 0 amount: 8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 387: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ECPGfetch on line 387: permanently raising readahead window size to 8
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 387: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 387: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 387: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 387: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 387: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 387: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -1980,22 +1968,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 387: RESULT: a offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 387: RESULT: b offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 387: RESULT: c offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 387: RESULT: d offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 387: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 387: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 387: command fetch forward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 387: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: 5 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: 6 offset: -1; array: no
@@ -2004,6 +1976,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: 8 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 387: RESULT: a offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 387: RESULT: b offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 387: RESULT: c offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 387: RESULT: d offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: e offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 387: RESULT: f offset: -1; array: no
@@ -2038,11 +2018,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 395: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 395: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 4 from scroll_cur4; returned 1 tuples
+[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 8 from scroll_cur4; returned 1 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 395: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2056,11 +2036,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 395: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 395: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 8 from scroll_cur4; returned 6 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 395: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2074,11 +2054,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 395: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 395: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 395: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 395: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 395: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2124,13 +2104,13 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 412: query: fetch backward 8 from scroll_cur4; fetch all: 0 amount: -8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 412: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 412: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 412: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 412: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 412: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 412: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 412: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: 25 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2140,22 +2120,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: 22 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 412: RESULT: y offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 412: RESULT: x offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 412: RESULT: w offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 412: RESULT: v offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 412: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 412: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 412: command fetch backward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 412: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: 21 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: 20 offset: -1; array: no
@@ -2164,6 +2128,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: 18 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 412: RESULT: y offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 412: RESULT: x offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 412: RESULT: w offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 412: RESULT: v offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: u offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 412: RESULT: t offset: -1; array: no
@@ -2182,15 +2154,17 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 433: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGfetch on line 433: permanently raising readahead window size to 5
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 433: query: move relative 4 in scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 433: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 433: query: fetch forward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 433: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 433: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2200,19 +2174,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 433: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: move absolute 5 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: move relative 4 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 433: query: fetch forward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 433: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 433: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2222,19 +2188,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 433: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: move absolute 10 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: move relative 4 in scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 433: query: fetch forward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 433: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 433: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 433: command fetch forward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 433: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2282,13 +2240,15 @@
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 451: query: fetch backward 8 from scroll_cur4; fetch all: 0 amount: -8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 451: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ECPGfetch on line 451: permanently raising readahead window size to 8
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 451: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 451: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 451: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 451: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 451: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 451: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: 26 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2298,22 +2258,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: 23 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 451: RESULT: z offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 451: RESULT: y offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 451: RESULT: x offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 451: RESULT: w offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 451: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 451: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 451: command fetch backward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 451: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: 22 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: 21 offset: -1; array: no
@@ -2322,6 +2266,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: 19 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 451: RESULT: z offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 451: RESULT: y offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 451: RESULT: x offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 451: RESULT: w offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: v offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 451: RESULT: u offset: -1; array: no
@@ -2350,11 +2302,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 465: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 465: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 465: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 465: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 465: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 465: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2364,15 +2316,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 465: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: move absolute -14 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 465: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 465: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 465: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2386,11 +2330,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 465: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 465: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 465: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 465: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 465: command fetch backward 8 from scroll_cur4; returned 7 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 465: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2400,13 +2344,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 465: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: move absolute -20 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: fetch relative - 5 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: using PQexec
+[NO_PID]: ecpg_cursor_execute on line 465: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 465: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2416,23 +2354,15 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 465: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: query: fetch relative - 5 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 465: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 465: correctly got 0 tuples with 2 fields
+[NO_PID]: ecpg_cursor_execute on line 465: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: raising sqlcode 100 on line 465: no data found on line 465
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 483: query: fetch forward 8 from scroll_cur4; fetch all: 0 amount: 8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 483: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 483: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 483: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 483: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 483: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 483: correctly got 7 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2442,6 +2372,12 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 483: RESULT: 5 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 483: RESULT: 6 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 483: RESULT: 7 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: a offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: b offset: -1; array: no
@@ -2450,27 +2386,25 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: d offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 483: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 483: using PQexec
+[NO_PID]: ecpg_get_data on line 483: RESULT: e offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 483: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_get_data on line 483: RESULT: f offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 483: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 483: RESULT: g offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: 5 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 483: query: move absolute -20 in scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: 6 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 483: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: 7 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 483: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: 8 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 483: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: e offset: -1; array: no
+[NO_PID]: ecpg_cursor_execute on line 483: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: f offset: -1; array: no
+[NO_PID]: ecpg_process_output on line 483: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 483: RESULT: g offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 483: RESULT: 8 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 483: RESULT: h offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2496,6 +2430,8 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 511: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGfetch on line 511: permanently raising readahead window size to 5
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: query: move forward all in scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: using PQexec
@@ -2504,11 +2440,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 511: query: fetch backward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 511: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2518,19 +2454,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 511: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: move absolute -5 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: move relative -4 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 511: query: fetch backward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 511: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2540,19 +2468,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 511: query: fetch relative - 5 from scroll_cur4; fetch all: 0 amount: -5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: move absolute -10 in scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 511: query: fetch backward 5 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 511: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: move relative -4 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 511: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 511: command fetch backward 5 from scroll_cur4; returned 5 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 511: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2600,13 +2520,15 @@
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 529: query: fetch forward 8 from scroll_cur4; fetch all: 0 amount: 8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 529: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ECPGfetch on line 529: permanently raising readahead window size to 8
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 529: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 529: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 529: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 529: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 529: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 529: correctly got 8 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2616,22 +2538,6 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 529: RESULT: a offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 529: RESULT: b offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 529: RESULT: c offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 529: RESULT: d offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 529: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 529: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 529: command fetch forward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 529: correctly got 4 tuples with 2 fields
-[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: 5 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: 6 offset: -1; array: no
@@ -2640,6 +2546,14 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: 8 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 529: RESULT: a offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 529: RESULT: b offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 529: RESULT: c offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 529: RESULT: d offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: e offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 529: RESULT: f offset: -1; array: no
@@ -2668,11 +2582,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 543: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 543: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 543: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 543: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 543: command fetch forward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 543: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2682,15 +2596,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 543: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: move absolute 14 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 543: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 543: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 543: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2704,11 +2610,11 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 543: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: fetch forward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 543: query: fetch forward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_execute on line 543: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 543: command fetch forward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_cursor_execute on line 543: command fetch forward 8 from scroll_cur4; returned 7 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 543: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2718,13 +2624,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 543: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: move absolute 20 in scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: fetch relative 5 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: using PQexec
+[NO_PID]: ecpg_cursor_execute on line 543: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 543: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2734,23 +2634,15 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGfetch on line 543: query: fetch relative 5 from scroll_cur4; fetch all: 0 amount: 5
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: query: fetch relative 5 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 543: using PQexec
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 543: correctly got 0 tuples with 2 fields
+[NO_PID]: ecpg_cursor_execute on line 543: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: raising sqlcode 100 on line 543: no data found on line 543
 [NO_PID]: sqlca: code: 100, state: 02000
 [NO_PID]: ECPGfetch on line 561: query: fetch backward 8 from scroll_cur4; fetch all: 0 amount: -8
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 561: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 561: using PQexec
+[NO_PID]: ecpg_cursor_execute on line 561: tuple already in cache
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 561: command fetch backward 4 from scroll_cur4; returned 4 tuples
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 561: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_process_output on line 561: correctly got 7 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: 26 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -2760,6 +2652,12 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: 23 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 561: RESULT: 22 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 561: RESULT: 21 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 561: RESULT: 20 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: z offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: y offset: -1; array: no
@@ -2768,27 +2666,25 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: w offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 561: query: fetch backward 4 from scroll_cur4; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 561: RESULT: v offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 561: using PQexec
+[NO_PID]: ecpg_get_data on line 561: RESULT: u offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_cursor_execute on line 561: command fetch backward 4 from scroll_cur4; returned 4 tuples
+[NO_PID]: ecpg_get_data on line 561: RESULT: t offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 561: correctly got 4 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 561: query: move absolute 20 in scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: 22 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 561: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: 21 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 561: query: fetch backward 8 from scroll_cur4; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: 20 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 561: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: 19 offset: -1; array: no
+[NO_PID]: ecpg_cursor_execute on line 561: command fetch backward 8 from scroll_cur4; returned 8 tuples
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: v offset: -1; array: no
+[NO_PID]: ecpg_process_output on line 561: correctly got 1 tuples with 2 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: u offset: -1; array: no
-[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 561: RESULT: t offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 561: RESULT: 19 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 561: RESULT: s offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
30.patchtext/x-patch; name=30.patchDownload
commit c809a50d569bfde4d6520e8ce57f71bbe6159498
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Nov 20 13:51:29 2013 +0100

    ECPG: During FETCH ALL, temporarily use FETCHALL_MULTIPLIER times
    the current readahead window size. FETCHALL_MULTIPLIER == 1000.
    No change in regression tests.

diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index f366a3e..a3384ba 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -1554,6 +1554,7 @@ ecpg_cursor_fetch(struct statement *stmt, struct cursor_descriptor *cur,
 	long		ntuples;
 	int		step;
 	int64		prev_pos, next_pos, start_idx, var_index;
+	int64		old_readahead;
 
 	switch (direction)
 	{
@@ -1725,6 +1726,10 @@ abs_rel:
 			goto abs_rel;
 		}
 
+		old_readahead = cur->readahead;
+		if (fetchall)
+			cur->readahead *= FETCHALL_MULTIPLIER;
+
 		/*
 		 * The direction is backward if FETCH BACKWARD ALL
 		 * or the amount to fetch is negative.
@@ -1808,6 +1813,8 @@ abs_rel:
 
 		sqlca->sqlerrd[2] = (var_index <= LONG_MAX ? var_index : 0);
 
+		cur->readahead = old_readahead;
+
 		if (var_index == 0)
 		{
 			ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 612412f..de0f3b8 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -32,6 +32,7 @@ enum ARRAY_TYPE
 #define LOOP_FORWARD	(1)
 #define LOOP_BACKWARD	(-1)
 #define MAX_CACHE_MISS	(3)
+#define FETCHALL_MULTIPLIER	(1000)
 
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
#78Tom Lane
tgl@sss.pgh.pa.us
In reply to: Boszormenyi Zoltan (#70)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

Boszormenyi Zoltan <zb@cybertec.at> writes:

Attached is the patch that modified the command tag returned by
the DECLARE CURSOR command. It returns "DECLARE SCROLL CURSOR"
or "DECLARE NO SCROLL CURSOR" depending on the cursor's
scrollable flag that can be determined internally even if neither is
asked explicitly.

This does not strike me as an acceptable change. It will break any code
that's expecting the existing command tag, for little or no benefit
to most applications. Even if backwards compatibility were of no concern,
I'm not convinced it's a good thing to expose the backend's internal
choices about query plans used for cursors, which is what this is
basically doing.

It is expected by the ECPG cursor readahead code.

And that doesn't sound like a sufficient excuse. You should only assume a
cursor is scrollable if SCROLL was specified in the cursor declaration
command, which it'd seem to me is something ECPG would or easily could
know about commands it issues.

regards, tom lane

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

#79Boszormenyi Zoltan
zb@cybertec.at
In reply to: Tom Lane (#78)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-23 22:01 keltez�ssel, Tom Lane �rta:

Boszormenyi Zoltan <zb@cybertec.at> writes:

Attached is the patch that modified the command tag returned by
the DECLARE CURSOR command. It returns "DECLARE SCROLL CURSOR"
or "DECLARE NO SCROLL CURSOR" depending on the cursor's
scrollable flag that can be determined internally even if neither is
asked explicitly.

This does not strike me as an acceptable change. It will break any code
that's expecting the existing command tag, for little or no benefit
to most applications. Even if backwards compatibility were of no concern,
I'm not convinced it's a good thing to expose the backend's internal
choices about query plans used for cursors, which is what this is
basically doing.

I saw code in the backend allowing a cursor to be scrollable, although
it was not declared as such. How about ripping that out?

That way there would be no incentive for lazy SQL coding using simple cursors.

You can argue that it would also break application compatibility but
on the other hand, such a code has always been buggy and should be fixed.

It is expected by the ECPG cursor readahead code.

And that doesn't sound like a sufficient excuse. You should only assume a
cursor is scrollable if SCROLL was specified in the cursor declaration
command, which it'd seem to me is something ECPG would or easily could
know about commands it issues.

Yes, it can and I have a patch in the series passing this info to ecpglib.

I am also arguing for backward compatibility on a different angle:
this small backend change would still allow using simple cursors
in ECPG while using the cursor readahead.

And it's not the first time drivers have to adapt to new PostgreSQL major versions.
If it was, I wouldn't have the courage to set a precedent either.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#80Tom Lane
tgl@sss.pgh.pa.us
In reply to: Boszormenyi Zoltan (#79)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

Boszormenyi Zoltan <zb@cybertec.at> writes:

2013-11-23 22:01 keltez�ssel, Tom Lane �rta:

Boszormenyi Zoltan <zb@cybertec.at> writes:

Attached is the patch that modified the command tag returned by
the DECLARE CURSOR command. It returns "DECLARE SCROLL CURSOR"
or "DECLARE NO SCROLL CURSOR" depending on the cursor's
scrollable flag that can be determined internally even if neither is
asked explicitly.

This does not strike me as an acceptable change. It will break any code
that's expecting the existing command tag, for little or no benefit
to most applications. Even if backwards compatibility were of no concern,
I'm not convinced it's a good thing to expose the backend's internal
choices about query plans used for cursors, which is what this is
basically doing.

I saw code in the backend allowing a cursor to be scrollable, although
it was not declared as such. How about ripping that out?

That also fails the unnecessary-backwards-compatibility-break test.

regards, tom lane

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

#81Boszormenyi Zoltan
zb@cybertec.at
In reply to: Tom Lane (#80)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-27 19:16 keltez�ssel, Tom Lane �rta:

Boszormenyi Zoltan <zb@cybertec.at> writes:

2013-11-23 22:01 keltez�ssel, Tom Lane �rta:

Boszormenyi Zoltan <zb@cybertec.at> writes:

Attached is the patch that modified the command tag returned by
the DECLARE CURSOR command. It returns "DECLARE SCROLL CURSOR"
or "DECLARE NO SCROLL CURSOR" depending on the cursor's
scrollable flag that can be determined internally even if neither is
asked explicitly.

This does not strike me as an acceptable change. It will break any code
that's expecting the existing command tag, for little or no benefit
to most applications. Even if backwards compatibility were of no concern,
I'm not convinced it's a good thing to expose the backend's internal
choices about query plans used for cursors, which is what this is
basically doing.

I saw code in the backend allowing a cursor to be scrollable, although
it was not declared as such. How about ripping that out?

That also fails the unnecessary-backwards-compatibility-break test.

If you read the rest of the mail, it turns out it wasn't a serious question.

Getting the SCROLL / NO SCROLL flags from the preprocessor is no problem.
The only problem is when it's unspecified.

Treating it as NO SCROLL (or adding it to the DECLARE command behind
the application's back) would break apps that want to scroll backward.
(Not ABSOLUTE.)

On the other hand, what problems would one face when adding SCROLL
implicitly if it's unspecified? It's not a workable solution either, see below.

As the documentation suggests, an application that wants to use
UPDATE/DELETE WHERE CURRENT OF ..., it's highly recommended
that the cursor is for a FOR UPDATE query. Watch this scenario:

zozo=> begin;
BEGIN
zozo=> declare mycur cursor for select * from t1 for update;
DECLARE CURSOR
zozo=> fetch from mycur;
id | t
----+---
1 | a
(1 row)

zozo=> fetch from mycur;
id | t
----+---
2 | b
(1 row)

zozo=> update t1 set t=t||'_x' where current of mycur;
UPDATE 1
zozo=> fetch from mycur;
id | t
----+---
3 | c
(1 row)

zozo=> delete from t1 where current of mycur;
DELETE 1
zozo=> move absolute 0 in mycur;
MOVE 0
zozo=> fetch from mycur;
id | t
----+---
1 | a
(1 row)

zozo=> fetch from mycur;
id | t
----+---
(0 rows)

Although the server complains about MOVE BACKWARD, it's not
complaining about MOVE ABSOLUTE, despite it's clearly moving
backward. The cursor position is tracked in the backend in a long
variable and it's not overflowed. This is also legacy behaviour,
changing it would break backward compatibility.

The other problem I see is with the documentation: it says that
the INSENSITIVE keyword is just a placeholder, all cursors are insensitive.
It's clearly false. Moving back to the start, previously existing rows
won't show up again. It's not strictly a sensitive cursor, either,
because the row with id=2 would show up with the new value of "t".
This neither sensitive nor insensitive behaviour is what the SQL
standard calls an "asensitive" cursor. It would worth a doc change.
This is what's written in 9.3:

"
If the cursor's query includes FOR UPDATE or FOR SHARE, then returned rows are locked at
the time they are first fetched, in the same way as for a regular SELECT
<http://www.postgresql.org/docs/9.3/interactive/sql-select.html&gt; command with these
options. In addition, the returned rows will be the most up-to-date versions; therefore
these options provide the equivalent of what the SQL standard calls a "sensitive cursor".
(Specifying INSENSITIVE together with FOR UPDATE or FOR SHARE is an error.)
"
( http://www.postgresql.org/docs/9.3/interactive/sql-declare.html )

However, if the cursor is declared without FOR UPDATE, both
the explicit SCROLL keyword (or implicit, if the query is simple),
scrolling backward and DML with WHERE CURRENT OF are allowed.
In this case, the cursor is really insensitive, FETCH statements
after MOVE ABSOLUTE 0 return all rows with their original data.

This is just to show that adding SCROLL behind the application's
back is also pointless. If the query (which can also be a prepared
statement in ECPG) contains FOR UPDATE, adding SCROLL to the
DECLARE statement would make it fail.

If you consider all these:

- certain combinations of query and DECLARE stmt flags fail;
- adding NO SCROLL is breaking backward compatibility;
- the readahead code has to really know whether the cursor is
scrollable so it can behave just like the server;

then returning the SCROLL / NO SCROLL flag in the command tag is
not a bad solution in my view. In fact, this was the only workable
solution I could come up with to make it work reliably when neither
SCROLL nor NO SCROLL is specified by the application.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

#82Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Boszormenyi Zoltan (#81)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

Boszormenyi Zoltan escribi�:

If you consider all these:

- certain combinations of query and DECLARE stmt flags fail;
- adding NO SCROLL is breaking backward compatibility;
- the readahead code has to really know whether the cursor is
scrollable so it can behave just like the server;

then returning the SCROLL / NO SCROLL flag in the command tag is
not a bad solution in my view. In fact, this was the only workable
solution I could come up with to make it work reliably when neither
SCROLL nor NO SCROLL is specified by the application.

Would it work to have a function of some sort to which you give a cursor
name and it returns whether it is scrollable or not?

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

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

#83Tom Lane
tgl@sss.pgh.pa.us
In reply to: Boszormenyi Zoltan (#81)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

Boszormenyi Zoltan <zb@cybertec.at> writes:

If you consider all these:

- certain combinations of query and DECLARE stmt flags fail;
- adding NO SCROLL is breaking backward compatibility;
- the readahead code has to really know whether the cursor is
scrollable so it can behave just like the server;

If you're claiming that readahead inside ECPG will behave absolutely
transparently in all cases, I think that's bogus anyway. Consider for
example a query that will get a divide-by-zero error when it computes
the 110th row --- but the application stops after fetching 100 rows.
Everything's fine, until you insert some readahead logic. Queries
containing volatile functions might also not be happy about readahead.

Given these considerations, I think it'd be better to allow explicit
application control over whether read-ahead happens for a particular
query. And I have no problem whatsoever with requiring that the cursor
be explicitly marked SCROLL or NO SCROLL before read-ahead will occur.

regards, tom lane

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

#84Peter Eisentraut
peter_e@gmx.net
In reply to: Alvaro Herrera (#82)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

On 11/27/13, 2:49 PM, Alvaro Herrera wrote:

Would it work to have a function of some sort to which you give a cursor
name and it returns whether it is scrollable or not?

That might make sense. I think this case is similar to the question
whether a view is updatable. You wouldn't put that information in the
CREATE VIEW command tag.

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

#85Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#83)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

On 11/27/13, 3:47 PM, Tom Lane wrote:

Given these considerations, I think it'd be better to allow explicit
application control over whether read-ahead happens for a particular
query. And I have no problem whatsoever with requiring that the cursor
be explicitly marked SCROLL or NO SCROLL before read-ahead will occur.

Well, technically, unspecified means NO SCROLL according to the SQL
standard. A lot of applications in ECPG are ported from other systems,
which might make that assumption. It wouldn't be very nice to have to
change all that.

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

#86Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#85)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

Peter Eisentraut <peter_e@gmx.net> writes:

On 11/27/13, 3:47 PM, Tom Lane wrote:

Given these considerations, I think it'd be better to allow explicit
application control over whether read-ahead happens for a particular
query. And I have no problem whatsoever with requiring that the cursor
be explicitly marked SCROLL or NO SCROLL before read-ahead will occur.

Well, technically, unspecified means NO SCROLL according to the SQL
standard. A lot of applications in ECPG are ported from other systems,
which might make that assumption. It wouldn't be very nice to have to
change all that.

Hm. So you're suggesting that ECPG fix this problem by inserting an
explicit NO SCROLL clause into translated DECLARE CURSOR commands, if
there's not a SCROLL clause?

That would solve the problem of the ECPG library not being sure which
behavior applies, but it might break existing apps that were unknowingly
relying on a simple cursor being scrollable. OTOH any such app would be
subject to breakage anyway as a result of planner changes, so it's hard to
complain against this, as long as it's happening in a major version
update.

I'm for it.

regards, tom lane

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

#87Boszormenyi Zoltan
zb@cybertec.at
In reply to: Alvaro Herrera (#82)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-27 20:49 keltez�ssel, Alvaro Herrera �rta:

Boszormenyi Zoltan escribi�:

If you consider all these:

- certain combinations of query and DECLARE stmt flags fail;
- adding NO SCROLL is breaking backward compatibility;
- the readahead code has to really know whether the cursor is
scrollable so it can behave just like the server;

then returning the SCROLL / NO SCROLL flag in the command tag is
not a bad solution in my view. In fact, this was the only workable
solution I could come up with to make it work reliably when neither
SCROLL nor NO SCROLL is specified by the application.

Would it work to have a function of some sort to which you give a cursor
name and it returns whether it is scrollable or not?

D'oh. Yes, that would also work. Thanks for the idea. :-)
I will implement it and adapt my remaining patches.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#88Boszormenyi Zoltan
zb@cybertec.at
In reply to: Tom Lane (#86)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-28 00:17 keltez�ssel, Tom Lane �rta:

Peter Eisentraut <peter_e@gmx.net> writes:

On 11/27/13, 3:47 PM, Tom Lane wrote:

Given these considerations, I think it'd be better to allow explicit
application control over whether read-ahead happens for a particular
query. And I have no problem whatsoever with requiring that the cursor
be explicitly marked SCROLL or NO SCROLL before read-ahead will occur.

Well, technically, unspecified means NO SCROLL according to the SQL
standard. A lot of applications in ECPG are ported from other systems,
which might make that assumption. It wouldn't be very nice to have to
change all that.

Hm. So you're suggesting that ECPG fix this problem by inserting an
explicit NO SCROLL clause into translated DECLARE CURSOR commands, if
there's not a SCROLL clause?

That would solve the problem of the ECPG library not being sure which
behavior applies, but it might break existing apps that were unknowingly
relying on a simple cursor being scrollable. OTOH any such app would be
subject to breakage anyway as a result of planner changes, so it's hard to
complain against this, as long as it's happening in a major version
update.

I'm for it.

If all such apps are expected to be ported from other system,
then yes, that would also work. However, I am not so sure about this.

One thing is sure. With this change, ecpglib can still work with
older PostgreSQL versions but the application's behaviour changes
if the cursor doesn't have an explicit SCROLL/NO SCROLL.

In my first mail yesterday, I wrote "such a code has always been
buggy and should be fixed" and I meant it seriously.

I was only half serious with ripping this support code out of the backend.
However, this feature might be deprecated and removed in about
3 major release or what the usual policy is. Inconsistency between
different clients is also no good. You can only enforce similar client
behaviour with the server behaviour.

Anyway, is explicitly adding NO SCROLL the preferred solution for everyone?

Best regards,
Zolt�n B�sz�rm�nyi

regards, tom lane

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#89Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#88)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

On Thu, Nov 28, 2013 at 09:04:17AM +0100, Boszormenyi Zoltan wrote:

Well, technically, unspecified means NO SCROLL according to the SQL
standard. A lot of applications in ECPG are ported from other systems,

That means by automatically adding a literal NO SCROLL to the command we obey
standard, right? That's fine by me.

behavior applies, but it might break existing apps that were unknowingly
relying on a simple cursor being scrollable. OTOH any such app would be
subject to breakage anyway as a result of planner changes, so it's hard to
complain against this, as long as it's happening in a major version
update.

Ported applications might be in the same boat. I'm not sure if all other DBMSs
stick with the standard if nothing is specified. So again, adding it might help
make it clearer.

Anyway, is explicitly adding NO SCROLL the preferred solution for everyone?

+1 from me.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at gmail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

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

#90Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#89)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-28 09:55 keltezéssel, Michael Meskes írta:

On Thu, Nov 28, 2013 at 09:04:17AM +0100, Boszormenyi Zoltan wrote:

Well, technically, unspecified means NO SCROLL according to the SQL
standard. A lot of applications in ECPG are ported from other systems,

That means by automatically adding a literal NO SCROLL to the command we obey
standard, right? That's fine by me.

behavior applies, but it might break existing apps that were unknowingly
relying on a simple cursor being scrollable. OTOH any such app would be
subject to breakage anyway as a result of planner changes, so it's hard to
complain against this, as long as it's happening in a major version
update.

Ported applications might be in the same boat. I'm not sure if all other DBMSs
stick with the standard if nothing is specified. So again, adding it might help
make it clearer.

Anyway, is explicitly adding NO SCROLL the preferred solution for everyone?

+1 from me.

Thanks, I will rework the patches this way.

Michael

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#91Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#71)
17 attachment(s)
Re: ECPG infrastructure changes part 1, was: Re: ECPG fixes

2013-11-20 14:53 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Infrastructure changes in ecpglib/execute.c to split up
ECPGdo and ecpg_execute() and expose the parts as
functions internal to ecpglib.

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
All infrastructure patches are attached, some of them compressed.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

09.patchtext/x-patch; name=09.patchDownload
commit 079e43293a2b65aa142252f5071277c42409ca8c
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:29:59 2013 +0100

    ECPG: Move allocating struct statement earlier in ECPGdo()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e5ee8a9..83acaf4 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1720,6 +1720,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
+	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+		return false;
+
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
@@ -1735,6 +1738,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
+		free_statement(stmt);
 		return (false);
 	}
 
@@ -1753,13 +1757,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
-	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
-		return false;
-	}
 
 	/*
 	 * If statement type is ECPGst_prepnormal we are supposed to prepare the
10.patchtext/x-patch; name=10.patchDownload
commit ee47f971b7985a0dd3031ad004e5f562acf57ba9
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:31:43 2013 +0100

    ECPG: Move char *oldlocale from ECPGdo() to struct statement.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 83acaf4..01e1a32 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -104,6 +104,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -1708,7 +1709,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
 	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
@@ -1725,7 +1725,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
 		free_statement(stmt);
 		return (false);
 	}
@@ -1766,8 +1765,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1798,8 +1796,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1828,8 +1825,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1886,8 +1882,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1909,10 +1904,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
@@ -1920,11 +1914,10 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	ecpg_clear_auto_mem();
 
 	status = ecpg_execute(stmt);
-	free_statement(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
 
 	return (status);
 }
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 835e70c..0e85ee9 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,7 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char	   *oldlocale;
 };
 
 /* structure to store prepared statements for a connection */
11.patchtext/x-patch; name=11.patchDownload
commit c674a76080b94067071b5c78187b8207e84234cc
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:32:14 2013 +0100

    ECPG: Introduce ecpg_do_epilogue() to restore LC_NUMERIC and
    free the statement structure.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 01e1a32..e977a4e 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return (false);
 	}
 
@@ -1765,8 +1764,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1796,8 +1794,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1825,8 +1822,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1882,8 +1878,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1905,8 +1900,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	if (con == NULL || con->connection == NULL)
 	{
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return false;
 	}
 
@@ -1916,12 +1910,25 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	status = ecpg_execute(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, stmt->oldlocale);
-	free_statement(stmt);
+	ecpg_do_epilogue(stmt);
 
 	return (status);
 }
 
+/*
+ * ecpg_do_epilogue
+ *    Restore the application locale and free the statement structure.
+ */
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	if (stmt == NULL)
+		return;
+
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 0e85ee9..f9a861f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -165,6 +165,7 @@ struct prepared_statement *ecpg_find_prepared_statement(const char *,
 bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+void		ecpg_do_epilogue(struct statement *);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
12.patchtext/x-patch; name=12.patchDownload
commit e8444bf1b990a0bc28cdc621e5ad1052a1a4b0e7
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:34:37 2013 +0100

    ECPG: Introduce ecpg_do(). The core function of ECPGdo() is
    separated out, so va_start and va_end are done centrally, and
    the function can be used elsewhere.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e977a4e..b97e241 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1702,10 +1702,14 @@ ecpg_execute(struct statement * stmt)
 	return status;
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
@@ -1740,9 +1744,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
-	/* construct statement in our own structure */
-	va_start(args, query);
-
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
@@ -1765,7 +1766,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 
@@ -1795,7 +1795,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 	}
@@ -1823,7 +1822,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1879,7 +1877,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1894,8 +1891,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
@@ -1929,6 +1924,24 @@ ecpg_do_epilogue(struct statement *stmt)
 	free_statement(stmt);
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters are passed as variable-length argument list.
+ */
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name,
+							questionmarks,
+							st, query, args);
+	va_end(args);
+	return ret;
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f9a861f..f0e9b3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -166,6 +166,7 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
13.patch.gzapplication/x-tar; name=13.patch.gzDownload
14.patchtext/x-patch; name=14.patchDownload
commit c6ac67e95f25aeeecb815b3de285c44cc9b83141
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:43:42 2013 +0100

    ECPG: Split ecpg_do() further and introduce ecpg_do_prologue().
    Add an error path to return if ecpg_strdup(setlocale()) fails.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 551902d..c43b59c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1704,21 +1704,27 @@ ecpg_execute(struct statement * stmt)
 }
 
 /*
- * Execute SQL statements in the backend.
- * The input/output parameters (variable argument list) are passed
- * in a va_list, so other functions can use this interface.
+ * ecpg_do_prologue
+ * Initialize various infrastructure elements for executing the statement:
+ *	- create the statement structure
+ *	- set the C locale for communicating with the backend
+ *	- preprocess the variable list of input/output parameters into
+ *	  linked lists
  */
 bool
-ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		 const char *connection_name, const bool questionmarks,
+		 enum ECPG_statement_type statement_type, const char *query,
+		 va_list args, struct statement **stmt_out)
 {
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
 	char	   *prepname;
 
+	*stmt_out = NULL;
+
 	if (!query)
 	{
 		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
@@ -1733,6 +1739,11 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	if (stmt->oldlocale == NULL)
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1905,12 +1916,9 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
 
-	/* and reset locale value so our application is not affected */
-	ecpg_do_epilogue(stmt);
-
-	return (status);
+	return true;
 }
 
 /*
@@ -1929,6 +1937,34 @@ ecpg_do_epilogue(struct statement *stmt)
 
 /*
  * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement   *stmt;
+	bool		status;
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator,
+				connection_name, questionmarks,
+				(enum ECPG_statement_type) st,
+				query, args, &stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	status = ecpg_execute(stmt);
+
+	/* and reset locale value so our application is not affected */
+	ecpg_do_epilogue(stmt);
+
+	return (status);
+}
+
+/*
+ * Execute SQL statements in the backend.
  * The input/output parameters are passed as variable-length argument list.
  */
 bool
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index c469220..83ea011 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,7 +169,11 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 void		ecpg_do_epilogue(struct statement *);
-bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list,
+				  struct statement **);
+bool		ecpg_do(const int, const int, const int, const char *, const bool,
+				  const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
15.patchtext/x-patch; name=15.patchDownload
commit be15602a125a025895a63ee68dd56954a39f435a
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:44:28 2013 +0100

    ECPG: Move PGresult *results into struct statement from ecpg_execute()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index c43b59c..e3a44f7 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1130,7 +1130,6 @@ ecpg_execute(struct statement * stmt)
 {
 	bool		status = false;
 	char	   *cmdstat;
-	PGresult   *results;
 	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
@@ -1426,50 +1425,51 @@ ecpg_execute(struct statement * stmt)
 
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
 			ecpg_free_params(stmt, false);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
 		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
 	ecpg_free_params(stmt, true);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1493,10 +1493,10 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (desc->result)
 						PQclear(desc->result);
-					desc->result = results;
+					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1526,7 +1526,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1549,9 +1549,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1582,7 +1582,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1605,9 +1605,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1622,7 +1622,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, act_field, stmt, var);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1641,9 +1641,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1667,12 +1667,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1684,12 +1684,15 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
 	if (clear_result)
-		PQclear(results);
+	{
+		PQclear(stmt->results);
+		stmt->results = NULL;
+	}
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 83ea011..50fe87f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -63,6 +63,7 @@ struct statement
 	char	   *oldlocale;
 	int		nparams;
 	char	  **paramvalues;
+	PGresult   *results;
 };
 
 /* structure to store prepared statements for a connection */
16.patchtext/x-patch; name=16.patchDownload
commit 161db6a11b0145c0bc73f8f8963f5fdd6bd24b6c
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:45:04 2013 +0100

    ECPG: Split ecpg_execute() up into 4 pieces: ecpg_build_params(),
    ecpg_autostart_transaction(), a smaller ecpg_execute() and
    ecpg_process_output().

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e3a44f7..00327db 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1125,17 +1125,17 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+/*
+ * ecpg_build_params
+ *	Build statement parameters from user variables into
+ *	an array of strings for PQexecParams().
+ */
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1421,8 +1421,17 @@ ecpg_execute(struct statement * stmt)
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
 
+/*
+ * ecpg_autostart_transaction
+ *	If we are in non-autocommit mode, automatically start
+ *	a transaction.
+ */
+bool
+ecpg_autostart_transaction(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
 		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
@@ -1434,7 +1443,16 @@ ecpg_execute(struct statement * stmt)
 		PQclear(stmt->results);
 		stmt->results = NULL;
 	}
+	return true;
+}
 
+/*
+ * ecpg_execute
+ *	Execute the SQL statement.
+ */
+bool
+ecpg_execute(struct statement * stmt)
+{
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
@@ -1460,6 +1478,33 @@ ecpg_execute(struct statement * stmt)
 	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return true;
+}
+
+/*
+ * ecpg_process_output
+ *	Process the statement result and store it into application variables.
+ *	This function can be called repeatedly during the same statement
+ *	in case cursor readahed is used and the application does FETCH N which
+ *	overflows the readahead window.
+ *
+ * Parameters
+ *	stmt	statement structure holding the PGresult and
+ *		the list of output variables
+ *	clear_result
+ *		PQclear() the result upon returning from this function
+ *
+ * Returns success as boolean. Also an SQL error is raised in case of failure.
+ */
+bool
+ecpg_process_output(struct statement * stmt, bool clear_result)
+{
+	struct variable *var;
+	bool		status = false;
+	char	   *cmdstat;
+	PGnotify   *notify;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
 	switch (PQresultStatus(stmt->results))
 	{
@@ -1947,7 +1992,6 @@ bool
 ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
 	struct statement   *stmt;
-	bool		status;
 
 	if (!ecpg_do_prologue(lineno, compat, force_indicator,
 				connection_name, questionmarks,
@@ -1958,12 +2002,33 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	status = ecpg_execute(stmt);
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_autostart_transaction(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, true))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
 	ecpg_do_epilogue(stmt);
 
-	return (status);
+	return true;
 }
 
 /*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 50fe87f..1f96869 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,10 +169,14 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
-void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 				  enum ECPG_statement_type, const char *, va_list,
 				  struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_autostart_transaction(struct statement * stmt);
+bool		ecpg_execute(struct statement * stmt);
+bool		ecpg_process_output(struct statement *, bool);
+void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
 
17.patch.gzapplication/x-tar; name=17.patch.gzDownload
18.patchtext/x-patch; name=18.patchDownload
commit 2b5d491573360ba1416fba831e62d95e785623c0
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:51:40 2013 +0100

    ECPG: Explicitly decouple the tuple index from the array index
    in ecpg_get_data(). Document the function arguments.

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 5f9a3d4..7f3c7cb 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -119,8 +119,35 @@ check_special_value(char *ptr, double *retval, char **endptr)
 	return false;
 }
 
+/*
+ * ecpg_get_data
+ *   Store one field data from PQgetvalue(results, act_tuple, act_field)
+ *   into a target variable. If the field is NULL, store the indication or
+ *   emit an error about the fact that there is no NULL indicator given.
+ * Parameters:
+ *   results:     result set
+ *   act_tuple:   row index in the result set
+ *   act_field:   column index in the result set
+ *   var_index:   array index in the target variable
+ *   lineno:      line number in the ECPG source file for debugging
+ *   type:        type of target variable
+ *   ind_type:    type of NULL indicator variable
+ *   var:         target variable
+ *   ind:         NULL indicator variable
+ *   varcharsize: size of the variable if it's varchar
+ *   offset:      size of the target variable
+ *                (used for indexing in an array)
+ *   ind_offset:  size of the NULL indicator variable
+ *                (used for indexing in an array)
+ *   isarray:     array type
+ *   compat:      native PostgreSQL or Informix compatibility mode
+ *   force_indicator:
+ *                if Informix compatibility mode is set and no NULL indicator
+ *                is given, provide a way to indicate NULL value in the
+ *                target variable itself
+ */
 bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int var_index, int lineno,
 			  enum ECPGttype type, enum ECPGttype ind_type,
 			  char *var, char *ind, long varcharsize, long offset,
 			  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
@@ -167,20 +194,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	{
 		case ECPGt_short:
 		case ECPGt_unsigned_short:
-			*((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((short *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_int:
 		case ECPGt_unsigned_int:
-			*((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_long:
 		case ECPGt_unsigned_long:
-			*((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #ifdef HAVE_LONG_LONG_INT
 		case ECPGt_long_long:
 		case ECPGt_unsigned_long_long:
-			*((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long long int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #endif   /* HAVE_LONG_LONG_INT */
 		case ECPGt_NO_INDICATOR:
@@ -192,7 +219,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					 * Informix has an additional way to specify NULLs note
 					 * that this uses special values to denote NULL
 					 */
-					ECPGset_noind_null(type, var + offset * act_tuple);
+					ECPGset_noind_null(type, var + offset * var_index);
 				}
 				else
 				{
@@ -243,10 +270,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		if (binary)
 		{
 			if (varcharsize == 0 || varcharsize * offset >= size)
-				memcpy(var + offset * act_tuple, pval, size);
+				memcpy(var + offset * var_index, pval, size);
 			else
 			{
-				memcpy(var + offset * act_tuple, pval, varcharsize * offset);
+				memcpy(var + offset * var_index, pval, varcharsize * offset);
 
 				if (varcharsize * offset < size)
 				{
@@ -255,20 +282,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					{
 						case ECPGt_short:
 						case ECPGt_unsigned_short:
-							*((short *) (ind + ind_offset * act_tuple)) = size;
+							*((short *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_int:
 						case ECPGt_unsigned_int:
-							*((int *) (ind + ind_offset * act_tuple)) = size;
+							*((int *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_long:
 						case ECPGt_unsigned_long:
-							*((long *) (ind + ind_offset * act_tuple)) = size;
+							*((long *) (ind + ind_offset * var_index)) = size;
 							break;
 #ifdef HAVE_LONG_LONG_INT
 						case ECPGt_long_long:
 						case ECPGt_unsigned_long_long:
-							*((long long int *) (ind + ind_offset * act_tuple)) = size;
+							*((long long int *) (ind + ind_offset * var_index)) = size;
 							break;
 #endif   /* HAVE_LONG_LONG_INT */
 						default:
@@ -307,13 +334,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_short:
-							*((short *) (var + offset * act_tuple)) = (short) res;
+							*((short *) (var + offset * var_index)) = (short) res;
 							break;
 						case ECPGt_int:
-							*((int *) (var + offset * act_tuple)) = (int) res;
+							*((int *) (var + offset * var_index)) = (int) res;
 							break;
 						case ECPGt_long:
-							*((long *) (var + offset * act_tuple)) = (long) res;
+							*((long *) (var + offset * var_index)) = (long) res;
 							break;
 						default:
 							/* Cannot happen */
@@ -336,13 +363,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_unsigned_short:
-							*((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
+							*((unsigned short *) (var + offset * var_index)) = (unsigned short) ures;
 							break;
 						case ECPGt_unsigned_int:
-							*((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
+							*((unsigned int *) (var + offset * var_index)) = (unsigned int) ures;
 							break;
 						case ECPGt_unsigned_long:
-							*((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
+							*((unsigned long *) (var + offset * var_index)) = (unsigned long) ures;
 							break;
 						default:
 							/* Cannot happen */
@@ -353,7 +380,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #ifdef HAVE_LONG_LONG_INT
 #ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
-					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
+					*((long long int *) (var + offset * var_index)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, scan_length, compat))
 					{
 						ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -365,7 +392,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #endif   /* HAVE_STRTOLL */
 #ifdef HAVE_STRTOULL
 				case ECPGt_unsigned_long_long:
-					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
+					*((unsigned long long int *) (var + offset * var_index)) = strtoull(pval, &scan_length, 10);
 					if ((isarray && *scan_length != ',' && *scan_length != '}')
 						|| (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))		/* Garbage left */
 					{
@@ -400,10 +427,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_float:
-							*((float *) (var + offset * act_tuple)) = dres;
+							*((float *) (var + offset * var_index)) = dres;
 							break;
 						case ECPGt_double:
-							*((double *) (var + offset * act_tuple)) = dres;
+							*((double *) (var + offset * var_index)) = dres;
 							break;
 						default:
 							/* Cannot happen */
@@ -415,9 +442,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					if (pval[0] == 'f' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = false;
+							*((char *) (var + offset * var_index)) = false;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = false;
+							*((int *) (var + offset * var_index)) = false;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -428,9 +455,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					else if (pval[0] == 't' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = true;
+							*((char *) (var + offset * var_index)) = true;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = true;
+							*((int *) (var + offset * var_index)) = true;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -453,7 +480,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_unsigned_char:
 				case ECPGt_string:
 					{
-						char	   *str = (char *) (var + offset * act_tuple);
+						char	   *str = (char *) (var + offset * var_index);
 
 						if (varcharsize == 0 || varcharsize > size)
 						{
@@ -481,20 +508,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = size;
+										*((short *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = size;
+										*((int *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = size;
+										*((long *) (ind + ind_offset * var_index)) = size;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = size;
+										*((long long int *) (ind + ind_offset * var_index)) = size;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -510,7 +537,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_varchar:
 					{
 						struct ECPGgeneric_varchar *variable =
-						(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
+						(struct ECPGgeneric_varchar *) (var + offset * var_index);
 
 						variable->len = size;
 						if (varcharsize == 0)
@@ -526,20 +553,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((short *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long long int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -606,9 +633,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					if (type == ECPGt_numeric)
-						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
+						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * var_index));
 					else
-						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
+						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * var_index));
 
 					PGTYPESnumeric_free(nres);
 					break;
@@ -659,7 +686,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					pval = scan_length;
 
-					PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
+					PGTYPESinterval_copy(ires, (interval *) (var + offset * var_index));
 					free(ires);
 					break;
 
@@ -703,7 +730,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((date *) (var + offset * act_tuple)) = ddres;
+					*((date *) (var + offset * var_index)) = ddres;
 					pval = scan_length;
 					break;
 
@@ -747,7 +774,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((timestamp *) (var + offset * act_tuple)) = tres;
+					*((timestamp *) (var + offset * var_index)) = tres;
 					pval = scan_length;
 					break;
 
@@ -764,6 +791,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
 				/* set array to next entry */
 				++act_tuple;
+				++var_index;
 
 				/* set pval to the next entry */
 
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ca3e0ba..438d3ab 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -433,7 +433,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -452,7 +452,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 	{
 		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 1f96869..f91867c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -139,7 +139,7 @@ extern struct var_list *ivlist;
 /* Returns a pointer to a string containing a simple type name. */
 void		ecpg_add_mem(void *ptr, int lineno);
 
-bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
+bool ecpg_get_data(const PGresult *, int, int, int, int, enum ECPGttype type,
 			  enum ECPGttype, char *, char *, long, long, long,
 			  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index bc94f2f..9985a6c 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -393,7 +393,7 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
@@ -578,7 +578,7 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
19.patchtext/x-patch; name=19.patchDownload
commit 4350c81eb0943173861f1225fbe50cc913ec6a3e
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:52:41 2013 +0100

    ECPG: Make SQLDA loops go forward. One regression test .stderr changed.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 438d3ab..1fcfebc 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1551,6 +1551,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
+					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
@@ -1564,8 +1565,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1592,14 +1593,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
@@ -1607,6 +1613,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
+					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
@@ -1620,8 +1627,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1648,14 +1655,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index acb3198..9eb54f2 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -148,23 +148,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -190,23 +190,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
20.patchtext/x-patch; name=20.patchDownload
commit 802f3d7077667e99881aab52853743500cd80abb
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:53:56 2013 +0100

    ECPG: Allow returning partial results in any order from the result set
    into an arbitrary index if the user variable is an array.

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index b2990ca..5d86c53 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -481,7 +481,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desperate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), LOOP_FORWARD, index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1fcfebc..ace6c11 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -307,12 +307,14 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction,
+				  int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
-	int			act_tuple,
-				ntuples = PQntuples(results);
+	int			tuples_left, act_tuple, act_index;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -363,7 +365,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -372,7 +374,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -393,7 +395,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -429,11 +431,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -450,9 +452,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1489,15 +1491,18 @@ ecpg_execute(struct statement * stmt)
  *	overflows the readahead window.
  *
  * Parameters
- *	stmt	statement structure holding the PGresult and
- *		the list of output variables
- *	clear_result
- *		PQclear() the result upon returning from this function
+ *	stmt:		statement structure holding the PGresult and
+ *			the list of output variables
+ *	start:		start index in PGresult
+ *	ntuples:	number of tuples to process
+ *	direction:	in this direction
+ *	var_index:	start index in the user variable if it's an array
+ *	clear_result:	PQclear() the result upon returning from this function
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1509,12 +1514,11 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
-						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
 			nfields = PQnfields(stmt->results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
+			sqlca->sqlerrd[2] = ntuples;
 			ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1541,7 +1545,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
+							 stmt->lineno, ntuples, (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1566,7 +1570,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1628,7 +1632,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1679,7 +1683,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(stmt->results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, ntuples, direction, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -2032,7 +2036,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f91867c..e09e351 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -29,6 +29,9 @@ enum ARRAY_TYPE
 
 #define ECPG_IS_ARRAY(X) ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
 
+#define LOOP_FORWARD	(1)
+#define LOOP_BACKWARD	(-1)
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -165,8 +168,10 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction, int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
@@ -175,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
21.patchtext/x-patch; name=21.patchDownload
commit 5c2af6d8a30361e7e53fe422542731f70eb910e7
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:56:15 2013 +0100

    ECPG: Allow appending a new result set to descriptors.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ace6c11..b28ab9c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1498,11 +1498,13 @@ ecpg_execute(struct statement * stmt)
  *	direction:	in this direction
  *	var_index:	start index in the user variable if it's an array
  *	clear_result:	PQclear() the result upon returning from this function
+ *	append_result:	the user variable is an SQL or SQLDA descriptor,
+ *			may already contain data, append to it.
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result, bool append_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1514,6 +1516,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
+						tuples_left,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1540,12 +1543,35 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = stmt->results;
-					clear_result = false;
-					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, ntuples, (const char *) var->pointer);
+					if (append_result && desc->result)
+					{
+						int		tuples_left, act_tuple, col,
+								row = PQntuples(desc->result);
+
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
+							for (col = 0; col < nfields; col++)
+							{
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+
+								if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								{
+									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+									status = false;
+									break;
+								}
+							}
+					}
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = stmt->results;
+						clear_result = false;
+						ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
+					}
 				}
 				var = var->next;
 			}
@@ -1559,17 +1585,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
+					{
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -1621,17 +1656,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -2036,7 +2080,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true, false))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index e09e351..ff12acb 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -180,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
22.patchtext/x-patch; name=22.patchDownload
commit 55325d3615609019109dcfbc16ec3dd1c994a103
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 11:56:45 2013 +0100

    ECPG: Use the more descriptive "act_tuple" variable name instead of "i".
    Use the variables declared for the function scope, don't alias them.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index b28ab9c..1326870 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1517,6 +1517,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	{
 			int			nfields,
 						tuples_left,
+						act_tuple,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1545,23 +1546,24 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 				{
 					if (append_result && desc->result)
 					{
-						int		tuples_left, act_tuple, col,
-								row = PQntuples(desc->result);
+						int		row = PQntuples(desc->result);
 
 						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
-							for (col = 0; col < nfields; col++)
+							for (act_field = 0; act_field < nfields; act_field++)
 							{
-								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, act_field);
 
-								if (!PQsetvalue(desc->result, row, col,
-										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
-										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								if (!PQsetvalue(desc->result, row, act_field,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, act_field),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, act_field)))
 								{
 									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 									status = false;
 									break;
 								}
 							}
+						ecpg_log("ecpg_process_output on line %d: appending result (%d tuples) to descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
 					}
 					else
 					{
@@ -1583,7 +1585,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda = *_sqlda;
 					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1605,13 +1606,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1642,7 +1643,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
@@ -1654,7 +1655,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda = *_sqlda;
 					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1676,13 +1676,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1713,7 +1713,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
23.patch.gzapplication/x-tar; name=23.patch.gzDownload
24.patchtext/x-patch; name=24.patchDownload
commit b18d5de20191462cd1952a9254c1f07743c4a52f
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Thu Nov 28 12:14:33 2013 +0100

    ECPG: Modify the parameters of ECPGsetcommit() so it takes a bool
    instead of a string with the "on" / "off" values. This way the parser
    does slightly more work and the ECPG runtime does slightly less,
    which means slightly better performance. Also add a check to
    not execute BEGIN if the transaction has already failed. Extend
    the same check in ecpg_do_prologue() and match these two.

diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index bbe44ae..eb2d2be 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -162,7 +162,7 @@ ecpg_finish(struct connection * act)
 }
 
 bool
-ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
+ECPGsetcommit(int lineno, const bool turn_on, const char *connection_name)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
 	PGresult   *results;
@@ -170,10 +170,15 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return (false);
 
-	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
+	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, turn_on ? "on" : "off", con->name);
 
-	if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
+	if (con->autocommit && !turn_on)
 	{
+		if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
+		{
+			ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+			return false;
+		}
 		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "begin transaction");
@@ -183,7 +188,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 		}
 		con->autocommit = false;
 	}
-	else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
+	else if (!con->autocommit && turn_on)
 	{
 		if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
 		{
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index a60e209..3f5997c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1866,7 +1866,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return (false);
 	}
 
-	if (con->client_side_error)
+	if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
 	{
 		ecpg_do_epilogue(stmt);
 		ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 02f319d..1ac15d5 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -48,7 +48,7 @@ extern		"C"
 
 void		ECPGdebug(int, FILE *);
 bool		ECPGstatus(int, const char *);
-bool		ECPGsetcommit(int, const char *, const char *);
+bool		ECPGsetcommit(int, const bool, const char *);
 bool		ECPGsetconn(int, const char *);
 bool		ECPGconnect(int, int, const char *, const char *, const char *, const char *, int);
 bool		ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...);
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ebc9b16..df85424 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -222,7 +222,7 @@ ECPG: stmtViewStmt rule
 	}
 	| ECPGSetAutocommit
 	{
-		fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+		fprintf(yyout, "{ ECPGsetcommit(__LINE__, %d, %s);", (strcmp($1, "on") == 0), connection ? connection : "NULL");
 		whenever_action(2);
 		free($1);
 	}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index c139e41..5abbf4f 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -61,7 +61,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 32 "num_test.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);
+	{ ECPGsetcommit(__LINE__, 0, NULL);
 #line 34 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-array.c b/src/interfaces/ecpg/test/expected/sql-array.c
index f770c09..befa89f 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.c
+++ b/src/interfaces/ecpg/test/expected/sql-array.c
@@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 27 "array.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 29 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-func.c b/src/interfaces/ecpg/test/expected/sql-func.c
index 5d524b8..823c5b4 100644
--- a/src/interfaces/ecpg/test/expected/sql-func.c
+++ b/src/interfaces/ecpg/test/expected/sql-func.c
@@ -35,7 +35,7 @@ int main() {
 #line 11 "func.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 13 "func.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.c b/src/interfaces/ecpg/test/expected/sql-indicators.c
index 22aacc1..168ccd4 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.c
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.c
@@ -111,7 +111,7 @@ int main()
 	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
 #line 15 "indicators.pgc"
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);}
+	{ ECPGsetcommit(__LINE__, 0, NULL);}
 #line 16 "indicators.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-parser.c b/src/interfaces/ecpg/test/expected/sql-parser.c
index 616135d..1d6c0d3 100644
--- a/src/interfaces/ecpg/test/expected/sql-parser.c
+++ b/src/interfaces/ecpg/test/expected/sql-parser.c
@@ -38,7 +38,7 @@ int main() {
 #line 14 "parser.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "parser.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 6c4d84f..bfb75ca 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -41,7 +41,7 @@ int main() {
 #line 14 "quote.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "quote.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 199a77e..c74ea26 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "alloc.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index cd28c85..3a559ce 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -210,7 +210,7 @@ int main ()
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 69 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 70 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
25.patch.gzapplication/x-tar; name=25.patch.gzDownload
�LO�R25.patch�=�v�F���Wt�&E�"^D�2QleF���Hrf��%�������������$@�������M�/��U�u���p:���&������k���#c�x�Q_7�����G���7�;���&��W��;���G�_�wv���������g?��tn�^�xN�N^�����1vu�`��[f�3�<���]ftu���z���M������o�7;=c�//�NN��~��8	#�,�8�b����<����,LB<��{n�y��z/��d/�)��x�s��_;��vY�����KmY���#|;Q�8����6�]f��?��3?�X�s��=�������T.�}"0��f5	�k��S����T����
�����N�p��#�]8�y��0z��p1s���c7��7��%��c�����f�Y8k+S��g.�zgG.���7�f��6�w{H�k�G��h8�*�E���Im�vx��M��������&��b�=�9$,��d1�X����4�MX�}
`����G��z������%;������x��{�Ngl�@�7��v��v)��V�U��/Y�o�����S0({w�iz��������/�������v:�8;�������W����g��D]�����?N@���lnG�����y�2�E.����oY�k�\N���;v
�3�G�����^���R�������n��D�"<�H#}k��I{6.�=��:�:bf���6S��k�������9'�������Rb(������Q��	�%B�_Kd������>����L�x�3���v�����
���P�I��L�k�7��!��hl�yy��Ko��(���6d-�{�8N@�8�-�D0�r=��?O���;�v]�W4`�3oji�p6}�k;�����*ol�2%�B�����
��^����b�{�'7�M����RM�z���T�������q�0b�����v����)p	��6`-����`�y�x��"7?�<?��i�tZ�$���(�dK��2��4�?a
��Y�@�=�j������2�b��i��}'�V��j�����ZF��,n�������4d#Z$�/q��W������K�R���\D* ��$��F��t:\���n+M�}��sR�� �2�,��U5���D��Qj�%�"v5D��������$������Id�b��]��q����&��9;�������:~ur��"t�����Y�k�zSp�XJ���P�.�;��T��WW�%�����G,����^�`��(�������&+4��{;-�`iM����0���.������k^���B1�@��)��#�r��m�p�������V�y�����M� �����V��u(�2�x
f�p9���|j���!�C��M"�=�D���r�SX���+us}�<��������K��O�L�*$����0`�96:#^������'�D�8f�H<i3((�pL���&O����?[���p3�g�h�8;����(����}���C�G��9���������zA
g�]�F�*h�j��K
FQ;��k*��G��������}s����}}v����W��������?�C;R�a��t.�Xd���Q�)����\�Su(���kH���X�i��yqqQ:I��q�v�8M����t���)�pj������g�
����/.3�J���"an8{�1�)2A���H����@�N���2���?��e+*�c6S��MI�,��b������
���9���@�Vs�_�=g�`���*��i%��I��q�R��Fa�d1�hNmP!��������@�F���5����<����RXw���O���-"D�!B_�(�U�R��P�v����s�9o���
���)�`_#5�|D���S�,���uWG�U�Ug���������m����P��A4�����iRh��}�K�% (���ma�]��XFDT��Z���������y��80�(i #��M%��P���0��������?����sQ)@<�^G���� �mB�K�&|���)�,���9h�X:CB�8y#�3�+q��>���I�]� 5�lVL�]����&=^��ka�ad�5`�R���8@�����v���X|���%dl�.i�X{���x��xi~��6���I]�f?�G�5Vi�T�~�I1���7G�/-�{�9��2�c�:������o�/����$"(�M�%�]��5��)'3L3�j��,��"�|i���.��H�5���D�x{���z,%�kT^`��{�!�?���Gi�H���j��x"��%>��E��M�����[����HM�uwG��Crr�q��#�oc�Q��Y��k�Q�3�����YG	gs�Q�$���cj
?t3�Nq��fQ�����B�S@:~�#�>(b�
9�[)"}���c�S��bp��F���b<��=$�����nG��Ou���%��U�"�W������/�z�2j�&��F�R�"&�Da�t���������N����S�����������PE
������l�L&��A7�����J����Mn))<�gB��)<dA<�@@p�c�&�5$mI� )}��vt����v���d;���I4:����������K!UXsi[Jhw����rH'��e�Rc�'�%��������j�<2p�{�.u��+��
B�8�V@��EA����4���6|��<U�p����K����0IF�n��������jB��j �v���DH~L����H�s����m������*��x�6��8���[yj��&��|�Gv���a�D��i���38DIs�e�4}���j3��&������A�����O��V��|B�V[�b�b�P��	w�;HBM���p����''bw���N�������WLz��ke�RQ56p�>+�Lt
MH�Z�l�*o�ds���u�u-�4����ff� 0E

1��X������t��l���2�:�R�����7�?=��������6\���ES� ,QX�������W% ����6]�3N��Y��]*_j����R��j���0V
���Lu����rx��^�{\]�W��Jn�s���������,�0��d3b���/a:�pO�ZVz�&&�e������g��)��
����3��R�]E�)����.�7(uTm�[sJ,��,,���Y�W��J���{�/����o��(��+�p��r.(����;�s����w�/�?�:��utqqv����AW���^����~�W������K���Q���Y�iw�o��tp�.��?�H)M��6�f)~��b��������g���.NO=���P5�?s���IuY��W�	����w��45\����W!�+������@F���(p��EB`�_7P�R���Q��S�Sg�V[���Z��4Pq��+�����0��TEs)���v��%����������`�=
[�;��J��L����������h���P�D^4&a$<�O�g���a)x�������k �{����C>���%�����D�����V��|�*��
t�\�;���%R������b��h���4������}�O@�2�r��"�?9���>�,cHz0�������r��]�RH�;����^�32����^-�U.fE�y8���lWhW~��J=�4M�6����;?�8zu��"��U+}����mj�4�i�\��� -�#��pNJ<���L��(`V~E�*r�!��-B�!�0��.��N�w��)��E����;0�H�W����.�4��d)�Bv��m212�*%}��=�t�2}�g �S��u���c����Xn���
t��/����`��������v`��K�xdd�7�A�#C��9x���IL[�>�z�"�[����2~R���
��*E���df.�B$3U��d��O���Gf��[����/��.�l3��i�����}|qye���f/M��1���?a���������Zi�*HsEA:���^lB* ������$�, ��
��1�LA��h��4�,"�6�|�l��T|Eb�gNJ�*\)�'q�T,���V�mrnt?�I��.������Y�=��{���+�\y����~oUp{+���������~��n��BIVJ��:`[�YF���.�N^_Y����o/Wy���*C�)t?+-���g�rv��&0$)V�wqtrxu���so)#����#����g���3Nj����*�>��
�Q��@�C��}���������J��R�A$�������is�n�>������[!��zu�����H��Ow�M/dn%�r����eBy�?n�����g��B����3<�����:���������	��l��DQ�'�ESq8�2��$c�j*���w<�&��Yw/���JC^��=�b"J��NZ��K3~J�Y�7�M)������mz�Pl�c�;L�@��RJ�
�z`�U��*��
S"����k`���E-�0�S����>8��o���}����=�������q����LG�|1���bPF%A�]�_�!;�O+����5�eF���� �9!��HBS���"n�����P������GR���,	7����|�
�����GT�L��2��������^+QO��rN�{p
n@�+��B�?����:�'v*h��
��&QK�j�T���`����TEs�i������z��Y��!�_�89���*�H���t����D��I��R�mw^����-�
�6xKq^��}]��0�����-��X��������8-�o�������.��B�0h|����7����
<��J�Z�{�\��E��y�����r�)��>iEQ/q�z��h��~6=������@;�`��M�V9gS�X����I�h*�0y���x �F�����(��9?��9��r Y���1����l���	&3 h��d��J� w��l�)���S�G�UEH}�<��T9r�Y���B��gwO7�gC6�wc�]�!�zhA:#Mu�T�s![(��w���	%31]sDJ�����n����`�;D��u��x�-\M�p��2��@?�+���V�����~e+�����v����&�u]c�)����H���R_!hz�d3�o��^P^n&$�����#��c2�����,�iS��&��
���x)�O]��TO��~��n��WN�����U@�r��jqP�nq]����Z&Ca�(
f�Upb��jAU~��hY%������n�Ts�SC�k�RQ$����l�R9$�%�f	�w��v#������7��GLM����QG)��S~�_���c�/���e�
��Wa	A��2E%K8���vm"�����+����iY'��G���/\�'���+=��������"��_?b�������3b��.�����`U���&������_���R��6w1X[��X�$@�e�-����iFO^���b����!gE�W4�Rn���N����.��o�fl<���0��b��X��������qH�:G][���B��]^�<Y+J{���]V��X�����Z��6aA����X�2�G���{_H-�{����x.������n�F�y1F�7�z�����_�y�x�m�!�t��KGz���^;�����Z���e�m��R�@�@���.r[���1�)o#7}7r���
�=x���q����a��o�?�]��V�+S�������h��z�Ta5��,�������(>1����+C���;
�X�	^=���7��r��w���i|
�#
�1[B�������Y��hR"R4f�[]�=�������Va���-��>��i���z�P�9����N��F�����:��_�7���1
����Ub��d�AKH�������N�;Ze�M� 8>u�w������A8�n������T!��2���u|�
o��]�92��I��7;:;���_\�����z��$�}�:��j�[S�����2�\
j�t�I���[�:�;�JN���T$���'
,�B���c4��������g�h�e���'f��o�n�OV7Fu����7���o<���0����w�7�����'�����o��!�"����ms�a#]���u/�_��^T�W�||�q��H�tt���n���C|�+(����x��$|���8?~��#A?�����9n���|
�T�b�G�oi�[��������}9_�Jq�gn�����*u���"��@pft�������n4��_Sp�"&t������K�B-9f����\��8eh��w��|}y���*�z�l����/�����!��p�
�l�U�?�eU�
(�T�'s�>"}\�U�	ok��s}�
�1�j&��Va���=sxF�s���E:�(Ch'2��b���P3	,C�h-����_��4��J��g����N}o�����QtUx��]��G���,��4n����O���$�y�7g�h��}3spT��N?~��Z�����L.,����^0u�����JW�[�.�F����=���ff�f������[;���}�y���3��b�6���O���5��,<&��x^7��1O�*U��M,sB�7��n���C`�7x\eN���k5�0<rp"����Qo��u��)�[S�����(���?�*�H��i
D�sy��mt���<�:���'���e�^'�J��Pfv��S�y��$�p��|w���	O�V/���oVi�����fmi"e���q]����/����0+�L�#f��&Y3��S1��V�iF�	RH���V���9I�/Z��~(���@�o���x�+��.gI
[fKz���-��N���9��e���5Y�AD
��y��L�:X������O����J `x�<�?*i���V��Ij[G�N���
�l�w���Q��F-{S��]�H�uw��3�m�fS�
�/'Ad�����V�K�F��6�p�
!���F�-c$kX��������3n������	XL'Pb��B��x\��g�Z��X��{\��i�1��S���X����l"�>����)#���Q�%F(~�����J�i�P��KY ����hw��9�![��Y��Bc�����6]���w��j�v�=�a��Q�`47���=u� ��5��4�%����b�e;���U[���'���O���/��8�
�[w��l"��U
��X?{9�"��8����l"Dn�������K~[��y�!�Q5F���b�"�����Q�Tt��gw	Q����bu��&rt������]��/H-4�o�hg����0���[�7���(�����w�zSvS3:��\���n�uLmW@Ec<i���_\��������|����4!W����9�g��<��
�
N}e��+�����{��������w�E��V�f!:�T���������[���oh���I�Q�D�N�L�3L_Ix����n����$B��d����������]�%��,=|��5�I�c���:�P�B&F�y��	|��S�5������
�7����QN�[{�b�����D�#���o7{��Bb�9�uf��H.p�m=s��@!~
�%��'���@���	���:�7Y$]-�!��~��ZR	���fG���>��M����&�IC{^�9�+9k[�$�'�7������������N`Xn'x���2�'XA���5w��|1�/k��'�pcC����NlC8I��Y����E�H�}~�^]\^��>��
v
H,s�n=;����eFE�������4%��nRy�=��G&)2,���J�Q��]�i��lrCzY#n���Q`Y�$�g�L�0��U�H����
�D�������/�����;.��k�)���	���/��@�Zs��w����S���Q�[���;�u��l�z �-�"C~���.f#������A�k,�����t�v�mJB��b��8��]/f��|�(v.�h�s�)gp��,Z��=$�����	x�fx�(������v�l}PEs��2G92�Y���-W�*;�A0m���
���<�r�8h��x���M��Em��,O2�H�)m:2C���,�0�Hi��������e8����/4�����f�.���
�
Gy�6*W�zu7*�Ai����B��6V��X�>�Ikt ^�C�y.;��� ���@�et��/k�ax��8�������ax��d�����)/��ds:n�
�zf�p����#3�a�G]m�8$W�q�w���A�-<�@]��I6�Z�
�@�2H���\��3�k-9�lC9����m����0����Y�rM:���=�5���m.l����nQx�Q��[����C�t������CP��{}�?�4}6�]oG�]�Z�7.#�(��#\&�+����$z1�o�������j�x���I�[qu��4�T���u�F�uQ��=�V��+�9U��T�����n9iSYN���	�)'����v	�F��A�!P��Q�a�1�NX����5k�c(�_����aBr2�D��g���#��v�i�i���[=��Z�!tgx�����{�F�d�r��	��q@����n�k4�w��M��s$��q2���� N����*}PZ4�!7�8� N�2���|j��X����������	�k����k����&��Jx��#e1q31��� �z����p�Q�RxT�j������4�%;����{K�V�������)�k*W�
�W;��['��'-?�d5��5{�g����������W�(�����y�
s=���4�^���G��{�:j�
��w(���������W����w)�=���r��!h�v�Zrd��F���,�O'v�hCv����G(�\�Y�W���h/�[P���cD�L���i)�g%��`3��m�uX�j:�GI��!O�)���
t�3~
�a��J�;��fYd(��0I�?�AB�O�E�]��p<5�(��9��$"��(5���|�G�1I"DkI���rqy�������%,�2I0����G��t���T��bP� �.*�+��z��+�fX�P�w�����r��.?��i���7%0��e���	�^��
��VuJ�^��
��;^s��|x���K������g<�o>�-�����������m�k��Y��n�^�]�v6�j�q\?����Jm��NF�I�OD�-c�(-{h�U�0�W�2���.�Y������5qv���6�S�N�)fT�*�H�x>��2����/�V�1�W�W��+�[t��M|w�����m�������J�F�^���*��8x���ob.�j-^c�y���i��j��N��q0I�e�4M���N����@
J��������#��A�����A�T�f�w��R�����������LE�q�,��
��=�
�8I����*t���
M�,Cv9�����3p� l�����O���[�6`��8����/����h��(�{[��\G H�m;��j��'��m�Z�S/��6�IV��I�,����S��o�����}V(�,���*A*$�hf��.��>����Q7�z�#�p73�#�`�ly��'��-���s:C�U���9�_��o���c^
�w�Ic����B�o�b�-�������>g�w����������3��%3[����#d4L���o����'}�-:
����o/n���Y�xA�P��E�\���m4f�5���������T�Q���N��u/���{���Jq_/&�E���4��
��������B�8�Tu=���]��F�P��cl�=�O���x�Y�����&���Mo0���o�C���m
��*�p����5��{�D*<�K��o)n�:~In2��~�Eg�;�J�a��OO�0\�T5*i"�~
��Z�1�r��]�N��A����]&Qs%�]ULm,�J� 6�E�n� ���XG8��9�f��N��	{V�	�#���?�N���NkZ�h����ye��<��	P��]��66!�U����4P�hk ��1���Q
�0�C�@��4{�
�,��#���M��t������9�Y	
�%l���Y������U�]}&�P�Gdk+��E}fTy(�S9���n�0���������)bj���7Kl��e��y�L�_
��vA�~�~�U[��Y����/�����]�/����f5��4bRh��Q��Tp�|S1��#{����nP����&p����A=ff��6*ym�>p���`��m����{�aFE���>��^�,�{	��}�&f}7�#�n���v��pfv�������i�ccT{V�2�m���c�s�h>
�?P�l�C��@,x)�p���T���E�9��AN����6�A�|��,��^��vgK�5�v���B!sh�E4k�>d��$��x�������}d�����]gx��4���2��c>���e9��y�<�e��gYW6��f��d�<z8Z�_R���X�M�i��IV|����,����9���j����l
~������;l~���b�� o�����l��d�y������d���{�l�"W���
��eW�C_�5�n�|2������L5x��i�N�d,����KzT��|zKb���Y����T��+�U�lM���b���>��3(�������>.|�hA�-����vu�q�[���m5.�G-�7-���Z<
X�����[9��I<�'�,7�O�M��1+��A��_�o��"7�>����O1�	;�i��|�~Io�$����{D�=u���������<r�p�Nf��(tl�s�Cza4T�"U&�H�.<�����Q���sC]��Z��0�e�f+��E���0g���g�~
iD�5�����q�����frY�`��z��������|�*��jq���A<Y��:�;�)�"Y��'�I��f~�E����UTY!t3�>�v��{/��F��'%][:����I�|�%�������������cC��B��I�C��B]�>m���GY�w�a�|+��Qd���{<�D��9p����^%]AU�!Shz?��&7��?��2�����5�K�W�����r�R���kx�I��*$���3��(�?$X�n�<-�w����&�	s�1����
���T�9^/�j!x�#�;�,��@A��������D�'��J/��@�
�&�zF;�,��]���1�-��5������_�?o�+<&��tTy�e�0�������"����)ga�E�WJ�FJ-�!��I�f _3J�x������:����������W��bt����HIu������@]�I(
?�V�m�"���c��s8��a�TN,�H�[[Q����j�QE�7d_E!�/�
B��R<=)��L��	�;���"���M*���b;Z!�*���{8ko���7�`_]^���@������{_� ^��{�����Xw�v�h��y�_�������	�'��2s�QHX��q��c{_#c�����=Fw�{��XIym���K���(�FQ�4�2v#q�����������;=?��eE�=��r��r�J�:o�<���
���L�c@-�w
n+q��P�i�| kK`����p���xJ�l��TDoo<
�QM���t�gw��v�]T&���_(I��Yb�����R�q#��:_��E��A�6���B�������������Q��U�Q��j���e��3�H�P�@o'}T���[nj$���h���I|�n�&�!�9I1T�A]�	i0���H���A�2=v~O����`��-�������cYS�y6�YP�>U����-��-���a����Q6f+������7$��6�J �Z%�o(�{8����Y���J���E����6�|�N�f��8���7b�4�+���������x�8���^H�0�����
`�B�
��W�UJP!E��p��i@�t�������b�9&�{-�Y��y����K�P������}�Jsh��r�:��Z�a�)�>�f\��a�Y�')W�t�c��F v����Cr���3k�z��<$���X6�������;�/\��Q"�X����c5��������.wzbN�������*C�L]J�������������-I����g��p���+�Y8�Ne=�h��
=����j���{r)x�QE�K���_�+��?���b��_D�Pe@*t�WS��K���#��i��ry�J2�
����/��K���g%I�*���C���t���\��+�m.���h�6U���6TR
�'rX���	��C}
���]�D���m�H�������"D�o������K�WM�����\s��DS.^R��:��&f�R�MC�o���c�
��F6QV�k;�r=Dz� ����Yn��b��|0��g��*���S�G.��J/$�Cf������e������U�YF�p���l/Z�5���:O�w�vj�gk�2�Z��5��Q�
x��f�m���.l�&7i��n��vE�F�FY�x�	��gYq0u� �wJ4bF��4���>S�����@��K	O���4	�m?��t/�ee1Vs�4`����X��M����!�%��|�n�A�����[p�;�0rC��R��cWG�n�T���V�����:��2��a(2�>�W�T�kv�_Q��n[�_��+ �4C�P��e���tkG&��U)N�"w�+���Z����)�{!}N�"bO1��1�V��
��Q��0���r3n�M���D�e��8��T�J�:��c~�c~��W�
��> ]��+�e�;�A��+�Q�����@�9j����[*�V��g
z6	<�w[����P<(�QE3gm�
�X%=��m�~�HlX�������Q��8ecH�g���&�B�.�2��M�(����)������UgR��8`u��Q�y6�����4����l�}%b|�<�a2�h�e��)J&>Q��8zg<�n��c�:f~qA��x��D��uJ ?~$J�7���n�x���.�[�4��������=�S�\g��B�����a���{��6��Kb3��������aY(���2C�UZ�����C�l�(���1�[Vnx�M?��o����)�R
���c1��.�/u��h-HF}n9T!�6�B��`��l��o�{�IvP��7<�<���C�)q����n���VHQ�P��Ij�����L
$��F~d�!T���*�)=�>g\��y�!'���� �N�,s`D��5��<��$���
�5��&������t�1 Bj��p��:.+��Jk�:��BAO4�A���o������Q��w�,������}�b#n]E��sg� D'�ok���U7���.TZ�>�aC85��]������ k�_�}C��,�RX�m����K�4���8�C���(N��<�x�=RDwY�!�r�I��sXj&��e��w�oyRw��+�����I�!�������rWZ��2����Y^Rr��gc������s:����~x�v���g��_^�1p���M���yF�2�f.o�>c���������.�9�	����2�����������[��J�%���x�8'�ee�Yu���������&������Bv���.��L���S/����?Y��U�
#92Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#76)
6 attachment(s)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

2013-11-20 15:25 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

$SUBJECT, the real thing. Needs all previous patches.
Compared the the previous incarnation, a lot of debugging
ecpg_log() lines are removed. The newly introduced regression
tests have much smaller .stderr outputs because of this,
the patch is about 800K smaller in total.

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
The ECPG readahead patch and all the small following patches are attached.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

26.patch.gzapplication/x-tar; name=26.patch.gzDownload
�YO�R26.patch�[�R�H����"����|��)
���=E���[�����Q�,��.wO?����������R�MQ���C`I��'��|����$����{=�=�v����|-e��y�������gy���G��o�T?���t����P�We��#�?���C�f��z�i�������1����>[�G�����vokG�z[�^��!�~��#q��S��"�^�=�������0�,�FR�(��(��$��~�8*d��=<�J��<
��J�|*��4
}/�X�\5��+���Q9�X�He0�0��~Ix�$�,{�O�(��af��x+ir�4����J��O���fZ����]�������3�R��Y�a��T*E3eRe�_�RY�A2�C%��!{!X��|�b�-IcI�RRu�Y���t���y
�fi�e2�6A8�Ng��{�`zS��O�M�O�]�$�+4�8���p{w{���n���;#����6:��J��V����������a{_��������������W�������7,�@B�b�oN��;m�F�s�����y���qF��_J�)�p�z�����
M��xo�@��H29�"H��u8����S������H��8�&d^����.��4����������H�E!����G�����3��T��l��+�"v�2��)��q��O;����^y�i�Y�a�����(���$0�P*�N��r�/��pC#V�=)����?�g���N���������'B�L���	
V���9 x�V���?���y����g}n/�W}|*$.��K9�`������������������d����]���&�\����L{`9��7?��@�<��$�E�bd�$���M��B��,�y����]�|��� 'C�tdN����]K�X��,�T������������c�B�Z��-G�<��1Sj!=F(������?������^���������Fa��� ��r��:H�p�8�ko����Inn��Kf�:�
��av���xS��U.��,�?��i���da�-���d�
�_q&�Vn�!J�0,E�Lf���u�w�up������F��7���6h�����E�Y��4��������!8{�$U�O=R�O���i�\e��Y;7 ��396� ��&D�'���X#�Q�O2���j��J��pCqXD��t���&��]�#^��O.�6D���`��f!""f�����|"���$��zp�Pd��Y��@�
��U�/[�q������
��M����B��I�Rn�G��Vd��S�����9���V���#��=���om�2�H�)�g� 
��C4K��GQ2#���8�����u���H���9a���#�K��N��$���(4��~��P���w{���}�
i1$��M�%oz�|�6���oa�$����A�P���w����u�?���9��/���w��7wb2GY������!�$S� |������1A����K%��R'�������}w�S������S�A���>��O�>^^����/.��������pvsu����`���E�x��N����|� ~�n�.0�;<�3S<�x�%���\��\��������|�q�Q���*����h�j��k�h\|���E>�������_-�2�D����&6�o>Q��Po b���n�D����@�#l��Ys��a�M��c��oC�����c�������$���b�.F�Y�Ph��
}��gp@���'M�)�RJe����%D����H�$�����.*}���(&�/(& &Yd��Rk��bt�c��4���s���UJH�
a��B��?���������Gsh^�9�s�8���ZU�tu�`�d��[8Qu�l����C�V-���i-u��R�q�^{������`
�0������Jm�Wdl�W��P�=��I,Y��(fm��S�G���(`9-I�*��Z�4���j�*��4e��Sk����9Y�������uy@RC!��
������e�mI=������P�V���r�����j�Y�R1^�j��V��b�B��F1�ZB-�?�y��}�;
B[G�VL�0�������}9�m=6��@>m�yd-��g$c��{0����>,��B�MD�H�#��1�\��K�C��V�������t���F���&)����h����(B��P�e�
EL{Y�E79M���y�2�xk�SN��n
�A�.�_Y`��N=��3��u�A-���L��	��}��� ��B'��.|����G�,��=�[�!C0f�Y���(�jF`�C	7��������)�W�K#��
�b�'���p�O�����UP�wh	sI�h2����� ,���B�'t�%HWCi`��XXg$3��aYv����)		�����*Gs�?z���-� �h��db�<I�%�cF^������<-��)=0��l����LOb��Y��9����G�������d,�#�A��5���������g���S�-LQ�S��zV�;�������^�B�c�q���l�&ee���-c���V����VeJ�� ��"��+��(2�XI�
�����7
P��v�"
�?�!\�`|����$gv�!�f�/g
�x,��k��`U S6�8�i`��Y�~�'q���E��y��^�5�����,�i�`�%�H����<��U�3*Asb!>�a����H��������!TZ�]���;K�P.�XJ�e6K�D��\��������U^����M!%�"���;d~V��3aC��5�����lS�&�
p��.�i �?q���X���~@a��K��B�1�h!��W�����4B�;��	�F��+<M�FK�D�����6T����mT1eSei��e2����4�fI�$!5Zv�i���dE/.r��@���(/�j��5�<���B2�����w��eb��
��\��6TMKh�!�+�
�t*?������h��F�w$�M�q�A��,��P���l0��yh�Ni�!�E"����I^all����G)�&)0�������W	�nAK	�$
����g?�oo.�X���*��J�_�6:��iG���rP���X���������%����L��D
_�������3/
h��a+VALX������SD<&QpT��X��q y�������RK�r��
�T���}9�%9��>��A�4%����7����o����=����c4��}%�Ke�Ci	�z��m(��Y2f���g����$0�R��������B�����z������!?�H1�Z�����#
"�b����f��cn�Y����p�_,/�~����Io�Q�k�PWT>�b"�
�m}��\'�����I��<�gh����W�����o���n�w���2�{p��4�|�e���j�42�')e\Q#>8� �4��2��eYE��/�;]u�y�����K��&�c���N9��C�|�+ ���X�^4�.�������)��������|���!�Q�,����F�U���[Q��d���m�)�d����O�bw��R�%<
���be)���jeU��8P��-WD��x�U7(4�d���1W��%|���e�t
�T��6e������i�o��Y�!55T�4lY
:nj*T�R<��W9��l����;�*OyXMa�������o!��������l�2,�n�Y�e�����r�y$O��UEc=���d��?���T�DF*�_x��R6�����$��x��T��-UgWWZsen�Q�'E�T�)j��l,3}�e��|F��]��u[�b��7��<M�5=jW-���p<�9^(?3f�G��(./����Ep���BN��4�z����g��L�D��?�7��k��1�[����X��Kl���Mm�����CP,�6^����sU���"`��Z;�6A�IM�,[����3��'�5$������3���(
�&Gq�uy=Z��X�Z}J������G���T���>����]2��m
Q*��b��]W�2��*��S)��Z����)���Xj�S#�i��H�#����C� �B���Y����-������XI��8�����#u����d�R��j��+�IP-�z��+-��i��B���Nn�4'Z����� ���������s�:��CY����A�b{h�=ab����n����,��h���K@��:��*]�@����b���4W�m�D�q01i���p��1j6Q[���3��]����Yh�#o��$3M4*������d�������IS]���`���(�r}�2	�O�H�����1�v�6���
�r�����IG�
2�e !D�fR��:}:H��
����I=�/�y�Z��j�MT����5X���"�aS�,t��6�<�y1#>dE���,j�R���
�\f�d���aQ?������z�������Fk�-���>��X#Z��������Sj�o����G>��]���?\�\��K$V#�B��T���d��T*���\/bA�0��2�X�EO���x){m6�ed�������f�-"����p^�fN-.H{�SO�F4?~��G�exL8�g�>g` ����$8J#I�{h|�QJ)z>�'�<�=[s��>K�-�e�M�cCXn�i�)�*�-��./2���L�u��Z(��8��a[0�q�'����;���M�%���\�~�I�@,�o����2���JSy5���TeG�@q�g�]��P-��S��,��E�^���[�>�����|��u��]�m�"7`N��)q\vJ������M
B��c�����r0�2�������}��~A��=u;�~���pg�����������My�/��C���S�k������S�Q����p�8�>6+�?�7��FJ�i4�����*�e6P�">��'q"~i����P%Y�MW�yFh�<��P_XdD_}�k���o���a�D��e2���b��my
����&��U��n�A������ �Ov,���+^�hE�����|��7j���Yb��C�&dh��sK�-Z�����,ID	���O�X��e~��k^����]���79��JO_�<�c�pHr
adGg"�B%����Z���J�2����	m\����C��m4�t�
�^�@��!��!��"k��$�m:����
�+�UQ�;������F��u��<)� ���*6
��N8u��
�@R�%���@8�_a���d5Q�.4�<^F��L�U�����e"��9���`#�sH�!&��o������8��B��a��^���������P�������SS��O*�n�k��mkC�K��l}�[9���6���^����gB}n�W�5�1g���M"�5�[�j��iu��*�7��B*R|.;�2N�����:lr"����r�����R�c����77�'�9���&B�&m���	t����oA�Ut��K�9�{��-���@iI��K8��p��/�t�Gl_�7p#����hl���9uLLh�(�kN�8��R)��)T�WfQ��������B�o�/���kC��W��
x{��fY%�C����h�P��Y��e|%�K����&27J=����wxU���V��9�z��}��>���u�JF�������U�U���8��i��+�0'�D��$�� ��E�oOv������9�L�<*��oVfl[=o��������=��N����wK(�RRj��d*�u��u�5`9�2��_��*1��E (4�U�~���S.=�x�G����'�K�^5�-a&O]&8Og������t�q!iV#l�-t,a��������,/��	���"��?	�q��9���j��p�������<y���5/�;�E�d�G%B��=�.�����)����������F��i�!��tp}���.�!J�7��l���������s
��E�������7mo���?;��i)�l���e�&�L�q����L���/Z�m����rO���n")��m�M$���������H���������'�Kd�yH��|&�o8��~�6��0n�2_���Jt��k����c@����O���D�BD�4�w2�P�I�_~]!�]���N���zC���.�B5������z���aJg�k ���
�o������&K��Ou��&n��bO4.\W&��v2�:�'���K��x*��;��9U>%�\-�PW5����ds`���.�t����f��yD������7�����3�@�I��B���
�*�w��-YL�
ty��P#a���M{����`>�{��i��{�����I����
�5��u��Wx�������G��o��$,l�/��8����5��,�%�&]KK
�L�+�70	�e�|��4�h�cu��P��|��n*{��g��Y�%��/���. Qt&l��[�Q7�{.�����~pt�<���a�c���x���Q�@P�9w��t�d�������)�Z�,+�6����J���fa��d_	M��Y]�E�.�6��,���hV�j�YHY���d�������i�C���;��D������k_;��'�<ER���T������������>)�d[n��	����hng4>Mr��
b�+���-`H��s	�f���#��O��&1�bB��t��-���\��V�z����� �}�Ov2�{ S;L�{�a�d3X��;R���4M�'�"|��s��-��2;�-��c�$���Nw"z.��%�+�0��*���&#�c`�q�\%�Q���$�������+$������k�`K�d���"�9��v$���X����f���i��f
����7��c��fX�W���"1F@�SP�`.	����
D����92��uH�l�����,0�_��h�.}�����{�m7T6���~i ��/��*�M���T�9�zF�9���a��g��E}�R`B���@�������PR�x�I��_su������������<�;
�#�/)�-����q��9�Q�!|��O�E�5�}$�A� H����^��BD1����cU���?X���l=��p����M�Oc�/�n�2�.�h�<V��,������5td����In
�������m*���/Ra/�Xe�_O�����x�';p�����S��KJ��C��[[W�1�'	-#����:8@�5�N�c�(j��	��������-�����<�`��8��G�k<��d�u;�������v��,Z��K���g��:t��8�rM���z������"�W~��/��J�[�y��XB�X�m��,Q���c7l��)�b(�O�#�K�i`h�i�
$M��*��um�SH���*y^�\��?
4_�	�>����i ��u�|Mg�o_��\_3s.�F�����O��������������g����_���mt�^�c������Y�V���wZ�%j��z�?����+D��J+6_��b���Q+LR�W��u�^�����S$���t���b���/]#6�%+w���;l�8R���)������,��.��#�����(�H���
!$x�6���4Ip��w,���|5�R9��i��2x��8%��7��l<`��or	[�,'����LU@4��;	��%� .n|9#����] P��o@M��?'�
D��B6�tb:�$Y���!��n9�.'0^����T��a!�|�F�
�k��h/���(�v�Ac0=d�
���l�(�S���zJ�����q��S���V'��A��*����)�X?K@*e�����$���}%����A��$����G��
� <�K�R���9O�I�X��d����:iONs�[D"�����-�~����l)�QP��<hXe{����a���A`�N����K�%��0{���/_�h����0c�D��2=�C]�~����pT�������]�c����@R5wI�-�VxD�?h���D�Z�W�,�,c�
i�������^D�}4Y�O�"~�������\��?�j�X������������Vc����I*���
 �.�x~#�&��Lj��P�O��0��t��TF�s���j$�Z�9�}:r�`������w��[~����d6x�
�&Q��8����H�.[ku��@g������'�v
^�d������I��}�Z`�kZBM������r}��C�����`_}mW�kQ��������!J�D[x���4@��|���%�o|�Y��Z���~���s���F���,[��y�zU�!����K�T�w<�5�F���)��o4'9�F�2CC�#���U���Q�HgOPv��J{R����2�#��O����W�g��k���9�?�]��>�<����\�$����Q����$="�+�'������|�Gj�[���wX��Lt0H�����qr(���
������$�TB���N
]��~yv�_C��s
i4�Z	�nw�5����U��1�V��b$����@*�����pr�-j��jJ�W�����K����<��vB
F	*���C*���E���,8�K���g\���)Q9�8i�Pv�F��c��n$����'���ON���S{�(J��I���::~�������&y��9��?Tu����:�
�"}�@��zW$sV���1E�V��7$;��%���W�U�N����2`�b��F��%X�\HeV�#�)��0^0����N19l�to������5
2u!�����{��^XZ}2c�,c���Va�>aZy�V���Z�?�����������1p���"�8�A����B��e'���CM��y���$1!���<]������8hu�6�m���W<�"r�OZAy�A�/ ��K���2 �_g��B�{�
����g[oXnMW��?WOgn�^���t*t��z\�$/q�\d��n��(��w���8�?�b/��!X
l W���s����m��CT�qbwi�a��{��9p�����8���j��6
�}$�l�� 3��)&B����59�L$���e�a[��'T��!���K����ocp�O�M���5z��_�W|����PdJ��J��X���F&�N�A�������v�^"��1T���$E+�%��)�ZM�b@CY�&�D�������+P[y��d�����IT��J��<-������ �b��D>;�F�hRKAa(�$��	���B�����~,	����$tX��!��1@2N�DvD�uh��H��u*kE|Gx�q=�z�?�� �����O�C~�K�����uQ�����'G
�Ig�,d���j��^�Qg�������C�j�a�t�/�j?�^�W^>3����#�L.?���k�`7I���LVp�=�!k�����h�t#%X�C���,��CakK�,��������76����|��(���/�N�y��)&6V�����&2�/tZ�5�f	������y%y��j+�}�����^�|%�+g�����Xu^�K%	�6-��gzO�3���[W��	t�7zh���o�d�y��
{�)���1����V�|��S�	A���
E���Ar*<��Q|�� .I���8��(e"<?1MK� ����G"0�vv��������~�2gE/"Z�i
3�'��p��X��|�`Mu���6<��X�����`�{���&��a���l���$n`|$)<��^��X���#����K����.�7H2[���]zO���{���>�.������O
4-����p�E�����p-o(&�@�:�'��,����U.�Q�Dd�����InhE�������fR�^+|o1��G�p�%61���
��U���L���fh��������Q�v�a,��������sDnTe�3H���+T��G����u71o*����2�|U�4��|�������5:_�h�H�zg5�����3��.F��o^������K�uu6�I����H��-'�:/[�^�{.��^�%�q�f��$J���>�25R�'R�f�Q"��=���5[t[9~R�Yb��1��g� �Cp���w������).������_?�����9y5E���m��"U`hC�y�H ��d/+,yGKq�0/��U��SD���8��I�I'+z�8zk8��K.� wg�=""�MX�Y�����]�]~GuU2�������J������,��M���V;[���4����H�����wwW��+Q�\|�x��f��?B���	�������-�.����UPS�
�0�"�t�9����z�V�$�5���J��1����#��;���O4Llr�JL_�eSb^"�W��o����Z�*��~;��|c�F��	��#Rh"�/=�{/��4�:1eZ���Ypz��^�%�������'	l<*�r��VM&�v<qF�R��������'8���NX���i\_F�9���"
��s1na�����c$�J`]qS�������W��%��e�1H]����@vB����$�%E*�G�R�q�U�MKQN��@��"�f��RR�g�U����)���]��/�|0��z��|�@=�������O���`�U��N<�8�.Q�d��8S���W�V�]-y�8����A��VqL2[8�)�]��d���0������^-60�]��P�<I�����A�[�R9x��b��L5%�R^������^Aq����Z�o���7��&
Y.��v�=m�38r�����
���b���T� �R���$Ae���G�[�b�S�����q���F�V/z��l�Z����������kZ��4�'K�X����Z*�,�&���A�V����(�)	��(������pIP����c��9~�o����b&!t���������H��e!��!&v�.�=D����8v�K0�dQ�r�n���z�`		����#��e]u�$�������1R�T��*_]��������{9!���!��������8��b}(��+��%�0J�|�����T��xHQ}���l�j��������c��l�z��������;0ln�-�����(�%;V�[P�e�&\��~r%��o=u7���|��_"�����2'5����`��5�����J�F�;��eb9����~��y��&%�� ���.W$�U9���`�WK�$7%����(�/|�M�AL
�e)I�K���������:���[�[P�=(In�_J#��/�t��_.,CeHP�d+?1zd�?��4��+C|���jN��F�wm��[t���|B�K(���&���8��"ag�vc�mQ��'�\AF�����M���>_�U"�e�i������!9P;�jQ�?�/���K���Q���4^�������E�g�TG����
O�Vpd�Ht�pD�2z�#d��)���9�<PC&'���I
���]`v+������F���(F/��<��Z2�W6AHx�t>��������z�NR��`��B�����B�FE�0c�r.���u��p������)��4�����5|\~�G�Z@p*�������9x����#;?Q��p�����P�`������x�������w�>������c)_�
t!��=E�����!x���tLvK�=e!��$�u��\N�UYl#�d1Z��G���Z�.�P �~1G"��O��Z]���4�y	���*P���|�����<��g��R��e?��6}#����<;�\A�����������IH\*�+��)����q+1�c8�.�n%"�:�������QFSs���*�1K*����� �R7<;��n>s�'�����j$�^�xG�Y�x����n�"��?�o�R22H<�n=���p��"?eF�����O�a�CO��.�@��"��5��i�9.�o n"�N@3A�%
g�A��V����/HL��p�)��t�;]p�id<�}?�$'9|��u�(H��7G�b���G���n�o�<3��c)����'��LOJ�q�(������@�����x�6����1�q����Q\�
��3T��	P0.�V��0���|$�0�����6iee��-tJ�%�Gq:f����+k-"��������g�05����x���>p����w\*<����4k*Sb�,"93����H������)_����^����>��9
�	���xb�`������������MG� ��Z7��z._��y����7�_a2!�a8����bv��#�bV���\�vV�jtn��
��e	3��&B�I�99��jD\��-��
����[x���/�hJ'Fj��9��'�7�Qy�T���c���)	6���M��JP�
x�2��H)�����|�"A�&+@&D��7]�g7�3~���9^1�d�d���5���w�=�$G"�(��	��mdV(!��s&z+�^$)�����7�~��}�pv"�5���?H��i�f53b��\G���h�\J��r��Y\������������:N��R*\�t���|JUz�*>��j�G���S{b_�����9����	�!k�����q���6.������'2w|CM�"D0�Js���bG�Iv9�S 2"���J�H������;�]��b�"��b&����GO"h�U���5��%e��g3E7��"k�������^�a
���!� �U�����J%���a���q<��<�4�#�����+i�/��B� �p�Q������Ty�����J�@�	It�Df���&����9-Iw$���;���{�kt'.j%>A4��7�T��������W��� N!Wd���;��_*G ������Lis����p��#vM
�W���[��0:�cI%X�T.��qA����+�I�c@��W4��t�.����:M@����U�����uo��d��vJ��{����.,��(�o��vps_2����	�X�!�;���-�Q��'�|��.*
^R�dg�k!"�A�A
@4�������E#�+���3���bGJ�|��u���q����[C����^��QE�c����>T�A������8V��+��V
�����Jc"i��U���v2�Z��p��=�|?|����\u�<i9������]��z1����wwR���0�)�LYn�?q�2��8�YFR]9���1�sI�I����cY�;4�SO7�~F���:w �/��=V������]<�>��=�p|��8F/v���^|�~�������V�d5#lq�$]�/1��C�EJ��t:V��a�����T�?��[&���{�-������_��4��\k�|S���d���]��q���������������[����
��@�y/��CT�*��������,�`S�`�.^*x�_0�aML��t�>����-����:"	����V�W'H
���.�����L��W[��=�1��}�pP�]Ks��\1]z:���CTm����n�6�)�U���|�x�6{�oy�F�=7X*�#����dT�}��_�)B��������M�`>�P��l����������$�M�"X��oG1
:.�@B��Y���4
��g��	6#��j��]��	
�
vS=&�mJ��@rl����5������� ��t�u	��6��K��:�����������7��(�0�pY{v��7��f��n���5��C�����(�'<<cw�$��T�=G��V��Fr�R���u������5P~NQ������fD�����=o1�#.���,�g:9��)�G�<M�'t_��{��v[����m�;]d�Z�N�I��L����NJ���������~ y��7�j�]U��~�Ax�\�������J����k
����]�9j�|������&����7���Z�DJN��i����g���,���/X�!�)���Z���[�v�y���n�R�P���em�:] ��/�������]�J/���	Ki[�1|X�k��1�qEo�>����.��������R���?���.���y(7�l%
g!v���A��J
L.��~�~���@��%��,���K���:&�kS���C;J3�U�S3��6b>���H��b$�#���nW��7���@�E!U�VC^��Ck��;=kw�kuZn�A��RDQ���n��%b� "��������O�~r�Q�1��'���v��m�.//�Vxv��^m?���`07�7�c$UyI����������g�?�a���5�HBZ�2F��%���o�7�M3��4���*H��b�KOg6�Fu&���;tr�~���XB
w�
��
C���+@$?�5���������X���,��`����� �{��#P<�j;��������|��FE$�y!�k	�=dh����Q(������?�*,��u����3�
[>�dg�\o��S��rJy�����OQ�2)V�4p&
)���~�j����
0�Go?�9y����v���,G�'����;�����@�����Y:Rv����[�a�����yv�z�������Y���`I�P���o��E�n�@<�x
N�O?�}X����9��#���������b������0�����������������H�B��4_��Z�t�����wg�~|��2�������I�-��i+�fr&�-��oea�79��F]7����	���[��u������
Q���C� ��8�Z�^�����hG��3����,�c�YD8k(�gE���-�1m�i��6>899���d�.{m�jV=���Bo��(�NMY�Uk��f	:@����3��&��i���g����:c���oQo5lb���K�I&n�!����G0�������|:�G�0.��;,�/����a��.���-K�"�"ncU3h�6�3��:�Rg������!y�B�����~�XZ_M�#���@ *�*/�Z��$`�$#��K�q�FhX6���������__O�l�=a�����D���������@�ReY�'�?�9}w��3R��_x�����y����Z����o0N����������2v�G�6F�Vl%`�g�:��D��{����,:�>�`+�������}BYm�omm��$�0��oy�P��jY��=N��!�&6��;xwt�6�&�J~��x��bf�����=�G���^��uZ�9f��x�.���6���������c���v�9���:��%$�(�A���;�����8�+�O������y1�,.^���wr��AT�E����������<���H����1C�+�`�5����������4u�pAw�#��g�[����LcP<�0�Gz���ywwwh�������b��'��
d��l��)�]������=#��+T����������C��8�Y���7�����C4���t���G����#:����pI��,�1�Eg�S���l4��������-���N1?�*P�l���i9P��3�-��=c����o��&�N
"���uq��K��x{��7�5�����
�OT��D9�J�Gw��H���5��V���|C���x�p�I
Sn�����|�b^�g�^��w�ht
Qj�y+)��]g<�^%��T����� b�A�u�vz"��ZMri�0����G�%�8�?ZND&��\d���r)����?�����,r��y���|q�L�/��7��q����a�i���V��]r�\�_�f��XF������U���m�_s�~�%��.W��#1v�^2��4���3l�C��+L_���&m['�3@;9[V��j0�:��=���s���\��,q��2?�~W���g�o��/�b|{S����]G�����:���[
��j��@�/t��Z�����	��gr�/����"�,�W��$����N�7�a�BG0�l�|�m�m���@���^5�R/�����Ub���-H6+�3H��(�D)aB��R�Y�'�r
6P��8_y}M6�k��?�}�����p7�������fN���H]b�.Z�6�1��!N2�c/�*��)�ud����qG�
c�2�e
H�:�A���x)p�Em��IhL	���k���J����N��������j�����Lf��Evh@����������Z1��|�Z6��8k[	����L�C����z #��2�^{�������e����� o����g��� ��,+�*��?�����o�Dip��tXD�~���G�������<��iv
���9!b����Hq���5��@�x	�l#�a�}KV�r��
%e�h����	�-%��OO����"�M�F�H�su��	���>�����Wm�C���������O�P
�l|�f���	������D����������(��3�����������p"�'�kg��vV�k�^�+�������
z�&�lH�ovh�]�p���m2���E[�3�����ou��Ra��@����dV��}B���j2������DX���a��������X������U���s�i���n���p�NF�vR�h� =;Ab6�?Xx��rN������a��F�����QN?���%�w�|���D�3�N������!@{��"[�O��]���L]�$^� �.����4�����(qDx.���?�|V�F���}wr�����G���Bx����s��b����V������������R\�����.���@�P��S��I���W���|��������`Sk���=����~�n�'l)�eQ�f����Vz��X�W4�������Y���7��-"d��X��R�LR��K�!��n%fI������B�����v(X�Q�^��2Y����p.��TH�E�i0�5���y���_Xl)L��PHJ
>c�xv�,����
��BsXOA1�l|�\���h���>$�����?�����?~��P���a!v�n�V����`�����(n ����a�$e!���)
�xH"������u�!.�6�LW]�o��a��$�'���L]�cB�����Pz�g,1�j�a�sf${�%���f'�~$hD���;r��<�M	��5���G�]
��g��A�������Gg�I��J����O<O|�R��_���=���>���~���l���4����'N�V�����:v�?H|�VJ=��&A�}��|Q��P����T'�	�D#����@�uS�W{|�v}��W�$�5q�5$UG����DX��S?�j����N�����+f6�Y�s�ES����n�j����p�=�3�k+%���4j���n��J�?�����!����S�y�>N��wo���������D�'����!F��C������O�]���/�$t	~�9=<���Q��?��_~8������w�'���>�I_����?�?�"�zrx�������c�3�����7G1
}<$����?�Oh_>��;n�~���$31�����������N��c�����7{z�!+�/�z����(g�v�i�{�����w��(�K���8��}34`�Q	$���X!��j@�(�3�����l�|�3�.�;���3c��4����OX����.���a!l��
d�����G(EYT��24��%5��%:M�!v}�cR4���	J�O?(E��I����RR������L���*4%SlJ8�|������*��Q;������*R%w�
W�S�hg�����|�
�]��)/��E�����?b%���8q��D�(�Nnq��������p����Ro�1^Nr5_3z��<��P�"�L���h@u�=�
#�������`'&���9�Q��q �P���n��gG�����1�������~�m��Q��y_��^�_
9H�*h���1`��"������l>�T�����}��0���2H�E���R-�w�sG�!r3������ZarK*�0&�Y��F����a1:�84�z_y����o���pM��!�D��Z�	o]�7w(���=
� �4z>.'�������{=�����RZ���H������t�%���d���:����z�X>�	>���p�%2r��<H��]|��3-��o���9\#�f3M*�����������s]w�mi���-�\��p��~��r2b��>b����4!
����H���|�t����ry�9N��@�?� ��y�����+�f�/w�K�����~}���sH�E��������k"�x��"}�jz�I>�,����yw`��������+�O����!b�EC�W� ��O����s�L�5I�\C&f�����/�H2��dcS��A�	��;[�M������T��o��{��q��������	�<Lq[�� g,�*F��)t�������c�Tc�����.�����1-���H�u����}#�gc� c�2������m��j��J�(G��i�.F6IK�h���r�+8�{Fw������vf���������^���s����?C
����(�^�&G
�'9j���~���W��0��?�XR?!�7�[���dC'O��
�o���Na��$�
p��c��S��['�j��tL�a9vR�%��&��G�`�l�].�'A��5�������'R����vq�J�F�*uB#5�_�^��d&nQ��T^4���f"+��aul��nS�������Y2��nc��Y�e�]�p�w,*��`d"}�	���$��M<5K`29��RD�v��zc���4(���-��Qt6�d�:�������1�4�ZNg3ZC����%�hh�dE�aN������$���[v.
d����.���}U��Ar.�$rm��+�z��6�u���n��������z���l[�m&{�����d����5�tj``�`!D�B��~�����w��P��<KU�����#K_ut���#2���$g[e��B��r��&�n�����5��XA�Hs����CB��Q�"i2���L�s��m�-�F�����d�rR\A���t�u��@@*�y�+w|;�s"��r;V�5a%���v��YM��RDa%� �Ph�����Dzp>�9�	���}T��y�1Ov��d�������z'���(
y���/hZ4��7��xg��M������9�s[B�=j�[),����,$�P-�2?�R�=��������&ng�������<D��s���Z��N{�"W��W����<�#u� [I�!;�Y�%j�I�:�Y�4�5a������1���L6�"�O���&�n�������;���v(��&F����Pa��
D��o��"������8������.mcP�1T����*�n��V�9�����,9Q%&��<���b���N��'��a��(�V��� 8qs9�f��A�� 5Zl}��`YF2��@>���dg8��
�S�j�m���5��_-����C'�g�n�	�/���"�C^������0����"�J@��*��M�z=�O��	�=����i�m�Rx�����l#��rA���)���zo���jN�
����Q�{�����[�y'Eu6(y��`;��r�`����O�D5�xd����Q<����#���$G_�h��6	31����L�K��|x=���kl����k������b,���(�%�o�:�.jf��E����]��3�8�|�E� �LuK���5��G��D(^���E
�A����/������Ub��0o.�-�M'���3;��)�ddM�����9��t.��V+EN�4m�e����3k��D*
�\S)P�v��D����%���x������n�m�-�d(�[��v���9;����1$����F:�g����H�3$G���L��^���H����T7��j�`+'����[�I����M�pj���;�8��n�(�t�SQm!T�m�E�V�d����;���&�nW�f2v����w�K�$'l�.���w��~o-�Y
7����� ��s�s�P�����5���[�����x����j��M�&����FM��h����sk��;<���N�x��
�6g�U�B��
M�o�#uMRg�����|u����Mgx���-�k��p������UH���#fWYL�3~��?��5b:]�N����/m�5q|3h2CoB,k
`��L9�"�v�^�^��e��6�����I1��f�Ok����s�=]/7���aV��A?�bBv�!I�@��V���w�S;Rh�q�2�2��i]�DaNE�"rF5�WbJ��|��^`%�3Z�gW4�U�)W��A��d�=u�N���Wp� "5|�`+_�V�<KP�.{�YF�$�>��B]��E0�^�gm�YE��:���2BD3y�xL����5������������l���"�"�#e�;/��t��0�����e~��(b�^�{��6��f�'���"����U(q[����i��"U����$E�XVH�L��Y���{�I��},I�_�����U����~�X���[�:�d4/i��&�<T��{���2	������Ql�|������-�.6����>]�~���e�Ep������z{� K�r<o�[.�#�f��i���E����Z�:��bv���McP�+bP
7�#VB� ������'��%f3�(��;����Z�%��=2�c'�����=Y���{c&'�I39%�
hf�P
��"��0c&���#&<h�j6�SC�������QS9�w����"�)����;6e*'�����}`�T�v2I_��r;�Y�xn;�]���k��K�t���&� H2�H2L�$)������c]���c�W�Q�%A���@4u7�F��h�m�� �c-u �2`�T")�Y���L!+��"��[�6c3���Z'7�WK���:�)�������/��o����=YmvGy7Kj���_bg���%%�
h��P�,v�$"�ew�DL�a�Kj���6�����w��	�>]�~�6�rI���1�{����oF?��rI���s�{��{=bM��R�\:�\'�Y��Z��k��E]�_�n+��,�2�rf������ ��g��_�~��|���1S+-���bm���9nz+���#�!q
\����}��gp�m��N\#�vz��hn����*%��W�I�;�B��u��^�G�5�Qv{<f����n�D�������]�N�l�|�P�^�����{�n�e��W���p�{��s&*��.�������-J]�=�������w{��`G6�5i�R��i��q-�����V��O�p��?����1R|�#,�x8��N�E]I����M�������[����w5��ir;�i;r�n1�3�� �2[��$����>����X�P�V�Vi��������{��S��n��Nor)���h�G�b4�LqA��S~(���&�G�:99=�
f��~5��f���������r��\����<^�J����[�T9]�F���[����8����'���&����Q�z�\O�w�	*�F��
OE�F�b�W��������m+���k��s��	�$A����v�L�DY�P��a�0�$���%
N����z�|
�����?|�����w�/�q����k�p��U�^�>�O��]�����Wv��Q�I�L�J�
��]���vw;���a��J�i��R�0N�jX6���n�u&3��	$eMN������< ���Ki������3�p�(�ACJ���m�%n�����F@l��e ���y@�]Rd%m��{���a�R�a��yALA�}��B:�2���]U[G��w5_,��B�.())�?�����g������������M�)��6��2p�~[+7��EJ����@�n��Qn@?���A��@��x�����IK�uP|!�,�[Zi<j�(�����n��9����p��k��������g0gB5�����l�k0��9C�����;h�����X9{c����3�/a���Z��^
���a��d3��9n�s��Z4�j�r�M�3��:�!(zz�z��n4��=�1xh��i������	��t��+������������b1��S�<��gc4�@�r��8vy1:J ���	������?������w��7j?��Ovp���z��"x"�e9w����%y�4�O���6}��cy���x��w���a��O�~�)��_����:|��� �����C�q�^b���<�[[�I"�-v�����1�	
�/�&'.����z(��~�M���0�-~���~y��Dh�`�PG�b����8~��0���o' �7/�#c0�k���N�Pf9��f��.��[��3N�����gd��4��S4#:;�'�u�u���E�<�hi�,��.&����o�I#�t�,Q=����)ZZ��L��Nfx\K��9)F��-fj5��y�6����6����+�]�o�����6�~�~������6�����������<�m)���o��������N|���t�����	��U].��'-,��b4���,E�z���:���t0�����Q56����C��- 9�s�]�	d
��.���A�V����O��|������C�}�,��3CD)����n=,����,'�\�e>�viS'�3v��?h�a�����]A�$�����#��t��ai�a�jX��@j�������2���;T��lg�d�������$�,�!H
�l�+I�lE��_ �?t�`�pLq����>�`\y�����>9i�&&�6!Sp�4j��s��@�d�����hJ^+j�T��J�!��:i'W$�$"�m��(�w�j�P� i�)�pd�$(�P4���)������a�T��?/����x��>��y������S�L��_�#��[��s#A�9�f�%l�zK������~��ba����<L����p+�lVt�����G�Ij��t��z���
��==(���T��{�hV���8�>= ������I��55����eW�����~���I�
�R��5��0���OG�~^2���?
c}���(������z�PJj&Zo:9<:8}��C���Lp,�zEIj�iI��$J�wJYG���ji��Hj��6$�q�e�;<��/���������i�?vv(yb������&���������g/2J�;x;��%��qiC8����4Ljg+"&�FV���+x������qI���t�B`/(� jKI����T�Sm[��H	�J��F�\�[KN�X6� ��#%��/Lb;y�i��C�5���TZ�����V�m�B�J�}��&��_o���1�W�0��D�hN��EP=�R�@��]M�RR;)f70kMV�;25�����s�wOOHSb;i�;f�z��,
VO��&��J�*�
�J�(9�W����=�����N�)��4��I�DO�������]�\�y�y��)�:�����������G(olK��&���&f1����������U��3���L���#�������vr��1C1����5uI��	��I�K������v��]Mg1��y�nx��IKJj�r�K��g�#���
_�V�U���3�z�t�je�p�������z����!�����p ��h�i�I�n��nD��z�y���#�V��l�p�5�ah�st3��w��r����\����T;��t��[H����:�,�\)7��ph�A��v
���e����NQE���cT���Z���_��NH��$g�G������N(�e3.����_Hf<�w�������9��-����.IqHi6�nP�[�r"�|
ZD����\S�b��������h9���L:N����F��0�������4��@-��SQ��|{RB�)<���Cmk����N�-���D�M�^�9-J/��L� �����v�`"Bf�"�t�DN�j��j���U�	+n�n@V���,�*���DRi�{Jl���Z�_���;���Z��t������h��R94%�Jl��F�J3{���I$�SifB/k��J3�4��9�G��N�}�S��)�*I��b��������TX�4}Bs3.���}�H��L��I���������%��EP�����Q�����er
t4����N)��;o���y%�y��W��Jb;������T�_���b�q���Y�1��DVh(@�U��**��9����I�.{��\^�rF����9�����1v��m���K�+�wN��
�T�B/��G����+ze4	��v2�V	�$����v5W�]��>�^�����==���v*�������%�j:���N�=#�v1����w���~�A��&dIj�>���u�O��Qv�-=fHb;k�����:����3�z���Y�4|��2��it-M���NeT�@e�A�Iw�g!��v��$H��(9�3���9�3������v�
�����FX��j�T,������N%���jp*�i����)���i�"����]`@Hf��c����b<O�r��E#m,�4*��>�I^����z�K�
-������=�F��s7���GG�r���&��{D�Y�|2�\\�f�r��������w�����Q����_np�����6�-�����Z�������k��z����l�~A-�gw����G���f���������t�dggg]��|���F�X
{���o�y���p���e�.�{~{��	D�%�&���`Q�����O{l�!�>�*�������@�^.\���|�^�=�������Xvb1��Dy�*�x�:K���~�uw�,���a��j�������"�\�����������D�T�����p�]<�5�M��aMY�Gk��������
�,�C������v����}�������o��u��=���]�!�9�m<�X�No]�x�<�?��\|�oc���.��K��J|��o��o��oS��Z|��os��F|�]|[�o����n��O��g����v'�����0�2�Y��w�?���������;���>r��py�B��m>U����=��'3�FVFar��}X���o�N��N>��]tj<��;�+[��E�S�6r���3,|�Md�3�����3tO�:S��l������uc�
��/�Kd1Ht�m�`��q~�������G��`�B��������dr0R��f�9�����	L�B�)�g��J*u��"��X4��t��u#��H
�����v��s��v�xt]v<�W��b��i�_$��^r��#�#��v���m��(�qV�j
��~���.�r�+;��7]��gB��o�Bt�i6';s�o1n�oba�|h��)������v�:U���)��o�?�����b}���)N8�X��824�G������G��@�Ft:���.a�e�e��;�md�e{�t�
����������h�����W���?n����Ks����KS�f�����������b-��kY�Z��H����Hj`-�bG�;3|X4VJ�6�!3�������w&t��Bj�xV���h��%���*�6������s%���Dj5}���~'K`&Q�7u��?\��55��P5h�a�!�����1hC��4�~<����U�6i����;E��(�=�2E��?�����O�2?
c�b.`�sI�\�"����3��>��bQ6�G��H<Z��4��T��b�>�u�$�Y��,T�c���"���#�����_������6Kf�����2�q���]j����Jn�%�H�G2����x$ch�?��OA���c�=��x9��9������9z�8I��be@,L�����-x�=��c�#�:�����4$���F�'I��2�&������'0�yD7�]�;�dhFYZ������R��${��K������������@I<wT���b.)����	���	�E_d_|o��8����J�����dhF�����E�u9�<p�.���9[=�3n�t��z��a��r�������76�����f�H�+������wF����+a����X@yRV��)VH����hc����K����i<2nN*��(U����Ixo�np�Jf�����
���H������_��#p�Jf������T�d(v���^���2F/[�N�7SNrS�,C�
"WU0�HA��S�*�>%���R$��v�=3���2�,|C����G�86�d,��Yp��e2����gDU��..U|���+h�x�V�o��*�m�6���E��m�b�����5�G������N8��k�q���h�E��:vDs2���]����n?��fZ��K�T�v&������=�����������v����C�8:j���l���5-{��3>�������C
y0��F�7�7%��O�g�I��
�k.d��T��
=N}��K~h���+<kY�����F�k��e�0.��"�3��RZI]���o�%�3�U������������o?�m,�y��f~'J�fv'�b�E�b-7�;-��wZT�NKO[�qk�xx������uP���dq'�ehfO�o�"(z����]wi'���g���<�w���������24��*9�9<*�������r
��]W����28��*~�9D*��������_�w~m,�y�dV��n6��C����6�j����A������V�!5�a�u%L5�V����E�����C�����a@yl�Y�u�0R��E���A�f|3L�f\P�9�B�x�c
h�S@3�-�9�������7���G�)���nh�CFh��hn��4^=���������T:m�����?r�j����*�b5v�[
�I��4�������n�Vj�-�b�Z�W�������o�*�����^��4J���u��V�mI������nUp�j���$p�
M���)�i<w�����J��{���*��5�WCW��~[(4��G���1EI
hF}*�����vq��](�/��7-���Pho!/P5)�*f�IQ�TtT"~-�`�m����NY�>������,�)���X�n6�M7��D����%8WL�g�\q�G�,e���'q���8�2o[*��[�28�X
hF�_V��p�����=L
8��3�y�����y����L������������&P�������.�M�a��Wz�
r*��P@t�Nc�P
hF�!WRn�z|Q�
�b����p�Z)�� eh�C<eh��S@3����p������5������>�R�����q���������f4;~%�6��k�k�k�k��?�/C3�~@��1�H
hF/l���f������f>��Mwn�bp�Qdb�$����l�;�:�kY�����a4�#0��������U�	�)�U��{fW(��v��/�U��?����{�(��)�M��{f�qC�P6�����)�P����z�D��=9�y����k�Wh�u�y����	��Sh=3�S@3G�I���rnl����n(���7p��^ep�Q����Q����Q����Q����Q�U��t�J�-$�\g~�[W�_@��|��|�-��c���J��(�+��- �XW�_@���|���|���|���l�q��V:n�%@�~�b����������eh�/I������������M��bm�bM�bu�bUw���24���24���24����r��[c�]���x|���U��_(4���2�����j&%cX�:1>�{�<~-k~�A�dt�C)��`� �cB24�V���	%C��`#�2:z��]�f�Ic�CI�4m#O�G%�aj�<��i)C3o6���_,/C3{�|%��c�k��$C3�5���������	���{�dh��f24�����^,_���I�[��}d~�Sg~�L��{O�R�+�=����6�%�������J��Iu/ �QW�}[@X��X��|���|D�Mc\w
hc�+�V*�X���3928�;dh��T�{��'S��wg�ep������Xn%����p0_W��[@�\������24�Ydhs����1�J�����YIW�o>��Mwb�b����cb�$��	��c�eM�:lo �k��NH���79\�8Lf�$L�pm����_��VhG{J��d��{�3Y��Y������r���*�eX%  �!V�i��5Dk������������V1���$��q;@��12��@7#�U.c�*6�@�^��t�L����TBz��m&��������]�5���m�����mU�]~��}S�i�02����o����w��[��!�N�&M#~�1�ni���}8z����@9��:�O�5��3�;e1@��F
P��h3(�P��Cd�^g|?_g<�Gg<\Ig��$��`����h���*�[q����x(�
�����3M��3+��3K�@3'�@3~����
N�v0R,�����!�G��j�c��m��PL�c�����3�a�W0����Za�&0L�[6��y�;�%������W��{��
��N0�oz\@g�=���!��&�*>���sl�����epf��u��aB�|�����2����"���dpf����3�L0�,�������]�5n�����@w������X�m����]�����](r�=��m��s��c�b;S#:h�e2h
�K�����@31%C3&C3�&C3~�����1
4���*�t_�Q����&c�y�]�f<'��xJ\��80��+mh���Q���^���*�p>�v���|V����g�0j[c���Aa�����8�R�~|d)����d��K�m�qzO?��l8�R|��u��B#hdpf#h�p�.� ����-��v�i*NS�1�A��������Tj|VS��^��xMa���8��8=���Z�P�4����\Y1�Xij6�F��}O�����z�^,7M���a�������Xn6�F��<�����I��/(��9��o�B�z0w�/QWlg�b�B���L!�?�������|���|���|��M��L�|���|��Mw�X�s+���q�>eh�-T���1���1����dh���dh���dh��"4�a0�b.3O�C�P`��$	����:���-��n��f���1�K�c��Z�pl#8���c%I��
���^���B�+�����^�Pf^���a�H����g\�)D��$�W�jJ�j�y6�j���24���ZX��@�xVS��^��XMqZM�j���-=���Z
J,���6�++�+M���j�p3�4��e��z��]���#,z8x1���b��X�m�0h���t�cBwJb��4�2�CEF+������3G��3$��3��3~���e�
4��1&C�}�[�y+���YW�Up��bT����Qg<VLg�2F���h/cLma2�W��m �W��=��_d&MM�T��N(]���:��'u��^��>��2x���L��Pc�����d��������~�N�I�;rZu��McT���1�yY���bxL�\+�����e�����ZqW�<\�b�{}���X�u^�����Z$�I\�{=���u�q�F�}"�
�7����,���r�G�.&�}H������n�k�*�+�;e�H��F-P�0��B�dq��*8��Dg>^Lg>^L�1�44��b24��b24��b��8�Jfa>�Sg>^Lg�&��/&�����|���|��Mc�X���S�����@�+�}[*=|w�[^/��1��.=4�����hr9�/0�4�^�<�00��
�f~�7N��&cJ��^������N#_*!:E�Qtr�a)��=S��KQ:}R����H���
��xvU���a'{��P�����k�Uk��a���k��+^����Uk4�:�����4�d5+��^����]�����{F��`����_�B�`2�1���q��)��60�>(Y�� ^e|�s ��g�24��D�f>�C�f>�E�f��8����h���S���?����U1�|���|����+@�f>'����q
4���)����@�|\ '�TW|N��M���	4�u�h��ru[V�������4fN�M�3Xk�?�kMH�mub��RF��z���[���
���)k�A��-]h�r��J�"����s[P��c��L���CEn��EV*��FV�����E)�)TL�b��5�d���*�����'&[��`���l�e�����F�i��}D�lY#������]�e4|���]!��1�"���
��	��IG�pv�}����������LY���Q��(�����x"��N�ya"C3��@3��@3��@3��@3��@3�Y�����g<�S�f<�S�f�����T���T���T���T�i��h��@8�p?���4��t�����&�`�	�T1Y���]&�"c�hF���,*E�P����3H����C�P6R����G�t�
��W�)��^�v_�L9R�U\��2�q�bU�7��.S�2e��IE����+��^�v_�L9��e�v��������U�^-W^�������N��r�U,��Q#�R]-����(m=�a������
����,�j9�yi��3���3�"�3~�����r
4�W�)�L_-Wq�������0:��A�yo����r
8�W�)��_-�@3~��M��rj�.��-<X���
���t��.ZZb���c���e�:9��N�=:��z���z 9&K�kw1�M����@���s���O..P�y9Y"g�[��&3����=���t������q�{��&����$q�[�������?������w���^��d2�_hO[����E���YO��&����f�������u��
j�-�c5��.���';PW��$��������	��`���E���@7soB|"��|����l-���"�1f�[�y8�Y�>��3�=�gCx6�u��r�^��}��OgOm�&�n�S�&����!��1����e�-�����%�@�����>G�/z.��-j��V"�bk����t�g����X��O��mx��?e���t!Z�C����x�������$x�)O��SmH"�$a&��$����a�t�L^�LG�Jp��(�8��Z$���)�&���\w������],�?��@F�-��x�F����l�"S4]�2�7k�b�_��
��/9[i�D�fJ�&6Y�y�?���E��v3����n�����m����u[!<��J����zT�A�J�����*~�O�H�K�����mE��1=w���������a�@	�@Un��9�P�&����(��	N�G�f�p�(���7�T�Y�7QD�
�������i2%Y�P��b��M����%���SF]4�Q�='���8��<J
�O%+��8G�y�)\Ca(�CE�9�)�P����F(a	��<g��Z�@_	�LE_}U���Z���*��R+�0��:I����{D�?��
�#OYQ��'���v�V��e<(r.��-�\~e��y���c��+{���X�Ha�Ha�Ha$���i�i�i�(��]�T�Z������L���m��%�^�HD���Z�.�Z"��#��#IH�5�����IB���D�f���E�ISL��(M�V���m��"H�����.������*�6
c�.j��<f�0z1c�>O����R������1k:�	kmUJ�mT�����t�o�w\T�'X����b�)j���S��CbE��F��jV��j��&�i�
�Y�Z!z����q�b��<�;�[Z��X9 ���=Gh,'^��;�*���!zXG��H��+�s�)7���~�<W�:�1�k}�pYx(^q��W^�%�>���^�>�&�lxNB,�3���] �v9���>��X�&�4v/ \H����e��������;pp��c���W]j���\�\����,��~{K��F*m���{�M���h�N<���b�������ld<���C]�t���^B{P����j���1�@��������t>�y���)� �u�����?������������gg
�y��nQ������V��?�������3_��b����?S�"�:����Dw���<����`�p�%��lT��=w1q��'���s����K����i#����w����S�.�����2��Vrt2��Zb�����}r����k����l��s�m$���7W|��.��+�m"��*��&�M��k�m&������w�m!�y��R|��>�o���/������g�������4���$�]ZV��<��,-�^H���t/��A���W����n2�8�O�2��\�8��������t2��A��|������<��������.t����~�)�a��01�]�-��-�������>�`�Z�_A���j��</!�`��NA}����������G?����i����3�A�����:,�i�<�V������sI�(G�m����|�aF��Rp������Vt3���q�=t�`=oL�+}������^O������e��}�,�Fg|���6��M�$/@`��W����x��2������ ��G2���;������ ���q^�S�@-���J�("A''��f �I`$T
��h���V��V�C$W���4�]-JTB+9����8�@?o�j���V��A���	LgX_9L��=-���JyC�*D��p����b�'���-(Xn�+���g
}-��J<S��a
v*�P�-���AB+���D��
c���AK��&��6��
���h���V��������w�� ��Bl�
��b���'�b�S�]�2[����`������J��/� ��������P������*���"3;�$e���O�c{AA��_A�^��.�gF�nJ�m��(�5s �ei!��fr�Y�4��G�5��ekQ.��	����O�sp�6��9G
Z��m��f���������A��Z ���*f��S\�����d�q!�cW(���:zH<���fJ��_z��z���oI��+b�1ELf�Q�E��E=^��f�Q��Z���f���x�������m9JKKHOR3�?4v�p�?5��������v����c���H_�)�-���-�R��I����� �\�O�x�}
$<�������9=�3����w?��F7��R����\��.,l�`��d���L�C��7'� �rg���|_Lw��������>��w�?�����==��m�x���\IW��1Y7��0
�+��|��o�N��N>���!�=��i-s{���y��K�+�X���U��{��e�5���t�������%��1d=t��l G|g�t
�dA��aD����{�B�����l�����V������R�;�"�7��z�]��Eo�]�l�#r�G�����
 s�!��P�e�I\����^��.9�ir��5����X���0��K��rD�l�.����~����P�^����>��,L���b����0��Cm�=l���1c���D4}G6����:��
%�rW�]-w���r?���,;f�C�/�s�C���W����D;�;��N	�����r�����|�@x�:����s�����}N�alm~�^�n�D�i\�K��M�1t��Xc��kV�����Z�jm��5�����cm�Y�U��E�|�&%t�|5�j����[��M��Y])HO>��!�5gG����C���������&��~�
��t����Mk9���v�C3�v�t�����
���r��9��&
����(Y{+�9F��:5�I�.��<[� ��L��gG��F������RM@34)��:U�zI� ��v�c���e���f����\�{Q-8m�1m-��}O�nIa5S���y�s��sM
�+Rm�{R"�I��E�:�=��"��������U���`������/."u��E��#�����?x��o���$�qfs<s�3Gs���>�i�[�c�����;[��������
$$���
/��
9k�M����f��3X�������P���I3@3�>���s���������G��{�������c��Nnn@������r�D\����u�6�t��+�+��������x+�}�>�6�$���
���}Q�+���5gT��������H�a��YC
*��9��E��w���-�M�������7O$u�����&6p%��"�G�� ���O�F�����3��������g1�rgB�����i��c��P��~y��Dx��}���#;�R����,0����"���k��2�;�RN����c�� ,��������42r������a�`�C�l(�K�BaY���Mfgx5����#��0_��U�b3/�n�Z����E?�z�6��.���f:��U�K�������woN�O�EQ�#����$l2����6@�$Cs`)��m�"���D�	|,K&��fH� �^��A��*Y�i������;�Kk^Z�����Y��f /���uA��S�����/i��]�����>!W{h�-2[��P7j�4
M0(����()�8c�GO���d��D��z�HB.����{.�C��i�Va��������S_I��b�>�T�:��M���A�W���,7$*�e�����3��f�w�a�y�U���KB3��]�'(�Y�'��9��v���vW�;
l=s����#�-d��t9_bR��^������!"������7�����O�	�-���q0
��'��p�����m&R�r4_@S�*��������������E�~�-o����Y�=ZJ�	�^��D�Oh_�+���#1�'x1O����^�wE�T�'a�>@�[����/�$��{�o�h�M\��4q�&.�����1��.�y��O�w�wk��W���;x�|�q��:wG�-j��i�f�vF�M��?W�M�Pi~���<n�����������������K]����|�l�`���
��=Yo�@���C��W�O�����7�i�N������'nS�V��6T����?�.��4}�:�C�Lar����R?��~��o=�E9��l�@'���%g����O��'�cj�)�m5���#�	\�N_��bm�rB/�M��q
��d�/No�.���!�	����3����xF�\b�#��k�p���{CI}�xl���X����t���:F�Q��������-'��B
��u�� ,^�!� �����0�uu�S�`�>^��JR/�N��c�G�Kl�	b-=�Jb;k�����*��dKk�����&Vv�����(�������q�-�)���A�������d���������#�[��Y�!��A �j_O�`�Ux��~8�Qn�s3)����Lf����'�?�D2kL]����(��DRMK��6�������O�p't��B7����x.�Klr0��v+#�t����<��@<9��9F%l�]��Glg�p0*��f�9��E�T'�-��]�3d���-MbejG�N����W�6�>�s���G���Z����Pw���+���|}�R(f�\��C�F�� �S��5�H�
D��h��i�8I�.�+�r-O%�D7��"�*[�q	!���U�2[�B��B�"m�QyEP��|4B����2��ZE���-�	[�[�-��W���!�����z\B��2k��V�P��P�H[h\^�,@5��l��&����VQ�lem�2/��Bu����cC�-����yb�C*[�x[������f2��h�PeUb�������-d��;�
]�r��X�Pe�	���B�!W�B��B�c[:�"L�Y�j>!T�B�M=������-d>�PT��Z��g^u��l�8!d?H!���+[�x[���g	��3���B����B�-����:�Z�B������������ ���/��=1T�BqB�z�B�%�y�����J��s��X�4��4�x���^����e
h�i;���|4���~@�>������LzP&]�VU:t[��gV�U�@�.�~B[eL�[�aPe�W���$WYx���y��
��T�*�b}(
��=T�@U�������9�2��
t�wR�g%|����\�R���r�r�u�l��K��k�	J`IR�TY	u!�eu�+��s�� ����� �s\�N����K��q��&shz2�������/:_�m�������&��~�
P2�nz<��@���d��=o1����
_8x�������{���������6N��<�,v��O.:_������=�q�L��a�u2�_hO[����=��[O��&����f�������u��
j�-�c5�C��7Ov�N��	h9_:S4��>�?��S�����trsxJ�
n��f�\������]������������I������������t����6��l�I�t�����y����m5c����fo����rlc��y�m���������k�V��J�����Ms1V'!o�I���9&)��7�Gs3L��������J�c��=������k�/�����J`�9{����u�w�F���������}/Q�r�f����_����HK�m��o.G�O������wV;;;z������j��?���(4��f�3o��O�
�[�aU�������������h�,��b6G�8���C�<w���5�r�`im7������L�m��lt�,_��z�6��.�-�i5jV��7��;��A��T����}�������i�i���w�������v+r�,{A?�b�z��������3���?���E����^'�=��#�*q_1\�q(aw���#-Jl�S��[��Em��m������/��������u�����v���G��8�n��~d#{�����S�����1��:��4��(�'�r�\�3�|O����Y�3�����5v��N��W-rie�S�:�Zx�1�����/u
�d�p���������	��'�v<O��D���qf=�Pm�x.���7YN>�uY��*XSq�"9B��v7�j	�p�y���g��s7��V���S��_��K��"���UL�|ZF5��;�V�K��H(�H���E��O0�|��6����0Z�+��~bI7�[X��	���D���0�W�,�7��E�40�����f�~r������J��<�J���[?v�Q'=-�|�=���]ww����]7�o�5��%���J��U:��*�9���h���"(L���F��2_��q{����{�>\���g����%5xx�po��pF���]<��+����+����������0���r��0/��v�(u���.�O����k1��e��ksL��B�����BUy�'gj���U�(��fc+m
�^��Bb�������!l"?�,b��E�)XDo��E�I��,"?��,�]�nA?���~K+��Z����YD>��������5�Q��f�0���k0�i8h�,w��k���{���0�63�L���=��D����b����������:B����?Bhg�����-=]�����H�9������I��O���GJ�x��|�������������J�RJ��pM��5`G���|{��MP�d^�`���t9C���D
��F�Q���vw������<�o3C�k���N�D\����=����X�m�	��5���;�
�9���+G1a@1a���KhnUo��`�������������`��k�4���E���� 2
"vY�5�ZY�;���rm�O2���Y�_z�h���|�- �C��r1�S�_	l�(6XY�!�tt����dB��������,#��Pv�3�:�<wu_�G�xw����q.����E��uH�9�2f	2f�D=��k�l>�K�2�;h�������S`-�	�=�9��A����:N��"��f?�~A�^�g�y���Sh���)���"h!K��]���X�`���e�+��1a�����>��a��D����K���s����sg.�����,�w\Nf�.z!���ARnf�s�!p<�v�r����������q$��|z��%�N�2m'�A��4�80j���_'P�W->+� R29J�TE���t��������.�NG��|� ����B�p�wX������NY:�WV�]��,�%�86=����^'$��	������[��5+��	�Z�|:��A�5���u;��������t�h�~�Yt}���&o,�k���K3��ti*+W�K3�.i��U�K3�CsiZ���r��}K?�����m����^6����l
��;6dA��.��.��%���mM�/�43�,#��Pv~��g��e�yf�v��;pww���N��K��-fQsx��zTQ��P�1������$;�0���mn�����d�Eu�Ot78��|*}����h/���\��$���c�8��������;v20!V�1!��Y������p����x�Y��CC�i4\wE4�<+X����K���]����+�����A&����i���z�K���&cksv��������� �d�%������Sp�p�$kp��5��?�k�)��x�:��b�in��!����gYVh%�v�v���xR�-`����A~7xh%��a�hS�h��M��,g:�NZ�\"-]Q!vkm�QvG��t�
�����L.���$�@-���N�H�����}�;i��@[+4�@i��^��vz
����h�C�
|��c�\����	_����J�6k�A�I~B�">�&%��^������K2���0^�-�E�b|qa��^��V�Hd���$��"�a��
H��N?�~D�h�o�/V��(>�9�;D?�3��H�+<��5E���";������q���zp����5��S^lXz2L���~��!>���?g@��H1+X�fUR�_����k���_�(�\���$��_'����^���|��������������A�u���s���C�����`O��P$L��S��&��@��3��>�'����?�����d&N>z4=.���+mM�?
~i�	��rd��?��������;�5���dy6��oHO�4����5u�qo���h�%��d'�?9�����V������H��j�1��)��������K�� �u'3\r�? �����O���A����=s�a=����~����~����~\��+���N��_��o�cJ?����~����_�w�dA?<��������L?��u����=S�J���N,���:	����2��
"3bH	1�|y�������w��w26��=�����2;wx�������G?���4��3C�@�jB����3��s������M���L<<boNn��*�7&
��w��#���THzii�`�
+3T��C�1z{������,�2�^>BO��*�������lnL�3���x��v=�H�'
;
��M�,�^�	n�����W���D�w"�O��I�A(k�s����sL���������f��FO��$#�����%�����!�����C�Ms��]���a}�[�FH�?���y�k9�����SK���+������[1"�rh]"����f"^{��}*
7	!���`��+*s���sK��%���%�S����������f����
�6��65���^�S��T+���0�����/���#�l-*��cg��^��/�
�xB�����g?�����BiV&��Jz ?al�g%1W9�H"����
���0��,%M�O��O:m[^�H�m�fT��7W!����i�Bmj���{�Rk����+�?n�O}@�eZ*���Cr��Z���o����p�Z��6���jg���q���{#��;>�����
��V6�DJ������uR\������oi�
��������p��i=�\��!�uejT�F���������t�R���=�n�@��o.��x�����%+
aE��9�3�"C�����f���/�X:2�\����T�I��j�V���eq�q������]>����BKZ�#���e�x�������+Wh��������c�9��%)�\���]����Vb���	���f��D1����h��k���*7i��.�H�3��q�Jp)�\��ZN�n?�q��� kB��I=f7��M*�X�6��X�J�&�B�E��
R�U������%���E�lN?tOd��!H	g?�[� �,H0����XPYv���^ ���
�l������G����C���s`���s�����������.�>�T,��ky���Yp�o�wl~3�|
��+Fc���=G�_��KwAN��!�n������O$/�O"��e�x6w����k�Z�W3%]�h$�fc;�U|GhV,`=�R�K�k�;_�B�%4�Snfga����������g���x����Y�42�����;���Z���E0�U<���*K�AZj�jz��Hc$�B�x�	�I�2,��"���ZL<�8��N�K�������p�����o��H�n���n�^'���'e��z��e��2�<�L0�����ep
������NF�����I�$8@��������qG�K� �v��.�]�������������u����x�9��0^B���>j�*u�C��������[�bc[P2�u��y�%�M��"��ML�	�l^�MFL�*+��Q)�
�7�F�{��#����R2���PR���S�N�h��*����Hv�E���H);����dgX$E�	� ��V�����T��AX��9����C���9���jh�s�[���V��G��IC��@`z:~��J��#6?����i���<
��k:H�oL�R�"���7H���QGsUg���*�\u-k�k��q��e_�M3C��E��<�}��0��������+��sZ9����������x9���q��n����bp��lI}a�����j��������������.��M��������y�yi��9��q`A�D{~������=���3�y7<�=/��trs��Iu�=�0x$b��v����T�sE{�y��~���K87�Yr��4�9�����@��7����b_���{��,��t�<rQ-��7��1�m��E����ye��	M8nCfq?���2���`���3���-a�0Ot����\v��+�-�4mzs��9��	�~,�$,h���X�GV�V���w���C�����}������5�fQ�~$CT�m���I
.��Z��WS5<fh�Ux�I��g�RP:����lG�])������F1y;h�\LH�v��q;)�7������m{��D�&��:a��"�h9_�n�������A&PT������/`�7�A��\L��b��bW�`,���U!n������������OX*�b���*1�	M����{U,F�B�-��d�\�/2NP�������+�m`"���?	���{���������{�o�h�M\��4q�&.������lJ%`��@4=�������&K���x>���d��#��s#�	���Qv��|B�������<n6�?c�X
�,������g���i���]y��8�ZqP��+�'?l6��L����������T���j�
�"��??D��1��G��9��!L������o�����C`	p�#������Iq��?�4�~rEpD�)�m5����.�0;���5�!(�f(g!����8���h�.��iw� >�,���^�qQ<#x.1J�z�5G8������>u<6A�w����\#h���hG�i����%�t�G��\V�f������~ /�a��@1��N��+��
�h�?R��r-�
27.patch.gzapplication/x-tar; name=27.patch.gzDownload
28.patch.gzapplication/x-tar; name=28.patch.gzDownload
29.patch.gzapplication/x-tar; name=29.patch.gzDownload
30.patch.gzapplication/x-tar; name=30.patch.gzDownload
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
#93Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#86)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

On Wed, 2013-11-27 at 18:17 -0500, Tom Lane wrote:

Hm. So you're suggesting that ECPG fix this problem by inserting an
explicit NO SCROLL clause into translated DECLARE CURSOR commands, if
there's not a SCROLL clause?

I wouldn't go that far yet.

Do I understand this right that the future readahead code needs separate
behavior depending on whether a cursor is scrollable? I would think
that whatever you do with NO SCROLL cursors would also work with SCROLL
cursors, so if you don't know what the cursor is, just use the code for
NO SCROLL.

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

#94Boszormenyi Zoltan
zb@cybertec.at
In reply to: Peter Eisentraut (#93)
Re: Modify the DECLARE CURSOR command tag depending on the scrollable flag

2013-11-29 04:56 keltezéssel, Peter Eisentraut írta:

On Wed, 2013-11-27 at 18:17 -0500, Tom Lane wrote:

Hm. So you're suggesting that ECPG fix this problem by inserting an
explicit NO SCROLL clause into translated DECLARE CURSOR commands, if
there's not a SCROLL clause?

I wouldn't go that far yet.

Do I understand this right that the future readahead code needs separate
behavior depending on whether a cursor is scrollable?

The same code is used.

However, when the cursor is not scrollable, it returns an error early
to the application when it wants to go backward. It still allows
FETCH/MOVE ABSOLUTE to an earlier position just like the backend,
in which case scanning the cursor is restarted from the beginning.

If the cursor is not scrollable, the readahead code must not serve
tuples from the currently populated cache backward. If the cursor
is scrollable, FETCH BACKWARD is served from the cache.

I would think
that whatever you do with NO SCROLL cursors would also work with SCROLL
cursors, so if you don't know what the cursor is, just use the code for
NO SCROLL.

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#95Antonin Houska
antonin.houska@gmail.com
In reply to: Boszormenyi Zoltan (#91)
Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

The changes are very well divided into logical units, so I think I could
understand the ideas. I'm not too familiar with the ecpg internals, so
consider this at least a coding review.

git apply: Clean, except for one finding below

Build: no errors/warnings

Documentation build: no errors/warnings. The changes do appear in ecpg.html.

Regression tests: all passed

Non-Linux platforms: I can't verify, but I haven't noticed any new
dependencies added.

Comments (in the source code): good.

(My) additional comments:

22.patch
--------

tuples_left > 0

instead of just

tuples_left

seems to me safer in for-loops. Not sure if there's a convention for
this though.

23.patch
--------

git apply --verbose ~/cybertec/patches/ecpq/23.patch
/home/anton/cybertec/patches/ecpq/23.patch:494: space before tab in indent.
/*------
/home/anton/cybertec/patches/ecpq/23.patch:495: space before tab in indent.
translator: this string will be truncated at
149 characters expanded. */
/home/anton/cybertec/patches/ecpq/23.patch:4019: trailing whitespace.
exec sql close :curname;

Tests - 23.patch
----------------

src/interfaces/ecpg/test/sql/cursorsubxact.pgc

/*
* Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
* is used with an already existing name.
*/

Shouldn't it be "... if a CURSOR is used with an already existing
name?". Or just "... implicit RELEASE SAVEPOINT after an error"?
I'd also appreciate a comment where exactly the savepoint is
(implicitly) released.

23.patch and 24.patch
---------------------

SO_MAJOR_VERSION and also interfaces/ecpg/include/ecpglib.h is changed

Thus all client applications probably need to be preprocessed & compiled
against the PG 9.4. I don't know how this is usually enforced. I'm
mentioning it for the sake of completeness.

// Antonin Houska (Tony)

On 11/28/2013 03:21 PM, Boszormenyi Zoltan wrote:

2013-11-20 14:53 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Infrastructure changes in ecpglib/execute.c to split up
ECPGdo and ecpg_execute() and expose the parts as
functions internal to ecpglib.

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
All infrastructure patches are attached, some of them compressed.

Best regards,
Zolt�n B�sz�rm�nyi

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

#96Boszormenyi Zoltan
zb@cybertec.at
In reply to: Antonin Houska (#95)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

Thanks for the review.

2013-12-03 16:48 keltez�ssel, Antonin Houska �rta:

The changes are very well divided into logical units, so I think I could
understand the ideas. I'm not too familiar with the ecpg internals, so
consider this at least a coding review.

git apply: Clean, except for one finding below

Build: no errors/warnings

Documentation build: no errors/warnings. The changes do appear in ecpg.html.

Regression tests: all passed

Non-Linux platforms: I can't verify, but I haven't noticed any new
dependencies added.

Comments (in the source code): good.

(My) additional comments:

22.patch
--------

tuples_left > 0

instead of just

tuples_left

seems to me safer in for-loops. Not sure if there's a convention for
this though.

I'll look at it, maybe the >0 had a reason.

23.patch
--------

git apply --verbose ~/cybertec/patches/ecpq/23.patch
/home/anton/cybertec/patches/ecpq/23.patch:494: space before tab in indent.
/*------
/home/anton/cybertec/patches/ecpq/23.patch:495: space before tab in indent.
translator: this string will be truncated at
149 characters expanded. */
/home/anton/cybertec/patches/ecpq/23.patch:4019: trailing whitespace.
exec sql close :curname;

I will fix the extra spaces.

Tests - 23.patch
----------------

src/interfaces/ecpg/test/sql/cursorsubxact.pgc

/*
* Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
* is used with an already existing name.
*/

Shouldn't it be "... if a CURSOR is used with an already existing
name?". Or just "... implicit RELEASE SAVEPOINT after an error"?
I'd also appreciate a comment where exactly the savepoint is
(implicitly) released.

If you do this:

SAVEPOINT A;
<some operations>
SAVEPOINT A; /* same savepoint name */

then the operations between the two are implicitly committed
to the higher subtransaction, i.e. it works as if there was a
RELEASE SAVEPOINT A; before the second SAVEPOINT A;
It happens to be tested with a DECLARE CURSOR statement
and the runtime has to refresh its knowledge about the cursor
by propagating it into a subtransaction one level higher.

23.patch and 24.patch
---------------------

SO_MAJOR_VERSION and also interfaces/ecpg/include/ecpglib.h is changed

Thus all client applications probably need to be preprocessed & compiled
against the PG 9.4. I don't know how this is usually enforced. I'm
mentioning it for the sake of completeness.

The soversion has changed because of the changes in already
existing exported functions.

// Antonin Houska (Tony)

On 11/28/2013 03:21 PM, Boszormenyi Zoltan wrote:

2013-11-20 14:53 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Infrastructure changes in ecpglib/execute.c to split up
ECPGdo and ecpg_execute() and expose the parts as
functions internal to ecpglib.

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
All infrastructure patches are attached, some of them compressed.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#97Boszormenyi Zoltan
zb@cybertec.at
In reply to: Antonin Houska (#95)
17 attachment(s)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

2013-12-03 16:48 keltez�ssel, Antonin Houska �rta:

22.patch
--------

tuples_left > 0

instead of just

tuples_left

seems to me safer in for-loops. Not sure if there's a convention for
this though.

I decided not to change this. The "tuples_left" variable starts at
a non-negative value and decreased by one in every iteration.
The previous code also used the same "test for non-zero" test with
the variable "ntuples".

23.patch
--------

git apply --verbose ~/cybertec/patches/ecpq/23.patch
/home/anton/cybertec/patches/ecpq/23.patch:494: space before tab in indent.
/*------
/home/anton/cybertec/patches/ecpq/23.patch:495: space before tab in indent.
translator: this string will be truncated at
149 characters expanded. */
/home/anton/cybertec/patches/ecpq/23.patch:4019: trailing whitespace.
exec sql close :curname;

I fixed this in this patch and all subsequent ones.

Tests - 23.patch
----------------

src/interfaces/ecpg/test/sql/cursorsubxact.pgc

/*
* Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
* is used with an already existing name.
*/

Shouldn't it be "... if a CURSOR is used with an already existing
name?". Or just "... implicit RELEASE SAVEPOINT after an error"?
I'd also appreciate a comment where exactly the savepoint is
(implicitly) released.

I have already answered this in my previous answer.

All patches are attached again for completeness.

23.patch and 24.patch
---------------------

SO_MAJOR_VERSION and also interfaces/ecpg/include/ecpglib.h is changed

Thus all client applications probably need to be preprocessed & compiled
against the PG 9.4. I don't know how this is usually enforced. I'm
mentioning it for the sake of completeness.

// Antonin Houska (Tony)

On 11/28/2013 03:21 PM, Boszormenyi Zoltan wrote:

2013-11-20 14:53 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-20 14:41 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:15 keltez�ssel, Boszormenyi Zoltan �rta:

2013-11-12 07:01 keltez�ssel, Noah Misch �rta:

On Mon, Nov 11, 2013 at 10:17:54AM +0100, Boszormenyi Zoltan wrote:

The old contents of my GIT repository was removed so you need to
clone it fresh. https://github.com/zboszor/ecpg-readahead.git
I won't post the humongous patch again, since sending a 90KB
compressed file to everyone on the list is rude.

Patches of that weight show up on a regular basis. I don't think it's rude.

OK, here it is.

...
Subsequent patches will come as reply to this email.

Infrastructure changes in ecpglib/execute.c to split up
ECPGdo and ecpg_execute() and expose the parts as
functions internal to ecpglib.

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
All infrastructure patches are attached, some of them compressed.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

09.patchtext/x-patch; name=09.patchDownload
commit 342d833116aea166fb378c81a6673e5cd308b36e
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:11:35 2013 +0100

    ECPG: Move allocating struct statement earlier in ECPGdo()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e5ee8a9..83acaf4 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1720,6 +1720,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
+	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+		return false;
+
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
@@ -1735,6 +1738,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
+		free_statement(stmt);
 		return (false);
 	}
 
@@ -1753,13 +1757,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
-	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
-		return false;
-	}
 
 	/*
 	 * If statement type is ECPGst_prepnormal we are supposed to prepare the
10.patchtext/x-patch; name=10.patchDownload
commit 67ab9b356494dbd4aeb5759090983e00df53e5f2
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:11:54 2013 +0100

    ECPG: Move char *oldlocale from ECPGdo() to struct statement.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 83acaf4..01e1a32 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -104,6 +104,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -1708,7 +1709,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
 	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
@@ -1725,7 +1725,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
 		free_statement(stmt);
 		return (false);
 	}
@@ -1766,8 +1765,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1798,8 +1796,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1828,8 +1825,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1886,8 +1882,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1909,10 +1904,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
@@ -1920,11 +1914,10 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	ecpg_clear_auto_mem();
 
 	status = ecpg_execute(stmt);
-	free_statement(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
 
 	return (status);
 }
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 835e70c..0e85ee9 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,7 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char	   *oldlocale;
 };
 
 /* structure to store prepared statements for a connection */
11.patchtext/x-patch; name=11.patchDownload
commit c863f533936b074fef46a673e3f168b0e82c9d0b
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:12:11 2013 +0100

    ECPG: Introduce ecpg_do_epilogue() to restore LC_NUMERIC and
    free the statement structure.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 01e1a32..e977a4e 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return (false);
 	}
 
@@ -1765,8 +1764,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1796,8 +1794,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1825,8 +1822,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1882,8 +1878,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1905,8 +1900,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	if (con == NULL || con->connection == NULL)
 	{
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return false;
 	}
 
@@ -1916,12 +1910,25 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	status = ecpg_execute(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, stmt->oldlocale);
-	free_statement(stmt);
+	ecpg_do_epilogue(stmt);
 
 	return (status);
 }
 
+/*
+ * ecpg_do_epilogue
+ *    Restore the application locale and free the statement structure.
+ */
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	if (stmt == NULL)
+		return;
+
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 0e85ee9..f9a861f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -165,6 +165,7 @@ struct prepared_statement *ecpg_find_prepared_statement(const char *,
 bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+void		ecpg_do_epilogue(struct statement *);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
12.patchtext/x-patch; name=12.patchDownload
commit 242ea934af9fe6f9e03ffab202e0d833b0c0b78a
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:12:35 2013 +0100

    ECPG: Introduce ecpg_do(). The core function of ECPGdo() is
    separated out, so va_start and va_end are done centrally, and
    the function can be used elsewhere.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e977a4e..b97e241 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1702,10 +1702,14 @@ ecpg_execute(struct statement * stmt)
 	return status;
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
@@ -1740,9 +1744,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
-	/* construct statement in our own structure */
-	va_start(args, query);
-
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
@@ -1765,7 +1766,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 
@@ -1795,7 +1795,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 	}
@@ -1823,7 +1822,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1879,7 +1877,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1894,8 +1891,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
@@ -1929,6 +1924,24 @@ ecpg_do_epilogue(struct statement *stmt)
 	free_statement(stmt);
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters are passed as variable-length argument list.
+ */
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name,
+							questionmarks,
+							st, query, args);
+	va_end(args);
+	return ret;
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f9a861f..f0e9b3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -166,6 +166,7 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
13.patch.gzapplication/x-tar; name=13.patch.gzDownload
14.patchtext/x-patch; name=14.patchDownload
commit 58bc69b755c0897449a6e0ed0fe90dc3bd612f8a
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:13:27 2013 +0100

    ECPG: Split ecpg_do() further and introduce ecpg_do_prologue().
    Add an error path to return if ecpg_strdup(setlocale()) fails.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 551902d..c43b59c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1704,21 +1704,27 @@ ecpg_execute(struct statement * stmt)
 }
 
 /*
- * Execute SQL statements in the backend.
- * The input/output parameters (variable argument list) are passed
- * in a va_list, so other functions can use this interface.
+ * ecpg_do_prologue
+ * Initialize various infrastructure elements for executing the statement:
+ *	- create the statement structure
+ *	- set the C locale for communicating with the backend
+ *	- preprocess the variable list of input/output parameters into
+ *	  linked lists
  */
 bool
-ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		 const char *connection_name, const bool questionmarks,
+		 enum ECPG_statement_type statement_type, const char *query,
+		 va_list args, struct statement **stmt_out)
 {
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
 	char	   *prepname;
 
+	*stmt_out = NULL;
+
 	if (!query)
 	{
 		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
@@ -1733,6 +1739,11 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	if (stmt->oldlocale == NULL)
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1905,12 +1916,9 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
 
-	/* and reset locale value so our application is not affected */
-	ecpg_do_epilogue(stmt);
-
-	return (status);
+	return true;
 }
 
 /*
@@ -1929,6 +1937,34 @@ ecpg_do_epilogue(struct statement *stmt)
 
 /*
  * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement   *stmt;
+	bool		status;
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator,
+				connection_name, questionmarks,
+				(enum ECPG_statement_type) st,
+				query, args, &stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	status = ecpg_execute(stmt);
+
+	/* and reset locale value so our application is not affected */
+	ecpg_do_epilogue(stmt);
+
+	return (status);
+}
+
+/*
+ * Execute SQL statements in the backend.
  * The input/output parameters are passed as variable-length argument list.
  */
 bool
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index c469220..83ea011 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,7 +169,11 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 void		ecpg_do_epilogue(struct statement *);
-bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list,
+				  struct statement **);
+bool		ecpg_do(const int, const int, const int, const char *, const bool,
+				  const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
15.patchtext/x-patch; name=15.patchDownload
commit 769a38262f43a6e5d6c5739cda710ab4f50bd098
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:13:48 2013 +0100

    ECPG: Move PGresult *results into struct statement from ecpg_execute()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index c43b59c..e3a44f7 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1130,7 +1130,6 @@ ecpg_execute(struct statement * stmt)
 {
 	bool		status = false;
 	char	   *cmdstat;
-	PGresult   *results;
 	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
@@ -1426,50 +1425,51 @@ ecpg_execute(struct statement * stmt)
 
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
 			ecpg_free_params(stmt, false);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
 		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
 	ecpg_free_params(stmt, true);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1493,10 +1493,10 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (desc->result)
 						PQclear(desc->result);
-					desc->result = results;
+					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1526,7 +1526,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1549,9 +1549,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1582,7 +1582,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1605,9 +1605,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1622,7 +1622,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, act_field, stmt, var);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1641,9 +1641,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1667,12 +1667,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1684,12 +1684,15 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
 	if (clear_result)
-		PQclear(results);
+	{
+		PQclear(stmt->results);
+		stmt->results = NULL;
+	}
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 83ea011..50fe87f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -63,6 +63,7 @@ struct statement
 	char	   *oldlocale;
 	int		nparams;
 	char	  **paramvalues;
+	PGresult   *results;
 };
 
 /* structure to store prepared statements for a connection */
16.patchtext/x-patch; name=16.patchDownload
commit 0ee438401c8e339912cc693ed9f140ad8c13bd95
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:14:46 2013 +0100

    ECPG: Split ecpg_execute() up into 4 pieces: ecpg_build_params(),
    ecpg_autostart_transaction(), a smaller ecpg_execute() and
    ecpg_process_output().

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e3a44f7..00327db 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1125,17 +1125,17 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+/*
+ * ecpg_build_params
+ *	Build statement parameters from user variables into
+ *	an array of strings for PQexecParams().
+ */
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1421,8 +1421,17 @@ ecpg_execute(struct statement * stmt)
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
 
+/*
+ * ecpg_autostart_transaction
+ *	If we are in non-autocommit mode, automatically start
+ *	a transaction.
+ */
+bool
+ecpg_autostart_transaction(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
 		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
@@ -1434,7 +1443,16 @@ ecpg_execute(struct statement * stmt)
 		PQclear(stmt->results);
 		stmt->results = NULL;
 	}
+	return true;
+}
 
+/*
+ * ecpg_execute
+ *	Execute the SQL statement.
+ */
+bool
+ecpg_execute(struct statement * stmt)
+{
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
@@ -1460,6 +1478,33 @@ ecpg_execute(struct statement * stmt)
 	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return true;
+}
+
+/*
+ * ecpg_process_output
+ *	Process the statement result and store it into application variables.
+ *	This function can be called repeatedly during the same statement
+ *	in case cursor readahed is used and the application does FETCH N which
+ *	overflows the readahead window.
+ *
+ * Parameters
+ *	stmt	statement structure holding the PGresult and
+ *		the list of output variables
+ *	clear_result
+ *		PQclear() the result upon returning from this function
+ *
+ * Returns success as boolean. Also an SQL error is raised in case of failure.
+ */
+bool
+ecpg_process_output(struct statement * stmt, bool clear_result)
+{
+	struct variable *var;
+	bool		status = false;
+	char	   *cmdstat;
+	PGnotify   *notify;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
 	switch (PQresultStatus(stmt->results))
 	{
@@ -1947,7 +1992,6 @@ bool
 ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
 	struct statement   *stmt;
-	bool		status;
 
 	if (!ecpg_do_prologue(lineno, compat, force_indicator,
 				connection_name, questionmarks,
@@ -1958,12 +2002,33 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	status = ecpg_execute(stmt);
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_autostart_transaction(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, true))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
 	ecpg_do_epilogue(stmt);
 
-	return (status);
+	return true;
 }
 
 /*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 50fe87f..1f96869 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,10 +169,14 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
-void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 				  enum ECPG_statement_type, const char *, va_list,
 				  struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_autostart_transaction(struct statement * stmt);
+bool		ecpg_execute(struct statement * stmt);
+bool		ecpg_process_output(struct statement *, bool);
+void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
 
17.patch.gzapplication/x-tar; name=17.patch.gzDownload
18.patch.gzapplication/x-tar; name=18.patch.gzDownload
�1�R18.patch��r���7���L��"	~��&��:��%ER��i��
`P���a��/���uo� >%3u;��qw���{�������`�2�����d<�w��^��L�L5�z�����p����z���l������������Y&��^z��i��_g_�3�xLok�I����#���+�C��������^��B���t�Ug/�^�A�f�d����fZs��^Q��8��l4-e�z1]0o:�<�Vo�+[�������t��-�\P���V��a@��@��C��M�c����=���ci�9��������1��y���>�g�,��j��*4W��l�������N�14�C��wL�y���nj�������~�9�X{�s{3C�6�a�����9v��P���c��-]��
�Pm6�MhD�L-7��0�-����s�]BYW�-h��a�f��
h�7%���R���Y4�PM��{�15��
��P#�7]����\��w��M]#
�����Uk0���f�F���_4zCxDg���G���=����Js�C%�G�d���.�do��w�_;���_|�n/7++�2�"�
�e���PK�b�-h��6+tS���������<���6��i-$�a�$
���2�4
��CcR���k�<�vH.6n���+��?�V����w��#%�m(k9K.���_m�b���#����x5K��M0Kx�l�3�K��a*\�W�Wk���B��gpe���a7��AO�sgX���Psf.M�V�����:�4%��r�@�E���w1�+�S��c���A�_8g�'%I�G�w��B�\�4���*�l{YmE��n[�W��K6���q+��W�k�*�O�6?� D'�J�����\�#��J���PF�D�g���F�
��l���R����T����������|C�//�^��N�^�:������T�m8Rz�o�>b�g�
T>pNt���������b��5���-d�Q��4�PC���\@@���$�������f4����pU����<F6r��	�I>�D��E����-,�	�)� [|2YXJ��'��3�=��l������8��M`1��f��}�BW�}\Wb8l$��bm���Klu������H�IOA���������!kA���\J����W����0��6(�������rQ��	��r�-$�r�9�@�*+�<�wj�\��f������F
$(Sh�8�VoBA����p�/�} q�����x�u�sOG���LKs��C�_j�8>���[8� #���cZ<��Wl��ji����uBJ.$�W# ��R�&�_�� �[ �RDa��N{������N<��j�#)�VJ�W���es������P�P?���$�J���C{�\�� �����,���t����3������X1�RX,�@�y-�5S�.�*��FC��Q��^GS�>����_LO��.�|'Ot��l��"��y�#��SS�x1GNp�l
q�.})�1���]5�����v�K��N&0�:����f���K�5����E�Ca�C�������wAQ��aw>����1�Ij�	�3���,v�Yy����~���D�gqS�)�=�=*�������3�3�us{}{��E�j+D"I.S��x6�D���+W����Y�N�n'��A��y�����x�93m����jA*!�O���A*q4�e5)T
�����oOoe��wonnOo���N����l����_~+V�H�|8 ��Nv?*���ri��������R����v�)d��H���)�&��|�4B��1(��|���V��,��Y������_��Y���������v�����i��^��Z�1p3���f���=z���q�^"�K[�f#j�7�y<R��E�?/�a�o����AKS�X������(Tp������;��;?��d���-h�;��P��c���
���^KZ���'g�ss3.*f�gj�����z��.U���.Q���r������o��\^�Q������T#,�7&K�j)���������9��X������T�VvH����h+�X�
�\IG;����m���/w>����~��7�@�EA#E������O��� ��T[t��������QaM�Bl\yZ��xV�������k
;�
p����#�x9�D*�)�D���'Ua��2�[����0��?�([MQ-�Vb��A����@�A�V��x��@��=�`sL�J�>��c_����"pI�����u���z���812�
E�4���#�yB<���2s&s%�'<�����L��>�c��!x�����\�<6�;C����^7Y|'����&���<��>xB)�f��k�_�z���7�y�������(P�m9[�@����/}��$����9�����Q��GY
_�TIl��0F�n��A����p<��������
�M7p���)D�7��cQ%h��g&HH~�mEG�^��[~��+y��p~0\���U����D�%�?"a���ax�����Z�sD�	�u����Q(����"f�T@���1y,��fy�C����d���{CD�!~�?����#�����^?
��H����Lk���x�j%n m1�_B�����*�J��E�t�B+���	�<�����/��w��h�]?:���,j9���v����n�Q8B�Qt���{G�$8��:	���q��Z�zS�$
��ND'��?�������������{Y�B�6���-��tW<��`�/��R���u�oe/��/.�-zB���<8�%�2L�BuYZ��B0����^�]"<a�����b�N]c���I�mL���H/�$�"�I�#�*����[.u�,Q��4�p�=b��~M� ]�`m�$@�E���=���Wl3Wta���-m����ms.k��|>]�U�7�[��D+�]���m�H��Sm>S::��^(�om�|���m/�^7H�����r�#W��67�'}�g����x�
K���'����t�c"�L"��!rJck�e�o��!GA�b$?�V!/,��'�cg�]�w�#�	j
���JW ��u���R['�@�������y�^����S*�boG����Z��../����E,y�f0S��a����y2�/��yQ���Tk;@
19.patchtext/x-patch; name=19.patchDownload
commit bc71ade711de63d001ed74ba01f48e115d5ca187
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:17:05 2013 +0100

    ECPG: Make SQLDA loops go forward. One regression test .stderr changed.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 438d3ab..1fcfebc 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1551,6 +1551,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
+					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
@@ -1564,8 +1565,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1592,14 +1593,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
@@ -1607,6 +1613,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
+					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
@@ -1620,8 +1627,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1648,14 +1655,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index acb3198..9eb54f2 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -148,23 +148,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -190,23 +190,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
20.patchtext/x-patch; name=20.patchDownload
commit 4574616787e4c97efb4897ef1266d67b740bef18
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:17:19 2013 +0100

    ECPG: Allow returning partial results in any order from the result set
    into an arbitrary index if the user variable is an array.

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index b2990ca..5d86c53 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -481,7 +481,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desperate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), LOOP_FORWARD, index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1fcfebc..ace6c11 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -307,12 +307,14 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction,
+				  int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
-	int			act_tuple,
-				ntuples = PQntuples(results);
+	int			tuples_left, act_tuple, act_index;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -363,7 +365,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -372,7 +374,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -393,7 +395,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -429,11 +431,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -450,9 +452,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1489,15 +1491,18 @@ ecpg_execute(struct statement * stmt)
  *	overflows the readahead window.
  *
  * Parameters
- *	stmt	statement structure holding the PGresult and
- *		the list of output variables
- *	clear_result
- *		PQclear() the result upon returning from this function
+ *	stmt:		statement structure holding the PGresult and
+ *			the list of output variables
+ *	start:		start index in PGresult
+ *	ntuples:	number of tuples to process
+ *	direction:	in this direction
+ *	var_index:	start index in the user variable if it's an array
+ *	clear_result:	PQclear() the result upon returning from this function
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1509,12 +1514,11 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
-						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
 			nfields = PQnfields(stmt->results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
+			sqlca->sqlerrd[2] = ntuples;
 			ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1541,7 +1545,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
+							 stmt->lineno, ntuples, (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1566,7 +1570,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1628,7 +1632,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1679,7 +1683,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(stmt->results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, ntuples, direction, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -2032,7 +2036,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f91867c..e09e351 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -29,6 +29,9 @@ enum ARRAY_TYPE
 
 #define ECPG_IS_ARRAY(X) ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
 
+#define LOOP_FORWARD	(1)
+#define LOOP_BACKWARD	(-1)
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -165,8 +168,10 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction, int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
@@ -175,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
21.patchtext/x-patch; name=21.patchDownload
commit 8d68b36dfa5cf0f617c6faaa4468bd42e12028d5
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:17:55 2013 +0100

    ECPG: Allow appending a new result set to descriptors.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ace6c11..b28ab9c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1498,11 +1498,13 @@ ecpg_execute(struct statement * stmt)
  *	direction:	in this direction
  *	var_index:	start index in the user variable if it's an array
  *	clear_result:	PQclear() the result upon returning from this function
+ *	append_result:	the user variable is an SQL or SQLDA descriptor,
+ *			may already contain data, append to it.
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result, bool append_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1514,6 +1516,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
+						tuples_left,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1540,12 +1543,35 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = stmt->results;
-					clear_result = false;
-					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, ntuples, (const char *) var->pointer);
+					if (append_result && desc->result)
+					{
+						int		tuples_left, act_tuple, col,
+								row = PQntuples(desc->result);
+
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
+							for (col = 0; col < nfields; col++)
+							{
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+
+								if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								{
+									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+									status = false;
+									break;
+								}
+							}
+					}
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = stmt->results;
+						clear_result = false;
+						ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
+					}
 				}
 				var = var->next;
 			}
@@ -1559,17 +1585,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
+					{
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -1621,17 +1656,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -2036,7 +2080,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true, false))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index e09e351..ff12acb 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -180,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
22.patchtext/x-patch; name=22.patchDownload
commit 5001e69ad29b3f1669d04426bb1f5d67e20697ad
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:18:21 2013 +0100

    ECPG: Use the more descriptive "act_tuple" variable name instead of "i".
    Use the variables declared for the function scope, don't alias them.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index b28ab9c..1326870 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1517,6 +1517,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	{
 			int			nfields,
 						tuples_left,
+						act_tuple,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1545,23 +1546,24 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 				{
 					if (append_result && desc->result)
 					{
-						int		tuples_left, act_tuple, col,
-								row = PQntuples(desc->result);
+						int		row = PQntuples(desc->result);
 
 						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
-							for (col = 0; col < nfields; col++)
+							for (act_field = 0; act_field < nfields; act_field++)
 							{
-								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, act_field);
 
-								if (!PQsetvalue(desc->result, row, col,
-										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
-										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								if (!PQsetvalue(desc->result, row, act_field,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, act_field),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, act_field)))
 								{
 									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 									status = false;
 									break;
 								}
 							}
+						ecpg_log("ecpg_process_output on line %d: appending result (%d tuples) to descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
 					}
 					else
 					{
@@ -1583,7 +1585,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda = *_sqlda;
 					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1605,13 +1606,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1642,7 +1643,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
@@ -1654,7 +1655,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda = *_sqlda;
 					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1676,13 +1676,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1713,7 +1713,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
23.patch.gzapplication/x-tar; name=23.patch.gzDownload
�1�R23.patch�<�r�F���WL����H�7�hK	-��6��Hr�9�-)�A@�L����������3.�(�uR��*1��LOO�������X��YV{�nY���^�5=���e������Vg�u0�:��^y��n���^�������,~�_we����������/�o���7�Ft\>5"�g���-v�M�c�^�}�o��N��e��v�U.C6<�g��D,
����Y���w74��������ezA�l�E��K7��`8�40��<pkir������h�F�-]�I=��W^ ������B^'�F0_.���"*Uvk�qf��V��Lq��m���������Q�!V�y>w+�:}������x�bYk��T�Njt�J��n1?�w�����_�q��O,�R%0��%��V`�����B�`&@)B�� �Vvo�A� �7[lx���cSn�y3"QL9@��%P�P�X2�2,K@]���y�d +�*`��B�3Ff�Bh �����&Tc���5��u��7�<�eF<�p�	>�=LVf�� RF�sx��Nh:6�C#�-�H&PB	"2+#��r��g3�h�A���3w���/�dZ����e���{6;���q�l�O:�|�@Y�z�r��X������7���ng�W�c����c�v�c��#�b��;�`�����ds�u[4F<X7:�6��W����xL�.���NN�\]��^��w�;4B
G�v����7#~"i���������	��"�"f�w�c��������7��!��Z�V5�`G���N����es�$����jtuq��������	 1�n�S�,K�"������[���~����K��ke�ps5��~��	���B�M�a��g������<������Z��B:+�L����c��={a�
L��Z�2�=w
����b0� ��zq��"����6����P����ND�u�j�Wc:����#Qp4������d��`��&�#��,�;�1()��M#!����&��t����&�!�U#2���)�o�Q�Y�L�*�i��wK-�
����J����� c�!�z�X)�k���[�5:Yd2z������j��RO%����!G�
H�`f����?���\o�Ec�Q7i�{{�~��l{����K��	��QW�(�^��m���y�d����v����_�i:K��W�^U�J�l�oj8�I\.�G�������������������g����|�}�����<��d<~u>�����X��U�6���b�j�*���eV��@!��CH/�i:�y�D��n}�m���� 'P�>����W�l�r;?{IX�����2b
���uh��*�v���G�����7A�W`>���C3���c�;�2����C���F	D{/��V���r�������~Ft��0
L#������k�
�T4����X��P~�F�c��l�N�#�3��C�
���������%���4Q�]��a�\�}gh=����e�����pt�
������j�i>�Cq?����Y����Ny�g��7����&}Q�z������!���Gm#���b�w7C^��VC�I����->R���D��4�����*\�9?�B�����d�j[����=�	�g��
q
��n9��r"��#p���?'� 8��N4����H�q)I .��7!���_v+cPAv~�N�������k6{�����O��c��w�8��[M��n���k���h���;5��2j;����`�����"�P�K�L��M��i��,0�.g�����W���tho�W��sx����/<�p2���-���#�����c��w#
�Q��@�F@��#�
��z���@W��50��g���M���hU��{�ab5�.�F�PVw���U��ba���Br���@�Cu�I�N�*�N�P��r|��O_��sE���������V�Z$>j�
$S�����vtK�s�������#)J����]��z.W~?�GM)1��S����$�?��u�����.W��$�Cl|�V����!����K���k������R��
6����V�����L)��J3�A%�m�m�B�X	Q,�,�N��:#H���T
A�R�^��d�Q��V�HzJ(>%
�m��.�����/�5����N����S."D;"�����@�c�������%����;+v�6"n`|��`��&����������o�5�m==oA�@�/�*x"#l��d8�
�����;$��+���W"=A����E�4'�-}�����c�%����-������5�t�TV�<��F`
-����XaK�01z�;

)�0z�Z!
�&\ZRB#l�+o.�� �B��o�YN�u����d����eA�����sb�la�1���]�Ymi��F�A�b��u#w�@������Gww
���7l�m����n~��hi�r�Y�#��9TN� ����������YM�J7��������gU�RI�#�=''ZuR�:�JL�	�KJ�H���GXH4m��s�Y	�_�7[;�����@���eY�k7���W��DR���0b����~E�����&
����<?��916�a�y����[�n�O����W�����o�RJ5G��aW*���	L�1
,1�Q�����]%:�H���f!���#\M�;����4��4���u��X��Gra-���iI� ]@q4q|�F?��q"N&e�QW�������$�h8��S^��5{=:?�&'4������n`��P�Z, �{@�y ������������|�P����|8���������&Bbj?�|cnD���r���j���d9���q��C��N�&l�8)y^�@d��0��x�b! '�I���-�!��!M2��h'�f���/V$H'R����`:�ic+�C>��B'kOb��W��g�1g�i��h�sr�H��h�S��c{=���v15�TX\���-�5!C����9�U�s�f��>0�a+INdj�G�k�5�_}�
��rNK��3���5�U���a��D0��M�l6��I��4����A0]�Rf�txr>�Z��[\��BM����-$���Q���B�D�����-P�~{�O6�md�J&�bI&2g#���6�]���= K�3yj���9����gTk�5$��ue���
cy��R=��$�Y;Eu���������`mm��Tr�=�W�+����)��g�8�cb�-�����R�������M����c:tx���Q�qG�:�=P�`��v��Age��QI��V����0����)Q� .����X�r7�$�����2L3��&Kq�����^�-�&}#�[��|D��)&v��m`�'�ix��!�Y��P��s�~���F	 ���t���h-3[J�WT~>S-�]�`\���R)��S�	^|�3&��R����T�g(����63�1#Ib��q{��E�����WI8$����Q����/�R���z�R�+d+�YED��oi��J�b��t����	�M�~H��~�A��f/��q�G�~f-�2�^�j�d,C1e�L�}q���S�����|���	�f}0�8��kJSg����y-���L2i�1s�@�l�I
��^
oN^��t1�a�����>���
Ucl�Z��Pa��]�\���*�����)v��T�Ag6]��6*n�0�.x#o]��MU\�l�(��F��X���78O�8��`h��������5^�)��&���i�%��7Ii��3H�#�� NV��:P�
sF~���f�v���)�������!X��7WWCp�G�$G���j�	�_��$e�	�#����BJ�y��~k}8Q�����%~��%L��VXlQ7.��R�U~�^��c��;����l�]������(8�����T�w ���C�fZ���!Y��TZt�wy_��(��u��6%J�%U��r�$��*�4��}�n���4�w�g ���J�84�$eK&�g��Sl(Nn�F�U-O%�����N�A"E�D�A9���)���*��8��Q5"��5�o�A�72��q��T�@�k4@d�����*��'�����c���jm�������X����U�Q��+q:��_O������������z���Z
��[_�?oe(��!�g&�I�>7	*I�_�(a0���V��V�r��dH07'�����M_X��.V8v�����3vy����EU�r���SFdL�Ge$��m}E�2���&0W������}:��c�����6�������	T����g����$��� m�<���G�'�O:P�ng�`��7Z��:|�C�����
'jo�
}��by0_�7_��'�#,v�+�Q�m�HF!��JF�u��m�VVk�����m�@I�m��L0�L�J��wF`S��t~�<��]��D=����H�H:�7�E��2��i`���l���[��a�0���H!�1���}��D�=�$�����~�iqs�`�	%�:�Md1�M�F�]����d#�����Fg�����S��n_�aP���c ��093��nK�_RC;�����SC�)�%��CtS�\g��aB8�;��s�z
$�M �"�������.]�����.cM�t5��w�&��G��e?=�/zY5�n0T������
�<�Q�����5Y�����,e��7)7�\��8������6�����O�m�EL�7���%���9uRS�0��$�O���:�*:�c��:����[Z��, �+����W��Ek=t����3�NMJE�%'���d��M��,�e+I�gL�f�1���<A�����<X�+�)��t�2�+=?����a	O��<"�z��������|�j%�C
:��"V���1�<n���;x\�C-�5�����o��������/j�nN\s��0`/[.��b<��\�N��d��C)�w-��s��'9���<���NJ��[���.a��s���-P���L�Z�3����$eh
��]����3p�o)�
��kG� ���u��U�THl��^�������r�{�[f��S��B�ia��:��#��W����V��ju��@��a�'+��:��V{�0����c�]<r�(G�G5��8j�^�P
#�Z��F#O��'Wg�����]�xx����
Y��������r���q������?'�����D[= ������i<�\�]_nN^���Vo���'"�zh������������a���u��o���xQ����b0	�q�Kv�W���;��������
�u�:US1�lR!��
.����],��
�:7y����<�U��y�5qs������]������	��4�~�����p_K] ��W������+XX������\�*�;�R$�+�s�O��x�$�a���Y
\p?
M��u����S�gY�.��GTS7m�z.�Gb�5_��m��XmD�-�41
f�����K�%'�+0y�� �p�b���M9�3-u1?]����lX��GI�l������E��r�D�T�.[x_x��c�a��%2�6}�@�z�^D������;%��>U���e�y�ze���E��XN��*�B�4�Q�
��Y��aip>ib��W9�U*66@S��X���}-����~	�{����{���o,s�b�9�s`���_�6i���4�S���DxLC1mI�E_�<�����i����b�q�
�Ki�i�!R��x�ZR����Q��jo1���7Q�����~!I�.W�5��<�r>$m>�4�����T�5��v�3�uMCC��M� �	��z��#���y�a���U��1?�k=��Y���;`���!PdS���p1�{V�����g���b��5�u-�(��l��}�w�6����_��&�+�H����>7q��l����{��J�l��%�>��t��?�@�)J�����,�3���`0sr����7� "�S@H�:{�h���B�H�}��L�>RB���z����:3��r��-_��(�U����2{��Jq�P�gb$An�XV�?!D.3W�a�p!T�z�1YxD�k�Q\@2������G���l��/$DA��]w	��B�-�U���P�}&�J`A�K�]*r�2�D��H��`]S�6P����3�]��Z���WA{6���f�Y�	�m��F���]Q\��-�S���	@���'���h����=��l2M�b���{�j�q�4�$������6�)m@����Z�ij�Z��u�m:�����r���C&�OA/��J?��j���]����7R�����juZ�\����S���\�����R^�����N{:�zZ[��8�Vc`k��
�)���fq���r�b���r@C���I�A��������jp��M�%da��j8
�Op��.�A��L��_,P+��6w�������M���a�4�*�&K�:Tp��0.�����/���;D�1�=�@��El�n@�k4�%,/k�"��b\����$�`D,��"�4����B
��Y-f�l�8�������W�Z�/"��/����p�����e��I[-"���":���*�!.i�
�}���`@��%&Ub�D�[���5���?����?�l��@?<���w.R�X PQJ�������C]�B�q�{}�0��3	U�`���zl���kAA�j��?�C8��l���m�=�wGAf��N�D�"�G���n��+e{#kY�)��Kk:�� {�C��APD�s��E�+��t(�C����>�e��S���N�9��Us8�����<�$c5i�<R���6���8� �t�k���kOI�R��E�><�Y�
�� �����
W��B��9l��!Lk��Q'�IB���/#�33rU��e����$�T���$��n��k)�Q��^�3{{�[9��!��Lw���B�`��!_R���c<��~����W)�a�]hZ�;����6��
����������d�4���-^��iE��5�T������!ICh�d�>e�r������
����b��D�\z����Bv��I|=_���x�)a$S�h�.��#`����5�\6�Mq�t�Vg�k6�������+�D8�m�4�D��!2r<���^�tzn���V���g���+����<T������3���3F���Hk��������J8�h���������}�=j6[����qHf��w�(d2��Wr��(SZ!S��u���f�Y����(L]-���;������yx�T	�N�S�_�+�/=�	���l�Q�M��7Yj�LS�����]ev���)_AF4�����x���K�g>��,jt����!"��b)�\iX^b�9�/B:E��/��$�$�$��2e���;l3`3)�$�(<��zOJ��!���w��#[^�}�v�k����x�+
����;!g������_�J-�y��)���3t��q��G�!_/�{A��� �m����V'��p� /��/V������h��v97���GJ���j�Y�K��AD�P��H��hA��y�m0���
}����'��L}�A�$6t�LN
�Nh��d���Pv���y��;X�)�5$X1$�^��c�B�t���A�	����	��-��*e�|�U�\��b��,��2��	�zR��������$�/�|F�QC6�Y=���O�.�b��5J����+��\�����F?����G���%kk�����qx{�Y�7���������
�d�g��5�`�N/��CV����X�Y���"���$��@�#�������j��:�wv�����b�)����
���Q�N�o�d�_Q���=��%�K���X�q.�N���TZ������&a��~��J�I)�9�����j�&�,�A������o?��]|���.�s"��R�H�BJ�4i^MW������O"��f��yf0��$�����9����)G�f�
�">Y	�PA��"�=~�&�!*&n�)�����[o��%�c�<M^#�	�h�e�������0�����N��*���w������N�8�T��)�w�����u�&f7�6$���.F��A*��?'�g�8�)Dx��	��
��&�������Q;5
ED6�e8_��M��"HK��6��QAm9:0Wt/�IW���j2m�Y��j4��I�B�c���e	|V%��d��9�
�C�;��n����mP":��cj@���)�����";����	KiZL���1f�J=n�
0�O5��j���m��v�/*HE�T��z@7IZ�"H	���p����������'Z��N�V�����+w����1�l`|P$��#Z����v���<~#�{�����P&N�K2�o>��1*�t/	T�!Y��'���������x��>�O��3T��|�-G���@�n���{M�M�>6�o��e���������<�$L�����t�
k�y" �����9�\r�|����.&3�w,p2����{l�V���l��P� $d���g�� �B� ���\#��l�[��]4/pN�&���%�������Q����R5p�q�;������j�����'KiX����[�.dR��)�	�:z��?�� �� �4�t������)5�q\8��6�������l�
�������x27|��D�����A��W��(��o����R�BDSu��(o2W�.��ZGi_�=�pb�����Q����w��(���J��.�9#&O8�8������)�����X�t��|I|�b>+�s�C6�[n��L��{]�����e�
��,C��x����1��#�u6� s|�%�<\8��_�I~��0*�"��l��rf�+[h�x� K��_�j{���T�h}0?q}���������3mE�V�SN�^��D���\_���������?8���'��E�_�`jU��8���)��FE��6�\X����
r@
]E��Y����zf5�T���r������v$���H��
���R����2R��"�RC���������Q�b"���dj&S��A�F���d����AV�D`�RE�N�&�K)���,(���R���h�dr�d|��*��/Jm��{l�T~�h3��M�2��r�i�
5}G�V��r%�V�������x�c���b���2���^�5�C�[����I���&r��.���(t��5�M������{3��Z*B� �����E�<�:��z!�71Y��j���Zt����cC&�O%.VsL���M��4�h�W@�n�of�0d��l.z���E_D�p�u������A!���D/�*�T����#���}���z
���9��T-&�9Q�Br,$%�5u�jP�8��b�s��M�"�0�	��8r
Q�0c^%lMd�����4��a�*!���AQ	��P�T)-c�aT[�����L�@E�6��x���H�JQ���W��
b�/x�����������bK?����U>Ei�j��-�^��#���"������/b���H� J��48����h�E|���4E�����3Q�I$�+���ReE_�������7�n{0�
���|��J�K�*>�O�O)J1���T(o��W(�~������Oj"��sL�<E�w���g��h'��3W]�4Ym0����!��XTNh��F��c��$�\�W�����a�'4T�]?�2��BH����
���M-����@�J������Y�;�wO��b�Azr2��I`��j�J�B�5��0i�?Z�������
#����~1����	�L]�(D���\�8S�r�K����������Y�A�+�hT����W�v�o�Og�-���<��������DI������9����	���s�A��N�����i�
��!R��4�.	%�x$O\���Qc���N���,J�k5�]��
D��1�+4�H�7`��F��XUbl��O���QsU��hZY������
� S}���;_�[�v��q?P�������h����}���m���,I��U����|�{��[f@�\��$�����,��V�=p�A���o���"�$���WJF�3!%��p
�����'�5&^^`O�f�)�g����\���f=�p�;�468v]q�{A�����S?��%�Z=�8����z���A�*�|	/����;^:���/����>R~���5�1�?��.W_��_�9��W_����/���������jtc�	xY��������l�]�=t
P
�"��_5~�����^�RTqc��s��d�6�w��5l�8���=l5� �� (��
:�� ��Pu����_X��+�o�_�%I"its����S`�oL���/�P6���1��_�5����mVfrs9������7��}�1}<�[���7\�SWr9��b-�����fslu�#g��Z���.�W�e�*��L��7��>C�0|��p�Q��x�����p�$�$��f���b �O'�}{{��D	�+�t:�c�pC��-!f`�bv9�l(�Q�))�E[!�����(����s6�zY!,�S���v5��l�}.�h�������X��F�:Y��N��i�[%
&����-W�-�=L
�%�y�@��_#��]��0�'�i�+nt���� �`�As9�z��?��.�V�i���� x\�����y0>�w������g��'g�&��4�#1;�O��1e�+8��(��V"m	�bkf1���4����%�D�nt:u
:�HGt5�7���_T���N�A�"��C�M�	x��/l��mr�E]��t0�Hb�*)���F�2�eo,��<���Ey�e���r����8?���
E����J�mn;�V�n��6R?�ZZE�R^Z%Q��#�-0F�H�v�>�[_����q��L���g�hF_MU5m�[�otr��M��������������6W���<��� gk�?�
r����
�����~+�]���Q��oKz�;���A��g���c���H��c�
aOP���?=>9;dO���'K�2�u�|�\��s�+5>,��2��w	�����������#������m����c^uz���FE�>���v��t�����V%(s���$S1����?=~w���[���%S��Z�r\+q���M����������U2J7H�`K+��|�?����^����������H����T������9i���DjHv�]F���<j�;��V��6}�E5��������_����=9��nEZ������*Dy��Hu�,1�{F���C6a�{����)I��W�
��1p�=��'
B?��}��OSI��g����Js�����ld��>D$�^���dvU��(��f�����B�@����u��;�b�;(y-J����R��iP.�x��^<c�j�G���~yN�M��/��4�)�����@��BR�mv�/w���kk�����������a�MfC���,�����-�7w���8)���b���u��������g��&������C�k6{��k���53A������u��>��3�m5������=��W�r�O� �
����ku��A��1����_!�?�?��T�&���|%1�� �3wV�����js�7j
}`��x�mm�T
�\��F�!�C����\�
�^$(A|ok0��!�+tjQ�� �.LD�t���Xh &G%�����Y�ae#R<oQ����20�Y
Z�9DR��B�����1���l�k���9>_�a�7����i�[N�a��5�����316���%C�zq������9�~i����`�F{���`�Hu�U�?D�EK���n�s&���/y��L���S�jigz��w���O�OI5��SP$�+�:]k#����=����e�/i[Q�z����"#�L�e��V8&���-��)H��>Z���3�MX7������/�f�k1q���(��/�
�7�y�B�'S�2M�=Y���{����rF���?>y�����{�7V������h��W&K�������e��BarvN�\�z�����>�
j_��b���~y�t������!h)�o[�v�i7�#���o�&�.�[��H�J�aRl�&�_tk��8%=^����
\�f�]��T
���j��L��<dwF���l��={�7(����[�M�jv(�#�[w��	W�h�Q(5��I���+�Z\�8�����|��u�Z�����b4�~v3�,�_O5��LTi��JR���"��Lf�uL!���$\g�V�G"�Q\Q�M�bl��iQx�8��p��p,�}R%��If�<m%�����3��Z91�I�~���L�
?s�Q��������o���/a�(p`f�5����)�KR1�M��Z����{��tMf^^�D?bl�������
aorp����T���LSfT���x*���.��FB�:��h�6�����
ze��lQ]0hHN�8���S�t��@�wSc$:=Y��������c7��}7}��c�}�G�j���*-�����V�7q%�������is��;U�^.�%�z����f��pm�D��&���Q�F�=n�r�Sd:�R���0�]����:����I���<WI�'����n[T{P�I9���Ua��\����b��2#�������ae��`@�G�_A���h����K����^��PV(K[vi]�?�l��>���r>�j-p2UG�T��B��'hv���3�W���@�U/����SV�~��1��r����D����/��1
���L$��!g�N�d��iTx�Bl
q���D��.��,[{K��}�����(��}1s7P�h�@���)��}6k����"P��M��7cS�e`��;��i���fl���c3����_�"���[�
[��!?����K�mk���wn�f��E��S��p�M�,���Z�G�<��1��)�@�|Sv��&��� �W��m�B�.�������e�:�zH��S-m
FX��%s�#iD��9i�������F|{�����TA��������^��������B��V�]��d��\1�6�D:6j"��-+���N	���T����^Te�S����j�����q�������"Y��W#�Xw��0c$R�������H T��V�E�k�-�N��������{22����lt+�������g@�u�JC�@����H M�'c�r��F�V�Q��H����K��i�k��f�&Q2m��]tE����ej7���������I��$����MT�M.�z����BRSY�nNY�N�B�T�vg��X��Rj�nNn�^�I��J���z�y�1�I�D���"%��${������sg����D��������q�B�l���,�$���E��^���~���qxRNR��^N�������M��i�����R%��G�9����[���CK�`wZ%��L���c�g����H��v��55�m�cuz���E�M�4D��_%'xG��R$_W���P�{6.�b���}l)Eu7H�*�e�B'�V�	ii�tb��R ?I	��� ��j>^��7E���PH���T�xV�*^v&	tQi�5�k�-�m��"J�Y���6��g���;���?%�g�����o�����K����2K���������9��S�!�Z�]�zHL����M���*��
1�VA�B��h��r�=�m'_�7+���'�@�4_xr)�*��eK����f����m��9�P)�@��r�D'M�6M�����(;�"��e�rH�w���W^�t���;�j�M�a��m��tIeE�TU�fBQql�����n��v�NYEE\TMQ�Rn9��s���7�l��L
f��;���]������)�l8_���{	_���b�CV���d�-��Ic�z2�5���)�T�X%i����[�x�e�xe���^���	b!������v�N��
r�������n��6�IUP~)C�
]q7��
��Z��?~�������W�!'<���
�S��iI���0�,VWM`����-����j��&��M<���e�N�r�u6����}*p��qI5���?�?�E��dESg�t�f�k���5,�(���JS ?]pK��M����Fah���c��"��x����?	������������N������(�]j�l��J�����!���uw������#�<~�(�o�":��rNd����}�����c���Txi�ne������j�k���W���cP{m����r�����h���Ne�w��!X�ml�td'V:*��������KA1��*��pX��5���;����1���n�9��Z������B4�p�6(H(x��	^J��m���b��S�7�/'3�y�0!����u��������ksX)�>���)<�J�f��8���)�I9�����s��I�����^=��|K���d�.��"�@���Z����|vw4r��di4"C�jX6X���v9O���T6N*R'\n�h�����'��}3e|_��&�l}�^��S����������Wllj��j~��H��M|%��qT�U���J���F9��J~�K$���?[��dW��ey5_�$y�����7����
�����������%���'��+��O�	��?����~�v!�P��1��a�&�E�Y��[F��`��T(�*bAA�m� �tL�A���
�����Y�S`>y� �+�G�����_��
F�VRL%Q��y�a���^��}f�����V@0����+TAQt�!�6�}>�V������I�r
�H��������QYK�@ 3�EMI��{�$ZbF+c�^��Y�t
Z���59�f��\{�)8��,b�����f+���z�3�[(�������A!�'S���k�����X\��.3I�L��t� ��7�9:Bw����!������Sp,^�}�j�+���sH�^��1.��}�����<�2R��z��;Z��z�G3�3Cx�5��`b���l�:���Q^���O/��E19����hq�jtzPH��W,?.����Hl�_.�O��X�^=���Po4]�a��/������g"\����4��l��>��W���i2�G~'��o������c���16\������bOt��o������Ou�����8��?���x����%����������+�x���*D^��F���	�N���O�������3F,�����K�.�>��I|���������������{p���h����~�pv��"h~N�k��w�9���r������y����Ur�����%O��R�����J�m�)m`d������b���E
A���?{Icp��Y��~y��0�
����9;'MYQHRh�r3W9gr���0fo>�q���)���1)���-���`�v*�����	ZH�^�.��Vp��V��-�����p
V���[,B��]�zfx�c��)2�T %�9��9����4K>�k�5������m�_����S�����bsMR�<N�MY���
���3���3�"���]����L���g=�h���bW��qr9�!z��0r��s��l9YM>����K*$�!��LyQ�&`�3�[�FRn��2�e�������f?�pu%A��s.�'�A�>E�8)�N!l�cF��4'^F�B�� ��6N� 7���;��K���d@7{��|�}�l�r��c�'�+v�������c��Cg=���O����7�c��|��t*�4F�-_���������\��*�pA*. �$��:>��%��E��@����P���~���*��U(u�@
���K���,n�HFgg\��,KK���N2��lp6L������'c����=�~JR\:0���"L}SYi,)���\^����|l��?"�+��~�W:�m��lW�U64[b�
�0��&�
p8>q�.�<�����(����������5w�+�N>�{�����������?�}VJYe�~���������s�X��[>���M��Tn�V���V3������YZ��%^��t���V�LUPrD	lO�*O4��ZU��(4��i����iYV%����~��*`f��I���:�`����D���/��hW������OjI�6�e�~�@W����m�yY�
d@1`�su���l�j�wQx�,��n��S��I�r/v�R�U4�V�P]EN%�%��\E���3.��=�V�q)�������T\�+�X�P�p��5��.�m�e����"yM� $OD�c����d4Y�v�d��������B��J�R�@�,�(���<`u�d|!����Q���UPMjH�$P����(��>���V�*��!@1�����y������t��)�*\"�J��t(�z�(~���B�z. @ ��[�	rB�S���Bb�U��V"_��s���Le�o���V
|�
���i��N�������<!��|q��>��~gDP����-�}��TkN�j���|�B�>F��� +�U:U�d@1#B|���"n2AnP�
P��_-�*Q���T���SnujC����b����z����"� vr�����8<x��n���q%~��x���;]��w�����]�2�p�����	�4<�y,bwW����J����O?����g���t:������x����]MF�����m���\OW����>Y>��#�����B��"�q��c;Ux�2��kY���.8^��j�����S���d�K�����.��^������dJ��
�i�`�|]Jc��A9�O%gGP����{\i�Jn	�Cy�FJ�B��k"P��0���b~�^�}%�L
.��o������O�0��U���	�;�{�l"�P�5�X�%G
G�������U"����
~��+�M���UDmEJt��D�����J�*����8���"y��'���{��:�J���P�h��35k�NKe��S����x��Q ������]+�������~�����7���r��X�g����hq��"���#(�e����s��#��0�M����wG?�;�+��/V�WV�_���YY�|�.4�C������
gyI���n������:����^��������?����E.���zu�^i�?����>9�-����w��
���dF���yo�8����?=>9��s�.,�!��!*���/UD��*CU�
(,MIL
�kM�	aa��$,���9~����2c�~8�n��Pz����w����19b�������m��VdD��l��&�~5l�p'8N��=�+����6�e>G)�#�j"�\My1�ot���G��
a�����n�C���a-|n���#�\��F����[��%7����Pf��Xk5��G�V`����!�%zf�Y�fD���������p���8Pv4�o��m�k�KD���)#��j�D��V+����_!�3��e�R�������T<��O�����:���-D��-Dg����Bt�Itn������?���FW����NmC�'������9;>9�pr� �c�)�7�=��:^��W��V�0��:�,u!�kR�he:�sR���~+��L���o����:��t�~��uL��^g�[�?[}�n���R�M8��r�)��z}!m����lc�rV����Zu��;Rm����8������T��	��+J��@��t��'��h�X�Lo�\=��j}3��zl6��SoY��Ku�ez�'��?�;;��������R�s-3	�����zK��.��L��n�z��[U-"�3��v��=� ~����!%p�N��d���?�]�U		l�aaw�;StS���{�����{~m�|��.w����mw������'sH?dZ-��n���m~�P�|�X>�%)���z��x2�,��(@Q�1�*�� ]E��3��(�����.��
���k%��mc�[ni��P|�j�*���@	��yS�9�_�;�����sn��aJ����J�5%���%2���|���=>g�f�)�a�s��#�E�vhL�T����A�)�9#�8��:�qufC���CR���I�')(��H��&���X
c��S�1-���-q��Qh�g�|�1!��%6>�_�
v���>��:v����`0�u�e*^�E�<�v9������%�
����R8nd���cL9)*�vzpm�w%���F��
�k2��X������.Uc~�j��O�5�k�#E����vM�����II��M@�br��/��#|�E^E�v�HY�0�� \_'\9����AD<J�Q���M�d���g�5�O��"u?�.���c�2m���'[�I�];::�)���c��D����a�<�.���'�9�'����R������o����������PF�'�
#�~
��C2/�t���do��I1 I9(-)�TI�T()��$��%)@�������N%%}����V$�]ZR&�/�����$�KH��#����x	2RF����B�}���j�Y��CE*n*�d('�(n����N	yXRM^L�~AU��uy����=h6{=�������ZTe���,����t������x�s�r����_//�;����.�*\Q�� v�&b�Lr��f�n�����3ck���r�����|da����qgl�Z�q�����k��x\�Z���vd��8l�V����&�����t+���Y�`����� ��A��������Z&��=��.����)'�YD�"��"���
p�/�C11�Pw��,��~�'��h��K 2��>J)���x��==8�jEh�$��HR�0$�#�?_�Q
.|�(�E�������i�Uan�>�J��N-��zs|�:jA&G�����E��>I�������2"�1�^*��)���7�)���8����������`Z�<��^��l:v�uFN��,"��V�B=��{f������Z�6�d����9H�����c��[�G	S�-f��=�d��(�O�I�����b�'1��b�'�9�H���>�o��w��/���M�Y�y�f���;���pP]5�	�D�">�"t�v�����pH��.�d"g���Qj6�~����	�}�z���|i��/
	����/����m0���x��z�o���+��~��WS�w�:B!5i�����S���/y���.��J��QR��`��[��o��Z|ml,7��C�l)X�W.��|�\5j|�1��j1������3��h�bR�+�$�J;�S��	��JA��#�S�!K�J��)d5�D�i�_^:V�NW��YBV+>����[�r�)aY�:,`W���U������l������X�b�R�N` ��HBh��j�|�n�<����o/�`�2�_��Y��f����Gq�!���������z������^R-:���O���u���x�Jodn7����M,n$Vg[�\����N���I<����Q<{�=�;��?�?�P f�yl=���&���^*�#Nty�Z\�P�I8�y�NBu�**C������6[,�h�tL��������7Cc��FI�V�����C�w�X�>�}o�I���w�Dx�n�,��V��m���
Z�vf��p�	K��L�>��t�]���&?���|��F��*~:�&c;.�}Q��2�][�H�-�A�%"����Jw�7ew�$�e�����mQ�U�)�$J.8��@xE1WNx%����;��W	�[B����/��(�����~����f��]w4*:��-bPi
I�'O}�8[�kw2��s*�j���������k���}�y��k�+��^
'�:2�}���k=�%Bc��@[9�"=�<_@@�3��^���H���H����$a]�@0q$G�cep_�f_*Vz��^5��\�9�����~`6�$��a���]�����G-�G�����v��b!�"�+l������D��#� 1��4�6/�v���Z��X���
��
/HY�E��yx��Gx��%�����t�
/(-�0�*q��������B����	���,^�����"T,Bj�B1H���@
&Q9�}��v�.-���i�N
F�]V&���^�+/��C9
�`XB�pG�DP-%������������l;c���lvGm��.\ !�(e�(iCl���( P����
�����:J3_��&�6��u���2Gb�g'}��T����y�n�*LG���P'�
3=��.�����P���l!���"(>��"(=���*w��>$7Q�]�q��/!"�K7�^Z�K��?�-�����Hk�t�v��w����Sf7����
j6e.��U���h�n���G;9�h3�RW�l�]�������l����E)��w0���s�Y-G�8���������
1����{����Q�6�v�S|�A5�({����J]�N$�]
�
dP�_��NkYV�"}2����e�4������^�R�j���iG[vI���ngG��Hbmt;� �I��n����b��\�;���p"��	1!UVF���"@J_�I%�Q/;S���r:�������e{����+��0�H�2��T�����!R��� �~H}<^-�a�Wf0?3�j�	�]�
��p�j"U�������Z����>M�H�L�w��k6[}���
G�E���P�v�a7,��G$����H���;�����y8���
���X��\^�0g4\i�3����k����2���R��;-l�����16���� ����.����o���{�K��T������M8?�T)�����*"��}����n�1�:�vI�N;�F���s�
��?���?������
m���B�.������x�^zE���AT��P��3`=�/�r�9Cw��	�o���$	����^��	���/�xT�9��:�-+.�������=���.~�^���8��`dF�[�E�fkA�j	$l��^�be6^���:�����l�\�����v`|��X�{�C{�s�{r������<H��t�.�NE�N�����m:��������T?u���	S9���N^�1�eeH�-���c�-<n�������l�f{7o������Y����`�u�N�n6��N���E�����#oY��.;�6�P������^���jo���_h5����5�8��?�o�Ql~�����v93���GNo�m6������ �1x���Xg��g�������v���p2���>�o�,�<�*�b�������g:`D&����0Q�I��IL�� ��?_dyX�50*j8p,����&w�2���
�<���k����y�W�G..��G��s��x���_����1k6_���|x	��3V,�R�|�|���P|{�����{p���Y�Pm������\��	�y���A:'X����@��4�x�G�)�m&����]��p���#B?�eo����_>�|a����i�oH(P������X��������	���������V�M�������,&�T�-�p4����
�N���Vsl���@k����O�
�1���S�%mI4���?�{��j�q�K���`���1��a�����B1�%�!�#�ix�TCu��J1Lz��%��Z���sR,�xD6.�[DP(�s(_L�������c��C�7�\8d���&P�)^�3�x��1�N��_x�H��.}�>��x*�4d������2�IOu���%k��<l����{>��v����t������y0.�%���lP)������|v���hI ta�t��e	R)G`/VIsS�6��8�������Dde��"������4e��.=�.�-9Q����g"�jEcn��77������+u����w���;��N��y�����g�d�V1��@Q��>QS~mD�r��h���������[Z����4YS����d	���5	t���	�z�r��L�=y�-i�.3�?^�[e�f6���Z��<����SG��L��\_�����-��}R[�3��=�V����D�02���(c��*��s�v����:q-�-}��<Yb"GV�2�b���F�>
1��!qa*�%�$��o�(�X����{�1�k��O�aE�����Kw�[WO����L����&���AQ�>��
`��V�*.����u�u������.����s��;\��>#�(�vkx�t��V�n��U[�S�nJ5d"�d�<����c�����P�goZ���&c�fy�a�|��&iER�-#U�TdPl-r�e'����N�C����+����z)���w
����W���(C��Ke.]�c������P����}6���������'{�d�T�.&sj����E� Y�SPC�WHi�z���&TCYk�]�tio���_�.L|/����f�������\c��
9��b"��1����L�O�Ts�X6	,�����fTb�q�3���o0���"S�a~qj���z�BX=�0=����<��^ZO�oh
24.patchtext/x-patch; name=24.patchDownload
commit a0a3204647bc38b0f2f5971fef514dd5c5eb2430
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:20:06 2013 +0100

    ECPG: Modify the parameters of ECPGsetcommit() so it takes a bool
    instead of a string with the "on" / "off" values. This way the parser
    does slightly more work and the ECPG runtime does slightly less,
    which means slightly better performance. Also add a check to
    not execute BEGIN if the transaction has already failed. Extend
    the same check in ecpg_do_prologue() and match these two.

diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index bbe44ae..eb2d2be 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -162,7 +162,7 @@ ecpg_finish(struct connection * act)
 }
 
 bool
-ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
+ECPGsetcommit(int lineno, const bool turn_on, const char *connection_name)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
 	PGresult   *results;
@@ -170,10 +170,15 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return (false);
 
-	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
+	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, turn_on ? "on" : "off", con->name);
 
-	if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
+	if (con->autocommit && !turn_on)
 	{
+		if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
+		{
+			ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+			return false;
+		}
 		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "begin transaction");
@@ -183,7 +188,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 		}
 		con->autocommit = false;
 	}
-	else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
+	else if (!con->autocommit && turn_on)
 	{
 		if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
 		{
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index a60e209..3f5997c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1866,7 +1866,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return (false);
 	}
 
-	if (con->client_side_error)
+	if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
 	{
 		ecpg_do_epilogue(stmt);
 		ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 02f319d..1ac15d5 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -48,7 +48,7 @@ extern		"C"
 
 void		ECPGdebug(int, FILE *);
 bool		ECPGstatus(int, const char *);
-bool		ECPGsetcommit(int, const char *, const char *);
+bool		ECPGsetcommit(int, const bool, const char *);
 bool		ECPGsetconn(int, const char *);
 bool		ECPGconnect(int, int, const char *, const char *, const char *, const char *, int);
 bool		ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...);
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ebc9b16..df85424 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -222,7 +222,7 @@ ECPG: stmtViewStmt rule
 	}
 	| ECPGSetAutocommit
 	{
-		fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+		fprintf(yyout, "{ ECPGsetcommit(__LINE__, %d, %s);", (strcmp($1, "on") == 0), connection ? connection : "NULL");
 		whenever_action(2);
 		free($1);
 	}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index c139e41..5abbf4f 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -61,7 +61,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 32 "num_test.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);
+	{ ECPGsetcommit(__LINE__, 0, NULL);
 #line 34 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-array.c b/src/interfaces/ecpg/test/expected/sql-array.c
index f770c09..befa89f 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.c
+++ b/src/interfaces/ecpg/test/expected/sql-array.c
@@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 27 "array.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 29 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-func.c b/src/interfaces/ecpg/test/expected/sql-func.c
index 5d524b8..823c5b4 100644
--- a/src/interfaces/ecpg/test/expected/sql-func.c
+++ b/src/interfaces/ecpg/test/expected/sql-func.c
@@ -35,7 +35,7 @@ int main() {
 #line 11 "func.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 13 "func.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.c b/src/interfaces/ecpg/test/expected/sql-indicators.c
index 22aacc1..168ccd4 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.c
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.c
@@ -111,7 +111,7 @@ int main()
 	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
 #line 15 "indicators.pgc"
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);}
+	{ ECPGsetcommit(__LINE__, 0, NULL);}
 #line 16 "indicators.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-parser.c b/src/interfaces/ecpg/test/expected/sql-parser.c
index 616135d..1d6c0d3 100644
--- a/src/interfaces/ecpg/test/expected/sql-parser.c
+++ b/src/interfaces/ecpg/test/expected/sql-parser.c
@@ -38,7 +38,7 @@ int main() {
 #line 14 "parser.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "parser.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 6c4d84f..bfb75ca 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -41,7 +41,7 @@ int main() {
 #line 14 "quote.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "quote.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 199a77e..c74ea26 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "alloc.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index cd28c85..3a559ce 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -210,7 +210,7 @@ int main ()
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 69 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 70 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
25.patch.gzapplication/x-tar; name=25.patch.gzDownload
#98Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#92)
6 attachment(s)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

2013-11-28 15:23 keltez�ssel, Boszormenyi Zoltan �rta:

Rebased after killing the patch that changed the DECLARE CURSOR command tag.
The ECPG readahead patch and all the small following patches are attached.

Fixed the extra spaces that "git apply" complains about.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

26.patch.gzapplication/x-tar; name=26.patch.gzDownload
27.patch.gzapplication/x-tar; name=27.patch.gzDownload
28.patch.gzapplication/x-tar; name=28.patch.gzDownload
29.patch.gzapplication/x-tar; name=29.patch.gzDownload
30.patchtext/x-patch; name=30.patchDownload
commit 29425979f229ae99fe32b8540d65919e517b1c33
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:27:29 2013 +0100

    ECPG: During FETCH ALL, temporarily use FETCHALL_MULTIPLIER times
    the current readahead window size. FETCHALL_MULTIPLIER == 1000.
    No change in regression tests.

diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index 1c24133..2d024b8 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -1518,6 +1518,7 @@ ecpg_cursor_fetch(struct statement *stmt, struct cursor_descriptor *cur,
 	long		ntuples;
 	int		step;
 	int64		prev_pos, next_pos, start_idx, var_index;
+	int64		old_readahead;
 
 	switch (direction)
 	{
@@ -1689,6 +1690,10 @@ abs_rel:
 			goto abs_rel;
 		}
 
+		old_readahead = cur->readahead;
+		if (fetchall)
+			cur->readahead *= FETCHALL_MULTIPLIER;
+
 		/*
 		 * The direction is backward if FETCH BACKWARD ALL
 		 * or the amount to fetch is negative.
@@ -1772,6 +1777,8 @@ abs_rel:
 
 		sqlca->sqlerrd[2] = (var_index <= LONG_MAX ? var_index : 0);
 
+		cur->readahead = old_readahead;
+
 		if (var_index == 0)
 		{
 			ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 612412f..de0f3b8 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -32,6 +32,7 @@ enum ARRAY_TYPE
 #define LOOP_FORWARD	(1)
 #define LOOP_BACKWARD	(-1)
 #define MAX_CACHE_MISS	(3)
+#define FETCHALL_MULTIPLIER	(1000)
 
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
#99Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#97)
17 attachment(s)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

2013-12-04 14:51 keltez�ssel, Boszormenyi Zoltan �rta:

2013-12-03 16:48 keltez�ssel, Antonin Houska �rta:

Tests - 23.patch
----------------

src/interfaces/ecpg/test/sql/cursorsubxact.pgc

/*
* Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
* is used with an already existing name.
*/

Shouldn't it be "... if a CURSOR is used with an already existing
name?". Or just "... implicit RELEASE SAVEPOINT after an error"?
I'd also appreciate a comment where exactly the savepoint is
(implicitly) released.

I have already answered this in my previous answer.

And I was wrong in that. The comments in the test were rearranged
a little and the fact in the above comment is now actually tested.

Some harmless unused variables were also removed and an
uninitialized variable usage was fixed. Because of these and the above
changes a lot of patches need to be rebased.

All patches are attached again for completeness.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

09.patchtext/x-patch; name=09.patchDownload
commit 05bcbb115157ce065276c5baf689ca5011311fc6
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:20:16 2013 +0100

    ECPG: Move allocating struct statement earlier in ECPGdo()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e5ee8a9..83acaf4 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1720,6 +1720,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
+	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+		return false;
+
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
@@ -1735,6 +1738,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
+		free_statement(stmt);
 		return (false);
 	}
 
@@ -1753,13 +1757,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	 * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
 	 * arraysize of indicator array ind_offset - indicator offset
 	 */
-	if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
-	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
-		va_end(args);
-		return false;
-	}
 
 	/*
 	 * If statement type is ECPGst_prepnormal we are supposed to prepare the
10.patchtext/x-patch; name=10.patchDownload
commit ada9ead8e5374337cbafded94f6f6a4d898404ad
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:23:29 2013 +0100

    ECPG: Move char *oldlocale from ECPGdo() to struct statement.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 83acaf4..01e1a32 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -104,6 +104,7 @@ free_statement(struct statement * stmt)
 	free_variable(stmt->outlist);
 	ecpg_free(stmt->command);
 	ecpg_free(stmt->name);
+	ecpg_free(stmt->oldlocale);
 	ecpg_free(stmt);
 }
 
@@ -1708,7 +1709,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
-	char	   *oldlocale;
 	enum ECPGttype type;
 	struct variable **list;
 	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
@@ -1725,7 +1725,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
-	oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
 		free_statement(stmt);
 		return (false);
 	}
@@ -1766,8 +1765,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1798,8 +1796,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, oldlocale);
-			ecpg_free(oldlocale);
+			setlocale(LC_NUMERIC, stmt->oldlocale);
 			free_statement(stmt);
 			va_end(args);
 			return (false);
@@ -1828,8 +1825,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1886,8 +1882,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, oldlocale);
-				ecpg_free(oldlocale);
+				setlocale(LC_NUMERIC, stmt->oldlocale);
 				free_statement(stmt);
 				va_end(args);
 				return false;
@@ -1909,10 +1904,9 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
-		free_statement(stmt);
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, oldlocale);
-		ecpg_free(oldlocale);
+		setlocale(LC_NUMERIC, stmt->oldlocale);
+		free_statement(stmt);
 		return false;
 	}
 
@@ -1920,11 +1914,10 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	ecpg_clear_auto_mem();
 
 	status = ecpg_execute(stmt);
-	free_statement(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	ecpg_free(oldlocale);
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
 
 	return (status);
 }
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 835e70c..0e85ee9 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -60,6 +60,7 @@ struct statement
 	bool		questionmarks;
 	struct variable *inlist;
 	struct variable *outlist;
+	char	   *oldlocale;
 };
 
 /* structure to store prepared statements for a connection */
11.patchtext/x-patch; name=11.patchDownload
commit 291985588ab9d113bf936df34a3b19952ec0f9f7
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:25:21 2013 +0100

    ECPG: Introduce ecpg_do_epilogue() to restore LC_NUMERIC and
    free the statement structure.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 01e1a32..e977a4e 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1736,8 +1736,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return (false);
 	}
 
@@ -1765,8 +1764,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	{
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1796,8 +1794,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		else
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
-			setlocale(LC_NUMERIC, stmt->oldlocale);
-			free_statement(stmt);
+			ecpg_do_epilogue(stmt);
 			va_end(args);
 			return (false);
 		}
@@ -1825,8 +1822,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1882,8 +1878,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			{
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
-				setlocale(LC_NUMERIC, stmt->oldlocale);
-				free_statement(stmt);
+				ecpg_do_epilogue(stmt);
 				va_end(args);
 				return false;
 			}
@@ -1905,8 +1900,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	if (con == NULL || con->connection == NULL)
 	{
 		ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
-		setlocale(LC_NUMERIC, stmt->oldlocale);
-		free_statement(stmt);
+		ecpg_do_epilogue(stmt);
 		return false;
 	}
 
@@ -1916,12 +1910,25 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 	status = ecpg_execute(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, stmt->oldlocale);
-	free_statement(stmt);
+	ecpg_do_epilogue(stmt);
 
 	return (status);
 }
 
+/*
+ * ecpg_do_epilogue
+ *    Restore the application locale and free the statement structure.
+ */
+void
+ecpg_do_epilogue(struct statement *stmt)
+{
+	if (stmt == NULL)
+		return;
+
+	setlocale(LC_NUMERIC, stmt->oldlocale);
+	free_statement(stmt);
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 0e85ee9..f9a861f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -165,6 +165,7 @@ struct prepared_statement *ecpg_find_prepared_statement(const char *,
 bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
+void		ecpg_do_epilogue(struct statement *);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
12.patchtext/x-patch; name=12.patchDownload
commit 7be47896829ee333f3d1e81f3a7cdddffdef3e80
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:26:18 2013 +0100

    ECPG: Introduce ecpg_do(). The core function of ECPGdo() is
    separated out, so va_start and va_end are done centrally, and
    the function can be used elsewhere.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e977a4e..b97e241 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1702,10 +1702,14 @@ ecpg_execute(struct statement * stmt)
 	return status;
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
 bool
-ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
-	va_list		args;
 	struct statement *stmt;
 	struct connection *con;
 	bool		status;
@@ -1740,9 +1744,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		return (false);
 	}
 
-	/* construct statement in our own structure */
-	va_start(args, query);
-
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
@@ -1765,7 +1766,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
 		{
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 
@@ -1795,7 +1795,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		{
 			ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
 			ecpg_do_epilogue(stmt);
-			va_end(args);
 			return (false);
 		}
 	}
@@ -1823,7 +1822,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 			if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			{
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1879,7 +1877,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 				ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
 				ecpg_free(var);
 				ecpg_do_epilogue(stmt);
-				va_end(args);
 				return false;
 			}
 
@@ -1894,8 +1891,6 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
 		type = va_arg(args, enum ECPGttype);
 	}
 
-	va_end(args);
-
 	/* are we connected? */
 	if (con == NULL || con->connection == NULL)
 	{
@@ -1929,6 +1924,24 @@ ecpg_do_epilogue(struct statement *stmt)
 	free_statement(stmt);
 }
 
+/*
+ * Execute SQL statements in the backend.
+ * The input/output parameters are passed as variable-length argument list.
+ */
+bool
+ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
+{
+	va_list		args;
+	bool		ret;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name,
+							questionmarks,
+							st, query, args);
+	va_end(args);
+	return ret;
+}
+
 /* old descriptor interface */
 bool
 ECPGdo_descriptor(int line, const char *connection,
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f9a861f..f0e9b3c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -166,6 +166,7 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_do_epilogue(struct statement *);
+bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
13.patch.gzapplication/x-tar; name=13.patch.gzDownload
14.patchtext/x-patch; name=14.patchDownload
commit d9ff326b4bed2929253aeac519a9b19b1e132646
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:28:57 2013 +0100

    ECPG: Split ecpg_do() further and introduce ecpg_do_prologue().
    Add an error path to return if ecpg_strdup(setlocale()) fails.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 551902d..c43b59c 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1704,21 +1704,27 @@ ecpg_execute(struct statement * stmt)
 }
 
 /*
- * Execute SQL statements in the backend.
- * The input/output parameters (variable argument list) are passed
- * in a va_list, so other functions can use this interface.
+ * ecpg_do_prologue
+ * Initialize various infrastructure elements for executing the statement:
+ *	- create the statement structure
+ *	- set the C locale for communicating with the backend
+ *	- preprocess the variable list of input/output parameters into
+ *	  linked lists
  */
 bool
-ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
+		 const char *connection_name, const bool questionmarks,
+		 enum ECPG_statement_type statement_type, const char *query,
+		 va_list args, struct statement **stmt_out)
 {
 	struct statement *stmt;
 	struct connection *con;
-	bool		status;
 	enum ECPGttype type;
 	struct variable **list;
-	enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
 	char	   *prepname;
 
+	*stmt_out = NULL;
+
 	if (!query)
 	{
 		ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
@@ -1733,6 +1739,11 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
 	stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
+	if (stmt->oldlocale == NULL)
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 	setlocale(LC_NUMERIC, "C");
 
 #ifdef ENABLE_THREAD_SAFETY
@@ -1905,12 +1916,9 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 	/* initialize auto_mem struct */
 	ecpg_clear_auto_mem();
 
-	status = ecpg_execute(stmt);
+	*stmt_out = stmt;
 
-	/* and reset locale value so our application is not affected */
-	ecpg_do_epilogue(stmt);
-
-	return (status);
+	return true;
 }
 
 /*
@@ -1929,6 +1937,34 @@ ecpg_do_epilogue(struct statement *stmt)
 
 /*
  * Execute SQL statements in the backend.
+ * The input/output parameters (variable argument list) are passed
+ * in a va_list, so other functions can use this interface.
+ */
+bool
+ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
+{
+	struct statement   *stmt;
+	bool		status;
+
+	if (!ecpg_do_prologue(lineno, compat, force_indicator,
+				connection_name, questionmarks,
+				(enum ECPG_statement_type) st,
+				query, args, &stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	status = ecpg_execute(stmt);
+
+	/* and reset locale value so our application is not affected */
+	ecpg_do_epilogue(stmt);
+
+	return (status);
+}
+
+/*
+ * Execute SQL statements in the backend.
  * The input/output parameters are passed as variable-length argument list.
  */
 bool
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index c469220..83ea011 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,7 +169,11 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 void		ecpg_do_epilogue(struct statement *);
-bool		ecpg_do(const int, const int, const int, const char *, const bool, const int, const char *, va_list);
+bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
+				  enum ECPG_statement_type, const char *, va_list,
+				  struct statement **);
+bool		ecpg_do(const int, const int, const int, const char *, const bool,
+				  const int, const char *, va_list);
 
 bool		ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
 void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
15.patchtext/x-patch; name=15.patchDownload
commit ddbfc1eaa80c050bf46eabb3a22b1f847d2a9dd8
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:29:49 2013 +0100

    ECPG: Move PGresult *results into struct statement from ecpg_execute()

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index c43b59c..e3a44f7 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1130,7 +1130,6 @@ ecpg_execute(struct statement * stmt)
 {
 	bool		status = false;
 	char	   *cmdstat;
-	PGresult   *results;
 	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
@@ -1426,50 +1425,51 @@ ecpg_execute(struct statement * stmt)
 
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
-		results = PQexec(stmt->connection->connection, "begin transaction");
-		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
+		if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		{
 			ecpg_free_params(stmt, false);
 			return false;
 		}
-		PQclear(results);
+		PQclear(stmt->results);
+		stmt->results = NULL;
 	}
 
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
-		results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+		stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 		ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
 	}
 	else
 	{
 		if (stmt->nparams == 0)
 		{
-			results = PQexec(stmt->connection->connection, stmt->command);
+			stmt->results = PQexec(stmt->connection->connection, stmt->command);
 			ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
 		}
 		else
 		{
-			results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
+			stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
 			ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
 		}
 	}
 
 	ecpg_free_params(stmt, true);
 
-	if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
+	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
 	var = stmt->outlist;
-	switch (PQresultStatus(results))
+	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
 						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
-			nfields = PQnfields(results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(results);
+			nfields = PQnfields(stmt->results);
+			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
 			ecpg_log("ecpg_execute on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1493,10 +1493,10 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (desc->result)
 						PQclear(desc->result);
-					desc->result = results;
+					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(results), (const char *) var->pointer);
+							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1526,7 +1526,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1549,9 +1549,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1582,7 +1582,7 @@ ecpg_execute(struct statement * stmt)
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1605,9 +1605,9 @@ ecpg_execute(struct statement * stmt)
 
 							*_sqlda = sqlda_new;
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
-									 stmt->lineno, PQnfields(results));
+									 stmt->lineno, PQnfields(stmt->results));
 
 							sqlda_new->desc_next = sqlda;
 							sqlda = sqlda_new;
@@ -1622,7 +1622,7 @@ ecpg_execute(struct statement * stmt)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, act_field, stmt, var);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -1641,9 +1641,9 @@ ecpg_execute(struct statement * stmt)
 			break;
 		case PGRES_COMMAND_OK:
 			status = true;
-			cmdstat = PQcmdStatus(results);
-			sqlca->sqlerrd[1] = PQoidValue(results);
-			sqlca->sqlerrd[2] = atol(PQcmdTuples(results));
+			cmdstat = PQcmdStatus(stmt->results);
+			sqlca->sqlerrd[1] = PQoidValue(stmt->results);
+			sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
 			ecpg_log("ecpg_execute on line %d: OK: %s\n", stmt->lineno, cmdstat);
 			if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
 				!sqlca->sqlerrd[2] &&
@@ -1667,12 +1667,12 @@ ecpg_execute(struct statement * stmt)
 				if (res == -1)
 				{
 					/* COPY done */
-					PQclear(results);
-					results = PQgetResult(stmt->connection->connection);
-					if (PQresultStatus(results) == PGRES_COMMAND_OK)
+					PQclear(stmt->results);
+					stmt->results = PQgetResult(stmt->connection->connection);
+					if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
 						ecpg_log("ecpg_execute on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
 					else
-						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(results));
+						ecpg_log("ecpg_execute on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
 				}
 				break;
 			}
@@ -1684,12 +1684,15 @@ ecpg_execute(struct statement * stmt)
 			 */
 			ecpg_log("ecpg_execute on line %d: unknown execution status type\n",
 					 stmt->lineno);
-			ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);
+			ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
 			status = false;
 			break;
 	}
 	if (clear_result)
-		PQclear(results);
+	{
+		PQclear(stmt->results);
+		stmt->results = NULL;
+	}
 
 	/* check for asynchronous returns */
 	notify = PQnotifies(stmt->connection->connection);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 83ea011..50fe87f 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -63,6 +63,7 @@ struct statement
 	char	   *oldlocale;
 	int		nparams;
 	char	  **paramvalues;
+	PGresult   *results;
 };
 
 /* structure to store prepared statements for a connection */
16.patchtext/x-patch; name=16.patchDownload
commit d9407cba81d224ab142d93f21aaf794cf3af61a7
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:30:22 2013 +0100

    ECPG: Split ecpg_execute() up into 4 pieces: ecpg_build_params(),
    ecpg_autostart_transaction(), a smaller ecpg_execute() and
    ecpg_process_output().

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e3a44f7..00327db 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1125,17 +1125,17 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
 	return true;
 }
 
-static bool
-ecpg_execute(struct statement * stmt)
+/*
+ * ecpg_build_params
+ *	Build statement parameters from user variables into
+ *	an array of strings for PQexecParams().
+ */
+bool
+ecpg_build_params(struct statement * stmt)
 {
-	bool		status = false;
-	char	   *cmdstat;
-	PGnotify   *notify;
 	struct variable *var;
 	int			desc_counter = 0;
 	int			position = 0;
-	struct sqlca_t *sqlca = ECPGget_sqlca();
-	bool		clear_result = true;
 
 	/*
 	 * If the type is one of the fill in types then we take the argument and
@@ -1421,8 +1421,17 @@ ecpg_execute(struct statement * stmt)
 		return false;
 	}
 
-	/* The request has been build. */
+	return true;
+}
 
+/*
+ * ecpg_autostart_transaction
+ *	If we are in non-autocommit mode, automatically start
+ *	a transaction.
+ */
+bool
+ecpg_autostart_transaction(struct statement * stmt)
+{
 	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
 		stmt->results = PQexec(stmt->connection->connection, "begin transaction");
@@ -1434,7 +1443,16 @@ ecpg_execute(struct statement * stmt)
 		PQclear(stmt->results);
 		stmt->results = NULL;
 	}
+	return true;
+}
 
+/*
+ * ecpg_execute
+ *	Execute the SQL statement.
+ */
+bool
+ecpg_execute(struct statement * stmt)
+{
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
 	if (stmt->statement_type == ECPGst_execute)
 	{
@@ -1460,6 +1478,33 @@ ecpg_execute(struct statement * stmt)
 	if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
 		return (false);
 
+	return true;
+}
+
+/*
+ * ecpg_process_output
+ *	Process the statement result and store it into application variables.
+ *	This function can be called repeatedly during the same statement
+ *	in case cursor readahed is used and the application does FETCH N which
+ *	overflows the readahead window.
+ *
+ * Parameters
+ *	stmt	statement structure holding the PGresult and
+ *		the list of output variables
+ *	clear_result
+ *		PQclear() the result upon returning from this function
+ *
+ * Returns success as boolean. Also an SQL error is raised in case of failure.
+ */
+bool
+ecpg_process_output(struct statement * stmt, bool clear_result)
+{
+	struct variable *var;
+	bool		status = false;
+	char	   *cmdstat;
+	PGnotify   *notify;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
 	var = stmt->outlist;
 	switch (PQresultStatus(stmt->results))
 	{
@@ -1947,7 +1992,6 @@ bool
 ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
 {
 	struct statement   *stmt;
-	bool		status;
 
 	if (!ecpg_do_prologue(lineno, compat, force_indicator,
 				connection_name, questionmarks,
@@ -1958,12 +2002,33 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	status = ecpg_execute(stmt);
+	if (!ecpg_build_params(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_autostart_transaction(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_execute(stmt))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
+
+	if (!ecpg_process_output(stmt, true))
+	{
+		ecpg_do_epilogue(stmt);
+		return false;
+	}
 
-	/* and reset locale value so our application is not affected */
 	ecpg_do_epilogue(stmt);
 
-	return (status);
+	return true;
 }
 
 /*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 50fe87f..1f96869 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,10 +169,14 @@ bool ecpg_store_result(const PGresult *results, int act_field,
 				  const struct statement * stmt, struct variable * var);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
-void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 				  enum ECPG_statement_type, const char *, va_list,
 				  struct statement **);
+bool		ecpg_build_params(struct statement *);
+bool		ecpg_autostart_transaction(struct statement * stmt);
+bool		ecpg_execute(struct statement * stmt);
+bool		ecpg_process_output(struct statement *, bool);
+void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
 
17.patch.gzapplication/x-tar; name=17.patch.gzDownload
18.patchtext/x-patch; name=18.patchDownload
commit d95c6625d1b1f6bbbf9970c5236465d0ffbf0c50
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:34:31 2013 +0100

    ECPG: Decouple the tuple index from the array index in
    ecpg_get_data(). Document the function arguments.

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 5f9a3d4..7f3c7cb 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -119,8 +119,35 @@ check_special_value(char *ptr, double *retval, char **endptr)
 	return false;
 }
 
+/*
+ * ecpg_get_data
+ *   Store one field data from PQgetvalue(results, act_tuple, act_field)
+ *   into a target variable. If the field is NULL, store the indication or
+ *   emit an error about the fact that there is no NULL indicator given.
+ * Parameters:
+ *   results:     result set
+ *   act_tuple:   row index in the result set
+ *   act_field:   column index in the result set
+ *   var_index:   array index in the target variable
+ *   lineno:      line number in the ECPG source file for debugging
+ *   type:        type of target variable
+ *   ind_type:    type of NULL indicator variable
+ *   var:         target variable
+ *   ind:         NULL indicator variable
+ *   varcharsize: size of the variable if it's varchar
+ *   offset:      size of the target variable
+ *                (used for indexing in an array)
+ *   ind_offset:  size of the NULL indicator variable
+ *                (used for indexing in an array)
+ *   isarray:     array type
+ *   compat:      native PostgreSQL or Informix compatibility mode
+ *   force_indicator:
+ *                if Informix compatibility mode is set and no NULL indicator
+ *                is given, provide a way to indicate NULL value in the
+ *                target variable itself
+ */
 bool
-ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
+ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int var_index, int lineno,
 			  enum ECPGttype type, enum ECPGttype ind_type,
 			  char *var, char *ind, long varcharsize, long offset,
 			  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
@@ -167,20 +194,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	{
 		case ECPGt_short:
 		case ECPGt_unsigned_short:
-			*((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((short *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_int:
 		case ECPGt_unsigned_int:
-			*((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 		case ECPGt_long:
 		case ECPGt_unsigned_long:
-			*((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #ifdef HAVE_LONG_LONG_INT
 		case ECPGt_long_long:
 		case ECPGt_unsigned_long_long:
-			*((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
+			*((long long int *) (ind + ind_offset * var_index)) = value_for_indicator;
 			break;
 #endif   /* HAVE_LONG_LONG_INT */
 		case ECPGt_NO_INDICATOR:
@@ -192,7 +219,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					 * Informix has an additional way to specify NULLs note
 					 * that this uses special values to denote NULL
 					 */
-					ECPGset_noind_null(type, var + offset * act_tuple);
+					ECPGset_noind_null(type, var + offset * var_index);
 				}
 				else
 				{
@@ -243,10 +270,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		if (binary)
 		{
 			if (varcharsize == 0 || varcharsize * offset >= size)
-				memcpy(var + offset * act_tuple, pval, size);
+				memcpy(var + offset * var_index, pval, size);
 			else
 			{
-				memcpy(var + offset * act_tuple, pval, varcharsize * offset);
+				memcpy(var + offset * var_index, pval, varcharsize * offset);
 
 				if (varcharsize * offset < size)
 				{
@@ -255,20 +282,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					{
 						case ECPGt_short:
 						case ECPGt_unsigned_short:
-							*((short *) (ind + ind_offset * act_tuple)) = size;
+							*((short *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_int:
 						case ECPGt_unsigned_int:
-							*((int *) (ind + ind_offset * act_tuple)) = size;
+							*((int *) (ind + ind_offset * var_index)) = size;
 							break;
 						case ECPGt_long:
 						case ECPGt_unsigned_long:
-							*((long *) (ind + ind_offset * act_tuple)) = size;
+							*((long *) (ind + ind_offset * var_index)) = size;
 							break;
 #ifdef HAVE_LONG_LONG_INT
 						case ECPGt_long_long:
 						case ECPGt_unsigned_long_long:
-							*((long long int *) (ind + ind_offset * act_tuple)) = size;
+							*((long long int *) (ind + ind_offset * var_index)) = size;
 							break;
 #endif   /* HAVE_LONG_LONG_INT */
 						default:
@@ -307,13 +334,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_short:
-							*((short *) (var + offset * act_tuple)) = (short) res;
+							*((short *) (var + offset * var_index)) = (short) res;
 							break;
 						case ECPGt_int:
-							*((int *) (var + offset * act_tuple)) = (int) res;
+							*((int *) (var + offset * var_index)) = (int) res;
 							break;
 						case ECPGt_long:
-							*((long *) (var + offset * act_tuple)) = (long) res;
+							*((long *) (var + offset * var_index)) = (long) res;
 							break;
 						default:
 							/* Cannot happen */
@@ -336,13 +363,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_unsigned_short:
-							*((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
+							*((unsigned short *) (var + offset * var_index)) = (unsigned short) ures;
 							break;
 						case ECPGt_unsigned_int:
-							*((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
+							*((unsigned int *) (var + offset * var_index)) = (unsigned int) ures;
 							break;
 						case ECPGt_unsigned_long:
-							*((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
+							*((unsigned long *) (var + offset * var_index)) = (unsigned long) ures;
 							break;
 						default:
 							/* Cannot happen */
@@ -353,7 +380,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #ifdef HAVE_LONG_LONG_INT
 #ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
-					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
+					*((long long int *) (var + offset * var_index)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, scan_length, compat))
 					{
 						ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -365,7 +392,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 #endif   /* HAVE_STRTOLL */
 #ifdef HAVE_STRTOULL
 				case ECPGt_unsigned_long_long:
-					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
+					*((unsigned long long int *) (var + offset * var_index)) = strtoull(pval, &scan_length, 10);
 					if ((isarray && *scan_length != ',' && *scan_length != '}')
 						|| (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))		/* Garbage left */
 					{
@@ -400,10 +427,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					switch (type)
 					{
 						case ECPGt_float:
-							*((float *) (var + offset * act_tuple)) = dres;
+							*((float *) (var + offset * var_index)) = dres;
 							break;
 						case ECPGt_double:
-							*((double *) (var + offset * act_tuple)) = dres;
+							*((double *) (var + offset * var_index)) = dres;
 							break;
 						default:
 							/* Cannot happen */
@@ -415,9 +442,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					if (pval[0] == 'f' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = false;
+							*((char *) (var + offset * var_index)) = false;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = false;
+							*((int *) (var + offset * var_index)) = false;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -428,9 +455,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					else if (pval[0] == 't' && pval[1] == '\0')
 					{
 						if (offset == sizeof(char))
-							*((char *) (var + offset * act_tuple)) = true;
+							*((char *) (var + offset * var_index)) = true;
 						else if (offset == sizeof(int))
-							*((int *) (var + offset * act_tuple)) = true;
+							*((int *) (var + offset * var_index)) = true;
 						else
 							ecpg_raise(lineno, ECPG_CONVERT_BOOL,
 									   ECPG_SQLSTATE_DATATYPE_MISMATCH,
@@ -453,7 +480,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_unsigned_char:
 				case ECPGt_string:
 					{
-						char	   *str = (char *) (var + offset * act_tuple);
+						char	   *str = (char *) (var + offset * var_index);
 
 						if (varcharsize == 0 || varcharsize > size)
 						{
@@ -481,20 +508,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = size;
+										*((short *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = size;
+										*((int *) (ind + ind_offset * var_index)) = size;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = size;
+										*((long *) (ind + ind_offset * var_index)) = size;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = size;
+										*((long long int *) (ind + ind_offset * var_index)) = size;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -510,7 +537,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 				case ECPGt_varchar:
 					{
 						struct ECPGgeneric_varchar *variable =
-						(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
+						(struct ECPGgeneric_varchar *) (var + offset * var_index);
 
 						variable->len = size;
 						if (varcharsize == 0)
@@ -526,20 +553,20 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 								{
 									case ECPGt_short:
 									case ECPGt_unsigned_short:
-										*((short *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((short *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_int:
 									case ECPGt_unsigned_int:
-										*((int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 									case ECPGt_long:
 									case ECPGt_unsigned_long:
-										*((long *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #ifdef HAVE_LONG_LONG_INT
 									case ECPGt_long_long:
 									case ECPGt_unsigned_long_long:
-										*((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
+										*((long long int *) (ind + ind_offset * var_index)) = variable->len;
 										break;
 #endif   /* HAVE_LONG_LONG_INT */
 									default:
@@ -606,9 +633,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					if (type == ECPGt_numeric)
-						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
+						PGTYPESnumeric_copy(nres, (numeric *) (var + offset * var_index));
 					else
-						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
+						PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * var_index));
 
 					PGTYPESnumeric_free(nres);
 					break;
@@ -659,7 +686,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					pval = scan_length;
 
-					PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
+					PGTYPESinterval_copy(ires, (interval *) (var + offset * var_index));
 					free(ires);
 					break;
 
@@ -703,7 +730,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((date *) (var + offset * act_tuple)) = ddres;
+					*((date *) (var + offset * var_index)) = ddres;
 					pval = scan_length;
 					break;
 
@@ -747,7 +774,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 					}
 
-					*((timestamp *) (var + offset * act_tuple)) = tres;
+					*((timestamp *) (var + offset * var_index)) = tres;
 					pval = scan_length;
 					break;
 
@@ -764,6 +791,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
 				/* set array to next entry */
 				++act_tuple;
+				++var_index;
 
 				/* set pval to the next entry */
 
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ca3e0ba..438d3ab 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -433,7 +433,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -452,7 +452,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 	{
 		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 1f96869..f91867c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -139,7 +139,7 @@ extern struct var_list *ivlist;
 /* Returns a pointer to a string containing a simple type name. */
 void		ecpg_add_mem(void *ptr, int lineno);
 
-bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
+bool ecpg_get_data(const PGresult *, int, int, int, int, enum ECPGttype type,
 			  enum ECPGttype, char *, char *, long, long, long,
 			  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index bc94f2f..9985a6c 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -393,7 +393,7 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
@@ -578,7 +578,7 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult
 		if (!isnull)
 		{
 			if (set_data)
-				ecpg_get_data(res, row, i, lineno,
+				ecpg_get_data(res, row, i, 0, lineno,
 							  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 							  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 							  ECPG_ARRAY_NONE, compat, false);
19.patchtext/x-patch; name=19.patchDownload
commit f9a364b20b3d57b42e04187f160b9f2ddd20502f
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:35:52 2013 +0100

    ECPG: Make SQLDA loops go forward. One regression test .stderr changed.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 438d3ab..1fcfebc 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1551,6 +1551,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
 					struct sqlda_compat *sqlda = *_sqlda;
+					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
@@ -1564,8 +1565,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1592,14 +1593,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
@@ -1607,6 +1613,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
 					struct sqlda_struct *sqlda = *_sqlda;
+					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
@@ -1620,8 +1627,8 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						free(sqlda);
 						sqlda = sqlda_new;
 					}
-					*_sqlda = sqlda = sqlda_new = NULL;
-					for (i = ntuples - 1; i >= 0; i--)
+					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
+					for (i = 0; i < ntuples; i++)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1648,14 +1655,19 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						{
 							ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
 
-							*_sqlda = sqlda_new;
+							if (sqlda_last)
+							{
+								sqlda_last->desc_next = sqlda_new;
+								sqlda_last = sqlda_new;
+							}
+							else
+							{
+								*_sqlda = sqlda = sqlda_last = sqlda_new;
+							}
 
-							ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
-
-							sqlda_new->desc_next = sqlda;
-							sqlda = sqlda_new;
 						}
 					}
 				}
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
index acb3198..9eb54f2 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.stderr
@@ -148,23 +148,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -190,23 +190,23 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: new sqlda was built
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 0 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 0 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 1 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 1 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 2 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 2 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 3 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 3 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: 4 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_set_native_sqlda on line 141 row 0 col 4 IS NOT NULL
+[NO_PID]: ecpg_set_native_sqlda on line 141 row 2 col 4 IS NOT NULL
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 141: RESULT: a          offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 141: RESULT: d          offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_process_output on line 141: putting result (1 tuple 5 fields) into sqlda descriptor
 [NO_PID]: sqlca: code: 0, state: 00000
20.patchtext/x-patch; name=20.patchDownload
commit a982b7f33dc4dac52d4038de7b80733a00caa07f
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:38:41 2013 +0100

    ECPG: Allow returning partial results in any order from the result set
    into an arbitrary index if the user variable is an array.

diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index b2990ca..5d86c53 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -481,7 +481,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
 
 		/* desperate try to guess something sensible */
 		stmt.connection = ecpg_get_connection(NULL);
-		ecpg_store_result(ECPGresult, index, &stmt, &data_var);
+		ecpg_store_result(ECPGresult, 0, PQntuples(ECPGresult), LOOP_FORWARD, index, &stmt, &data_var, 0);
 
 		setlocale(LC_NUMERIC, oldlocale);
 		ecpg_free(oldlocale);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1fcfebc..ace6c11 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -307,12 +307,14 @@ ecpg_is_type_an_array(int type, const struct statement * stmt, const struct vari
 
 
 bool
-ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var)
+ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction,
+				  int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index)
 {
 	enum ARRAY_TYPE isarray;
-	int			act_tuple,
-				ntuples = PQntuples(results);
+	int			tuples_left, act_tuple, act_index;
 	bool		status = true;
 
 	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
@@ -363,7 +365,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					if (!var->varcharsize && !var->arrsize)
 					{
 						/* special mode for handling char**foo=0 */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 							len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 						len *= var->offset;		/* should be 1, but YMNK */
 						len += (ntuples + 1) * sizeof(char *);
@@ -372,7 +374,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 					{
 						var->varcharsize = 0;
 						/* check strlen for each tuple */
-						for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 						{
 							int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
@@ -393,7 +395,7 @@ ecpg_store_result(const PGresult *results, int act_field,
 		}
 		else
 		{
-			for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+			for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 				len += PQgetlength(results, act_tuple, act_field);
 		}
 
@@ -429,11 +431,11 @@ ecpg_store_result(const PGresult *results, int act_field,
 		/* storing the data (after the last array element) */
 		char	   *current_data_location = (char *) &current_string[ntuples + 1];
 
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
 			int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							 var->type, var->ind_type, current_data_location,
 							   var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -450,9 +452,9 @@ ecpg_store_result(const PGresult *results, int act_field,
 	}
 	else
 	{
-		for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+		for (tuples_left = ntuples, act_tuple = start, act_index = var_index; tuples_left && status; tuples_left--, act_tuple += direction, act_index++)
 		{
-			if (!ecpg_get_data(results, act_tuple, act_field, act_tuple, stmt->lineno,
+			if (!ecpg_get_data(results, act_tuple, act_field, act_index, stmt->lineno,
 							   var->type, var->ind_type, var->value,
 							   var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
 				status = false;
@@ -1489,15 +1491,18 @@ ecpg_execute(struct statement * stmt)
  *	overflows the readahead window.
  *
  * Parameters
- *	stmt	statement structure holding the PGresult and
- *		the list of output variables
- *	clear_result
- *		PQclear() the result upon returning from this function
+ *	stmt:		statement structure holding the PGresult and
+ *			the list of output variables
+ *	start:		start index in PGresult
+ *	ntuples:	number of tuples to process
+ *	direction:	in this direction
+ *	var_index:	start index in the user variable if it's an array
+ *	clear_result:	PQclear() the result upon returning from this function
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1509,12 +1514,11 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
-						ntuples,
 						act_field;
 
 		case PGRES_TUPLES_OK:
 			nfields = PQnfields(stmt->results);
-			sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
+			sqlca->sqlerrd[2] = ntuples;
 			ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
 			status = true;
 
@@ -1541,7 +1545,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 					desc->result = stmt->results;
 					clear_result = false;
 					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
+							 stmt->lineno, ntuples, (const char *) var->pointer);
 				}
 				var = var->next;
 			}
@@ -1566,7 +1570,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1628,7 +1632,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 						sqlda = sqlda_new;
 					}
 					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
-					for (i = 0; i < ntuples; i++)
+					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
@@ -1679,7 +1683,7 @@ ecpg_process_output(struct statement * stmt, bool clear_result)
 				{
 					if (var != NULL)
 					{
-						status = ecpg_store_result(stmt->results, act_field, stmt, var);
+						status = ecpg_store_result(stmt->results, start, ntuples, direction, act_field, stmt, var, var_index);
 						var = var->next;
 					}
 					else if (!INFORMIX_MODE(stmt->compat))
@@ -2032,7 +2036,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f91867c..e09e351 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -29,6 +29,9 @@ enum ARRAY_TYPE
 
 #define ECPG_IS_ARRAY(X) ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
 
+#define LOOP_FORWARD	(1)
+#define LOOP_BACKWARD	(-1)
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -165,8 +168,10 @@ struct descriptor *ecpg_find_desc(int line, const char *name);
 struct prepared_statement *ecpg_find_prepared_statement(const char *,
 						  struct connection *, struct prepared_statement **);
 
-bool ecpg_store_result(const PGresult *results, int act_field,
-				  const struct statement * stmt, struct variable * var);
+bool ecpg_store_result(const PGresult *results,
+				  int start, int ntuples, int direction, int act_field,
+				  const struct statement * stmt,
+				  struct variable * var, int var_index);
 bool		ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
 void		ecpg_free_params(struct statement *stmt, bool print);
 bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
@@ -175,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
21.patchtext/x-patch; name=21.patchDownload
commit 8b3e1fe4c0aa3d75e1589a0511144adc9673b695
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:42:49 2013 +0100

    ECPG: Allow appending a new result set to descriptors.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index ace6c11..8f746ce 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1498,11 +1498,13 @@ ecpg_execute(struct statement * stmt)
  *	direction:	in this direction
  *	var_index:	start index in the user variable if it's an array
  *	clear_result:	PQclear() the result upon returning from this function
+ *	append_result:	the user variable is an SQL or SQLDA descriptor,
+ *			may already contain data, append to it.
  *
  * Returns success as boolean. Also an SQL error is raised in case of failure.
  */
 bool
-ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result)
+ecpg_process_output(struct statement * stmt, int start, int ntuples, int direction, int var_index, bool clear_result, bool append_result)
 {
 	struct variable *var;
 	bool		status = false;
@@ -1514,6 +1516,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	switch (PQresultStatus(stmt->results))
 	{
 			int			nfields,
+						tuples_left,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1540,12 +1543,35 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					status = false;
 				else
 				{
-					if (desc->result)
-						PQclear(desc->result);
-					desc->result = stmt->results;
-					clear_result = false;
-					ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
-							 stmt->lineno, ntuples, (const char *) var->pointer);
+					if (append_result && desc->result)
+					{
+						int		act_tuple, col,
+								row = PQntuples(desc->result);
+
+						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
+							for (col = 0; col < nfields; col++)
+							{
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+
+								if (!PQsetvalue(desc->result, row, col,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								{
+									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+									status = false;
+									break;
+								}
+							}
+					}
+					else
+					{
+						if (desc->result)
+							PQclear(desc->result);
+						desc->result = stmt->results;
+						clear_result = false;
+						ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
+								 stmt->lineno, ntuples, (const char *) var->pointer);
+					}
 				}
 				var = var->next;
 			}
@@ -1559,17 +1585,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
+					{
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -1621,17 +1656,26 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda_new;
 					int			i;
 
-					/*
-					 * If we are passed in a previously existing sqlda (chain)
-					 * then free it.
-					 */
-					while (sqlda)
+					if (append_result)
 					{
-						sqlda_new = sqlda->desc_next;
-						free(sqlda);
-						sqlda = sqlda_new;
+						sqlda_last = sqlda;
+						while (sqlda_last && sqlda_last->desc_next)
+							sqlda_last = sqlda_last->desc_next;
+					}
+					else
+					{
+						/*
+						 * If we are passed in a previously existing sqlda (chain)
+						 * then free it.
+						 */
+						while (sqlda)
+						{
+							sqlda_new = sqlda->desc_next;
+							free(sqlda);
+							sqlda = sqlda_new;
+						}
+						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					*_sqlda = sqlda = sqlda_last = sqlda_new = NULL;
 					for (i = start; ntuples; ntuples--, i += direction)
 					{
 						/*
@@ -2036,7 +2080,7 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
 		return false;
 	}
 
-	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true))
+	if (!ecpg_process_output(stmt, 0, PQntuples(stmt->results), LOOP_FORWARD, 0, true, false))
 	{
 		ecpg_do_epilogue(stmt);
 		return false;
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index e09e351..ff12acb 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -180,7 +180,7 @@ bool		ecpg_do_prologue(int, const int, const int, const char *, const bool,
 bool		ecpg_build_params(struct statement *);
 bool		ecpg_autostart_transaction(struct statement * stmt);
 bool		ecpg_execute(struct statement * stmt);
-bool		ecpg_process_output(struct statement *, int, int, int, int, bool);
+bool		ecpg_process_output(struct statement *, int, int, int, int, bool, bool);
 void		ecpg_do_epilogue(struct statement *);
 bool		ecpg_do(const int, const int, const int, const char *, const bool,
 				  const int, const char *, va_list);
22.patchtext/x-patch; name=22.patchDownload
commit e7e276f599885de6c16489280c657961f7793cf6
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 12:48:47 2013 +0100

    ECPG: Use the more descriptive "act_tuple" variable name instead of "i".
    Use the variables declared for the function scope, don't alias them.

diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 8f746ce..199e857 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1517,6 +1517,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 	{
 			int			nfields,
 						tuples_left,
+						act_tuple,
 						act_field;
 
 		case PGRES_TUPLES_OK:
@@ -1545,17 +1546,16 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 				{
 					if (append_result && desc->result)
 					{
-						int		act_tuple, col,
-								row = PQntuples(desc->result);
+						int		row = PQntuples(desc->result);
 
 						for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction, row++)
-							for (col = 0; col < nfields; col++)
+							for (act_field = 0; act_field < nfields; act_field++)
 							{
-								bool	isnull = PQgetisnull(stmt->results, act_tuple, col);
+								bool	isnull = PQgetisnull(stmt->results, act_tuple, act_field);
 
-								if (!PQsetvalue(desc->result, row, col,
-										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, col),
-										isnull ? -1 : PQgetlength(stmt->results, act_tuple, col)))
+								if (!PQsetvalue(desc->result, row, act_field,
+										isnull ? NULL : PQgetvalue(stmt->results, act_tuple, act_field),
+										isnull ? -1 : PQgetlength(stmt->results, act_tuple, act_field)))
 								{
 									ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 									status = false;
@@ -1583,7 +1583,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_compat *sqlda = *_sqlda;
 					struct sqlda_compat *sqlda_last;
 					struct sqlda_compat *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1605,13 +1604,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1642,7 +1641,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_compat_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
@@ -1654,7 +1653,6 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 					struct sqlda_struct *sqlda = *_sqlda;
 					struct sqlda_struct *sqlda_last;
 					struct sqlda_struct *sqlda_new;
-					int			i;
 
 					if (append_result)
 					{
@@ -1676,13 +1674,13 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 						}
 						*_sqlda = sqlda = sqlda_last = NULL;
 					}
-					for (i = start; ntuples; ntuples--, i += direction)
+					for (tuples_left = ntuples, act_tuple = start; tuples_left; tuples_left--, act_tuple += direction)
 					{
 						/*
 						 * Build a new sqlda structure. Note that only
 						 * fetching 1 record is supported
 						 */
-						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
+						sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, act_tuple, stmt->compat);
 
 						if (!sqlda_new)
 						{
@@ -1713,7 +1711,7 @@ ecpg_process_output(struct statement * stmt, int start, int ntuples, int directi
 								*_sqlda = sqlda = sqlda_last = sqlda_new;
 							}
 
-							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, i, stmt->compat);
+							ecpg_set_native_sqlda(stmt->lineno, &sqlda_new, stmt->results, act_tuple, stmt->compat);
 							ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
 									 stmt->lineno, PQnfields(stmt->results));
 						}
23.patch.gzapplication/x-tar; name=23.patch.gzDownload
24.patchtext/x-patch; name=24.patchDownload
commit fa0e771fbf602fad0eb5bfe958ffc498d2e8f8d4
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 13:23:57 2013 +0100

    ECPG: Modify the parameters of ECPGsetcommit() so it takes a bool
    instead of a string with the "on" / "off" values. This way the parser
    does slightly more work and the ECPG runtime does slightly less,
    which means slightly better performance. Also add a check to
    not execute BEGIN if the transaction has already failed. Extend
    the same check in ecpg_do_prologue() and match these two.

diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index bbe44ae..eb2d2be 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -162,7 +162,7 @@ ecpg_finish(struct connection * act)
 }
 
 bool
-ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
+ECPGsetcommit(int lineno, const bool turn_on, const char *connection_name)
 {
 	struct connection *con = ecpg_get_connection(connection_name);
 	PGresult   *results;
@@ -170,10 +170,15 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return (false);
 
-	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
+	ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, turn_on ? "on" : "off", con->name);
 
-	if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
+	if (con->autocommit && !turn_on)
 	{
+		if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
+		{
+			ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+			return false;
+		}
 		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "begin transaction");
@@ -183,7 +188,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 		}
 		con->autocommit = false;
 	}
-	else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
+	else if (!con->autocommit && turn_on)
 	{
 		if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
 		{
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 33c2673..fa45814 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1864,7 +1864,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return (false);
 	}
 
-	if (con->client_side_error)
+	if (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR)
 	{
 		ecpg_do_epilogue(stmt);
 		ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 02f319d..1ac15d5 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -48,7 +48,7 @@ extern		"C"
 
 void		ECPGdebug(int, FILE *);
 bool		ECPGstatus(int, const char *);
-bool		ECPGsetcommit(int, const char *, const char *);
+bool		ECPGsetcommit(int, const bool, const char *);
 bool		ECPGsetconn(int, const char *);
 bool		ECPGconnect(int, int, const char *, const char *, const char *, const char *, int);
 bool		ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...);
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ebc9b16..df85424 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -222,7 +222,7 @@ ECPG: stmtViewStmt rule
 	}
 	| ECPGSetAutocommit
 	{
-		fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+		fprintf(yyout, "{ ECPGsetcommit(__LINE__, %d, %s);", (strcmp($1, "on") == 0), connection ? connection : "NULL");
 		whenever_action(2);
 		free($1);
 	}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index c139e41..5abbf4f 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -61,7 +61,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 32 "num_test.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);
+	{ ECPGsetcommit(__LINE__, 0, NULL);
 #line 34 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-array.c b/src/interfaces/ecpg/test/expected/sql-array.c
index f770c09..befa89f 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.c
+++ b/src/interfaces/ecpg/test/expected/sql-array.c
@@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 27 "array.pgc"
 
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 29 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-func.c b/src/interfaces/ecpg/test/expected/sql-func.c
index 5d524b8..823c5b4 100644
--- a/src/interfaces/ecpg/test/expected/sql-func.c
+++ b/src/interfaces/ecpg/test/expected/sql-func.c
@@ -35,7 +35,7 @@ int main() {
 #line 11 "func.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 13 "func.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.c b/src/interfaces/ecpg/test/expected/sql-indicators.c
index 22aacc1..168ccd4 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.c
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.c
@@ -111,7 +111,7 @@ int main()
 	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
 #line 15 "indicators.pgc"
 
-	{ ECPGsetcommit(__LINE__, "off", NULL);}
+	{ ECPGsetcommit(__LINE__, 0, NULL);}
 #line 16 "indicators.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-parser.c b/src/interfaces/ecpg/test/expected/sql-parser.c
index 616135d..1d6c0d3 100644
--- a/src/interfaces/ecpg/test/expected/sql-parser.c
+++ b/src/interfaces/ecpg/test/expected/sql-parser.c
@@ -38,7 +38,7 @@ int main() {
 #line 14 "parser.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "parser.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 6c4d84f..bfb75ca 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -41,7 +41,7 @@ int main() {
 #line 14 "quote.pgc"
 
 
-  { ECPGsetcommit(__LINE__, "on", NULL);}
+  { ECPGsetcommit(__LINE__, 1, NULL);}
 #line 16 "quote.pgc"
 
   /* exec sql whenever sql_warning  sqlprint ; */
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 199a77e..c74ea26 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "alloc.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index cd28c85..3a559ce 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -153,7 +153,7 @@ static void* fn(void* arg)
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 47 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -210,7 +210,7 @@ int main ()
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 69 "prep.pgc"
 
-	{ ECPGsetcommit(__LINE__, "on", NULL);
+	{ ECPGsetcommit(__LINE__, 1, NULL);
 #line 70 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
25.patch.gzapplication/x-tar; name=25.patch.gzDownload
In reply to: Boszormenyi Zoltan (#98)
6 attachment(s)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

Best regards,
Zolt�n B�sz�rm�nyi

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
Gr�hrm�hlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

Attachments:

28.patch.gzapplication/x-tar; name=28.patch.gzDownload
29.patch.gzapplication/x-tar; name=29.patch.gzDownload
30.patchtext/x-patch; name=30.patchDownload
commit 0640bcefe4452e04417c61af3cbb70ccadf12554
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Fri Dec 6 13:49:32 2013 +0100

    ECPG: During FETCH ALL, temporarily use FETCHALL_MULTIPLIER times
    the current readahead window size. FETCHALL_MULTIPLIER == 1000.
    No change in regression tests.

diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
index da83c92..7e231d7 100644
--- a/src/interfaces/ecpg/ecpglib/cursor.c
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -1517,6 +1517,7 @@ ecpg_cursor_fetch(struct statement *stmt, struct cursor_descriptor *cur,
 	long		ntuples;
 	int		step;
 	int64		prev_pos, next_pos, start_idx, var_index;
+	int64		old_readahead;
 
 	switch (direction)
 	{
@@ -1688,6 +1689,10 @@ abs_rel:
 			goto abs_rel;
 		}
 
+		old_readahead = cur->readahead;
+		if (fetchall)
+			cur->readahead *= FETCHALL_MULTIPLIER;
+
 		/*
 		 * The direction is backward if FETCH BACKWARD ALL
 		 * or the amount to fetch is negative.
@@ -1771,6 +1776,8 @@ abs_rel:
 
 		sqlca->sqlerrd[2] = (var_index <= LONG_MAX ? var_index : 0);
 
+		cur->readahead = old_readahead;
+
 		if (var_index == 0)
 		{
 			ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 612412f..de0f3b8 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -32,6 +32,7 @@ enum ARRAY_TYPE
 #define LOOP_FORWARD	(1)
 #define LOOP_BACKWARD	(-1)
 #define MAX_CACHE_MISS	(3)
+#define FETCHALL_MULTIPLIER	(1000)
 
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
26.patch.gzapplication/x-tar; name=26.patch.gzDownload
���R26.patch�[�R�H��_E���@��
�!�l�%�3����\��6�����p<����yn`o`n�<���R��	9�5��RbK�W������L�a&�������^G��{��}?�����%wz/v_��m���E�$����@���������N��x��J����������b$�L�]/;n�y�<B�MCq&}�'�;����]�����V���5X!��>'A �<UI*R��=~�1�������H*%�E��"����BgB���2���P�y�G�P3)���7�E��ea+�+�F/����Y�@
D)�s1���2�P��S~Hx�$�,{�O�(�Faf��x#���i�����?��)~���<q389{?��t�g*��������T*Eo�����L�^(��d��J2):�B��|,�b�-IcI�RRu�I���t���{
��i�e2�6A8�Ng��-0��R��L�-��&]�$Fkn4�8���h{w{���n��W;c����6:��Z��V������������=����.�2���T���B�^�~��H�!Rl�����z�
�h����2�{�:�v��'y��@�!�����Q8J�t�������G<7K��Q$�l$�{�{8����3������X��$���^����.��4������wLP�I$��"���i��QFn��t=�?�"�"�����L�j�>z����'���|��<�2�l��^|��6
c)�	�!�J���RJ�����04jU:�B?���CD�L������~	���#��t��}A�
y:1g�mM�Z2����g�X�p}vr7��lp1��B�b$���
�P0�����@��ps3��WoK���y�e[�o�-�8LY�������9�Z��}��$#��e3>	���0��5���owMn���T99��#�p���v=q$c93��jR��cd�B�J{�[�a��b�����}�����9SKf�=D*������?�����
N/Nn�[�B��� ���r��:I��s�x����6Ih*^ru=�\��aLt
�[%��[Z�V)P��?��1Y�Er��0��uC�J����*������m8���d&������N���A��x{s���0���m�������������H�z�<=���{*R���+��;)z���,�:�pp���8�
BL�lBTx�J���Ep28u� �E�j����a��0GEV��zJj�Q�?�!��mC�h�v�m"#��s��Od�r���J���3�
��R���j�U��-��X����T�ap����A�+��c����������~���Qd���O6��&�L"�iJ�	D�0���F4�{%sr,?��_�kw�k9�tjX]I.<��t��;��
N����BS�gu{G�{���m����S�~�I�MOx���oG�oIRR��^o��R���v��j�:�\\\���g��������1]���_k���T�QK��
U>��C����1A�f��K-��RG�������}7�c-�P�
g��� ��_������/o���w�(a������pvuq����`���U�t~�N������N|��.���-���nC��
v�
�)��bI��+�����s��H����D�P�a]F�{;�~�b��~{����Z3ej�B��dMm;�z�C��@��]]������G%���Y's��a��JS�Tw��F���-���'�K;�E7�������a�B�m+�����M"4~5���Hh)��c��W���c�2�'���#u]U���T[9�*L���L@M���L�������t�si�c���)�M�T�4�!�(�!�
�$m�����}����
��sJ3���<�!j]�������]bn�D����:��ZC���W���2hZ+���z%NM���)X��FV�*�\�A��\#��p�Nb�R_D9���G���A	�I*HV������h�n��TVf�('7y[7u���r����1������
9Zh����N�.�n+��n���e����B�����V
T3�2������h��!�b��_H9[��j
�T>���~���4m�X1���x������v�w�^���~+�[qY���7����=�z���Oo��g$Q��Ht9���
����5h�u����&1��Qu�2�KJv@�`$�{�7��y4TGy�B�^�h�E.��k���&����3�[�����A����D���<lCm�l�33�i��)q;���	��0	��ez
_h��%�*KE�Gy�d�,0k[Y_eB�(s(��sT4���<����zi�s^2�Al�����N���6c�
J�#a.	M��%�3��6ZV����i����HX/0���l}X����=$!A:0��5|B�A �h!�{/��@�e��q�L��I��r��s���C���u�7��s+6mBF~���'���,��\�i��#�\����X2&�m�����B�����������q�W�/���S�����w$��7����� >&d����l�.eu���-����VdI�`H�2%cOQSmL��'�\"V��&�m��-Tw�]��F��Oy���/0���aH������0^����d<X��M6�f�"v��9C�I���`�t�B�z*��hMsE`�p���(�B�=xk	)��T��[�T��*
'�5��9����p
��'R7y�����(���\��dI�
c�K����IY ���l~��X�e��D�Z-B��C�g�xO9>4N�����L���6%k��a�=������
����������.4���2X�u��@hIHOc�O�c��B4�>\i:�5Z�MD�\�1^�C�]*��A��l�,�Q�LE����,I���F�.0��{����e@�E.�������,[S�S)%�.y��HB\&f��`���	iC�����r��1���H���h�H��.��v�h����3n9�{��EQ�����6����$��0;K��f�F�@<�>�J�7���F=g,�&_%x��}�$X�(X��"���8��:��c�#S��2*��kt6]���U%J2�p�9��-�s���KH3�No��^u/mE���^�>o�V����������SF�'QpP�����q"{��������Rk�r��
�T���}9#������0N����\�L���o����?����c4��}$�Kc��C�i	�~��m(��Y2�T���g�a��"��Q���������,�/�"�a�=MCj~��b��6��G�D��D���fi������Ep�_n/�}����Io�Q�k�PW�>�b2�M�m}��B'�����)�t?�Wh����W�����o��Wn�w���6�{��,�z�m���S�42�')U|�F|p�B�i6DOe���e��\�t�M�%:#��.��T��B�8��$����xj�~�X�R��s�s����7����U��M��m�gv -6��nESr���CV�
�plSQ��^����q$�K�����B�1(%R;k����Aq��'[�1������0(,�d��W1W��Jk��%���,��n�M��r�n�Z&��t�jDC
�"�%_�M����
���OA�i�]�h��M^��u'T�)k)�~�z�\�"9�8*�=>����������fJ;��.�G�`��P6���/6����2j �i�QJ���9��-f6cA������iU�n[�������\9��|T�I�#�eZ��g��L�u�%)���.b��-�1S��V����5���vq)�/����#f���U]�[�"9�h!�|p�CN\�3]�&�P
#O!��{�����8���<pc��
�>����v�f���!(����%V���cM���"`��&;X6��I3�,'����s��X5��������������	�%Go�m=&���X��zJ?������c*��)<��s]�.�S�o�>�z��������� FS�U*XUk���(%={K
wj `�
��qD��
u��#\*"\��!�|�Y����<���>+��a��o��H,a1�p�1TZ���tT+�> �F*h�,�4> �ST7��>��@�%Hit&s��6'��;���a�:��,aZ{��N�=3�0����h�M�^�eVQm�����% ���-L��A N�ZE1�SJN�+�6A�18���
�B~@6W���4����������R���lL��7�q��&������i2��u[�
��T��p@��SH�Lr����LC��=R53���Y���
;�D�����0�4G���qHQ��#���R�����hkR����l����:{�r5�e��(���y��c������N��s/f����l�S�������Z��������<������Q>�,�G�9�:�&m��<q����#��5��*�T��L�0���fpMc������������>_�B�`5b(�Nu,*Y�hJ��a�)�,�K��S,)�a�J(Fj=��+�kC���"/�_��Jd��!�)E�H�5�a���@:�s5�y��a`��=�e8�-�c <{��11f��$�QH"�C���QJ��I?��o���%�~X�m�/���1���rwOGM	T�fA�p	x�9�OnZ@���0���*_B���W�$|@�j�!����3q����l�,�$���
���,�OE��4��W��ZxNU6���et
�R�>���\���s0�H�g���n��{�&}���f�r���{������������ ��<��=���I(s-��
��Q��S������R����+�r����}�{^�z4�I����_,�c*/������m��?���z>������}�r�3!�|��m��6AS�\+����rYgC�)��w~G��F�Y��$B"k��|��
�C^��X`D����/���\��$&�!mV
��6��S���U6�������q�.bD����Q|�ka��]�\'+$6_������aP�m��X��]��C[u�6H�?L����$�I��'
M,Y�2?D�5�k����R�]��gL�����"�mFpHs
atG'"�B%����F�E�VHRjL�������b�9)�6�9���^{_�����1��!��"k�'q��6�{����s����s c�3�e����OyR�yOk��f(`c:�P�5)HI��0���P���/ ���:u����*�%b�����.��o������yp�3b)�H|��N���w��@��g�w8��K2^{O[�
��FZcH��~j&4��Be���`{mmXpe����r#gs]��V����+`qvY�H*��m�������x���]�Wk��""�9�n?U��XVhK���m�H��#.��,��&G�������8*uQ��E
wyk����cA��i2.���{� ����2_G�������W�j�r�5���(��c�A�s<��t.����}�.2�=m��W;����	�%t��3.k�T��
J����YBTH�g���h�0�����t��}i�/Z�W���;F�U��W�����U�p���$f������d?FGx��P������a�������yI�rk��v{�����9jg���XW�T�kG�|����L�8�z|�N����41C�=�I����M�fr�A!gw������A1��,*).�����AQ�����%TE�(5x]2�����z\���y�{S�/�f���
�"��.G��J�)���L���r]����u�Z�V0��.\��j����m:��T4����:�p������,��s
��y�v�Ix�c-y������y�DQ�lq�A����G���:������c��_�xrq~6�yf.��]�;�<y?h�e��C:C�8nn���I��!Z��vJ�3B��M��������m�X��g�W`<M#��,R��L����;n�q������%K��V�\QN������`#�M$P����$��rv���UX�������/��wt�!����Y��x
��`��uhX��<��+��X�-\����8n���)���
��GST�d����"���B�&�Na��6"V��J�U]"�*I�8���*P$-�H����@4Up���	�yM�
O-��
M�����2h\��L���d���!��"Pj,.I_���6>�]���)��*����y���� ����v���YC��5�'A�#�`���������3j@�I%�B���
�*���mY ��ry/�P#a����y���Z`(��-�oi��>��H���I�����K��u����
�8��9;|{t����K���o���b��(x_�g��W�=a���T�R�R|��pY����vm�v�|Ep8����Me���J�������D��Yy���@C"���Ux~�w��s����""������\gXU�=��"���7�zT(PTy�h )��o�Eo4Bl��V9�����1�45��i@�YX"��WB�reV����s��m.��d����N��B��>�$c��D��wL�$��S�.�m%�W%�U��z8�d��a�S$EN@u9zA�` ��K\�����u��F�����q�vF��$�� vV���;����]
/�����Ab\Dx��AP'A]L�����w��0	�������\�!@�������N�djo�	Yb��C,�t�I=~o@*�
q��N�$X�g�pO|��+B�k�	�����.v�*&{�������08���RC�
+�Wg�w�g?�-�<oUl����U2"X�hs�b��/
P�[Q����N[��*����0n}�I�$�d��<.T�bq�V�^��'Q��	T�z�*_�,�T��AU^�s��)NA+��$��v�$�B�[���k��m����{���~����mrn��K�b;���]S9kp�V<�TC^W_��U�����.s��8�^s����x��>��K�	��'��b����CI	�1&M+^��a�%wk+O<�>����'����#0� �
�#�L���F�p�{?����lk���?���x���e!�����K���?�x��)��z���j����_`u�%c]���x��OY8'����/�������C�;a�?g1G�Tl��\��nI����8U����Ov�����3��n�SB��C��[[WC�c�OZ�2��up��k<�N��QT������	o	�[(�k��y|���q������x,�I��v�1#pYo�`�X��s�n[��'u��Gq|�������U���3������^�+�{@����
�����X��G�,Q��K�c7l��)�b(�O�#�K�jS�h�i�5$M��+��um9S�}��*yV�\�O?	4O�	��'��i ����|Kle�o�zaZ�2.�F�����'�o��������>����������7������~y�B�s��B�<�]��{�@�DM�kBs"u��YV�c�~��U,8�<j��I���W�������)u�^�n�����p��k��u�d�n���u�m
�J��1�s��|I�RK&&5DH	-��"����9�<]�p�8Md_`3MR�v��=���\��TLx�<j��
��2	���
�������\��"����� S����N��*��KO6��	����3�+���g��g������!Ua��l;��^�&eJ����
����F�`���*0�;1�^�A�Q��hd��+Cc�w����l6%P���s�!x��SJ'
�A����*J�!	C�*�d�%�`�����$�����Q��3�-��L"��U��������1Qy,I["W�7��%������'&y�����!a��4:��h��m�����4�K���U�^�j���0U�7`(YQIez��.��O�O�yMa�^)UW��������d��f&����"���
g$oGPh�����Rr�6�����B�'����D������pg�.�~�siNp����b9��m�x�D�,�k��K;�'[M����Uatq��yZ6O`R��������Owj�rw������t��� �+UO�����w����)���RF��7�G���d�$���������'�I������&��a���=Od���0&Ro ����$�e�����m��WOY�fR�f3��rf�gf�2���g(
����-����@���v��UKP���>{{�����?�� ���yE�3��ydEgz���j����[j<qGs��f4�AJ_HZCsH�
�=%j���H�V������.��Q�&|jT����?K�\?��'�����=�����L�?���<*B�����SsI^;z�+�,uY�$��������c����B�H����cMrl��QY�����$�Tbr��GS�\�YZy^�_C��r
���������T�l�J��i+���(�xy�7��v6��^N��K�pRMI��"��>@i]������s'`��|����;O;3:{��~���M���e�������dW^��-���6+xzp�n������+�M����T��D�/_as����~��/���EeG*��6��B������E�j����$��w��S����#�.h������@���}b����7�{�����t�R%���J,���������~���I��Mj�	�.R���l��!.�V�f$�<�h[��%']��
�!�_B1��b�:�^[N�>se�+�>��t��.\qu�|i/����M�B%��scCbG*.�zj�4���"}7���fg�
9;���%'���v'����I�?U�� �.i�^����D�F�A�p{�=|@i1�^Ua��_�W$�
Rn��w�,��]�yEy
�E=��e�t��w���t&�J����L�B�����M�
]J���$��x����zex�����7�� �]X���r��8���B��R�p�!����������<�o�Fg'"��V_��
L�,������p�|��;x;
�r�S��
�.��v�8��1U$]S�fI�%�{���w=�vF�PZO������}�'��LEC��IH���e���A4���I�[4|��C��%b��O��^�)b�,)~M�V|(K9�$ �|�n)D�Zm�������f2�\
;C\�$�zO�-F��j|��^�t1���6/��I-9��p���'XOS*g�x�|f3Ft��9AC'�t3�U��h8>��][��"i�Ed�E���1��FEYP�|���DG�6[[��
yy%��%2NVEY>+jP���}��U��#�c=�G1�m[�:�"C�a3��b
@h�a�t�'�V?u_x7J>3}���#�`�M.?����`�J�Z�������0=��OW�-���a�r�y���Ub"lm)��_����"�yf~���*G�b���<j5��F�7�=2��D���6�F����G<���$�Q�E7�a���������$D��a�� �����\�p-��n��y���_o�iq��_g<s��`_���~OF�U��O������l���"����
O�l�6���Ie��s��A���p#�������	��E4-	��v�8�D����yAE9����� a��^������OT��:		���y|����/���4��X����R���3y�Lp���y��$,4���K`�8$�:X�n�;_��%����K�B���~.��H�X���z
�
�z��_������Oy�G
�-�����D4�6:AG�*��z<#��N�	f�8K�;)Wlq�Kn�4�0f#����G�����Ngz�'�j��v��X�/��}F��F�*^���&�x�`"�>+bt�0>C���$"�&n��KY�
���5���m���1��BM��Mo���Y��9�O0[j����S�e�����R����A�|o�w���6�����)��W���cW�`]��gRH6"r�p���N���V���v�4�wV	7��e&8���"�[�L�T�������@�c�O
U��"�O�1KlU2!&��l���q��������;>�����������C������%��q�SzE������`_^
�^V�W������a^*
���D�+*t����NR�zW��NV��~��o��\ A���;yD�[����x_�w5v��U�S�53*
�W��8��B�Rc2I�lI�L��t�I��~ A�WpK�����jPbq��t?)�2�-_���)y$���;uQ��'�_RG�+���dajE���r�G���H�tI�k��;�.�#�!G�v�s*)`}~�p��������d�����@�%� �k�v	vK��U���6vD������cP�C��D_��^FW��u"�4�92��L=�`K���;�5/M�xTZ�H>�0����h���(�[�3��o�0�+�.�z
!����\#�����D"���/���P�����0�q�76D�_�K����,c��)b������Q
ITK�TP�
�'�*�$ �������`�E���i���������5S�����=_�`���p���z���&�U���	s�F���/�x,Zt"�]�(�.�p<�3p�"���Z��q�#�r��.1�����d�pS���s��S��g���w�Zl^�k�_!�i+7�g;\{~��.t��oE���jJ����ia�Ai�����)��4�
����u�\����-z��cn��9���8��E"G�xA����]Iz�l3�{��D���AQ�;�O1��^�*D������53-�K��W7�z;IVO�Z�r+����T���aE0,���������a<SF[al�/~i���b�])��Cv�:�����LB��cyq!#����A�}CL��Y\���1���������;����6�G���G��1��"��IGY	�*C5K����eX	�+�J�;�r�!z=DU��Q�C���7�ePt��Y�X�E9��@��$�T8TPR_�!7�����E�D�:fd����%�:.�z&m�:����[e{6�/���Iw�a��=�W�;��:�[W��M����)�Y���SQ����I��!�jXjmMv�2�$�R�Q���b�XM�Q)D��vhj���A	����@1����`U��n$� ��.�M�q�������d�D�S��C�[���R�$������e�N���V��S`�I�[���H#�s~��������P����-������N�'M���_��������/�������^�0���r�|�����.��P���D���^[x�E#�~<"xE�Cz=����St��aYaZ���X��hH���Z��������+j~Nh%��l�C5P�b���������������Y�2!�����Y�mH���>�������qeeR��v�m��J��/��!'�A���O�D��;|�)�y�A�L��MZ<���.vj!>�^gS��-Y3�x�++s�����F�4���X��8t�'��58�G0��/2E6�k����=2���T�����={���$_�vv"���=�����(�c'HC���tU�'G����>���������(_��u���=�������!x���tLvK�<a!��$Gu��\N��Tl��<Z��G��Z��N A~�!��O��JU���4�y	����P����|������?��e��R��?��6~�"����<;�LAhr��c������i!HL*�+��)-���q+6yc0).���$$���������Q&��E��*�1������ QR7<���n�p�������*$�^��G�Y�x����n�"g���o�R�2HS�n]��Bp�~"?aF"����N�a�C�����@��"��5��i�9*��/f"
��@=A�%|
g�A��f����/HD��p�)��t�;Y`�wOc4��8�,�D|��u�H��7G>�b���G���n�o=)��c����'x��O ��r�(������>����?�{�O0�����WxY��(*7���*f��(�aw+Y���eT�����a{K���c�:%����(3�<]�����i��~�qn���t��_e�=<
�������;*��^��BKf�c�)1u�����AJ�I��Z����V���T�HZ�wDOl}���y�L\��@G4|=���~�{���C�u��r��y@=��^����d|������0��r~0��@��R1;T��L1+D�a.i;+Q5<�TX�����Gexa�$���b5BnM������Fx�&�d��K�������m����K��`T^@�8���=�=eJ��
�9b�.��W�|���8J=�g.R�����
��1���M���
B�����r�W�9BY��|32�2�]p�(�����}� �!�J�!����J�I�2?�8�M�_�kO���� x�R�t��Y���v_��Z��D+�R����X�����x��F^����q���P���WdS��kU��W�="5F����
�'���@���O�
yX� �?o���=�q�$^�=���kjJ!�yU�AD�;�Nr����|�Y��V��@��>�O�����*����,I&?5��;vr8#�R������+	{=�	��Z�O��d�'5�Z
k�6g<����R���V*9���Z��%X������&a���'�v^I#\����;������,��������@:�NHR��&4��7h5�����-J�#�nU�1l\��l�;QQ+��)�Qo��'8��W���n�� �Kq
1�"��5�1��R9I(dW��eJ������3��{�hP ����������K(���rH���f@DF�:����\���A���3N���i*,��J7T�������Y�4���c�b���.,��0�)S�J;��3������m4Dt�Z��e7zz����BN�������j�pq��|�����`3�y������Dv2�dQDTD�f"�cqQ>�y�C�~�@����|�E��OO�� zi��U`&��&�*���8[��8U@ZF��;�W��`����a�T����s3�+V��h^e
�o'S���kn7�����������x'-��*���V�?}�\��������N�;nc�9�;)�-��g�'�QJg3��H��}��53�x�h<����`�
x��^b�u���Eb7����K<n��<w�&����/*|�#� )�����N0����_��g^3�}(����#��KL�{�Z��:���DfX�rdf����{M���mo��{Kw[��8��1�w!,������!���Wt�j<����84>���+'n�I=�u��k�������
h���
b��t*!���B�|#�@��W
��cX������3�!xK���p��HR.)�7��������+9B��9����#Dd|�Ff�5��F��\+�C#WL�����]�V{���u���|�w�/��ky���=�L|V��������� ����n�k">�`�������OzUD������&���e�{H�wl�iL�ix6��M������
�7 �����1����>������,�!�|5�����]J������J7�R0�/6�T���zpl�p\���^���h@�����[�P��w��������vm�����96'��(��w���`cg'y��w��c��� {I����'�e����F��+/(G��������G�^����]w1�%���!F�]X��tr�K���y�RO���ht1pF�Fc8nY�vY�f��~R���A{����"��mY���a�a�%__�[���*4��S"Y}O����{0�^��'�G��V��������:+�jg��<�J����@�M0����+������H��y�{v5���:�C~`QH$��b����%�~�3~���!���������`�
������q�|]V�y�����@�fT���S��m�4���sU���a��� 2�H��"y^�S!������c��kw������[����EK	hQ�j�:�.f�L��}����s�������O>��l��d6�����%��l'6����xo0�����1���$��������|��g�?�A���9h���=����z�j"KN��/�Im������*�2�3x������S��B_�b�M����k�j�-���wR���W�D~�]-��������;P~�7Y�C���'�5��|��#P�nj;��@;����9p���\2�<��B(�X�dh����Q(�����zU<]��#^�~�fw
����v��l��T�V���Q���[X�S�|�"
��BJF^/
�Do~sG��7���oN�����������Ry�`�����S7%��E��r(U`��IN����!}�&�K�
gb��^���D����l$��o�C�nxE���O �m<'�������go����n����������D�>���������O������D�����+y:���x����g�?��x����O��Bb&���c�H0�����[������M���huE�xT�!�N=�� 	���Y�U�*��qH� ���4������JiJ�1~>����v�����e_����$����@��,"��@�����t[��@�
���U�����[rn��S�9oUZUj��}t��H$�i2���"Y~��y*lH�3V���&�V�&@�SX*=�~{S���g�0P�l�]a�B?������f���3���]�CO��$EQ�������m�g��V��������kC:&�"��Z?��a��������C����5PU^���Y`�����taI���&�fw���?��ll�N�l�]a�����.�����`i`TX�z������w����;������������?�����f��U�
��C����t���c8��m�	����
�a�#��;|����>�g��O���Ua���l����6�����vT����<f��i6�����|S������Go#j�����L���)�a�1��K�c{�h���Vg�\�1�-E��`Y��n�f5������l?���]����,<�����U�7��s\I����T>�;=�w��E���7������P�6�?�I�B�/�/��"F"��P�F-�8����6��3}V�����i��h�-n�~���F�xxa��t����N�1�����ZM]�E�XD��m���K���=������_�
�>�^�F������������A����F��s6t��|���?������K����
9�m���FS�w��F\����������������+����E�>���8��3V��_��k�h��4P#���[�X8����o�p�� n�}���D��A�#��}p�����H�X#Hj�� h�3�h��7���0��x��9��G�!��z��}~7��!��>o� ������x<�Jrc��c��h4/Z�q7�R��j
�K��K�]�.�����r"2aO�"w��K����a���|c���P�]��������|P^S?��{
����tuj�� ����u8s��2|�V%=���eX�N��;�C,A�(t��/����C��1'��0���a�C�7�`������i�:I������V�A�!��v��
8���~��E(����7gAf���'p�<�{�������/��7��o��U�'=���l��u�Y�`���-���	��B�����z��`�x&�����\,�1�2z%�IR	P/��n���/t�����7��&q��5��J)�*u�*I�1��q!vh[��b�B8��|OD\�q@j+����SN��
�g�����b���v��o�!�Fr(���rj[���5�K��EK~�f;f4ZB�x�YE�!������7��\yJ\���L����9���$���\T�5���� `N����������J�i-x�&��`O{�d���nh������������Z1��l�Z6�;k[1����L�C����z #��2�nkP�:�o��e���� o��_�g��� ��,+�*��!$z�b�7S�48�m:,"j~|��	d�VhK�L�t�]�%�(C��BL�R��)�t���vM^h/�md7,�o	���P��m��$�@��R���D��+���l�P���|�l��X�C�*�Z�J|�"=�j���.�>������ �IF�{��$XXs�zi������!b����G�N���^OV�c�=~^�����b^��j^��h��v�F���4�ECZo�C����#g�g��t(���x�����^�}���n�)�.����>�U�u���(���"�z��0�; }X�g����8������5i�9��"F�B|o�����hwZ��N�����$A�1����n�s�����SG�����p���(/��3�;�l%�t�X/`o��t�_3��}�m�r��d��%��ivH0z����W��F�#��pI��q�X4�Ye��!z{xr�����'���@x����y�+���*A)��9:�x��������,���K�.���'��5��0e��4�s5�<�/^�b���=�ljm#��_�gs� �/�5��-��,�/��W;:��A�"Zk���b�}�Q�0�������%@�L���[X*�I@*����8�����E,i���`��X�6�]�KPW�9_'K��2�e���)�H8
����wj�%O>������9���0�3��g7��z>��wah�)(���o�Rm]��sL����������?��'��E-@��l�B��]��4������'�7�Q\C*�m����I�^jo�4��!�`^`6R�Ve���2-\u9�����Nh[����~
3u�	�b���CEx�?���x��add/�l8#�.�xf�48���"AC�?]�����mbH���� �7(���O^�,��������Gg�I��J������<O2|�R��_���=���>���~���t���$���d*�5�:�������V�� �*���z+M�V{$h�����/��lu�N~#��F�����D�����������S"�hI�k�6k�����k�����~��bA����a��TW:�t8����$���%����X����h
��� %����+M�����&;����?��/?8������~9|{���������
�HO���?A�����������#�"�p$_`!H��8~szp������?xG�|<}��v�������wo��$���v��_�}=98�x���-���L�2y����QDCH�(��������
���:��dc&���?9|w��g���!���������i|1��w"���r�h���V��\8����Eq�XRg��������>c�J �M��U3�����<�����r�D?���P��q������!�]�|���}qX�@a����%�d^4�B	���"����-.��--�i*����1(�euIP
|zA):gO����� ,%:.%[`J���D�)�bS�)�������hP���~��[�D�*�CU��8XE{8C�h���i��P ��w��&F��X�XW�J�]p��e�XQh���)U�	7ou�$q����Bc���-��f��-	x`�e|E��DO���j�{�IB���{�Y�NL�	�s��
K�@�*
	�����k�����U1�������^�mv�Q���y_��n
�_
9H���i}����gy^B������l>wU�����=��0���2H�E���R-�C��#�9�����AOB���%�P����W2\}���x2�Q�{����?�=��#���N$v�2��F��v�x����^�	��S�@�I�|\Nz���f�aw�v�g�50�����\��L}���)��K<e���SOu�9;B�b�|��*�#Xa�Kd�_��$�����A�Z�����/s�z8�f�T�-��y�=���{��8N?����%[ ���&��-���:�?`����4!
���3�+H���|�t����ry�9��QC�?k� ��y�����+�f�/w�K�����^}���sH�E������O�k"�x��B}�jr��?��/����y�o5��5�u���������?@��f�P�=H��S�������\1�eM�-�����Y$9ly��3��&��T5�QaEB���VdS�E��7�=i����^y#����y#*�r�Sd�'���eO��:��x����qL�jL0���!Z��2����.	�NZV=�o��ld>U�W�4�?����]m�S���q=����!_�m��WC�
���]A~�=1���Y)ly1�9m����s0�7G�a�����VsNQ�f�h����5�C@/���+g�y�[��W,����-b�L+�'>�
�B��
��p��A�i���M�1����I��Zx:�fX��W����?��6�$�Qw��I��{5%�+ez�0�������]������O�w�J��H���W�B+INk~�p!���D���J�`X�`����?�f�`/fD�Lv�S���.�����.��������/��"�<������f	L����JQ��'���u[�Q2AQ[$;��lb��u�Y�7���p���=�����X���I4�Z2���0'����~L��g^�-;2��Ap�7����*d� 9I�6��W�W{�����9�<��?����<��l[�m&{�����d������tj``�`!D�B��~z����;~w U�G�%��ee:���W����LEbb ��V���w�4�v�B�9�6;)�5��XA�Hs����CB��Q�"i2��M�s�m�-�F�����d�rR\g���t�u��@@*���+g|;�r"�r�V�	�����c'I��T�*�V��� ��.aO����p�<��������;w9�������L{}1���8�^��	�~�J�B^�$���M}���,��rt�x"�0������[BC{�:�XB��YHR�\Le~�W�T9;�����u��xi�&���zp�9Z�F�:o�[������j�W���!�����
H
���-e/Q�J��Q����i�	��U�]��&e��j~�t=4!t����
�m\�������61���^��
��!��(#xKO�/�u`,����Z%b��vi�������/����sU�������&�]�`��*�0����;8><�������W�hZMw�����h����-�G2���r5���d�)�<a'���p�
�['�-7�0C�kD�Z4�M)��N��d�\6_,2�5�-D���V�WU]�A`%!�E����U�e�&��z����
x�D�����2�"��5bY��F�;�����UVqM���_�_�:k�����v����DQ���U���Co� r�Z!��s��8Q1�#���~�v�p�H7�g��6���L�L�10�>�%1�@O����8+�����k;�����%�dI7������Y.aF���%�(q$��B/�E/_a��4H?S�R��y�8���*��$8`Q�k"�2��*y7��m���0��Kp���y}6�����l2�&c�����BG��^��J���N��kg4���o�R�����<�B��X$�DVC�/�&�[�t]�Vm�n�%CQ��LD���8������ �$��6�a>����'D@�9�7h�B����D��N���yV���a�d������M�m%�mZ��P��������d�G1�����js��Ns-���$K6�(�����mS����]!�#����iKR���.������l���e>���x�f!84�,�v�r�L��M�2@5�f��psn�7����R"�]C7����5�j�����w��q�18o�:��+Nl��R��E�x�&G�����03�y�B������&�-.�k��p������K���BfWYL�3~��?��5b:]�v��
�-m�6q|3h2Co,k
`��L9�B�v��^�^}�����6�����I1��f�Ok����3�=]/7���aV��A?�bBv�!I�@��V���w�S;h�q�2�2��j]DaFE�"rJ5�WbJF�|��\`%�=X�gW4�V�)W��~��d�=u�N���Wp� "5x�`+�4W�<KP�.{�YF�$�>��BU��y0�n�gm�YE��:���2B�3y�xL���5���������3�Mm���"�"�#a�;/��t��0�����e~�
��c�s^�{��6��f''���"�����+q[����i��"U���{$E�XVH�L��Y���{�I��},I�_l����U����~�X�����:�x4+i��&�,T=<w���%dj��5��K�&�����1VW�Z]����=����+������1�{������~�x�h��9��?G���e��c;��5j9���u�)|���Q}����V���nF����A���'�uOV�C�f�Qt�9r�sZ�{��]J��{d&GN�39�{��}*����L�!2�frB�����,v�I�'�a�L�g#�L��\�l '�x?H�m�c3��(�r���I��ElQ�m��wl�T����s������m���FM�Vz�4��vj�8s������S��qgMA�d@�d�Ia�;-���"�{��,�@��94��n���p4�l��5���$GA��Z�@Be�^��,RJ�<F3)�\V|mE�c7�m�ftw~�Nn���V.b�unQ2m%'���_"g���%�{�����N��\u�D��Y�KB�����Y�.IDB?��~	�p����s'm�]I��k�:=����+l���/sc���'���~��������	w�����p��C�N~�n��:�����,m�,���Y�eV����
�>MAr�N�����W��X9c�VRx�#����Ks�tW$�)FHC�2����u�{��K�����Fl���!��*��U
d{� D��w
������^�Xk����x���SA�(��m���{m���"��+�l�L�����w��N?�n����������gLT0�]�/�6�S&+�+�[�:N�o�
���9��I�C�N��@�L�4i��&SkXz^���O�?�?@��_���)~�	H<��N�����M~B�&�eI������wlG���$����i;2�n1�3�� �2[��$���H�tLnQ,g�U+e��4WwTp�uE��v�)Mr���m'7�D�g4_�CP1�E&�� d�)?�������G����{S�y�OK3���y�1�5��I.�\�pZ/U��Hh��~��.l�i|�-�pE�b�?�����'���&����Q�z1��L��cT��&��;��������H�)�5���f��[����,+2I���g7�l8�}Xd�BYn�I���d(C6�(8�{��M�5,?gf��������/�q����k�p��U�^�>�O��``d]�+=C�(S�W&d�rq���j�G�F�|t>H�@Ti2)�T*�iY5����~�����qeIY��sb2z�F.�������\�L��c�h���!%R���6���L��t# ���2�����<�`�YIk��Dhug��Y�bt^�S�Ff%������liW��/�^�K����JJ���6%|�G��#�hf��gk���ch��@t��
t������
�f������A
P�������8n��#S�?Z(d���b��u�K'�@���V�7Jx��i<(���fNtp3!���Z��f�bF�m�)��@�'3��[��if�Pc�I�4�fs<�_+gw�|�{*�%X�����f5�]����`��~1����S��Pe�\.���|F�X6EO��������0-�cZ}y� �z��1B���
/�����q����Y,fs�s�v�g��l��RN_�./��!CG	$z�;���s~{Y�o����������Z��j���@��V�7[O��,���c�|2�$����k\m�w�?��<
 ���|uF������,��"<��e+/����'�A(b�I��?T��%a������E�$��"g�\�8��Q}�49Ap���gG�C~��#hl��^ x�1l�3�f����%��B���#l����	����~������ �<��<�=��*}C��h>�a *���nm#�8�b\�����~t����O����x��e�=Z8C,2��9DKU`Q]g1N1aO�A�����4bK��Uc=�,���e�q�d�d���\�����`4��b�VA�����|;�F��X|s����R|��&�����o��T|��f��\|��~���+�-��[�����E|�*���o�{�lU;zV5�����p�J�.����'K���/��p�4�e��}iT
�
��)��|�yHN��cWvY�l�q�b���������7�@��8>�xz���/���QJ0��n�[Gt3w'��g�}���m����W�4q1Cw�h4]A�$�����%��t��ai�a�jX��@j��6�����2��;T��lg�����J�����,�!H�l�+q�l���_ �?t1�������}8�����C#E}r��M>LBeB"��
i�j���+����H�_��!��V�x��T�:LCH|u�N�H6HH [?+Q��DU���~��S���(��Q~S�h\3�)JSX}�l�{�,��UY.�_�����=���r�'�s!B���'L��_�#��[��uBA�9�f�%l��K������~�eba���o	x� #J?��V$�Y/��A�QG�v�LQ�(V+�Jz����z8P\3k�L3�r�YeZ�������^�w B�5���T'j�k��]�����{1Z$�7�
����b���ebQ�y�����xXt4��a����f�JGk�M=(��p����h����hg��X����T���+I�����6�<h����3��9mH�����wx��_����oRwS��P��t7����&�������/�g/RJ�;x���%��qi8����4�kg+"��FZ
��+�������q
I���t�B`/(?j�KI����T�Qm[��P	�L���F^_�[N�X6e ��#%��/Ll;Y�n���5���TZ��b�I�Vm�\�J�}��&��_o���1�Wf0��D�hN��EP=�R�@�]M�R\;	f�7kMV�925�����3�wWOHSl;I�;b�z*�4
VW��&��R�*�
�J�(8�����������N�)��4��q��O?��g���]�\�y�y��)�:�����������G(olK��&���&b1��������I�U��3���T���#�������v2��1C1����5uI��	��I�K�������v��Mg1��y�nx��IK�k�t�K��g�#���
_�V�U���3�z�t�je�p��������z�b�)�!����p ��p�i�I�N��mnD9�z�����#�V��l�p�5�bh�st3��w��r���9��=@-��$vX;�O'�m���Yh�Rn$�����V�������NQu���
[������9��$`��'�$���,�I*�����3S�#�Pp�f\.�;<����x��
����+�s��[��1\����l6�R����0D��j�:�(r��'�"�����1��G���rz�;w2��?���ja�����9`i ��J�'�t���v?��FSxL��&����+��:�_eC��� uZ��/-J)�A�4�Oq�<j�D���E6����������
9E��V�$�����%iDUt��������II�����iw(�����2����E�rhJh�N�	�:�f� @O��k����^V�{�fVjf	��'�"��"�R���R����a�@�S-��G-��h�{��f\�����f;�2�t	���)��m�	)�m'���$L��1���#'��hk�%��B��v�����Jh�H9�����vR)E�Aa�4!�������s}��c��2�,�P�R?*��UT��s�+���\��uxy�,�Mt�f������Z��Mz����F�^W���J�8��^��fS
��#W��h�q��>�I9�N�������}��f���+��z�!����?��_z�K/�J"�t&%��"{F4�b����3r��)	���&�M���}8��F��O��v�z���v�>
�Z��u~���e�������i�,�EiM��X��;���(���X�H��tOC�q��H�<�+Pr4��
Os&g`G��'��$�1C��
�4V�`�XJ[��!��R��;���:T������S`?`G�fEl;T?y��,(���rx�e#':��<��i�������n��m'~1F����R,E3��N|���M���g3����n�m�=�>��,Dg���xrq����	����b�K�]G���r�g��z����w1���iw9�������d�|A�@]�����m��Lfc�+j�?�F�����'�z��������������������&��jv��E�}�d�g������G�9����"��_�e�C�({�gD�����7��`�sD�x��j����\8�k���|{�������Xvb1��DY�*�x�:K���~�uw�,���a��*��v��d8E����;��sG<�K��U_P)�D7������^q��4���x����^�������b�1�=��.on�J����CoN��8����@_�-1����%r�����E���q��g�g�g
���o#�m,�9����v)�]�o��W��7�m*�]�o3�m.���o��o���������Y|�"�}�����=�fY�1���u�����)����?������!�.�^�3���j[�\����d�����(L�8�+�������z�����I�E��o��+����^d:�m����v�����t&����u��iYg������!�r����3�n����6��|�,����,g:���Y����@<9��u�Th~q���=rZ�LC���`C}��PX�����)�g��J*u��"��X4(�t��u#� O
����V��3��V�xt]t<����d��i��'��^p��#�#��v���m��(�qV�j
��~�����r�+:�e7]s�������L��2�lNv�0>�b���D��
x���S���=�-��t*�)H�S������cq9���q.S'pR� �'pdhF�<��5I�Q�h�����t�;-:]�����jw�H��v
��f-��E�Q{Qk����d-V�d-��ZY�)��fY�y����KSk�n�%g-v�Z���K������������Z���Dwf��h��Xm<\Cf4\CR�����L�m����,W���(?J`Hm�Hm^���5@��J�m�\�8�j�dI��N��(L�8�o�dIo�6/�k���j�r�C,�A�3b�!:i��x�E��m�7iiw�)Q8���e��&%�E���g.^�v�\��K�����y2��Eg.�c}�S��l��~�x�(:i��)�u��=2k�If���Y�������y"��EG$���%����M�m��r5�/
Oe������J;/<�L�;����d��G��H��Z���,�^�3�)|��rts���96/s��q��H���������9Z�H{����G�u`�QXi<H"u��XN�teT�w!-lm�a��n���wd���:���}1���IJ�R�����
��
�E���h��/��x�\0�A24�A:���������q�G��������i�����b�y�x��+Ks$�z�g0����� .�!�0����>���1qol �=��E�?L=�RW�{w[�H���%(V�
}#������`��S�����1(��&��
r�8\�g�m�xd��T�]=P<*�u�����2n�*����Jvm7'p7�J~��_�(���G(����J~m�k�}-�P�2�l�����^�Z��)�'����Y�N�D�*gr��\��U�}1J���P$*���{f��e(X�������pl��X�S�*����dJ�e�����?\\*�v��W���D�
��.��|��m&
����J%����[�m�k��.����c�p*�	�Z��]5����|�t�<�<�dF;3�[�^�#��������L�/Yi]{��+����e�5���t�����}<:����l���5-{��3>��g����Cr�?��F�7�7��O�g�I���
�k�e��T��
=J}�fK~h����=k������F�k���e�0.���"�3��RXI]���o��%�3�U������������o?�m,�y��f~'J�fv'�d�E�|-7�;-��bwZT�NKW[�q���xx�����������d~'�ehfO�o�B(|����}]wi����g���<�w��������24��J9�9<��������b
��]��:��28��J~�9D���������_�w~m,�y�d���n6��C����6�j�w���|A������f�!5�a�u%L5������y����C�����a@ql�Y��
�0R��E���A�f|3L�f\P�
s������4n+&�ft[ds�?���co����S���(����(���#(��\�i�z44��7	���)u�R�-&�7~�@���;[Up�j����p�\�i�64�1�	��D-��
Z������RU������rU�]�
M���	�i<�����R�-U��2�|
�W��������I(�~���{�@�x�:4�'�n�9�f����qk>��
._��6Wh��NMc��������}�m��t[;W����o�Zp�]��4�B��jR$n�����	���D�*Z��v�������&}�I�P93=�#R����28�l(�n���(u
p��t���� �(X�}C��HJ5�q�e��T����ep
�����,�{�-q�{�p��g
8�t\�28�.&�y��M�=4�YYK�QM �-B��
P��]4���R�/������!��.�� ����C.��F��� p���9y+���R��A����x��4Fy'�f4Kw��6�	�k��k��?�!C�}��T�K5>�����5�5bM�hv�R�mT���������>��<1D_�f>��Mc����^�Pr��n��k��
�|�!���J����$���I?��6vRfu���&�:v�"�#�hVG`,�c�����c:S���I���4����v�W���I�y7*��Q�;S���I��D�V�h�?mC�R"��<��u�u���;6�r"r��
�y�F7�4�*8��
��#24����f2�'�f6�z��/�
����4�3��P��wo(������r����������������������.�r_�����K����&�._
>�8\��(z��<[24�1�24�1����Q����C��._
>�c��c��c��c���R�-u�K�|�������U�������_� C3+C3[*��do��������������oeh��oeh��oehf�oK��!(��������de�+_�?Wh���ehy�'��L
���tl|r7��y�*Z����V�2�B�rRxT�,@���dh��M7������"ex�t1r�B��D�F����i�F��
t���y�y�R�f�l����X^�f�b�R�������gI�f�k&C3�7��������,���{�dh�/�����X�dm�������~�����M��`����{,1��m�!�K�1,(4�!O�|+���C��._�6��n\�����G���N�����4�����P:@��{grdp�v��tZ)��R�%�|m����4]MM���R�I��`�._#7��#
�|��'�eh����4�IMc^���I�!��._�|�!���J�`�����I"�oEBK��u��@
�V����}or��q���I����j|�%"��i����������w�#�`g6���^ �+6�-�6�`��U��J@@�C�@��k������55���{�)�d2%��'{�v�Mcd�)�nF��\�j�l���d3�t�|������3���?V���[Q�;_9j4�C~�&-c��*�;�6������ad
�s��v��s��|���
C�sM�F�n=b�����q�(p�>
~�}��rv'q��(����-gtw�b�B�� "�f,P��<���9���~�
�x@�
�x����MI
4��

4�7%)�tG+�����+���PJ�ySUg<�Zg>V\g<�R�f<NT�f�'���Z-�X�O�KC�����*�{��	 �H9*��k�)g�4�`8�cs���M`�N�l$����w�y1��s!����)�8�`�=�������{\��C��L��|F�1�*�4�1o����n3��3:��"��U�3e�%�ID�9�k����ki�3f�8bQ����[Q�;_9j6�V~����%X��cw�����-�;�]"w>�;W�6{���L��,
�5��Ev�(Ft���d���� s�5I�f>bJ�f>L�f>�M�f��=���ch�/%U������%���8����xN\����
4�q`24�W�(��_i�@3~��M�U$�|V�N{�������
�a����Y���6�+��q6����&.�0�B�7�t����4^�����^@��p|/��w����F����F�h�4]�~N�]�[�������&?Nc��,�3C�G�1��x�� I�J^S���xMq428�q4zx�����za{i#��bx���l$������I���1<_n6�F��������#x��lD��y7���k�Sr/q0������`n�W�0�����5B@�B
hr
)���w���1���1���1�FA����1���1�������<7��|���[�24�Ac24�Ac24������������4��h��Lf�F?��!��WAz
Lgu9�[PV�������c��0����Z��FpL�?6�
��K��
������W��{ci�����=��N���Y��V��8+H^������l�����ehfw�����B��� ��JVS�����|��![zx��&�X�
m$WT�W��
����f��������;�#,28�GX�p�|x����w����a��e������  =4iE2X���V  ���Qg<�Jg<HLg<Ng�2F���h�/c����*�����w%�0���������3�
�x����e�
4��1*�4^����d�����@����})��8L�����_�@���3.'��Ij{E���K�3�3�"lB���/\�����z��S��e��'qo�i���24�Q�����e!6���1%s-��#f��y+O�k�]!v��p������1��|��y�^�rk�\&v���J�9��ep�����K��r�+�4nJ��}�;��^p�!]�*Z�C���U�����"��H@��h�r
#���K���K��x1��x1���������������t�������+���hO��x1�y�X�C��Nw�g<4��b24��b24��ba�wW�
r�3�~�`��m� ���)wy����,�v�t��E�>���r6_`�i�]�y$a`�����o�(�jM�;����#�92y�F�T@t
�����B8���r3��p�����1�B��f5����
��KV�N�#���5%�������LK^�xM��<����&����hLu~�YM12i��jV���}Ai;_5B�E5���K�=�������6��b�����;S��o:��_�x�~ ���g_�w7��eh����|���|����q
4���)����@3}\�sK��b��;���A�yW��|N ����h���S��?N����8_N ��.��@���{�h��6�(�L��4�(oVu�i�6��`g6���&���%���lG��%�"�?�v^C����vk�R��,�[��~����(DB>#/�����G�9@��Y���:  ���T���,>��t�B�S(�l�dK&k����)U��)�OL�9�J.[r�����e�Ue�F��+.��t��F�}A�;_
�h�j�i�D�M9brEp�1�%���'���������2��c�����X'�A��	(P<�O��Ddn1�
4��D�f<�S�f<�S�f<�S�f<�S�f<�S�f:����%�U1�x��x���=,C3��@3��@3��@3��@�����[�p.�~N��n 1�V>A]�M�����|��P9�L�y��+���a�YT
��Pg!g���q���h:������"���1��rS�����0�b�+�L�er�2��2Fo4�7\��e��K.����'�W��`��p�b�������-}c/*Y��<�Z��d]"w�Q#������Hhi�F���Z.�;EQ������Ek��~����r*8��Dg>�Cg>VEg�j9����h���S���Z���%�
0�at
8�1�
8������p���S��ZN�f�j9�����<`���{�N�/�7h9<�:him������������=:����@���������,����d6q���V��s�'nz<��@���d����b�;����9�X�K�]�:_o0g����SQY_�D 6��O.:_�����K.�q������O&�������l4:�f�k=���hw�|���N�Ovvv���w���5��Uk
:�����@]I���w�s�*�gL/����F1Wz
���	���/��[}����A��L���oa�1d�:�Y�9���>��	��b�[���?���=x�;{j3@6�t��2P6�u���x���&��w�d'�p�(nZ���^��9t|�s>oa3��[{ff��0|f�|L]��?��������S�}�O�>�6<���|^���W��O"�w!�r���\<��$�Jbf"
I�����FLG����t���W0|�|��6���K���m�����q��I����b���	2nA��k6B�|�f#������)�Y����r�V��~��J3!Z���?����.�e�f,�8���!�v�v3�=��n3Dl\��
��Q�V��G(-��D"T�`G)T�P��|�D�W*	�6�Dn�(����!��
�P��N&��J����p�0L�8��4QP���lFp�>R5[�s��v6p�������	#�t�l���]<K�	�j��&K5m���0����0��q<�����N�I��aj@Vx*Y�$��8L_�
O�
C�*D��L��
���7D�H	K���9���b
���fJ�*��������U���ZX��Qd���~w��#����-^P y��z>f?������\�+�A��b�,����WF�_&��3F����[���@�F�F�F2N�H��H��H����n�5K���
���������
]���E��-�U)���%��<��<��$Yc���������$��Nt�a�
�n�����+�Rk��J�V[7�����O���]��Ye�Fa��Mb��Gl�/f��G�I���Vj�y2�Q� bMGB��"A���J)��jyb�c1��������*��A���O�S�1EM�z��}H�H��p�S�j�Y
���9-YA4+X+D��1�G+&�v��^SKX+���������=����r~GVUX�#�@B���.)zz��6�F�[�o���j��xL��Z�,�W*��Wx	�O'���������}�I�%y�A���4�]��1��D/\�I �����s~{Y�o�����������T�"��D�Zh�7W7��m�+�q���2���J[��5���;�-������Q�Y��\93��������`�K������i�^'����d�����l����dy6��o^@�-o�,�ecpU��2},(�rvvt�����1�^�-���w������@b^�=�@���x�K\U�R}�g�VDW�s����N��w�g���z8�-�!��yT6��������'�C�9����;����%�n�F�g������S�.����H3��V2t2��Zb�����}No1W���3��������6���B|�������������6������6�n���������oK��V|�,�}���ow����%ZS;�G�Z��V����wiY����w���x!u�����Vp1g
^e�����\�\v4=��fs	�l�.�N,�����d4��`���NaA+��)�{�3�]����w�DS���cab8
�-��-�������>�.��2�"���~�E���y^BA������������>����i����3�A�����:,�n�2�V�����EsI�(G�m�����<�AF��p�����Vx3���q�=t1�z���W������x��v\<�5$���/��� ^B�������#k��_����tO2����ff�[I0�~�������-g�:)��/~r�?����/��Z�5�?PD�NN0�+�@��4H������1��'�X�P�R'nv;Z���V2��
p�~�����1��y���d
����r�u�ZP7���2��U��*�s����i%#[P��W����zZ06��h�`���DL��[2�i!��V��	[�,�N0������iemcf1�����1���'G����K?��Bl����b�����b�S�]�2���_�`������J��/B?��������@�D���*�G�"5;�$a���O�c{AA��_�A�^��.�gJ��K�m��(��3 �ei!��f2�Y�4�G�5��ekQ.������O���6��9G
Z��m��f����)�����A�ZZ ���*b��ST�����d�q!�aW(����zH<���fJF�_x��z��oI��+b�1EL��Q�E&�E=^��f�Q�:Z���f�����������m9JKKHO\3�?4v�p�?5��������v�����
�#}����j7iNH5�'	B�����3�>���(@�����]���9���o~��xt���K�'��s������
7�%zl2I,�9b���$��%6��=1�e�cL��f0�g�z��}889����z����������<�c�nd�a&W�'������7O>���!����i-sy���y��K�+�X���U�����e�5���t�������%��1d=t�no G|��t
�dA��aD������B�����l�����V���h8���wxE�7n{�"����t:�7�G�X�h!9��@��@���6��0���������]r��
��FkN	Q93� &��
`r�������]����n.t�o����
U�M}t�X�.��
�� ����a20����{�0Tc *"�,�w�h��lb�
�u�2J��.��\�r���~p�mYv�4�_�6�>��/G�pG���w�s����;�?-o��##[���7���un��
����[�C���(���L!���R�,">��R��#�Xc���5��$*=���k[�m�����kkdm�7�����
2���
�MJ�R9�r��������;����:R��|2g3B�c8�� �������a�70I}1�M����@���u����r`���fp�d���~���k=�����Mr^'I�';I3P��V�soquj<��(/\8��y��A�g�Z""��">��2/�u�%��z`X
t����fA�=��t���_��T+����J�����c�Z���2�,2���j&�{��f�����W>���������B'�u�}�d��uG�p�Wa���UV~��.������!��o�����~����$��p6�3��<s4�x<�1-pp��^5�pfKz��oh���AB����������T!g������l�e��p��+�+�rfc���9�����\�^����#��~��a�r�<��$A��-���P�pu��&��#�:��x�
']������uo=����Cx+�}���6�$8��5���=Q�����gT��������P�a��YC
*��9��D��w���-�M�������7O�u�����&6p%��"���� �����F���@�D�����v��]
gB�����i��c��Q��>�@"<b���}����g���q��[p_u_��W��F	'k��o	����dz�i��F���xiRC����^�G��@6�%j���������L�&�3����m��!�p������I��g�D-q������V�V��g�UK|3�_��U�j��>|���������(�y���S���M�?7?i$J24��R�����*2
KI����d��i�$�0�5M�=����{��i��������r]�����i�"�,Mi���9�����F
�5��.�r���v^!�"��(�u�2!I������������3�=�tL�H�K�����$������?�p��'��
��m��F] �X�J��)�������t����������� V),��������4S�k
��K�2�n^b�Y/�Z/F�N��?Vg����#}�����i`����f��o!+�����������_���
�anGoV�����
^
M��lq����nxr1!�����7���D��\��h�V�\�^��P�v��\;�����p:�Cc�w���R�e�W=)���W��q��H�/F�	�G����7���]�����I��������1	u��.��c��@��u\���q�:+p���Q�&��'�+��Z���d�z<�x\d�����5��4a3x;#�����3C�%T�_�� �k��p<����/��������C]����|�l�`���:����`��}�'���P�h�a�.�nr�D����!)_O����V#l��z�~���4}�:�C4����1��~�S�<���r�r�#�8�N�/KJ"��;��>�����A|���U��F��@2,$p�*}
o���Y���i��5���8�F�Dr�2� &����:����3�����;���|97���C�M���?�Z��\�U�h�0��R��3��sV�B�Q�*����+4�����e5�b(�4���'�����S����Q�b�)B�XK�����)bm=�Jl;����z4��v��������R$��lk���j�f��t�G�)���.�'�b���yv{3�v��>�V�f��p�`������!�k��j��h����LJ.�gf{��-1�q�O��SW���w2�J/6�T�����
}�}�4����.�	m����f�#�C�-�����5B�����3g�{�,�@�+O>`A�Q	�~`��e�X1*��f�
�!�v*[&	*
�pg�"
�[�����>�������m}$`�F�g-��1���%|qH��#�Bb��J���?p1��S]�#�(dN ��`#Q��M�sG����]�$�(� �t�<����*m��%��+�V^�li�o����F�A�dP����zlb��*k������&l�N���S\A�2/���"�J[�q	!�����2[�B��B�<m�qqEP=T4B����2��Zy���-�	[�� ��A�6/�Z�E����B�y��)m��m!�:L�^���9����B�-T��{+�J[h��y�n�^(t����cC�-%�ZR= �\i�o��mi��0�z2��h�Pi=61���J[h���X�~^��k	��y9�y,b������� ��
�.m��m!�g�%`f�<�g� ���F���cC��jim�2�Jf6�Z�(S.�tr��X�PiE	!�A
������B���P�����
�����#�����M$,�,S@�M�	9����a�����X�J�����X&��d��b0�2�������l<����:tq���*c��
�J#����'����nT�#�@eHE��!��@�S����0�R*�o����G����pU�{���=+�#'�����z�3����dcF\��x]c�Q����J�i,��]�=���������������:wGt�]�������74���9`W,���~�y�:m�6���d6q���V���8q������/'K4�u��������.��]:�r��z��8�]�V�2��bXw��'�����E�kU2s�`��1��)�]��Nfc�+�i��h���|�|R�������;��N��������P�Yk������{��v���N�@��r8E���s�c~�95�h]L'77��T��F��`���	�����%�m/���^�+/��J�\�oh�.��H�X��h��Q����N�8�k�mx1N�V=�N��N�����.G6�����������l����m�{Q������SW1cu�f����a�2 otcIq43�to��b���dV����^���7c����6���3�(������!����T!B��}/Q�
r�f���T_����HK�m��o.G�O������gV9;;:|wpvVf����GG�;�
������-��i
�gXU���%~�����cg4.��b6G�8���C�\g�����r�`im�������L�m��lt5\���0�Ze:�]V����U��sw�?g~Q��U�*���=|�z|B���4����������������]�
];��B����{���^�}<>=x{���w�?�(�����mG���K��|���~�!�+F�k:
%�NP�~$E�-g�:�c�<��l���?;7s�
�F��h�8cg��l�Zr���#-;GZ���H�#�9:�r�|��M��b
��@��!�(���r�\:3RWB�G/Y�3�����5r��V,�7M!2i����B�Zx�1��������}2H��o��"I?J��h��a�L���)�qf=uQe4t<3w��|v�
���U���yr�Q�GJ�p�����g�/5t1�L�>��X����V|�%�7��V����~�Yh�~g�+�x�����?;����,��,��vZM�
���Z��h9/���%�h�S��'XB>�+��t�"�D��C=��T.�u8@��ZV��ru3���w�b�g�']�=�;N��j�F���e��5�f��U!�/j����������FV8���"�e��pz�yK��l�#@�(1���e�:�e�?�<\L ��V��7��Ag$����L��}1���2�h5�����(	���,���m��Ri��H�{�;}u��bl��@������QHp���\V�*�<�Z4�g#�����JZ��W�d��X�����m�-�q���(�dfv�hdv�F�F��9+�h�E���E��t,����"��!@��n�
��,"�2je
YT��<L�-�La��#��7v�i9�L
�h3��$j���O$��N�z����-����~�	�oc�-����o��B&�w}Gb��q�U�n���9z�<�	��	B��D�����"��Kf>�.�+MfH)�1�57��*s~�����7~��z�"��e`h,P<C5CuG�N�j4������,�k3
C�j���6qj����=����h�m�1��5���;�
�9���}+G1�O1!��2
���fV����FyL��W`]=��8[��
&;���g_��Zd�O�#S?��i7�q�Lc�1�=��k�}����R�:��F�^��3wY�0'��)�*�J`�E��J�
iP�������%
��^���di?��C��B�a�����>��N�����,7�b5��!��~�=}���eK������8.����~�;;��#�S�s
4�=>�}��*+�	o�s�z�
=��3e]��b���B>R��h�!K��]���H�`������+��1a����;��a�ZD����K���s����sf�����,�H]Nf�z!��[~R���s�1}<�v�r��
�<������Q$��|zz�%�N�Rm'FAN�4�80j���_�P�7M>+)� R<9J�T����t������1��.�v[��|#��&�B�p�C�u[�UVg�,
�+��������)��J�����k��K���f��\��k->�PM���L��8�Nw�����3�d���6���^-
.M�X���)�f�G��TV./��]�p9+g�f�������oe��{�~�o�_�,���h�����PwlH�2-]��]�aK&�[�h_ri�YD�����~;O�{��3E�i�/:}��8���f&E���F��u��RE��AQ��K����8�;����_��}���V���-��Q>��D�������K��HV�rq���S���|��rg~�����0b��{����Lh�����,L����	�:44�F�uVD�}�����x�����U��K��@�p�e�d�o3.J�0������.j2�6gwYM,M(Nxqp�>
��g\2ZlI1p[�i)G�H�'�\#������"X����/����x�}qq�eV�e�I`7��8���i��	|�d'p���Vx�D�E��:h!�t&�N��q�"��K��+*��n�
>'�n���LW�v���������<Ad�H��Fcd_8�vR#���
��Wp�[���n��!�.�l�����o�X�]�(@�^J^�p�'�R��x�+C����������I��s�/�b�8��!��WL/���u1������y��L����`�DYX�,R�I���������N��J�/��'�������'�
O�oM������(����wTa���_���d���}������.>�je��G���/)��?R�
V�YH�D��Ag���t��JY�;�I����l4�1��x:9o\�Vb{��<|�s���7�������7G��Fc��)��g/�H0����4�qM�A2���dV�<���Ov����;���8��������5���TC���>���%~�s������3G5���dy6��oHO�4;���R��qo���h��e�'?9������������H��*�1��)��������K�� xu'3\r�?0�������-�T���Uy6|�����s�1�c�����qI?���;�O~����)���3�1�7^�����p���~������������O��L*M���;�PD��?������?���D�h���x~���o�l���y`�9�SA��N���������zG3R
g�(^MH��f7 ��ir2�e>s������G����GP��D�\\������<I.�C�g�*@�w��;F�WZX�CU�?CY&�b��A�)T]P���NdN0�p����i�%)�D}��3�����2���F[-��y����A��wk�����4���`=���=�4�K�h��{F����t�Gr�?��\���	���a,��6��ql�,%a����qIx���%m���SY�_f���k�]O1�tN_�BM��?��#�c�%��s9�L�k�{�O���:!��`�>l[sEc�]Pon���d����drJ>98�?=������_Zo��m-�n�-���3��F��IY�
#@�����"^<�����?vv(���|�W����d7=����EJ�2����V����W4�rVBs�r��$"y:��
�?��R��z�B[0������E
%�fbF�y}o��*��v�
@��(�&��\�3�v��'�w���"L�>������y�1g�YD�Q��lh�l(�vK���RQ�7R������������9iisH��M�.J�jQ!E���(
����:�����H���c���2Z��Fij��!p��
Y!��R7**i����
4hs������:.���\��V4��c8�)r14<�+n�C����KG�����4�DD��6�:�����+t�F\'�F\����q�<r��\�:����/���x2^xhEK��r����>�o1v�c\X���Enz#���0D��5Z�<�'�"^��������h9�����y�K#R���+Cq����-x�dj�������79o��&��4�c�p��/����ui����E�d:`B*�Z8�� Z5�pYl�\b���Z���d�C�D6����p�b�:%�������U`��*����Jj����=q]���~$�m�8��h;�6^;��������]��^���I�Rx�������fy��7��'W�d4&��st�uxy�,�	0<����9������I�3���� ����l�^��t���$����W�
�^��u��R5/��q�|
���O�����F7bf;;�_���<����G�U����*jB�\KS�iE����W���R+-�i�E�i��#��L
���&�K$A����j1qy���tJ_R<$D�g��3$]N�|3�F�t3�mw:�:�f<)���m,�L�	�g������,�k�����f:M�����:m��m��i�3�3��AW,�����W����i���������@�:��	���9��0^B�����*U�C��������[�bc[P2����y�&�M�*#��ML�	%l^�M�L�*+��Q)�
�7�F�{��#����R2�I�PR���S�N�h��*����Hv�E���H	;����d�X$E�	n?��Vq����T��AP�%9���C��g9���j���s��[���V��G��IB��@`r:~��J��#6;�D��i���<
��k:H�kL�R�"���7H���QGsU����*�\uMk�m��q�ye_�M3C�����<�}��0����v���+��sZ9�������;���r.���p�M����]^8�%��5�
����%�����7�e�v�v��7q���f�/3�J,���!8�	���>����z�����^�����������������3&���D�����=��zH��=�:�+�+�����\bx��!���>G_Xx�y�b��=Q�t�pnP��P`"�N�Kn#��u���v7��
8���:28��8>�	�m�,�%�&�v2B�u�� 6��%l��N���W����w��Eu��M�aN��%�#�������
�K{�
���b��.y�r���;��s\����,l��dk��mZ����r+�%o{5QS��a�v^7���x�-��[Q|N�v��B�����h���&����nW��s�0Q~
��?���j�O�n���-(����%��?<�H1�i
ldE5Oxx����|�������)��+v�	����][Z���r��P�v��\cq�K�[���Q%6�i]��z���pY���]/"���C�E�	��7v8#��d�Hj��M�}���d��-����v��.��c��@��u\���q�:+p<�R	�:M���g�h������5�O<.2Y��hx�:�
�������
�,��6�12�� �k���/X;�EV���d��x3�����%�u�o���t|S�8�������^�&IX����K������qa5�je���H������b�&���_T��7��d~�"�8�M��d�a�$	���?�<�~vDpD�)�m�����.�0;���5�!(�b(g!��^�������.��iw� >;,�b8����xF�\b�#t�����#����t��	Z8�c����A�U%G��8|gH�-l,-!���8*W���0�$g�����D�����t�:2/������zH]�
27.patch.gzapplication/x-tar; name=27.patch.gzDownload
#101Antonin Houska
antonin.houska@gmail.com
In reply to: Boszormenyi Zoltan (#99)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

Tested git apply and build again. No warnings.

The regression test also looks good to me now.

I'm done with this review.

(Not sure if I should move it to 'ready for committer' status or the CFM
should do).

// Antonin Houska (Tony)

On 12/06/2013 02:01 PM, Boszormenyi Zoltan wrote:

2013-12-04 14:51 keltez�ssel, Boszormenyi Zoltan �rta:

2013-12-03 16:48 keltez�ssel, Antonin Houska �rta:

Tests - 23.patch
----------------

src/interfaces/ecpg/test/sql/cursorsubxact.pgc

/*
* Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
* is used with an already existing name.
*/

Shouldn't it be "... if a CURSOR is used with an already existing
name?". Or just "... implicit RELEASE SAVEPOINT after an error"?
I'd also appreciate a comment where exactly the savepoint is
(implicitly) released.

I have already answered this in my previous answer.

And I was wrong in that. The comments in the test were rearranged
a little and the fact in the above comment is now actually tested.

Some harmless unused variables were also removed and an
uninitialized variable usage was fixed. Because of these and the above
changes a lot of patches need to be rebased.

All patches are attached again for completeness.

Best regards,
Zolt�n B�sz�rm�nyi

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

#102Peter Eisentraut
peter_e@gmx.net
In reply to: Antonin Houska (#101)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

On 12/6/13, 9:58 AM, Antonin Houska wrote:

Tested git apply and build again. No warnings.

The regression test also looks good to me now.

I'm done with this review.

(Not sure if I should move it to 'ready for committer' status or the CFM
should do).

You should do that, but I'll do it now.

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

#103Peter Eisentraut
peter_e@gmx.net
In reply to: Boszormenyi Zoltan (#100)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

This patch didn't make it out of the 2013-11 commit fest. You should
move it to the next commit fest (probably with an updated patch)
before January 15th.

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

In reply to: Peter Eisentraut (#103)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

2013-12-21 14:56 keltezéssel, Peter Eisentraut írta:

This patch didn't make it out of the 2013-11 commit fest. You should
move it to the next commit fest (probably with an updated patch)
before January 15th.

Done.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

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

#105Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Boszormenyi Zoltan (#99)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

Boszormenyi Zoltan escribi�:

All patches are attached again for completeness.

Thanks. I pushed a commit comprising patches 09 through 14.

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

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

#106Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#105)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

Alvaro Herrera escribi�:

Boszormenyi Zoltan escribi�:

All patches are attached again for completeness.

Thanks. I pushed a commit comprising patches 09 through 14.

Now also pushed 15 to 17.

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

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

#107Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Boszormenyi Zoltan (#100)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

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

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

In reply to: Alvaro Herrera (#106)
Re: Review: ECPG infrastructure changes part 1, was: Re: ECPG fixes

2014-01-16 22:13 keltez�ssel, Alvaro Herrera �rta:

Alvaro Herrera escribi�:

Boszormenyi Zoltan escribi�:

All patches are attached again for completeness.

Thanks. I pushed a commit comprising patches 09 through 14.

Now also pushed 15 to 17.

Thanks very much.

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

In reply to: Alvaro Herrera (#107)
Re: ECPG FETCH readahead, was: Re: ECPG fixes

2014-01-16 23:42 keltez�ssel, Alvaro Herrera �rta:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I will do that.

Best regards,
Zolt�n B�sz�rm�nyi

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

In reply to: Boszormenyi Zoltan (#100)
14 attachment(s)

Hi,

Alvaro Herrera wrote:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I hope Thunderbird did the right thing and didn't include the reference
message ID when I told it to "edit as new". So supposedly this is a new
thread but with all the cc: addresses kept.

I have rebased all remaining patches and kept the numbering.
All the patches from 18 to 25 that were previously in the
"ECPG infrastructure" CF link are included here.

There is no functional change.

Best regards,
Zolt�n B�sz�rm�nyi

Attachments:

18.patch.gzapplication/x-tar; name=18.patch.gzDownload
19.patch.gzapplication/x-tar; name=19.patch.gzDownload
20.patch.gzapplication/x-tar; name=20.patch.gzDownload
21.patch.gzapplication/x-tar; name=21.patch.gzDownload
22.patch.gzapplication/x-tar; name=22.patch.gzDownload
23.patch.gzapplication/x-tar; name=23.patch.gzDownload
24.patch.gzapplication/x-tar; name=24.patch.gzDownload
25.patch.gzapplication/x-tar; name=25.patch.gzDownload
26.patch.gzapplication/x-tar; name=26.patch.gzDownload
����R26.patch�[�r�F��m>E�G$�"Rw��6����#KIIf��b�@�Bh4 ���a�����@^l�s�h�,o����*�$�88���-?�N�Lz����`��y;����`��v�`g��a�`o���{��Q�q�gIz$�����o�H���w��&Q������Q�~N����oU�'�.��6.�L	!��L����������v��+Z�~��h`������8���JR�J/��K������0��,�ER�(��(Z�$��~�8*d���?�J��<
��I�|&��,
}/�X�\5ziW>��� J������q���o��C�%yf�S~�D�7
�0[t�I/WL�����D��9���m���������o^��>S)������R)zS&U�e*�B�%X$S?T�I�2��,A:K�zK�X���T]q'�%]�*����yf����F�����@~oLo��&�hK��I�>����0�g1����~�����X������N���f��j��������w��-�o{W���o�sq��+q~�����kVD ��H����f^��6D��/�s�����y���qF��_J_�RD�(���3#�z��,�G�dr�E�8����t�&�R�d���R$c������W r%y]$;i2�
���2A'��+�BB���G�I_��9���T��l��+�"v�2����q���v�:���H��[����uJ�Fa,�4�;�Ri9VJi^80�F�JGR��?����������/a�w������/(X!O'�l�`���[K&��x�����_����\
����I/���7��vp;��������w%�L��<����7�b��,�����xw���D-b�!Mb�����������l�y�=��q���&��xK*��M��Q8
c����8���xd5�z�1�G�Q�=�;�a��b�����}�����9SKf�=F*������?������^���n�[�B��� ���r��:I�p�8�k���K������\�x�0&�������--E����������"9�F�l�:���X��W\�`�������m8���d&������N���A�������1a�Me)�&�M	�K�1�%���4�0y~1�T����W
�	vR�?WY2u��&sq&'&��"������0C��dp��QF�v��u_)��a(�����������+~�CT�)$��(�p
�F�<DF�[�(�=��,�8?	$�\5�glb'�������6�[����Q!���4�7�"���I%���#V+r��)����a�ko��k�{Y������	)��d�R{FQ*L|8�
�E���O���������Z�#�V��E��|.]p�N����0~����C��@@��S�����z���������l�.E�3�'j����[�����;h����n�]�X�����sz�bpw~{����VLh+���r�8�c��d�B�����~=mtLD��Y���C�B~��I�����;������n�s���T|o.��n�C�����w�����K�0��A\��8������;0�A�"~��+����|/~oo�.��;��33��z�����S.��� �?V�b9��!����r�
)������&��w��>�����'��f���*C���v��H�B���e�.�%�c���J�7��N.�?�x7������M��P�[z�IO6�v��n$Q�sw1��z�B�,V���?��Dh�>i�OQ'��R*��6�� �7��e�� Y-F����EG��r�U��>����heQ��K��K����)�����-SP�V� i�C(�Q�C
��H����������x���f��y�C��>��[3%�������''�u�z��hE��Mke��V��:J���/�S����>�Uj�"�`�0�2
Fr�	p�Nb�R_D9���O��������$$�hvj
��l�N��c�+3h���<O������d9�VG���C��iLI
�-
4DK_d�B�a��l����2Cu_]�����c��g�J�y�_h4K��F���/��-�bv��Z*}��?��g���i����`<[�}O�t��~/�=d��
��V�G��������v������-��I�$A:�C�%��8�<l
�h���*@�IL�`T�@�������+������#d
�Q^F�P���5Zt��h��g�.��7f8�����������F��1�$��}<#�P�4��|��7J�
�����(L��7����-pIq��R�I�j�1��V�W�P3
�J����w�6Oi�r�^��W��p[=���>��|*>��������H�KE��~��L!a���U�`;a�,�@�6����u�23[�e���t�IH��@�
�Py�8Z���'%n��Fk�&Ss�Q/��0���<���h�i��
x�����M����)��I,�3�3�v����6�zwy5���	d�#(x�F����xv{�����/�A\�U�3������~+�I�����n��!��	�����'��KY])m�F�8�u��YR8��L��S�T�S`v��"���D��	j�z���nW,��`�S"� ���&9oGo��"p����b��&V2e�
������'�G��qw�>X$�m����J�5Z�\�.�� �����f�ZB��6���'U8����CF�#hN-�G;l3\�`���M������J%ynWg<Y��r��h�R".�yRs96��3*Vy��*�6��@�C;���Y%>P���S�xF�&.�u,�M���w�i��������i�3b��c���.e�M*�2��p])2Z���S�6����D�Nl��~Q'c�W�Pa�
cvPy�+�*Ks�,S��o��,K�&)����0��'7(fp�K��xmFy�6��T��FGJ���'�E�;���Yn# :rAB�P5#e�#��dL�# ���4Z?z����5Z�#!n��[�G<;CQ�3��h����6�=�@7��3��&y���?O���R�M2`�Q����W	�nA+	�$
���wg?��\^����)UB����5:���iG���%
P���X���������%����J��D�X������gs/
h��a+^AL�����g�)#
�(8��Ml��8��H�M�G���d�5\9sP�S��}����H�qL�j'CM��l��&xS���Re���@H�1�V�>��������P���6��L��s����3����rX�(�r��A���|C����N�z������!5?�H��z�����#J"�j"yxy�4��	��ldT�"��/��>��ef��7���5M(�+�	w1�&��>�B����M��w���+4Q�R�+�a�pd|����+7��UG\��=��t�q��6�T�)
I����*
�Q
#>����4��2�����~_.w�����E_��M��H�i�v�G�Dw@���r�h�])��%��sP�d�o�P���y�������3;���v�{��)9V��!���S8��(E_��p��8���[xZD
i����)���feS��8P��-�D��X�j
�	������R�_��N��N�a��R7���bf�Z7W-��s:k5���Z���/��A�MM��\����4
�.G4Y�&�[���������^=N.E��~��d����u���m3�Et���#y4��B(�W��jR�G5����(���	�W�3�� IR��_�������O���J[��m>*����
�2-@��P�e���������w1|���)��k�OSd����Uh���o������3�K���.�-c�a����r>��!'����u�a�����������{c���<pc��
�>����v�f���!(����%V���SM���"`��&;X6��I3�,'����s��GX5��������������	�%Go�m=&���X��zJ?������c*��)<��s]�6�S�o�>�z��������� FS�U*XUk���(%={K
wj `�
��qD��
u��#\*"\��!�|�Y����<���>+��a��o��H,a1�p�1TZ���tT+�> �F*h�,�4> �ST7��>��H�%Hit&s��.'��;���a�:��,aZ{��N�=3�0����h�M�^�eVQm�����% ���-L��A N�ZE1�SJN�+�6A�18���
�B~@6W���4����������R���lL��7�q��&������i2�wu[�
��T��tD��SH�Lr����LC��=R53���Y���
;�D�����0�<G���qHQ��#���R�����hkRO���l����:{�r5�e��(���y��c������N��s/f����l�s�������Z��������<������Q>�,�G�9�:�&m��<q����#��5��*�T��L�0�����=����g�wg���7��|�
������b8���d��)���e�x��B,�N��\�+9���8�d�
�F��,X`��~��)�g�H�t�"��|��S��d��`�)����'����L�I�@�������?��Fi �`
O;F)U�'�$wG�ek����a��%��r�|fn��=5%P����%�E��?�i��B���
�|	��j�\u����m��$�jz��}�7{�W���D�8��78
���L�>yF��^MCk�9U�P0H���g��5tKy�>jKxp9�����#������o$<��YW����
�S�}J�����V{S�����/��B{&�\��L64oFE�Ou���_~zK�.3[������nw����^�h��}y�X��T����^{g��������r=dFP�I��Y����H�H�6J�O���x��gpt��������?��K�����T!�5��
>�����!/�_,0��}�c������\��$&�!mV
��6��S��/U6������/q�.bD����Q|�ka��]�R'+$6_������aP�m��X��]��C[u��6H�?L����$�I��'
M,Y�2?D�5�k����R�]��gL�����"�mFpHs
atG'"�B%����F�E�VHRjL�������b�9)�6�9���^�@���1��!��"k�'q��6�{����K����s c�3�eG����OyR�yOk��f(`c:�P�5)HI��0���P���O ���:u����*�%b�����.��o������yp�3b)�D|��F���w��@��g�w8��!��������\#�1$^M?5��D���fo�����6,�2���W����.Lk+m�p��8��x"���xIH�ksB��m�������V��V�O��y],+��%����s$��An�Q�q����{�n���(o������Y�Y����W�4
ic��N�c�V�y���S�_I�A��t5d����IKb�]��� ��9^�b:}���b�����^���S�����������q*���j�r�,!*$�����h�0�����t�����ji^�o�iV5�_pd��������>\�����y��E�Bi'�j{{�������j�������v������Wr*��.]���������<L���q8���/�$I'ib,�|{��NG���"����B��f��
a[�b�-X>TR\0?�1����O�/K��RQj��d&�
���5^9�2�
�_��:1�E"(
4�]�����S.��z�G�>�T'�s�^���`&O]&�Ng������t�q�hV3|�=t"�����%i9XV��x?��j=�p����Z��
�_�����l���1�P�C%���u�q��a��j�������b����\�	�twx}�n�.���6��t�bq������:ZC����7mo���?;��4�K��]�2uw�w�8�83������h[�,����������F��H
�h�iI$����88���$���Z���j$}�E���8���?	�_"K���Co���l�����,����r�x�+^W"�+��5Z�
��q��+	R���
�������A�'Et�	t��Mt��b��6"V��J�U]"�*I�8���*P$-�H���7@4Up���	�yM�
O-��
M�����2h\��L���d��-N|(5��/�T@�o�s�fJ��J���j����5�"����]��h�����I�����w�5tt|������@R��Eu)��J����a�E�l�\��&�HX*�yw�i&�6��^��[���2"����_&|��q���y����^�'9g�o����}I�X��m^"YlR����TY�J�'L���j�AJW��T.���v�S���B�g�������Q��\=�\W��W<+ox�hHD���
�o���t�:��B�PD����r�k{�UE�S�(���qS�G�e@�������	��T�F#���k�����,�#N3Qs�����%R�}%4)Wfu���:W����,L6���mZHY���d��������i�=yJ�;��D������U_��@�<ER��dT����[������)Yg{k�`���gng4Mr��
bg���,��K��}	�f���"�cO
�:1�bB��tu��,�IP_��V�w���N����OvR�p S{L���b��3M��{Ro��[/u�'�"<��s x�3_vX�^�O��-htt=v���T1��N��@?����a�f�BUXy��@8c�c<�!n��y�b;f?�����D���dxQ�*��R�uu��W�����q��/2'&���q��������|=�*_O���#U��`q�*W����8�C��Hq
Z�%�o���&�h:�*G_;��h�u�6������V
m�s�O]�]�yO����Y�����5�u�__e�1j����2�,���5�^����������^
L��>���SMUuJJ�1iZ�j��.3/��0X[y�9�9��>ax��%��al�1f�
�7�8�C��I���a[�5��)�����k��/C)F]�\:V�������H����8w�VK|������,����c]}��9i��O}��~�o����0�	��9�9���`��"v�HR������x��'8Lf��?�:�&�J;����ue�|��2���H���\��t:���B|��O��L��xK��By^�<����3>o�~��c�O*^���y��zk������t��zf�=�C<��+�d�.������x��}�W����_���/��+��j�c]H�A�D9c.�W������D���>
��N,Q{�M������49, ������L!�����Y�s]?�$�<�'@z��b��#���
��9�}��i}�,�Dy����?��O�����-�������g?~�����;B]����,�2��,y�����|�z������,*2D�
����������Xply����U�`��j3�S�1�$ �J�!���K��}�X����+���6+�cp�z
�����LLj��Z<eE$g�s�y���<q����f�����;�{��~��O����y��<�e2���.�0g�%�;���E�
M��A��'9�)���QU�%��lN��l�gJW�9]=��=��I�]#�3B���3�v&-�FM��X�Si�1����=`�U`wb�����@�!��v�W����5H�0!�
lJ���S�!x��SJ'
�A����*J�!	C�*�d�%�`�����$�����Q��3�-��L"��U��������1Qy,I["W�7��%������'&y�����!a��4:��h��m�����4�K���U�^�j���0U�7`(YQIez��.��O�O�yMa�^)UW��������d��f&����"�h����Z���,��\�
i��d����E/��)��v4��G�"��������\��?�j�X��v��H��x��sIc��b�I���
 �.�x2 O���	Lj���z��AS[��N
R�����td�A������R�4�^
y�j<��|��(eT>p}Cz��/M�I��k������UzERu"o�}����`�{r����%����lv=%�s�y0D�ox�5��S������~��Y���L���J�1m`�#2$/��]ro�T������c��w��/f���-z^Q��@0.CY����4��9����O���d��3H�IkhiVa2��CMy�i�J�[U�e0�B��O����;S�g��k�����?�Y��>Y���K�)��"4��yX��15���������P���O�9���[z��?�
���D���*9�$���J���I�^*H�M%&�x4���������5��-����8��,-?�9M%�V�$����������w~9og����*k�T'����
!������5H����<gqF
����1*���3���l���[��d\�^�(Q9�8ikHv���b��n���'����NN����p����h�1L�HT��6����������K^Tv�"�hS�/d�	��_$��;yqNB
{��q=%��x;���]~�p�M
�����!F:y.�q#���Y/�O,U�8����{��x@���p�=�7Q
�����4���`�r!�����vI^��iUnFb�����=[r�u��P"�%D�MJ ��������3Wv����K��W����������T.TB�`<76$v����O�-�����54;+V`��Yv<�-9Q��>�;�]��M�������wIKu���V��&�0Z�2&��S���H�!����z��J^��*H����2Yho�������z"�
�`�H��z���L����u1�N�~}{C������I���&�������
���n�4#|/@l��6��!��9q.2�����R��C8��5�E�=�yh����NDlI��V[8��Y��+�=�������w�v,\�z���%\]l���p��c�H��P���K�����zp��.���:M�y���OTU���B�������?q�h$)���B�h�0^�3���K�����$o��;R�YR�����0P�r�I@�
\�R������W[y��d��v��VIT��J[�<����	�* �b�?��m^0�9�Zr��#>��O��� T���9��f���s��N�f��H��p|p�/�"4��G;D� �����Q+b,������������1l��<��;��JbKd����|V���/��_��;G��z�bf���uE�@�ffe;���0���xO��~���n�|:f��/3>G����\~�������&�	,oE�#�az����[(:!��P	�b�>M%���D��R.���/EE/D�9��2��c�U8�"�H�y�"j���o{d2����mx������.x��=^I��9�n8�v3/��[GCI����3,A�;V��=d��Z��t�L�����n�iq��_g<s��`_���~OF�U��O������l��w"����
O�l�6���Ie��s��A���p#�����R����"���Ah�G�D"`������������^�0gE/BZ�yS�'��p���d��<��cM�B�H�EU,���|�����<��	��D�<�mp@�%�x�t,I7��/����n����%M�@�s?��k$[,��������n�{�x�/�ew�a�����#����Hc"���#v�n�
�H['��P�����+���%7J�m�r��
��h������^���Z���� ���&Fp�������qz��I.^<����5����"�E 	���/G��Rj�d}�`
��d[��y7�PG�y����+#EV�hN����9mb��i��%efa��h�wrP3�����<c�
�b4�|���������XWg�������5�rb��"�������M��U�
�m�	N�d���)S#�~"f���,;����<�SCUq����z�[�L���,�8�}������7�g��Oq���''��x������x5E���l��^��/�m�<X��WC��������?}���B�*�D5���
]�(B������U����������f'H��)�N���V9�)B(�g�������*�a��f�`F���J�g�Y�VjL&��-��i]����x��$��
nbi�=��Q
J,;��'^���+��P=%o�D}�!{�.j���K���x����,L�H=�C���u�)��.�}
�x�b:�E}D?�����xN%�����~����~��H��z��.�n��
�����h9��Q�uj{���K�����*u�ND�&��"G�����l��?w���%�I�J����F�1�M�a�Ev�`�`�~p���Fqe��V�!�����k����P�=��H�[�8������bXW��1.������#`��|cx�eRW#�A�8����a>�A#�jI�
�Q��d\e�d�R��07l��t�0��T��r�}t�f��~z��K"���^.PP�v��$�*��~&aN�h�6���E�N���@%��v�G~.T��UbWK�3Nr$t@���%���~���a�ux.Yx*���<��.�S��KqM�+�3Mb�&�l�k������\B��H�;UMI��C>-�6(��_T�7�B;�������u�����K;���EO�{���;g7��'_��#B��/H8���+IO�m|���������2(�zg��)fQ��_��5[��|#:�f��{i|���Vo'���R+Rn�v!tw��5;��%4w����r�;�gJ�h+�m~��V!�*����2L9d���M�P�$��p1�1Y����7��.����HQ��.J��qa,�]��-�s^�(!a�|4��x�{��*b.�t�����1T�T��*?]��������s9!g��CT�Mu=D�=q~3��PEWh��U_���$�JBK�C�%�e�r���x,
P$N��cF��n	^�����g�������U�g���K�t��6oA��q�p��������u���z�O����_������>eNjD
1T��Rkk���'���*w���jR�J!��C�P�
<Jh�~f�AU�H�r
p#�(n�pInJ�{����_x$'���d��R��:&Y�>muE/urE�����O����F�W���w��_.,�Be��_�d?6rd�;u�4��+C|���jN����wk���[tz���A�;(���
�&���8��Ba��rc{ma�����E�����M�G�>O�U��e�i���b���!9H��ja�?�/���K����9��4^����A��E�g�TG�����
O��d!�Hx�pH�Rz�Cd��!����8��WC&'���I����M`v+�K����D��>�$F����<��Y2�W6AHh�t>��x����pz�M2�d��������B4*"����x<�b����������/�t��������s/���S�??�������H����D8:���{J�C��Q��N���
���vO��O�}A���1��Q�~�����z
9(a�+�B�l�����0�y�B��I�0�|1������&�y�C�*����!8�@��"�C���������1iR�!����7��8�+5�������x���K2Cm&��EX���yv�����a��)��c�B��T�W�sRZ5s�Vl��`R\��IHX�?V#"�9���Lf��Z�U>�c�S��3�A��nx.1��|�,�K���s�UH��������ReU	�2�E���N��e����$�.����D~��D�Q	��8�\�����/�r#.
D��k���sT]_�D��z�bK��@�Jc�@[�a_��1��S"+��w��6���h��q�IN�����
���o�|������%���zRX9�2��1"OO����@&��3��Q�)�?%�}
��|���`��1�1����QTn��3T���P0*��V��=���<$y?�����6nee��-tJ�%�GQ:f�y��+k-"��������g�0����{x�w�>�����wTC�����4�*Sb�,$93����H��y9��y	b����^����>��9
�	����b����h�����~�{���C�u��r��y@=��^����d|������0��r~0��@��R1;T��L1+D�a.i;+Q5<�TX�����Gexa�$���b5BnM������Fx�&�d��K�������m����K��`T^@�8���=�=eJ��
�9b�.��W�|���8J=�g.R�����
�_1���M���
B�����r�W�9BY��|32�2�]p�(�����}� �!�J�!����J�I�2?�8�M�_�kO���� x�R�t��Y���v_��Z��D+�R����X�����x��F^����q���P���WdS��kU��W�="5F����
�'���@���O�
yX� �?o���=�q�$^�=���kjJ!�yU�AD�;�Nr����|�Y��V��@��>�O�����*����,I&?5��;vr8#�R������+	{=�	��Z�/��d�'5�Z
k�6g<����R���V*9���Z��%X������&a���'�v^I#\����;������,��������@:�NHR��&4��7h5�����-J�#�nU�1l\��l�;QQ+��)�Qo��'8��W���n�� �Kq
1�"��5�1��R9I(dW��eJ������3��{�hP ����������K(���rH���f@DF�:���?_���A���3N�K�4

�W��b��M�J�,[WJ��{�jWe�b���`���VwVeX�6�"�c-m��=�}b�G!'�'�l:q��n/.]�O��Z�l��c5o�<p��Bf!�l"
���
����L$},.��b<�xhB���(�a�{����`��a2��	��D/���
���X��P��9�g���
�B�H��s'�
��0435�!�*>�pn�|���M��L���d��{a_s�)��D���\u�;i9�V����J���z���;nw�q3�	�Iin��>>��R��8�YF]������3E�I���cV�4�K���}F/���w �/��]V�����W<������`�� �/r;���{�~�y9����d.#,w�$V�/1��AjEJ��t:V�a!����k�?�5����{�-�m���_��4���\k||����d?�_���������������'���]���b
>_~7�uC��*�U�������,a��`�"�_5x�_0�aML�/t�>�C����-�
��*"I����V���O
��������L��W[��=���a�p��]Kr��\1]z:��w�FX��6�����5�/�P���[7��2�YBVg�:����:��!�����U���:�+>y�U��r�r���OZ���!�����1����$;6ATj��wb*tT���v�S��4jH��b#&�h����T�+�v)����z*��J����Sqck�����q��~z	(���u"[�lqC����z������5�vjC������9���E1� ���;�8�C���C.D��KJE(�<A-C�v4"�^y�@92��'��E8�8B���%������.�_�va�?���.�C<B�IJ=�
�����
{����.���^���^�'��dgg'!DX��e��������|	|�kl������L�d�=].���U�zQ$>��q�[
��������P�������*O�y(7�4fw��L�����sT#�>�����������E!��S��=�����Y��%K�6��VgH&Krl���g�EU
��{*�����l�����e���������/��i�]%��(�W�;�h��Ad^��yE��&�B��W�!/�(�c
��q����fgl�RP�h)-��@�V������I��o�r�6v.`��8����u�
���F�������]^b��������
s�G�>FR���`~�Z~x1��KxF�����5<�?^��z�"Q4��G��l+�b��3������8�1�����Z�w��/���A����)��]����"�r�JHB=`��bH`M�\�G����B����������$��L��Wk��M2'Evf[��;U!���-��|[G~���B��3QH�R���"��o������=��������	xc�����+������I�9u����]4���T���%��98?AJ
�ag��,�X��K��$����Z�U�H���������r���@<�x
N�O?<?(,�?����	�����������D�>���������O��p|��"�HU��<���*��������g?�x|��2��8������-��i+�frF�-hH�b"6���bl�qP��K8���$�]��^dEV������\���
BW+%-��������F�g�:V�"�Xc
%�j�(���"�m���Wf��d��3�~���lmU���
)������z�w���R���KgF��L�I��|�O��S���+DYr�I�^����V�h�Jk��C�����!����[gWs"���l3��PS��?�a��]CO��$E��h��D�m�g��O��A����;�kC::�"��Z?��`��d�����B����.0�^����;`��d��taI�1�!���5)��Q���,�������w������K���CH�e������������f�p��~|��w��y���4�����o0Nbm���������wh����Y	����?����wo��c�y�~���X=�
�����G(������V'*����[3T�6�Vtg��j���y���������5��V�K��r��0���%Z�6���~�k7Ws�`K�,3X0���YM�C?��Q��{���vW9���:�n#$�(�A���3��9��&�+�O������y�,*������x[�T���
�l�����qK=���H���C�*�`�5������L���4u�p@w�%a�g�[��4n�(^�Q����������qlk5uE4Mb���
�/�/%��;����gD|�*x�z�={sr��7�S����wt�F������a����@�=x������M*����������Y������%?`������P��+Vz�-�}���q�g����>������i�F$���.�p(�o���� ��:�!�����(GX���L1�a�^�F��
R�A��g��Vo�"�a�-�"}>��~G��+��������!
�>o� ����c�U<J%��i
�c��h4/��q/�R��j
�K��G��=�.�����r"2aO�"w��K�����	���|m���P�]����k{Z}�^S���{
����tuj�� ����u8s��2|�V%=���eX�n|};�C,A�(t��/�����yx����`k����!���1Y|����i�:I������V�A�!��v��
8�������"��`����Y����+�B��=CG��x���������*���|��l��u�Y�`��gKZm}����_�S���t�L���%���XDc�e�J2���^:���:!�_�9�����5�Mb��k�[���U�EU��(���B�`�����f�p)P����ze��V����SN��
�������[���v0��o�!�FrP����L[���5�K��EK~�f;f4�@�x�YE� ��Q���7��\J\���L����9���o����\T5���� `gJ����������J�i-x�&��`O��d���^h�����������Z1��l�Z6�;k[1����L�C����z #��2�l|u�%������
��@�^�?����� %�,+�*�$$��b�7S�48�m:,"j~|��"������R>�F`�p�)���c�������@�#�t��a�&/�����6���`�)�h�PR����EWK�h��
~z"�W�yP[l�P�����l��X�C�*�^�J|�&=�j���.N>��������IF�{�$XX��zi������!b����G�n���~_V�c�=~^;����b^;�j^��h���:dr=M�[4��6;4�.o8rf�-2���E[�3����ov��� ��0��U�v@�z�V�>!mQf5a�D��[�������*>���<4�5=��H���E����c�j^��A��l��)��q����$hcHb6�?Xx��rN������a��!����0J���%�w�|���D�3�N�����NC2h��"[�O��]���L�$`���
I�v�U������G�g����������6B�C���������O�u�������O	1LU�RJ+st�������#�y1Y�K��]x�:~OB�j~�a���iVl���4�/^�b�B�=�ljm#��_�gs�p�/�5��-��,�/��W;:��A�"Zk���'�}�Q�0�������%@�����[X*�I@*���8�����E,i���`��X�6�]�K���9_&K��2�e���itH8
����w��%O>��+�-�	r
I�XY�|?c�xvc/����
�CsXOA1�l|�\���h�����!������������zd(j��",��n�ZV�����`��(��
l���a�r�|�=���K���=<$��F*����a�A���.��S�0�	m^���a�.�1�_lUx|�����K��FFv�y����t��3#�����	������w�(lC�wM�����A���l��5�"�����tF���4`�z��������G�!�;�+K���<���x���yJ�8P�O"�iI�BXc��m�^���_���P�`�I�j��2_����:��."��oD�=��3<:��B�T��^�_�]~����%�����!'��6��&�Zf��V���v����S]�0���r���,����!������F{8��w�)q���gXi5L�Q6����`�����|���)�<f������w����
o@Dz�_�<�	b��;�?�����������|�� �K������)�W�w��������G�����N��9x��������?�B�zrp�����[�1���e��������>�`Q���������
���:��dc&���?9|w��g���!���������i|ac�;WdE9[lu�f���w��(�K���8��}34`�Q	$��)
�j���-J0��A/M��-�/ �a���r���gcl����v�w�	+7s��a�w9,�
��r@���y�{%�#�S�F���f��D��0��o|L������#A)�����=i[STJ������l�)�"S����M	�iN���9@%r<j�Ico�E�dU�
p�`��Y�U�����o�C���!$O���"`%z`=�+�ft}��3�%bE�pr�S�T�&�������N�z��r�������7$���[�!f=G�}��v1���td;1�'���*,U�5($�v[C��=;:|wpvV��V�F J����Uv��eF�6�}��5=(� �/*�a8>k���>	
�b&k���9�4A��=����(I(�d
P��-��8$�;��������$�
+�[R	�	0����p%�a���X��'6����@����!�$��!�K�Y�5��&��c�qs��z�%�#Oif�&��q9q��g��f����Z�~�����ZPpe@�_x�����/���&KO=����u��������@�`��C,��|�B�������j9�~w�>��:�$�iRi�4��������8�tK#��l��d��Dd�3��*o���5����4����p� �������������8~GD
5����X����^\��������/�
���x��J�"�!!/+f�J?}����!��]���1'������;����h����K�+�O���!������Ajo�*d6t�5����.k�l�L$�"�a�[_b[bz���66UMjTX�P.���{��
}OE��6��W������t�����������I�9c�W1��N�;�lm%�DS��L�6v�E��h!��K�����U�9<�c��!M���%mkGW[�Tr�@9z\O3t1�A�!�F[����^�a�3�+���'���3+�-/�8g�uq��;�s����� _����S��+����$G
��������aF����K�'D�}�X0�d������23�m��;�)lP��DZn<`Sb����w��}��N���c'��$����=�
6�v�}%x$�^MIzJ�1L~&�<.(mgm��4�h�]�R'4R��u����J���5\H�ES=����,V�&��6�+��Y1���%S���
��s��=��u�{��B�F���pC�JK��S��d����(��W�F�u[�Q2AQ[$+��lb��u�Y�7�c���;�^��l��v/�d
��L�(1�I�8�w�$��~��E��{z��M�3��
5H�E�C���|�U������ba����ml������Q���_�m���d�������LS��C���N
�,����Ch��O<��������D���L�X������HL$9�*��������]t�n��5������YM� 
|�9����!	!Y��[�4�nD����������j#nI�`I2�	9)�x��O:��re  �z����3��F9�yr���oB6�A�vZIRg�4�J!����D�C�=��1�%����|2��Hr���>��s�c,��HO���v�]O�
N��3P
��%�_��h�w�e������	��%��;�6�����}n%��"�K���B�����K�v�rvFc3'_����i�&���zx�=��a�a��;�q�d\�Z_�������x�a�Hl�
�������Y%���bU_3�2���]���i�P&�~��'M�CB7�������^_k;�Q�o#Z��un��M�"��2������rX�RKj�U"�	i��]�����j�\�V��O����kB�U	�����Ayi����S���)h�#����p'N�\����y@��|$C���W,�H�Y���v�����P�u����
3�F���E���R|�$�LV��5a��"�\C��A��k�~U��VB�X$Z����Z�	|�d'��	�=����i�m�Bx�����ZF�;�����SVqM���_�_��b�z��v��i7��N�(�tP��=�v�-�t�
97�����*��H9����h�c��G��=H�����Medb�������(���z�M����Y@���_;���X��5,Q&K�	��u]��r	3
..�G��8 9�gz1-z�
��A������+����W�P�$��
^���_V��am����a�\�[��N��3{v/�����9�G��s�\t��f;-so;)K�M�����A+���4��	�]�"&��	6a��"������h[t�,�"�f"B�]��|�o� `�&�������g>!���a3�$���$4t�$��+�Z�&���'C����l�o*�m�"\�Z�<��%��&[?�9�A��T��v�kQ��!Y��GI���n[-��m��nW�f<v�$���j��qN��]6�r�2���Z<r�n�D�U9A&w�&������k�9
�����o��Y)������u��I��@5f�t��{�����w�];A�����3��T�iS�&�����"�3m��Dk�:�Pv~�&�3��e�K���*��r�5�g��C>����UV������3e���B���ai��{K��q�M������ZX3<S���������fo$�
��w�fR�,�����t�&��{O��
�-�y�C�u���X���uFHR>�����|�����p��������j�Z�Q�Q����R�����187/�X�����8�����U1DE����d�1YkO���6�D��/�H
��%�����������C��>���4�Pjq����Y[dVFQa�*x6���F^�0=��{
�:l��h�63��}AS[n�<����H%���l?�+�1:clf��B&�X��W�^-t��_k%'���"�����+q[�����ZaE�L;lE�H�R���\��G�2�1(�\�\5�X����>�	]����~�,(E�#6�u��&hV�&�LfY��>w���%dj��5��K�&�����1VW�Z]l����t���W:�U���sc���7����4����ysl9�|�q�E��[i$�Q��U@�Yg��W�U0�o�����������6�2�$���jv��L?�n6GN{N�{��G��w�����7b&'�vOV{@������1Df�LNv�Y2����4��D?����l��	����
���iw,rl�~�T����1�{��mJ��4��M��q<2�|2���T�����No����Nmg�@�Z���s�1��	 �)��#I�"��q���XW�uo���h�5�Fq���;�F���QkM4�6�Q���:�Ph�TB)�Y��L.+��"�m5�m�ftw~�Nn���V.b�unS2m''���_"g���%�{�����n��\u�D��Y�KB�����Y�IDB?��~	�p����s'm�]I�����}����+l���/sc���'���~��������	�z����p�t6\'�Y��Z��k��E]�_�n���,�2�rf���I��� ��g��_�~��|G��1S+)���bm���9nz+��#�!vr\����}���p�m���]#�vr��hn����*��W�I�;�\��u��^�G�5�Qt{<b����n�����V/h��;t�;E��W��\�z3?���~�n_�O7������`~��_�#l.�LV W��(u���j7�A���R'�m:m��29\��)��L�a�y���?����=~}�c���'X �pv;�����6�	���%Y+S'7���j ���*�#�vd��b�g*IAe�aI�Q��<����X�@�V�Vi��������{��S��n��V+��� "�^8��b���,2�E!N���VWf�=�d���+���{�xZ��=vz���������������x�*�GBn��SetaM�KnY�+j3�a_��k��L8�6��L�gF9��}=��m���M��w(<Mm��_��SZk�����l���k�YV&d�i��n<��=�}Xd�BYn�I���d(C6�(8�{��M�5,?gf�}�������/�q����k�p��U�^�>�O��``d]�+=C�(S�W&d�r�DGV�������|�>���dR��T"���jVsN�	7�������&���d�n�F.�������\�L��c�h���!%R��6���L��t# ���2�����<�`�YIk��Dhuw��Y�bt^�S�Ff%������Z��jKG��{5_,��BD.())�?��(���8���E3C���V��.��D�@���
�m�� l)�~���u_�A�G�����I02���B���!&-]�A��t�4>lj���y������S���yn�D7������n+f��V���	�|2s>������f�5v��O�1h6����X9�c��.��S�/A�����&�^5���a��d3���9n�u��Z4�*�r�M�3��*�!(zz����n4��=�1�h��i������	��t��+��������k�Sg���}����a��1�_ H9}M�����%��]�����e���������;x�k����';�
��[��l<���;������<T���q�M���X��(�����A~s`X3����x���z����C����0�)&�v�Ta�;�X�q�*O��q�Hc��)r��d�~F�+��	��'D�Vd=�wn?������G�?�mV��@!�d0^��p0~����q=A[���������1����s_�o(��g3De�|��m�'�P��V_x32��P�|�	��������G��"s	�C��P�u{�	{r
�w���[:_���Ye�M-��k&�P'3<�%�������3�
zf?�?k��\|�oc���.��K��J|��o��o��oS��Z|��os��F|�C|[�o����n��O��g����v'���Y�U��Y��f��.����]^1�__O�"F�I_H���i:�\����
�IS����������Z1d��.���A�V����N������p|����C�'�+d�QJ0����[Gt3w'��'�}���m������M\���9��+��c��\\������<���4,�5�U
+�H�;��[��`^&4�`��������A�T�����e=I@�m=b%����v@Q���.l��)n|�����}�+O�4�Q�''-���$T&$b
��F�6|��Bh����5�M�kE��J<@U��4��W'�d�d����
�%�NTe���=������7��5��4�����-ro�E0U��/���3z:�����?Y.�Dx.D�����#����f��3u��F�x�u��|	����6B���0�_f�X��=�=dD��5���?�%=(:���n��)*�j��^@)B/��zaO�kf-�i�\��U��9N�OHk��xR D\39hMu�6��l�%�x��c��A�xC���~M.&L�X&�����Lo*���EG�Hv*:�k��t���4�����	��N��O�}�vv�1�%Zo�(I�(-)��D�q�L)������ YMM;q�����>�x�G%^^.~����cg��'�����
hoBh��;����|�"�$�������XH��6P��si���A��v�b�P b�j�E����{;9����$I�N�*�����������	@@��e
�p����o��U�����eS��?Ro����������)<�^���J��i? ��je�F�E����}lR����9�sze��H��D�_���+�
�����.���`v}#��d��#S�M9��<�|���4���t�#�����R�J�`���kb�)���P����Sx�IJ�=��������OCMX�N�������O�n�%������o55Z����<����B�x���M�����m'���Xm�&��{-m�p�{����:��(��Hi��'$"���m�P�p��{M]����q�$�%����\�A��[]Mg1��y�n�VW���N����[��Gl;��T�2�V=]g����J����t=��?$5a��3��S�C�m1
5�@\;������T�:��r���u�G�;�(����`k���06,��f
������=���=@m��$vX'�O7���uYh�Rn$�����V�������NQu���
[����:�9��$`��'�$���,�I*�����3S�#�Pp�f\.�;<l}!��<�,
���W� ���/�c.�$�!��l��F�o)�a����huQ���OpEL��%c��������w2�d8%~�
�����&0s��@��7ND��Y��A@	����.?M��)Wl;)t6���b56
zA��(=_Z�R0=,�hk����y�����l�9E���r�VM'��I�Y��K����?I�i�)���jMA[��Pl;k��e�'����
�0���*��\uK��A
��&�N��	������Y��% ���8��v��CH�"��KVJ��ECMN��v������y��q!����G����d�%�k��^���'�,��p/��0�>����v��,�k�����v
qv0�y�n
�+��#���6Vb�I���%����.o3�������~� �\CJ����VQiW�9��vL�Gp�����Y���0��n��1��/������po����0�9�f3pR%��3���G����$���I}Z%0�r:��U_�w�X{�"���W����Cb�)E�K����^��D��LJl;E��h���m'�g��ES(��Mt���%���p>R��>	�D��6��!���}>����,�j#�����mg���Y���(����4w\;�9P��9�������H��)�#� yzW��hN���L�����Ob�I*�c���bi�24��B���Cl;��/w��u���I;�k��~������v�~�v�YP!��}�e#':��<��i�������n��m'~1F����R,E3��N|���M���g3����n�m�=�>��,Dg���xrq����	����b�K�]�#��F����|��]w��^����c�B�kU2s>�P��apX��u:O&���5��F����G���z��v������t�dggg]��~���Z�X����C�~�d�g�����u�.�s~{��	D�%�&���`Q�����G{�o�!��*������vA�^.���|�^�=�~����k,;���~�,p_<n����C�:�;���`�0�Fp_��bbOF�k{q�~w��G{�|Y��*����^�����[������,����t�����]��os�!���vys�T�?��zsrv���wG�:o������.�����6�P,b����<����5�v.��������o����v%�M����������v-������v#��!�-�7W|[�o���'�����E|����lS�e�,�b���'�xp�^V�A���po�tR��{!��6��mms�D��z#+�0���>����7G�'�����'Y���NG����V/x��������}�L�ks#������C��Cv���A?`>B�XG{�m���Y��V���8;�Kgy
�����M0R�������iyl2�)fs3�l}��PX������3w�%��yb�Sp,�|�����~�'�M
NaV�d��};O<�.:�KV]�j�4�����(8���#�#���\m����Qv����xu�A��V���]�i,����^�B|3��dH�9����|�q�{	7�Ak���no�)nk7]�S�L1@
��n��H�S���)�'�s��8���81?�#C3*pt��>�I��zD���@��N����������q�����l��.�a�b�^���5����H�b�J�r������rin���wi����4u���6\r��*Y��w�ZV��;�24�;�X����������k����kh@j};7��	��-�Z;����2��C	������y"��h�\I���+�ZM�,�����I��M�,���eu�39T
Zn�`�0h�wF��"D'
����h�}�����&-�N�" 
G|��L����������S����K��)��x�\0�V���S����X�T>�(��#k�'-��G�tJv]�k��:y����d�=*����f���[�Ic�`��3�kSAt�%�\M���S��8����s����G7���d��#��Q�<�1���c�'��W��1@
��a������r����s'sR�2 �&sd`Fe�<��x����qXfT��G�H��_#V��$C]Uc�]H[��cG�<���.�Y24��,-�E��C{)�i�����%�b|�E�ft�E{�w�$��J��^2���x���h����/�/�7�b���Ff��k�Ae24�AeZt�<���{8^��������7p��j>��c�0Lb9`���e�}LD�{�g��SO�����vl�;#F@p	���B��#��8)+Xw�+$���}
��I}i��%���g�47'hW�Jn]r�8���[�
��%��][��I��E��_������[�#p�Jf%�n�k�})�P�2�l�����^����)�'����Y�N�D�*gr��\��U�}6J���P$*���{f��e(X�������pl��X�S�*����dJ�e�����?\\*�v��W���D�
��.��|��m&
����J%������m�k��.����c�p*�	�^��]5����|�t�>�<�dF�3�[�~�#��������L�/Yi]{��+����e�5���t�����}<:����l���5-{��3>��g����Cr�?��F�7�7��O�g�I���
�k�e��T��
=J}�eK~h����=k������F�k���e�0.���"�3��RXI]���o��%�3�U������������o?�m,�y��f~'J�fv'�d�E�|-7�;-��bwZT�NKO[�qk��xx������u����d~'�ehfO�o�B(|����]wi����g���<�w��������24��J9�9<��������b
��]��:��28��J~�9D���������_�w~m,�y�d���n6��C����6�j����|A�����[��Cj&�0�J�
jnY�S�o�-��{RF�gR���9Xwd�1,�Has�a
4�~���0�qe@�f�
M�=�	�i�VL��������
�4k3
�@3��Q�Q��GP�9�B�x�hh�o@3�#S���N[L�o����Aw�������o�)�&�B�x/lhc�@3��Z�����5k�_����Wk7��������{i@�x(4����j[��e������U������P���+4��'����uhFNJ�vs����vT�����*�|5��\�i�>:4�)J@3�S���]�m����re������W���
M�-�9�&E�V��8.*��
�J��"��<�j[3��S��O9i�*g� s�B
8�<V��
�C��bC�2��n���9W�KY�o�q�@��6�����
8���N�������x���� �y����Lg��.��a{@g��$C3�>��i��'�f4+k��6�	��E��3�*�3��&C��CX�������u?��%��$���|������C�._{7� o\�V��0H��O��(���f�.9�f5�|m�|My�=dh���j|���c\�6x�&��C�	���_���*���������'��'���������i�>���J���-�|m�\���?$C��[)�|�?	�"�'���N���������������0������D�n�������z�=�+��ra{��/�U��?����{�(��)�M��{f�q�P4����G)�@����z�D��=9�y����k��k�u�y����	��Sh=3�@3G�I��srnl����n(���7p��^ep9�Q����Q����Q����Q����QU�/u�R��%�\g~�[���C��|��|�-��c���R��(�����!�X���C���|���|���|���l�q���:n�%@�~�|����������eh�/I����������-�M��|m�|M�|u�|Uw���24���24���24����r��[c�]���x|�������+4���2�����j&cX�:6>�y�<~	-m~�A�`t�C9)�*g� �cB24�V���	�C��`C�2<z��]�f�I#�CA�4m#��G�aj�<��i)C3o6���_,/C3{�|)�s�c�k��$C3�5���������	���{�dh��f24�����^,_���I�[��}d~�Sg~�L��{O�T�K�=����6��%�������R�Iu�!�Q��}�CX�._��|���|D�Mc\whc�K�V( _�=�3928�;dh����{���S��wg�ep��&���Xn)�����p0_����C�\������24�Ydhs�$��1�J������YI��o>��Mwb�|����cl�$����#��M�:lo �k���I���79\�8Lf�$L�pm7�>��_7�VhG{J��d���{�3Y��Y�����r���*�eX%  s�!V�i��5Dk�������������V2������q;@��12��@7#�U.c5K6�@�^��d�L����TBz��m�����������5���[&-c���U�w.�m~�M�q��~���[%��	����w(�w�5i�����wS~������(�U�}����s�Da\}�o9��Szh�9�6c���?D@���p���Up�zTp���p�oJR�VP��)I��;Z���%�]�,��R�����
8���
8���
8���
4�q�
4�78)�����n�#���|]R���v1v���O��D�P^{�H9�y�1���%�m�t�e#1����cX����}�qe���L��������v��pf��Z�L����$Y�gt�c��M������6�>�3L(��X�>�P�^��D��C���l��>cF���#e�_�����f�mu��1��NQ��:v�����Y���s��%r���sEn��>���y��P[cLXdg�b@��HF�O�q	2�[�h�#�dh���dh�c�dh���S��9F�f�RR��k1J�[��x�3�������U�O��@3&C3~�����6
4���+�4^E�g��v6����y��`FmK`,�U�/l3��gS��o���,�~S_���yA����=J����
����q�N��k��l�N��%��4�����.9M�i��4�=�28�14zt�J��j
����5%�����G#�3G����Qk|�&��6�+*��+M�F�h�p���1^��^��e�f�i� x>,�0��:�����F�hAp��pc�0��6��9%��s��Hhi��
���LQ�P��Q#)���'���{�����������i�	��������+yn�s�1�|�����*C34&C34&C���|���|��Mc�X��=�gQ�d�i�cH�m{$���tVG�S�%a�
���:=8�y	#p�[�%�m�t�c�q� I���X���}�}e��7��k��k�3>���:������a5������*YMY�1���Y�y^�fv�Y��(�j
���d5%��O��W�1�����QkA�E���FrE��|����[-nF���([�s8�"�3{�E������~�����X�"]������&
�H�P��
d~w1����Q�������G�)��_��@3~�M�e���t_�Vr����d�y���p��bT��S���Q�f�2F���@[�L���zH��i�D�/2��&`*�W'��{�L������Im��`��s��`Ft�S�M����e��P��x}C�R|
v�L'�$�9��y�S��1������,�Fw><�d�%s}���2o���~+�+��?.S����>f����:/�kQn`�������{A�:��N�?�>�u���A�|e��M���#r����?��_EBKyH���
����X$�C�	(T�P�a2�xI�yi��3/��3/&��|���p1��p1��p�����w%�0���3/��3o��r�������f>\L�f>\L��1\,L���^A�}S����-���;�.�������N�.��������\����5
��?�$�zr������=���b'���q$2G&/����
�N�x��aX��Tn��RN��6�8&R(}r���2�]U�G�j���b�1����5���|��i�k�)��3���$#�|�����7�)F&�<Y������/(m��Fh�����v�����"���W�����B�7p\tg���
L��
�>�W����������0��������c���?N�f��8����h���+yn�sU�3`'C3=(C3�
����	$C3~����q
4���)�4���	7���h�]z�s
u�&�}���@���-��n�x"���cz�������Z�Ru���8��Qd����k��?ry�n-�C�Z`��@{K�����A�g����7�3�(�� �P�[d~��
8����g��nQ�t
%�-�l�d�3Y�1�
8�1����#'X�eK.[r��l����h�{�e�.[� }�/(q��A
_-4m��)GL�n4��D�{����p��1���{�S�pv[���pFw�(�	t��u
O���g<�[���0����T���T���T���T���T����,yn�sU�3��@3��@3o����p*���p*���p*���p*�4�p�4��/�K����HF��OPWg�y���t*��`T�.�N�1�
4�w�m�Bq(��_���{f\��e(��m�q��H:��y����pF�r�/L���J.Sr���L������
�)u��2���$"{���pF/X�/\�����2E�}K���J��*F��+.Y���s�H'�j9�*Z���^�����NQ������^���{�_pD@�w��
��4Q���P���U���ZN�f�j9����h���+9o�y��|��|����7@g�j9����h���S��ZN���j95X�������B���
Z��S-�
1v]q��|t��y��G���hZ�~�[=��������&��^�
��t�:��M�'�^��,���.F��^���.��]:�r��r��8�]�V��������p�c<��|��Of�g,�0�]3����<������f���^������^�����iwv;�>���Y����z��D;V�=��o�}�u%�N2��n��8�0��&]�\�5t3w'�'B��gn����b�a.2c�������u��.<s��!}6�g^��*���5�gO��������[���jXw����X��am��2q�Ov2NW��f��@��E\�C�>��6�a+�[��gf�\��3S�c�����|�-x��?e���t!Z�C����x���	����$x�)O��SmH"�$f&��$���a�tDL^�L�������8��J(��)�&���g������Y,�?�~���[�2�����!_���E�h�n+dJo�l�EV|�n+dr�dl��-�	����dU�	��n3a����^;_���_�"6.�m�L�(k+i�#����Q�*I��*�B�xA>q"�+�d�O"�e�K����J(��N'�f�e%�UQT�I&f�Ca��
���P6#8a������p;8�HSUfE��A:p-���]<K�	�j��&K5m���0����0��q<�����N�I��aj@Vx*Y�$��8L_�
O�
C�*D��L��
���7D�H	K���9���b
���fJ�*��������U���ZX��Qd���~w��#����-^P y��z>f?������\�+�A�}�thy��+���\���\���T�B E
#E
#E
#'ZH��H��H����n�5K������������
]���E��-�U)���%��<��<��$Yc���������$��Nt�a�
�^�����+�Rk��J�V[/�����O���������2n�0���&1n�#6
�3b�#�$|K�+5�<�N��N���#!�n����S��F��<1����K��fy��E�� v�U����)���&]=��>$V��j8�)g5���Lj���� ���k�e����������������yx�  o�9zOc9�����UA�!���*z�K��^9��M����F�"����iuX�����C��C���
/�����q��������9	�$�0�8�w�������H��e������pQ ;������~�J?+�������O�* ��Ht���}sus9�V����.!�y����^�j�����2�x�*�����3����x:��
��D/��I{������=�U>�'c<�?�f��?n'���|~�JmySdA,����7��cA������wgg5�y��nQ������f��=�������3_��b������"�:����Dwj���<����`�pl�%��lT��]g1���'�6��w����K��U�i#�����S���)L�d�z�jt+:��Q-1�`�K����>��[L���~������6����#�]�o�����6�~�~������6�����������\�m)���o��������N|���Dk�����4���$�]ZV��<��,-�^H�ki�^t+���3�2g_S�d.q�V4=��fs	�l�.�n,�����d4��`���NaA+��)�{�3�]����w�DS��l���p0|[���x�"�x�~�Of�i�������
�UU�^�y	i�ht
�����>@��}8>�xzW�C��N��2�������������l[�[�g�%��g��`b�@l�H�q�ZfL+[���b�a������1=���_GN��z=��x�kH�'�_��'�A������3[G�6)���_��df��3��F��`f�x��I9�[��uR4/�_��!~�y9N5�_u�`kL+~>����`6W��'�h�P	0��scZ).OX��\!�N��v�(Q1�d�*��
����kcZ��Y3�$01�a}�0����nL+�e����Ub�V�9�JF��`�� ���)��`lL+�L��Sh%b
����A_��rXL���`1�s;h����V�f1-�,�e���`lL+~o������!�2H��y����ja�1���bW��&`��+���|%^�CI�T�"�E$vqx����1jY��V�bV@%��Q�f'��$l?<���t�`/(y�+�"��+�����JI�u���#Xe@�z$�,-d�L4���������ZZ���f�r��������M!Eh����VK�6pL3�M���b��J���m-�Lr1]�)���KAq�����+����a=$�Lz3%#�/���	=�i�
��$����1��"&��(�"���/{\3���X]-VI\3�DO�`���������%�'��;K��_bNid^�PZ;Q����F�x�/����BP[M�R��I����� �L�O�x�=
$<������x9=�3�������N_���b)�D�r��Y�6}��F��B�M&���!G����D����w�/��y�	y�f�
cV�b���'�xp��������������<�c�nd�a&W�'������7O>���!�=��i-sy���y��K�+�X���U�����e�5���t�������%��1d=t��l G|g�t
�dA��aD������B�z�my��1�gs�����=���wxE�7n{�"����t��7�G�X�h!9�@�^+���@m�a$&q���{=����������rf`AL��6���^&#jg#t�7l�{�������U�:h������t1�m�.�A
��a�>������p�Q1f��KD�wd+l��#h��QR.w���r��].��[n�jELs A�%�Qns�S9�r�w���(g<�z�S~G�����ydd�=�^���Vs���
����}N�aZ��L!���V�,">��R��#�Xc���5��$*=���k[�m�����kkdm�7�����
2����MJ�R9�r��������������R��|2g3B�k8�� �������a�74I}1�M����@���u����r`���fp�d��[�n�7�z``�9����N�4�Ov�f�d��L�����x,'Q^�p+�l���2�
DD�D| e^�>TK4��$<��TA����0{X�����V+S�$3V�w(�j��j�iK�ik�?��x��tK
��H��������kR8\��j{P��zO
�,z�y������d�������f�]~q�+./B6���o~�ydv���O�P�����-0��1�#� �n�y����lIOz6�
��6HH���;^(JMr�����A����g�<�]A_��3�f�f�1|��M�����'W���h��C�+���&	�=�h1�������m7q����	���m8�%>W�W�{�!�}���V�}fm�Ip..p�k�Y{���c�
���M�	���u�$�w��T�{sN+����j�h�o�^�e�?��y"����%F7��+���?���E8��F-�+z��:��:��Y���x�+{qf!�'ih�����a>��u����/�G,����q?��,u~3n��|�+���Vz�Ufv�Q������[p��#��^yz����FF.^���b��� ���`(�
E~����` �!+{"�������~�`rH>�+���nRl���-QK�������U�U���e���L��jU�6���=|�z|".�jy�'>`����_�%�cK��n��O���$���ci2��4Cy���&
��T��N�=\��T��_Z���Z�.mG���4y�x����]��pE���xI#���n��	���E;��h��b����Q���ih��@i�mgGI���z:&w$��%z��}Fr	��e�s�j����_�
��m������.L,|%����TS���[:a��U�_i��������R�^_�`c�)���I�%R�N7/1���w��l�I���g�����>k�]I�4h����f��o!+�����������_���
�anGoV�����
^
M��lq����i7<�����d�
vo3�*0�����U1�w��<�T��-'����lykO�wh�����P��L���'%�}B�
^1�� ����8���y26�fp�"�+�8w��7	{��B-����bLB]�����Y�:.P���@��u\��
��k�b����t��p��p��5Y����'��sgd������&log���@��rfh��J�k<�q������}�������|>..���f���gK�4�o����z�2���?�B}�=����0��Mu�_���|=q�*�b\X���Z�?��F��/����l�=���c.;J����i2�u��hG�q�_0��D��;��>�����A|���U��F��@2,$p�*}
o���Y���i��5���8�F�Dr�2� &�O��:��z����s�QJ����9�9_F�
%����	Z8`�W������-F5[*��b&��`�
Y(8*W����x�����/O^V�(���bLA���hq)9H�P;%<��5.��"$���h*����"��GW�m']���
!��ibe�|�-��b��5\�4��3�v��G�)���.�'�b{��y��3����>�V�f��p�`o�����!�o��j��h����LJ.�gf��u,1�q�O��SW���w2:J/6�T�����
}�}�4����.�	����f�#�C�-�����5B����g:���Y��tW �|�����.��#���X�fs3�l}�BH����I���.����d��&�2��O'w��x+�2�>�s���G���Z���hSw���+���|}�R(b�\��C�F�� 
���5�H�
rD��h��i�8I�.�+�2-O$�D7��"�J[�q	!�����2[�B��B�<m�QqEP=T4B����2��Zy���-�	[���-�W�����cC�-����ye��K�-m��m�N�����"����?!T�B�M�We��T����-d^
�� ���C��"�J[�q	!�<������P���y�s/�q�dP����*���C�-�	[��Owp/���P������B�)��C���������t�E�v=T4B����z@�	�-�	[�|�� �X��Q���>1T�BQB�� ��
�.m��m!�g�%`f�<�g� ���F���cC��jim�2�Jf6�Z�(S.�tr��X�PiE	!�A
������B{B(��inc�lN���BRx�&\�)��L�	9����a�����X�J�����X&=�d��b0�2�������l<����:tq���*c��
�J#����'����nT�#�@eHE��!��@�S����0�R*�o����G����pU�{���=+�#'�����z�3����dcF\��x]c�Q����J�i,��]�=���������������:wGt�]�������74�C��9dW,���~�y�:m�e�>���l�^���%�q�����T�_N���u��������l`�.w��|��p��.n�Nl}a�������.�xr��Z�������a��fJm������B{�l6��x|>n>���hw�|���N�Ovvv�������5��Uk���>�y;qGX'X��|iO������_pN
b�G���
�)*�Q�"�}s}��&c�w	w��/Z�E^�+/��J�\�oh���H�X��h��Q����N�8���x1N�V=�N��n�����.G6�����������l����m��Q������SW1cu�f����a�2 otcIq43�to��`���dV����~���7c��[�+�)f�Q���9l��h���N.P���Q�D�*���n�R}���7"-1��V��m?A�����D��o�Y��������Y
�UC�>���(4r�f�3w��O�5�[�aU��r����������hj/��b6G�8���C�\g�����r�`im�������L�m��lte/j�T�j�2��.�M�i�*V��;��3��@��T������?=>�c�@�G�_Z������~rZ}���c�����B����{���^�}<>=x{���w�?�(������D���G��|���A�!�+F�k:
%Z�>��H�[��u��yvQ��e��?97s���l#�v4r��3�e�]-��}��v+G��.��H�#�9:�r�|�]�&h�n���C�����J�i��/�������h���EV���.���y�\(��uSF�@�i������do2���k���>$\��w�D��%Sx�L�a�L���)�qf=uQed����;YN>9UY��*XSr�<9B��	�#�X8�\@~�������'S���,�)i��_h���,��l���d�i������
D9^a,����'�X���������n�	�A?�P`B`�-��bp?�d�t�vK��y���Z�C+�t�Rs7��yP����m�\��)c���F�������j��Fo��F�a���`�MV�8�:D���Qy�9�b��������Cew�e��5$��/J�D�f}�d��>��	���*��f���;��DB\;x�iW�/����;Z
"�:�"J��,&7����tG�u�����#j�H�5���_���/�63�SD!�
�csY��<��=�h��*F��]����a���Bb����������l"Om�V:[Hf�,����"Zq��,";��,�]�����XD���"��!@�-�,"�uYD�e����Jw3x�F[�5����a�n4.��Zv&�I��Jg��0��0�b1�:�*H���
��<\G(;���'���;�@,�[��������6�WyzM�j����~$D�'��Wq��?��Z�/��`��P�4�!�����\v��������eN�e��(K����@�M�`m�u�M��7�v������6�04�����M?Rj��xc:�a�1V�������l*���W��[9�	�	i�i��4��7��\0�c�e���y����TU0��5�>Tu�"+�x��!��V��_���*{p!���8�	^���u�����g��b9`N,S<U����b����LG�[��K&��./�"�~e��1����3E�w18��F����q?���[L���:�`qd��c���[�5L6���q��-�������)�������S�����I�'UYLx�����W����<S���)V��)�#�9���d|���O�����QJp>��)-��V�����z��6;�#�R"���0��x���'$g�%K6R�����^H~�������\~LOs+j�I�q�������Q$��|z��%
��R�CFAN�4�80j���_�P��M>+)� R<9J�T����t������1��gc:�B�m�z�X
[���m�WY���t4���
���s*K�G�Z��T�C���X�'\�f_�vo5���
'\3h����j
=_�`�~��t{vk�������{m����Z\���4�
kS.�(������\^.M�$�rV�.�x��iQ3��`�C�n�o�_�,���h�������K�4��e��h��4��L�/�5����L
����A���v�j���g����\tN�q>�t:�L�o1����f���z/���1�6�'%�qw��YG�ls���m��M?[���|����N�S�S���F{������!!%����47���d�������	���	������Lh����,L����	�:4{��������g+?�ci=���\��x������:;�$�f\�>-`pYC2�]�dlm����X�P����z$��d���b�����R
�.@�d
N�F���%�
9E�o[6_,2�5�
����+S\�eY��l�:$��|l����4h��^����@+	�=�E��E{��h:e���v�����i��
���k����;*e'�Up��.3��cr���$?���&�y���.�a'���kk�f�+
�����N�f� �.�l�����o�X�]�(@�^J^�p�'�R��x�+C����������I��s�/�b�h�����+&��cu��_\�������L����`�DYX�>,R�I���������N��J�/��'3{q��{���u������H^^\dGQW��;�0�U�/vxQ�����~���|KO�I��2��#v�����)f��,�J���aw����2dG��bw�]��o��hzb/�tr��z�>���%y�d���o����wo�>�=@��.KS>��^@�`0	�AOip����d��dV�4���Ov����;���8��������5�<���&��}��[K���n��R#�l������t>�!=!�`���^V,H�>����7�1��r���������Y�2�"�>�L�0VL����w�2p,�/K�����p�%������>��[��bkk���~�����s�1�c�����qI?���;�O~����)���3�1�7^�?���p���~���O��3������O��L*M���;�PD��?�����W�4Mi"e4A��<���_���	6�I�<����� ����o~@��}8>�xz����T���	I�;���9MN���gn�6u"�3q���9������(���1Zx�t�g� 	����a�w��P�up���JBv�J�g(�DR�y0=����J^6����	f N��=��$%��Ov�_�`Yf�@�h�
�;�PZ� �~�n����5�f�P����=����!q	�-�{/��r1�����H����_�K�A;>��C�3�%���M��R�����a}�]�FH�����e�i9�����SK���+������[1"�1f]"�9��f"^{��}*�	!���`��+*s��zsK��%���%�S����������n=F��z�lkQt��l�|/�)]��O�
U���w��x!�H [�
�����h��w�+��5��5&�q��/�g/B�P���,�b�.��������+��c5$���X��^P�����&�#�����&��-/j(�63*�����x��T7�P�6�cT��F�5�sP�������>	���L-a��!���h�����9k�"Z��b�dC�gCi��X��8F�����j���g�����IK�C"%oRtQRT��)��{MGi������A��dL�G����[������45JS��@��T�
if��Q!PI�e7U�A��7]O\�q�|����������N������Xq3�A��g,�/pP[i*����m�u5E+t�
W����n����}����y�,���u�%-�^���2d����-1bx�Z3,�.�����q�qaI�C$���,�R�����hu \����xiKLc��������w2n��.�H�3��q��"0����������s������P,g�@���Mz�p��6��
��;����	��j����Th�t��e�!r�i>Gj�.������fRN���A��,H'����,��;uTY�UVR�e�����f��#�o3���G��������gV�pnE��w�r�PN"�����]��,8�7�;6�)}>���%�1�hv���/���� '���f���xtX�'��'�p���F��[��F��z5���F2�l:�S_�w4p�z����K�������(4_@�?�fv������LL}�_���G?L�VM#���	�s-M-���Z�^��KK����������0F2)4��0/�)�|(r<<�����C�����xH���L	gH��T�fx�d�f�V��m��nF����X�N�����`q&��\j��2��A�o���8�l>��6	��\�&�;s;so�t��:H����v�V�4m5�����jx�~�c��.~��3��P��V�i���!�RpVb��x�-^�1�-(�:��<I���n���&&��6/�&C�T����(��f����[���X���uRd\)���Y(����)u'V4bd����^�V�Eja�vbE#���b�)&���"KX���s�R]koA���P@l#����P@�3 �1�>X���oM�r�[���$	!����X�1�+{���h��.��j~�4,��� a�1
Ka��#�� ��G�U��S'�$s�5�a�9Z�U��}u-���(�|�q�S`�9�,���H]��@���1��������_{6��� Nt�k�>p������pfK�k�����K���k�w�e�v�v��7q���g��3�J,���!8�	���>����z�����^�����������������3&���D�����=���&���S������b�_
.a��g�������3kO=�^C��'�}�.�
��
LD��r�mD~��P���������AG���'4�x2�{��[	��?�;!�:�}���%l��N���W����w��Eu��M�aN��%�#�������
�;K{�
���b��.y�r���;��s\����,l��dk��mZ�2I��VXK��j�������
n8�q�l[
J������(�+��=u��(&oM��		���+j�"a���-~<�m�����T'�[P�-�K�mx�bt��<��j���4C���6hq���	Sl�W�J���a���*�m�r��P�v��\cq�	K�[���Q%6�i]��z���pY���]/"���C�E�	��7���}e�
L$5T�&a�>@p�j��m����v����g��@��u\���q�:+p<�R	�:M���g�h������5�O<.2Y����u�P�a�f�vFT���Oh����|��5���g���"����e2�Z��A�����:M��+/�T+��|�����������I�����-��9q�*�b\X���ZD��F��(�0o�hu6�X;���c�������4���,�vD��"�u�9IB"����G���O���3���z�5��E f�B���7���,�^����"��b��15�%b�0��'��W���9.�g�%F)1B����|97�����&h����r�k�v�Mb���!�������N����\��
r����q���e5�b](�����ud^�!�����z�
27.patch.gzapplication/x-tar; name=27.patch.gzDownload
28.patch.gzapplication/x-tar; name=28.patch.gzDownload
29.patch.gzapplication/x-tar; name=29.patch.gzDownload
30.patch.gzapplication/x-tar; name=30.patch.gzDownload
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
In reply to: Boszormenyi Zoltan (#110)
14 attachment(s)
Re: ECPG FETCH readahead

2014-01-18 18:08 keltez�ssel, Boszormenyi Zoltan �rta:

Hi,

Alvaro Herrera wrote:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I hope Thunderbird did the right thing and didn't include the reference
message ID when I told it to "edit as new". So supposedly this is a new
thread but with all the cc: addresses kept.

I have rebased all remaining patches and kept the numbering.
All the patches from 18 to 25 that were previously in the
"ECPG infrastructure" CF link are included here.

There is no functional change.

Because of the recent bugfixes in the ECPG area, the patchset
didn't apply cleanly anymore. Rebased with no functional change.

Best regards,
Zolt�n B�sz�rm�nyi

Attachments:

18.patch.gzapplication/x-tar; name=18.patch.gzDownload
19.patch.gzapplication/x-tar; name=19.patch.gzDownload
20.patch.gzapplication/x-tar; name=20.patch.gzDownload
21.patch.gzapplication/x-tar; name=21.patch.gzDownload
22.patch.gzapplication/x-tar; name=22.patch.gzDownload
23.patch.gzapplication/x-tar; name=23.patch.gzDownload
24.patch.gzapplication/x-tar; name=24.patch.gzDownload
25.patch.gzapplication/x-tar; name=25.patch.gzDownload
26.patch.gzapplication/x-tar; name=26.patch.gzDownload
��CNS26.patch�<�r�F���Wtq"�$D]m�27���U��WR��M�XM�I�4����c�q~`~ ?6��
4@P�w������	�q����0~�X��x��D�'���_O�U����H���D��_����d�?99h
�l������������t����u(�3������_'��5I�[��<�.d�N�?�@���?�������/�A�Ht��~�K�����N�0���:IE�d ��1�+_��0��,_FJ�(�e�E�l���*�����y��c�G��K��K!��(�e&��Fh��'F��Qd@H�z�Tq@��v_�KBN�<��i?M�HN�(���x�psM0��t}%������%XR����#�� P�x�J	�9K%x�*�q�L��W���"K`�J�P+��4�!���a���nI+��V��8\�:T�(5�{L�,S��j�t*z��_��{:�������3����0�g198:�����?y}8&�O��Z�^o+�V������D��x�{�Zt����n��}t.���J��^__>�i���e��R��B�CH�)S	?�������k�H(�]�
?�G��8�LY����4
�9��������m���OQ�_U�A�m9������$�g 1*���������={	\,,��W=P�8P���H��I��I#!@nEr���B2�T�k��uc!?�{�$c)2$���u����X��� ����]f�JJ�6E��&��NE5�B�(�H�����_��G��G����=���A�# �K��YB�z�ax���J���3k
�.���l1��s:���up!.�y1d�l!B?���������a)X�U��`�*����5|tl��N��d�<��>\F��]��WAq1Q2%{	;��~t7�?���n���%��x�e�-�ZL�,��!��A\��8B�����I�����t��lF&A�B��c��i
���c��lvIU���1��0�s���$NT���Hd�Y���bAQ����O��5��&F�;<��(F��*��u�L�b���A�ND<3R8��_
�Fg{�F!����7���>�\F�R �)�?���uG�h|�QYLb8G�Rh�5�V������o�3��=�2	����
9������������3�+)x�����D�8D���r�Idv<�0���t�T�Hj�� )������<���(o��� �&n��w�����\��h�xn4��Zx�� ��rF����
�4NU�f�J�>��h���u�,����A���L��z
�B4�T	3�"|P�p��u���M1(�T�@��6(��9��-�'~���'��v
P��2���!Xi����+M���I����$3�3���"�T�x���9)��#��S��9��]���
��T��m�=�H
�e,g(���=~��\�?d�]�( ,!eCe�1B�\�hq�Z@��3�:�T����������������$�m�,�m)�rN"v4�q�@H���O�������\�I�+V�d��
�����������A_t����#��9�����1E(bQ���[�M�`!�tm�
�kw�&q1����3�^L�h��3���qxuy1Gz{��g��,|��^���#��Si��
�(z���b����E�O�����
`{h���9�X'9	��B��;^�(4Q����0�88������+�M����@�����~����'m�S��[�I���Z�(�5J��
��>�4�D��x;b��5���~�{p :'�e�7��
��n�q����������;�XCf��a���+�g��41���U
!3�peq3wJ�no���y
�����Z2�R����
�bK��5�>���V�����Xb`�������������7��u���������?�/����~ts�p	1)^�,nn�����
~�������.����?�?<������X�=<�2Kx�������}�U������gQ
�v��9e1)T����2�:
���Uz�5.���!y�j�Q��O�����hP8N�U'L��%O�1����),����HM�0�����p6� ��B��XT�&}-�)��'�~g��>>��~��Q��?-�����	*s��q#��DC8Q��b�Ty�*����N+��3����!�/H6��@9�"�A����MU���`N�N����u^������"-����K�����#���L��[!��Qo��]p��1%cU�$h!t��-�����`�h�f9F�5��Y!i��z�TQ���X���Y���#��V=�tJ��i�+M�I��z)�@����tn����������������+��tb�;AN�m	����@]`n�v��r�6���������4*M�Qi`L�S��Y.���������'�v^
2g���6��N�����zB�v������x�e����O����]q����7O46���k�����������G��&����D>�������\��i��5���/5>��U����&�`D�������a,d�Qyv��F/�����Vaa
* 7#�6O�@��`=��-4S�-\a\>�*���%(v��]_�3���lS�b�Z%VY�s�����������`N*P|+�66���m-5���Et*p��P"�*����4D
$��/��Wg�Mlib�S��*��������6l�Q�MI��P�bv
�`����e.��^b��+��d,��+U�������B��s�q�cY��|���������=�r��Z2c����^������@���<����wD����e���<���@��@,O��4a�4�
���&�Vt[����?����8��)������pq2z�k|6������PsFf���h`�^����;S���2����!�����-;�x�D+�z����w�$nZ|�Z�������I�m�U�5��$[[��M�6L�|�6�MSYm�2F���J�}�``m�����������F(�
)|���E�c���6V�a�����0'�p�W�:���&�,�L[���0n���	eG���VIps
G/6�:��w.�Y���h�V�U��R�K�f��!LV��z���L���X,����P���X�02@����G�9����p+�
u1���[?
�.��
���?�
��A����-7xyW��Q�����RrSB@?f��n����"ei�����X+V+g�I��&����r�����P$b�@U ���~��i�{�'�s@�Sre�z���\rv5D�L�����]kh��&E=k]t���A��q�]��b)����v9���OI�Vg���Z��r�4��]a�Hk�b��t��-N�B��`�0����MK��n24I������@T<���jH�2�P�{Z�X)���1):�����9��R�dU4m	TX�A�i;��%�mf�U!�x�]N�����w4���,���0�+2d�9��j8=�����1��a���Hj������
G��h�V�wB�(b��e*�RA���s����4�e<�80��$m�S�.0U.�9�A���JsO���E��32.��j�bM2����Pw'
�K�,�0 :���	M�� &�����:?b���JO[����yF!�F���z*�R��L��Q��8�G�&y@c�t{��t�)�&20��������_�G#�D�ru��~��������,�N����w��]���,k:������������h��(�Mv�P3����8�+t�*^�E�/��s4*V�
D��.��}�-�3��
���>n��H�]WFH�
c���{V��U�z��Z���"���8N�	w6���Q�����U��w�BA�����<.���Z�)c�Hch�������(����bE�R�	��)�9�������+��d"y���E�4��)�[i���r��H�LxZ�.��aFUb2x�B	������V�2NA��_�p�q�
���[c��bT�|�4M�s�����C#d�B�
FF�h$g�8 �Uq�9��n�eF����y�$q��OR�4p�>� ?3���b*�
^�Q�s�r���g:{�>�U�Oo8�,��ib��h��J���v����4HJ�M}�L���]�����a��L$�:��=�����L',�
�2�/�z~B�#H����&H"V�aG
N�V�+UP*V��b&�a���GCmg���M�U���k�1K8��Y(�h����r�\����2�^q��]�e�n2�s����!E9�Ml��5��P����S�f��G�t��-r�qR@{:�-_����,
�0S�T��\�<��Il�����oR�G�����J��d��Hu�^Z�'I
:��?�P��6T�E���se
n�Q�'E�T�	6$���x��TP�]��MWlC��7n,=��59jW%���@���������4���YU�(d,�#0m�S���;(�U?�Y1�zI
�|m��g��;#(m���
��j�!�V�Y��7��>�ltb���?�7e��0��&�db����7�Qh�R4C��Le�3��c��{RH��=����� �������"N#G=E�<�2�G��'�'����&�X�����2���e8Fc�U&*E�j#H�OV)���Xq��{��@��#�����C���s"��������������'�:��)b�]�7bKLX/&!
��'5lR>��U�p�	Z@�������:ju�LC���
����3��$�92����F�rL��o�N�8t�ma�k���osPd���:4�hp	���C�k�s�'7BE1�S4N�~��p
��Ij�v�}k���'3F�	���2n�v%�R��N,�l?�3J'A1�����3qJ���	��M^��0�^��OO��8�,$Jf�����,B��3$5!����v,m��&\��x����	[�Ja��@,Uj4�"f���A�<x��tt�,��u#�AD33��7M2)[����(������/�cu���F�GS��T��H;[���[#k�H6�#�s�x�Cl~uI�������%Y!���VgJ���\=���ZMF�T�,�x`s�w��F>�
o�����7fa���jD��"9e]��R��,���P�[�!j������P�������uyNA(P��^<����C�&�Pa�7d������'o����0����zsK�H
Pi���0F����j�����i�)%�iL\QtD�i3!e��%�jr�e��L���=���PE��h����@��(�6U�����T^�������,������$U��g��D���i��@"�������e�����J����	hmyNW
����zu
��<]�+3T���5��I&��?����P��fIrS���}�2.)%����������c����v��\L��66;�G�oy�����n��e�E����@�x���+_�~u�Y����/�b��
%��������0��t����$=�*o�����������M����*k���3	H�6����'������xt�����s�"/�a��@�������,������/��7m9�I����+�3*
�h+J>_�b_}�k��oo���XN�$$�16��`nwl�U�J_�l�!<���H/��]DUd�~�NQ��kA N��6�X�}�OD�A.vv%�����	4����#`�����A�9G�i���R��E~�����L����D�O����c�K���u��j��k	C;�vh�T�Z���;iPO��0~�'�*���@��Z����������1�[4o`����������J��g��������zT���t�_�S�S���W�9�i�a�}=h���oh��^��7�a�`_t^��\S0���%:���8I!�@`�b!��4�@�\��#��`�������}8�Z[��.������m#
���_�z�F�%Y����d�&n�w�8k;�������h[[YrE)��w����$R"(�awcI$0��`N�b����0x�}���%[�9O�;<�������<���*�c>���c�\�$���"�O�������^u)�!;xL	5�
	B'�|��lW��
�
����T�o�zWc:�HI���yI�m?�4��R��4�) �&�V�'U��������{W00��b4"�\L,�}I�8�"a�[H���o�2�&�B������a�*�C��"�L�������}���q�!�*�X�C(��\�D����	��20v%W���O �Au�"F�s��8��A��/p��~u���Pa�7����r��	�2e��Z�,8z�{�<��hH�+d���D��_���
7����P	1��*��+���dW*,~�>�o���\fQ�SX��^��K!�<zk�"D�@��w%�d�0�W\�h�t5u��_G��ZVWix��YLR	-"�{��0����S!�@��`��3�����
��PZ�[.$��6-P�^r
DJr�9lc`��m�(8��Px�.��m��=[/0A�B������X�����~�{?�;N�0�[��vB0���d�(�!u����:0|�h��V����<`����^�J0e0��E�,�/����(kfz��?�U�����u������y��LG%7��8��Q�������5RV����=C����y�*Vg-H���~
��h�6;���<G�H�P+AWT��#B�j�����6������*���I%��������3*�[����=��/��Bs�!�*�q����<�h�b����G����	-	c��^���JY��fT�P���T��$�p��%$E�����^�br��b	�� �����B��� ������Q5����P9��|omE8�Y%����W��B��f���woX�l��:"ZR]>e�u��=u���=�)���2a�Te}U:�o�Y�����+:���Un�����G���i���;-7�8s�S`�%+�TF�}h�Jw/�{a�����lf�NGHD��?�r�i���kP�����=S�P6�wz<��N��oQ��he/�b�n�U}�Ij��AHc�S�h��t}OU�I��]!J5��=�U��[\a�n9�����-��\Ec
5m(���%nm��k4�\n�#`��*v�����b'S�;	������+�C��o�����	���G��+���C���x�r���LG<�M

fG�t�y_���UP�y���e�}�C��&%o	���_n$��|k�Y����d��>�������W�^����0q��IX��-i�0z��R������F�X4e�h���!k����CK��$z5wz1B;M����G�
�t'.b����$m�^8�e��"�K���<�J� �����|���^!��9f�N�*���-W�����k����J8���hRd\���!;D`���<*O�����,x�	���_����������*���2�����.C�5�L�zIG�Az�oN���������#�P�A���<��s���T���`f��8���h'����65+���H�����9��j���i)L�0�M<�R���z��_����Y��f�G����bez�Q&F���X��i���v���5M��S.u7�2����!�`������Z�V��+.#�+�9��*���rO��.�"j4�T��',X�;<9��W��&FHPl}��j=&!7.)���.�o�������!d[��G��4�l?$�?Q#�T�u���7�
	�BJ���f@���_2\��](1�i�W<M�v�V���� �8�5 �\wC�X%TWC?��O�������KVy`�
���+��w>fA��6� ����2����A�f���F��b��Z�=`,����*tU���#Ia�TC�;�]�p�D���Q�������bZ-H�k
hjUCL�t�V5>�A)�u�s���$��g�	.O|��/�����������R^�-#��r.�IQeF�Yve�y���-�gq�<�B�m1��a�VQ��`MTO=MML8���tKZq���2x��c�^)���pL"l�����I��]���I5�mRM`�T#m��Pq�nZ
�&Z��C�j���10�H�d�4Z������6�Gx�s��-�nJi�J�U���y��f5\�����#����*�k�1�Zgc���bS���������W�����}����SA�X�tn������%���4*y5wH�������=�v.�c��{�����i=�qf��Xo�q��K�'�|�c��4p�+��\����&��!���������M8��DJn>����A���"K
5�*�n������H��0����}�����3�0<���tB��(��g���nI����8�c��Q�Ov������K��[B����������I!�P������r�����2�:_�O��L��$�o�<�n���	�'��C?_�-�8������cF����AT���K���X��'���G	z�������&�+0�P��h���W|;��|�������T�%[�X���q��K�nxo�S�b%*�O�#����jS����+D	�W��uy!*-/�^����'���=��[���n(8"=j���,���k�
��i�Q{J�>�=:;~
�����=�7�����G��������DC���I_��\&���g���^&"��g�oI6a����6�"u��Q����
���Xj��.)�^��� �
nR��)bxI@��C>�����!���U�}
��&m���V�
�%�K-����!BJd�)�D��|{��K.����U|�1/#�����]b����d����	��/�1M^l��!�D\��9S8�4���E�JVO<�C��xs'�W1e��4���ds���{��xFl�����c�\�T�5�;#Xv�q�!��cl����m~ZCl�Hf�!{�#c����0l;����5^���� ��	�V`S�D�����x�s�&P3o�Z��;� )���`��-q8r7��B`�.F�",=��]����o��Z7-#<5���m!)����#,����������:�'&E����0����5:7X"b��X�jK��KH����zY� �o_�Y�#��ZJy�����IW����;�hL�k![U����A���v= }�3ci�T@R�C�k�=���D�H2;�:���"e��� [&�^����l�,-��Ve���_h���2&�}��d:��U�6�%�g����a���q���t�?�	_�"���eC�]j���z\S[���0�.����o������@p�.�=�_�$P!^���HF�f
@����o(�4���5I�W}E?(��/���W���x{�M������.�QW-iL��@���)I����!K}#`V�WOYRFR��#���|�gf`�p��34����Q'H���.��z	�qy��o/�b�;���[��K"�sfX0.'U���;����s�n��x�c8����p��~���~9Rc�v9$����4`T����>�w����>W�Oe�)K��f���T����'*EG��Nj�������j.&F��i��.�p�7a���Y�
�/����O�@�1^�i����JT,���������������]�)������CHww������4�9g�p�Y+�����F�Pa��;�������z�rU�X��c5-�����/�T�5�:W��y��� ������.r��{���/�K����\o����U��l
����\N�2�m"^������I����+�M���1:c�
ZRV��/�����������+^T~�$�h��/8
���/�W����= "��e����koG��n��o�
���U�6�H����=<���z�~��y��q[-��k������{�a�aHRX��fo������tF�>����"�������+��R�������s����E6)a1���D�w�}��WV}8���#]�c<������CL��*�B.>ar���@Vl&.h%�4�����������
�G|����)�����������1�R����
�������`�e��<J����rQ&Cr�U��}��"�*�-���D5N��]�yEE
�E=�����s�~��<��F�3c����h$�����r�i�+$�2�7y]����m0x>�p��S{r����,���%v|s�R^�#n_�t�RI���W�&]�����m7:?��@}�C�4�,��������`�����V�����
EW�[i;|��q��*��)U���!�-m�B;cS����N��x���U����T�"���_A4t�d$	)�����hD7^�s������~q��zy����R���-���i�<)��-_I�[�"x��`{�:�W�H.=����wR���Se�Q$�\;��,%����AC�3�R�@x������i���*��d^<��%#:B�����t���H������
_tEhl�o� ��A�!a'��X;e�����G	b,�hmy����K�M
,�:�,��Q��2v�L~�"�A�C�1"��o���I�F���v�5�g����y��S��w���W�1�
f���#��~�N
6�2�U�|`y3�9���t=�B�	��J� ����i*!������	ZV|�_��^��s�����c�e8���(��	##j���o{�2����mx������NEV�QI���v�m8�v�(��[%%�B1D��)�G%Hy�*���<�2K0���O�#{��9?-��Y�k�g��l��sce�/��
��!U�mr����^�K��0�	��5CS��x`:�'���G
D�i4l��V&�?Z�p�8e��������r��O��{A���� ���OL�:	�dPh_�����m$��b*���p9�{����"�]��Q�<�mp��x<�X����W.�r��,~ar�R(��&��@�
����E�aw���p��y�����o"w��Z�����D��9��\G���=�v�g�i��`�3�h��p?�P�T�"0e#xo�k������a66�5���r��5��5�\N�'�M��2Hv�5e5����+�y;0:J���=�G��"�E��F���u�}�����U@���mK����&%�h�>ovufya����&����c"�
���X�v	v��v�3��,��Wm�����������cW�`]�&c%$[<��g�����x���;zd��$v��t�y[f��h(�e��(��(����y<��<~ O��0U�*r����%��m�m�>�����������Z������������+�[PT���-��N�)����E|y5{Y�_������GA`x�$��bHT����%oE��G�N_�J�d��
�����m���[x���CY�n�s�"��}��+�b^���3�5c&
���@HC�VjL6��-��iU��X��y�������-��M�/Q���+��T=o����C�N��:�	����Q���)nY�^�y:<�o���Z�!����5H��
�i���P#B��9�4�>�O8Njr��J_��eSln ����g���[�:���	y�>������)0�����o��T�:e������xF�^������J��^�x��
��V���Y���3l-E-�U(\2c?:���;��2�����bM�+��F�` �p�8&�Fg�;@���+�uE
a��ol��Z������o�����Hy+T'td��n�(�ZQ��zT =�PYY�4�4�
�.2�$+[����rU}t�f*��k��/	?�A���P��v��$����~�0'j�*�����E����eI~#0������EE��v��9KC���]b�[��1�l�Yw����������y�:���s�(�b/Nn
�v��,�n
]h������S�TTKu2���:@e�����)����
����U�B����-v��cnx��_g�|�"���+Q9����HO�m|���V����T2(�zg��ifQ�����9[4�b#:��R���������$��J�H�����Y&�|��$���A���*t�0����0���_Z��#�X��e�v�n'>������L!��gyq!}��X�A�}C���������~��?OcY�z�n��nh�G})d�P�z4�����,kb.�tT��e�c�f���E~�%f��J6����8D���
�6�|����f��a���*��h"'H5���
��J��A~(L&���(@�8������vK��2vS�������/|l�������'�?�- �{2nu�ueu������T�iS�����SQ����)@�C=,���:P�|RQi��s�H��V�nTJ����C-7�*����(eU���2��6�@s��KrSr�+�y���[�q"�O�A���-��q�a����V�2Q#�q+|�)�������m��|��~��4���2(Tu~�5AK��c#G��S��A���*�o�[Q������/'������^�0���r�|���KO���Bq�C�r�{ma������!!]as�5���<EW�V�E����J@j������H[^���DM��s"+������A��E"F@�{�����O���g!�Hx�pH�Rz�Cd��!!��}�a���.'���A����MPv��K�R��D-�>�$�����"��Yr�W5A0�x4��]<��B|8��f2�,����]Y��5*�����i<����Cq���+p��`:�_,������ ���S�������>|���=�g' ���n|�R���>v$v6L���=;:9�8���]���G����	>�.�S�A�^/�B@d�����YJ�	���a���tx=����&�<�����
a��Z��N� ���=����T��;]�����_H�$���{��R�a���a�2�n���������k�>�*��<S�!��@0���xalZ�I�|�;����37n�&o&��������U�c5"����1�A;�d����Z��=�9�D�>�%u'r�)���`A^Z��k���J~<��J�K�W�u���)�4����e����]�gBp�~�8a��rLBz'�(�ag�U~�D`�HH����z�����G�3�`������>�3PV��
���D�IG�Y�����)�KF����G5%�3W�+D@*��	��.?�(Qtc�Ia�0�p��<=�c>��@~���F����T�wd�)D��p�����w��c^�e1����(���d&v ���[�R�/������n�����UEo��)y��E������ ]Uk�y���sJs2��T�h���iX����>��G�Qy���(��g`9V�S�) �8�dR�"��zr���z�%�eF�z�#zr����(b'�;f����9q������,����C�u`����$���W/Fp�U2>,��G��4��v~0��@���);T�QL1+D���h;I5<�TX�����Gex�a�j�G�x����������^�N{1����rh��gs��a�i��,3���<��9q/�_O�RpPClB������(��-�9��R������.b�j��WL�~p�5|t��g-����N�Pz����Lr�� I
"��W�S����
�Pu�Xo%�E��,N�x����:���`'�_#<�iz:����`��/Al�2n��q)�C��	�fp��R��n
�mki�8V�J�p����
�S��kU���=25F��	|���[ �
R�'��<�����
F@l�@.����`�'4�|EO�"E���2������1g��������J�H�����>?�]�r�B��"�%��O:��������uk*4�J��E�f�f�����[Z*�S������?���\)s,��*w��d�Ys	����<�$�c)��	���J�_�!@�~:N� �D�����y�7���H����$�;nB��z����z�����Et���a���g����Z�NN@��F��Tx^����!"��/����,�p����$������T6��Sg0��{�XP ���z������'���@P9��
���`�Dft���P��
Kx�d�k/<����F�P�`�}U��*m�4�l�-���-���X=���l1�T����VweX�6�%�c�l��=�}b�G!'�G�7�Tm���.�'�x-�>r���7�b����Y�%���@Pv�	����b(��G&�8�$A���+�
��'���L@������JJ����J��������2�
+�4����+�S2����0�T��Do�����R,�6����j?���vS�=������w�����[����r���7�;nw�q3�	�Iin�]~|b��tA	6���$��wy��F��M�;��Y/��K,]a��1�H�nd�����vy�K�f<_������>�q�������{���+����a&�-s��L��^�u~��"�_G�����
QA��_{�!p��4���-��p�l�.�����xd������
q?F\���������������'u��&�L1�/	���!�Eh��;t�����
B�|CJ`Q��/�N1�}���>r�7 ��]$����r))�W�������]���-�����!�z�#�52��������Z�`��i�_�Ea��lBW���|/y��f�x��n�<p��guHY����E����
�pM�g,��=������^8��,��$��@��z	���>��=
����	�R���W������O}>�6P���F,d�q����45�R:��o�~*��*����H���zpl�p\�����U�ub�&%���*"�hBg~��o���X�78�5v];��UYU��p�n:!��w����+V��X�����!�Y�}[�c�d��#1�=��nx8��"�>'���	Mqx3�l7�k��kw���f^NW�W�S�iC!D���j�NI����.n\�t5�������r������$�����~�j���k5{����6���N���Z�&��dgg'!F �F�UiXd?�@��_Hq���������$����N�;�zA�������8�"�X�5������g���R&�����v�W�?�AuTiF@�,�
m���d�3��nI1��>���@��3���j�u1����g��Yi��q��/�Z�����^�����u[qdl��#/v�a�����t���;�����7��SN��{w����$AH� �e��t������t��M�H�~-����,�9�- u���������u
�@��gx'����o�\�q�a8�s|�$.�����W
�{����.�F�}�M��%�|_����4�d�����@�#���
���p<w��d�;(w���%T��N��'^�Y���Py��l{��C�����O� ,w4���!(v3@������w�"��.8\gp��=�z=u(E����CJ����u�����[�����SX�L�_!2����F���
�����������������0�~8����{�j����l?�����������xr�>~�>�M�����=��G�kt7���%�����$�)%����\[�v��~�*����#$��S�cd#|����o��%��c����q��p#��]/R�x&�vo����\^��c���y��j�BY����F�����F���?�$����o�2yG�2K^����w��>��.����C��z<n�!�v�$c�y*�	8:����2,�8�>�8��R�x�t���	�8��������{��+jm!Q��CwO<<}�>��zM*yo��?Y;�T���7U4N�7Z���)�7�����V����F�~�����{{����g��+�]�-�)�R�	�R��K~��'zl��?E!��w������-nf�����S�s�B=YHKD�e���c'w�(G���9:}v����6\�O<���������pu/c�spy�'�s��S�}S��O?B�,�����,��DO��b�ECv���d8 ���m���5��PX�HG����W���	�����a%^\�����x��y������~MU���G?����\f��~����@-�jP��pa���C�[�"�+I������]��x"���$V��$Rh�)��O��(�UR��2�O���'W=o)�`r�A�P���k�!p�!��(4��8C��w�r�����7G������9;�3�B�����)+����~�ew[�Z�j���Uu�J�
���i�z�h1u������!B=�"}��Ua�?
7����At\�N���,��(O��9?����_��������������2����(��LJ��O�
O^1,e��i�*Ye�qNc��4�;=��V�Y�j�!�v�x��R!�9����s��9,����02un�����eO��X�����H��15�om��M���7qv�[�&��"w@�D��2���i}�:f,�*�#�#5C�b8�+�/�ee#�� ����/~"?���A7��p �%��Ws0�(<��'����`X^xqdOE�^�;��@�W/��l�����?��H
��9}vQBD(�b�i� �}_y�<(h��	����]���Z�
��?r�I��_q��I���������Kb0�3%3�x�%�THb����$8y�B��<��������^M��c
�*~k�A0���Vw�5�=fKC�O0��v�"���e�	�-_F���@l�bm���������y�����B�����,� q��r�p�[�]��gx�?xH7�;U�}���v�Q����J~8?~G�����G�7�L��ag����������s
e�^���rqx���������A������Go��(5P�;��}���SHeu����D��EOG�����7`?�"�����j}���?9�]��h�������-���6t���+������/�X�fd����w���*��_?�����s�{�x�:~G���7`d�a��hC=:f�n�X�>�Q��O4p�v�G\u���6ZqX����AW���q#K[S�}L��w��O(y����L�?��O��������uR���#��l&��8�iC��cJ������?�T�.6������]PM�2`-������o�����kPc�r�����:X�6s��t�E���r\q�%�F�V���5�v}����9��ow+��a��+0$T�����{}�P���m�Op�y��`#��W��pPE
U�/��E�${T�#{�����1����(y�o�}�����r�,���L��\��Fer����%.!�k���w���P�Nv����Z/�>�������w�-u�"z��%��Ft-�8��R��Y�ws�&��.�`�f%i���s��(�-���k������#,�����r�-_wx1���=l5}r��b�<�ex9�
s!�1��w�,fo:9n�n�A�s��4[�=���:�����b�.��GT6��`| W����%��2���'O)��C��KR����=�����s����`���F���F��u������$�xA"Y,������8{V���_�QY{z7�pn�@�=b�z�v{������|Q��I/_�g���#~x���$o>k�����$4���U8�9Pw�x��sV,f(�V���|���m>�]@M�go�#��x���ZAgG"����N�P�0���@/��g����D�-lB(DC��tgP�����-xJ�__Ry�;���$���`���~\w�y�?���,����������B�^�y�2/
�,��W��u����]�O���:6�.����5i�������!_�"9��5{0�A�_�JI�*Rv��k��U�3�$����Z�j�����|�}��I�G�1��'��=��$8t���D)�F�qZ�_�D���I]Q��������#l�L�����P�n��"�+1��sg�1�UF~P?���z�P�In']���;S�Y��u<��:S{����`�������
M�b����A���Hy�l��7�S����-��`��W��?%�e���	�������P@��
����r{�������x�u;�PP����py����[�c,VL.E��_��/����OYh����-��~������W���Y(�T�,�G��$dMN-F�GV�� �� X�9��8�2F��=�����R�
�q�<#W����v�(O�n�U@LrQ}����������]�j\��r���Nk�������gp�Erw

�����So��]�e'T^���*������m�f��^� m#mB���Hm-��f�I� |��%��x���n�m���|3Z��@�Ta�j�������Ey�-=�L��y��=�L�	�K�/��S��/g�RTG�3X/�6���9��lc�v�����2q�:Q��0��[�Oc���(�QAY��'�'�d�vf
kk���dH�i��|���Y���c�D���������C"G0�����
hm�����(M���J~����d8�"\:�BO���r/PYz�Z!�����rG��|�j��oJ���x�Y� O�"U��Z!B��?��3�uB�e��/U�����Z0�{�uj��\q��m��n�z#�G�����2�?^���M0���j��2<��Z�!�]�E ��K��>>��oo<�q�Jf���t�d��jT�z�q�'��A2Ba�����4�x{P����s������KM�mUEGU�D#�D �z�`�(�������#�`�j���������.��L>�vp����!k���-b�P	s]c��A��.g�]��2����?3E�+�����L��a����!J!��2�b�i�p��xu�D��Pq�����%@+��Dc��*R�E�EA���o����X�W�am ����$�hEjZ�/J`X����=��&��A���t���'���Kv��E����������VZ*�z�F�cH8���V������
ok�������-c���q������
�)F�q���^H���*��n���$ka��LV�"����qLF�a��aQ��U�mH�6�!|�iz(�I����!�������������{�����3�pru�:�i2�N���w?R+f<��:���n2��uDH�V�q��3�3��]��
B���Gg����al'S���|��;{>�;�ct@���J�Eu[/�7F�������j��������;��+���
v.�!�a+�x�<	��AL�\��d\��,���x�B_���3�"�r���4/|��wZ����dLH[���b������������;%�*��n_~��K��9�#�G��#9�O��?���L<���������`y��#��eo�s�����9���F��\�<�o��=�D��/��AdiYZm8�J�8�;mW��5�|�����w��mq�������w~����c�����O~�����~��x��^��4�x<n$��r~��x%<�R���r����OO����z�
1�#62�xa�+,��m�I��������G�04[
"pETX8�c����M�L���XR��-���~�������i:���}�3�.�������w��9>�)oW������q8������><�� �(�Z�o�3���������,`U�U�����������}h=:p�Iy6�p�L�ff<|�+<�
��z1�SZ�2�7������g�9��hL���Y8��W(0X�l�o&���������� ��H���A��g�%���b!o�=��@����]�	��x�p,�4_x;8f����:T� ���>D
��v�ZTm������,��]�������C����g:j}��b���f�X��x���^�+^^8�|��7���r/�+<	C�Tv��4��s���#��R��������bLJ��P%B����0�KK
8�T�f��@��c:B��������
��~�
�X���D�]�4%��2�wJ8J��*������\�9}{x�������y�k�.~����5b�:�P���2�;���W"e����B(�<u!;�H��B� �.Ca�!���X*�kI��#i��J���F�d������Oz����(q[I��	5�M��$�f5%
ui�!n��
a������%IB����fI�&���}����rA�
o��X6���R���>,���2M@P�Ugt�9`�
�P��Q�z�<����F�#��B�g���5�/����$��fx�B�_L�11g���p�S�5?
s�����x�����y�������)���/�����$�qZ~��K��8���3���r�8��~:K���	�CV�����j����Z��h�u��
���0���P��:������f���o)[���	5����e����a��x�(,����qE�X�s�&;z��/<�`m�AIh)�o~"�~:�B��������&�<�3������08��z���La��1���a��\T���|��
���x�
�������J�Y�+9L��Z�e5���[���4^��A�T��m��8���$�g%Er�v�jv�Z�����l��\�V���K�Zd�s�|}8���8TH
 �-�K�����	<������T��������������R�����I�
�W�!��}����ov�;����w������G,��������e�SK��[����Q��ad���������8;b���+��)��`_����8���(�<_���q�3$.����<9z���O��>I�t�g����k:�^5����#6"�.�`�>;��������';���9����m������wGox��gj���9%�@�,�����k�����������0�<y�M���&�D�{q�>����N�)��u����?�;����8a��z�o���w���?ap��J��%�����_!M��9�`9Z�{G��px�������;�xr������
#H����z' m�������!�08p��������f\�s���Nm��i@��P�-����j�WNk�q��],)�������Y��.W����cm�m�[�w��5�2��^�������{X�����.���Y� &����a�"��Q�&���x2W����=  ��%>����|r��GH���#�+g����� _��=m,Y��v+���:w�"���������a�>�[SJ�����	�� Q���A�$�������#;y��[���:��}8���my�#KB����^�H\V@
�hih9
Y��]	<p�#��G�G>���>�������}$:����G���$g?�d|�#�?zD2zo�Y��p�$>	��Y�e��P��y������� )�=�X�G�����d$����8v��9����SNr�"(KE6U�
z1��Q�",������s��T}��(	��/r�#2UH��z'���z�2e��c�A }�W�	�]������+�S�B���u�9������a7�eu�}����%��2[U��o���b6��CZ�v�d?u�&5���u������
�5��-��&����M���2V�[���*�M%$�?5�6��mvZ<�L�����(&�������e0�?9�p���9R���h�l�]���RCO����K1��x�E�g���O��b?��v���mY�+�|��M�K�
�4w4c�`K���;��QO���QJG	�+�q�RJh\�+g�hO8����1m�`�S7�:�o��9���u@,������An�R����.]����*�nUF����]������B��rYR�eS��4A�2�" ��B��<��B��eO�m�[V���k�n>Bv�8���M�-'vl�^���N���H�5HI]&P��YfO^-��-��W�`/�����+��r����������.������X�_r���l��y������S�(���n�!�u!�#�1���������R���R��y�bb�c�����c>���&�����Au{|�o>����8l�&��UJ���.����%l�t�Ip�R�d+E���*Xvr�8��:1w�9��AVd,�o��w��������j/bw�*�G�`����P
�����o��m���F�(��fx��>v=����_y9_�W�`.^��Lu�/���W`��9��W���T�����)/p��W���^���r���Rz��
�E���Z�(�k��m���\���W�</��)�+�;�K�������G�����w�����c$����*��rag�s*��+d�����&Ef}��l��(o�-�L#t%P�vw��� ��	1���l]��V�����{�4k�M���H�����}����$O���v��	/5$�?4�?4�?$~?4n?�O9����Dk�����:.�7�,b�$����}��`�m� u�#b9|��tDT^��M��/��8�d�9�=?*��P���=�����"p>A��]��V��g������~����4�)�	�E���6�/lg����=�e��FOl��J���8�LuIN�,{����F�g�e�X�%?bIO{,(0���-��]QH@����C	&/��E2tH�����5IcK�_���P��Ia�d�ee���X�Z��U&s'�������zDf���=r�yO)?���k���O>�|���z��GSF�%V�]���:�l[���,6��u�8\��<�L�c)�I�g����N�W*���j�����B��*�����������5(�re<az! N��0�Zh��b\�i4�.;{�|�~�Np�x�b�GeW�t*�6��O��49�'���������ey��_���8����$x�$��y�=~�q�TOa�9�W&bev!O0����`O��I_���"�����B��$23�pLW���������Y	����p������p��B|�%��w���o��|j�j"�`9O�Q���P���V����A81���f���&�sv�a�O�L��j�4Z��v2��/Y�T��R�wJIj�be�)����z\����Z��P��NZ���^P�e�7��y�;�|�q�m;���^��1��]�`��xjv���K�1l�EY9�U�����TE�X����_!�1�`��#�v����)D1���
��n�V����+��\;��k�(^Go���-~�=��	^��?���?�a�p�^���.KS��+��4��6����(}q�L	�]T�����w-���F�	����Pc���`�V/��An��x]����w�p�`����5�g'?�����g���j��-q�}����=����K�5���~��3�����g�zm3�Llme~�SX�����f���q�Itu8���N�)���g��{w���K�N��ut�����z��,H�d4�G�p�����O�g��k�0�"D+��������'�a���w?��V�����o���2��h�a��v�w��Ru���j�j��������`f1����&?Q��C���{K5yq�|�8n��<h��,xi)A�~+����c��-����D@&��V�cq6�����58�=DE�������z��[��if1)B���o��$�,�I��l^u�v����sZV�p�P�dRm~�l��Y���4�N�>�=O���{v��1p��L����{17�7B���?F�(�����=����������
(�';�S$����"����9������|��vV_�����}�7��/0^����h��=k������#��%H�7��%&7(,�c�ui;����7/���pi�+���/H� ��$���
Ng���2���
��
'����e����k5���j\O��������}���2~��1��!$���I�d�_P�>A������&���u��1����/���x.������d7Q����{J�����g������w����������d��z%pd��`��������"�9�$z+������#��RD8k�6E5@u^��@�,[��U~��vY��^$��Ih'O��������������Zu�?��i3�.m�� ��1�
^cHf2!/�$�p�N_[�t��(n����g�����Lh	~)�h`Y�-vxU+%�o�Yq}E��p�*�p�*!�'�L��	?�E1\��e"����Il���H&0_��1���
s�����Z���?3��X��"��]������o3 _SPg�l^�����~��_B!`��]
sN������&�Eh��+�V�Z�@��{GV���l�j�f��l%������z=����}F���D\+OJ��$�4�p��2���<#�sJyC#�B������z�������t4�"�����R*��?�H���H����������^V�"��e��]�g�>�@)���}S%�6�}*a#K�aBK�)�78/������|]�������{Q�x��bF�^��#?������v���bSI�_���0\�=VQ���vU���h�Y��{^�H	�����5������K.�E�8v2��h@���w�xa�hxY���L(�Ck�K-���K8���j�����R&��N*��k�Y�6��a�+�?������AY�R0?��g�h#�
G�t�H��[.��>xFK<#�j4�g]��B�4�
�ap��_7�u5���bZl�E"g�a(f���;��.`>�W�(Oi6�X"�`=�O����
�������Z,F��2��AH�������:6��X��%@X_�O�P�&sp}|S����,��J�#��jGQ�:�*���	/�/�+M�?�L���Q�	�fO:�1�hz� �B3a���:0�
~�?m�W��P?-��c:D�JIxh@[-���3�:��=��r�B!t��-�x��P���v�Jl����M6�vso��0���LBE��7z/Xp��{��Y�X�3������:��_�y�����W&���nCW�<�=��'P�;x����KkP��_���v�`���{w�UY@y����m���1�%�`��������4|YA���������)mg��/O��)�
����/����i���"C~SQ�i^���cZ��\���vXC��,/L^����m�+4������]��(����~�Sr h1��7�����qF�1y,+ �/����X��g1��,�����������a�~&��e��j-���\	�H�a�1�ZZ��K+2��/�t;[c�(x�V^.��, ����(SF>��$���>���D�r�\�W��i�	�y�I�/�2,����c��qZ'y�YR�fk>�v-*q��{9�_�_Q������O�E�M�Y��,�`�b�IM�%Y�-s������\!�)W�[�o��8%x���?]��������r�B�)o���*_��D\_����E�$����������-|�QBF�"Z���BLtF�YF��Y�����4���l����&���'����E8_W�!��GO�v�C�u}{� Y������5_s��N���ie�&�/O�!u�����<u�w�����`Ft�A�9�hA�YPgP&��`�����D�'R+W6j4;��@����I���tJ��<���4�����U9��[DNT[�z}8P��V'*CtU���k��\~���M�F u5������;�gp�V=��#Q����\n)�0��A�H7����`�����y���Dr!�3�4�+�3!u��������B�n��h�	SX������KbkB���HA�V��Kf
5�p`��j��d����@�k�m
_��b�&M���eV9gq�(�}��RIp$�	Z�
$Ry}��Hj��(z���":=+��!I/F���D�"���B�����aw&]�	���&-VI�U�Xak/�rZ�pv�j�;g3v'�X��D��	R��;F���I���5W��B*o�';N���:Z��/�N�+����@��%�+[wW�Twus)��S���k�*�v��,��fzoql���������C
���7���O��^!`#��bbk,&��9b��n���pbk����Al�X�!�Wq$7��!T������M.$�����
�Ia�������C���}�$�r���<;�X!����I4F�9�a+�tE"]e3.���sD��}��h���(VI�U���������F���1�N��S��!R��nA���M�8&��9Ry3w��a�����,�����N��dG|I�[�`6��}��!����Z�����F=���=�����R#E����UK�d��'v~=���r�X����z`�-�:	V��A��aI��Nu���7�+�W�U^_Pz,��H��fM��
�a������#N�����pW�$�*o�SwK4��M�:�X9���F��L�rB*���A��������p��c)��i�����,��9}l�h)��f:�����Bn?���l�-��{2�M�����I��[�(������U�V����ou����@�M��U�����J��a�����*������G����{��.��?�����h/�&� '��%�7[���!W��(��//�#	�!��?�k�{tf��7���\q{�����'�:��L���
[�/u���Ot����\�a�3��{�(���3��j���,X8�\��0��m'�E��>�+"�"����z����h�F�QT_`h�rF�����&
���]���3��h�N�Y�X0�8}�sC��N2���p5.�J�(�t6�mV��,�����-x�c��K"n �i�U��E�Y��.�k�������]��P�5+�����f��W���rY(����!�60�=��cW���c��B����-T�����%��R9��x����w"U��d:��5������I�7��`���Mpe�G��1��/i����il�Da����T)���Ca��^~s����# ���o�����n�[����8����)�J���Q���dQ���E��*]+_E�]��vW}%��~������������Ng7���$D���`�U�VJ@P�5����J�XP�Q+�so&���4��V�5myp|*9H,+����W=����r�SQx�L��F�P��K�w4��c�������=�O�Z��R�����_��.����/��@&U'�J�H�[�F�*��>���c",H�����$�?��AJ����Lg��N��yI���E�z���/�b�|"G��tn�F���oc����������]��3�I:2�`(^B��z#i�l��9�s�w��v��.�N�V_��<1[YzcZ�#����^F�G_�������y��#gU�6���FI6�FL@y���`��MvFe�z6�a��SK,�D��l3��>�|/4fs<��N4��7�	�wx�����*,iq5���5�l��������kd����az:��^C�7�]�53e�a��x��Y���
v���S�i�ug��k�T���M�1��0�q�������_�wG��l�g<�c�iH�����!`{�uE+M�����%����)�5L���.[�/)mx�<�pi�����m�?;;e%��tR�uJ��;�;�#)����o�(�+:��jx#
�?L�pR��n�R�{?����4=��K#7���t��Xx��1�z�5O���m����n�h�>�V*��7�Yw����p�0��N�*6$��%P����D���{�h�sa�:��V����{������q6�R�X�xA��+u*B*V�"������
�����0R�:�S�h8c����������������`�`���n���h}:UP�o���}4�����?�;������g��x@&W���&�r �����P�4p������������e�g�?�:�������Z�8���h!��m�
�
wg�:�������6{'��#/���B��F�����������AW�����:�K�����������}�o�#E�p@~!]�eC��>�����?�X!9��#P
��B�u���!3��������A$ ��-�m�������>�(��_:�t���
7�'�1E�sj1��6<�3G���/��F7(b�JL|	�j0���I�D����cSi=��+�g��s���/�Y��s�w����3R��b�w3�l�%��������v���hN�Z�<����p���K��/�
�7G~�������m(��W~�]~�o���X~��ow����T~s����6��>�o����������g�f������Y2&@@���i�\�k�i��������������1�:akU��:I��P5��pt��'r�������#����B
JTJ�
A�"s�
Gr7q��!�1�����1Pg�=�o�2t)Cw'�o�o�
�M�CM�����F�tu����q3j���'-������2�4Tf��N��a%u!��lO����$X��l�J���P���� ?reS�p�h���'���V��]]o�*|����Q��[�l���K����2�<?W����$N�ju�� m�,c�jHB��t�E"K��	���<~$��?J��D[1�o
����������o�%�-�TI�����O���������lv O��a�_����H���1���rF�
�&Tw5@��u������X����=�����W/	x�H�XG�j���n��l�:��
��`�H������l8P��T��smg�2��q�mzDZ�^�w A���Ak�����T�/�����{1Z"�7�6����������u����\o*������#}���Q�M]G+�M��p�80�z�����������n5����M5%��%%V��z�:#�:Z���=HV=���88��!��C�}����W�����������CV`e�u7�
^�����K�>x�k�����@����vb	�P%�@�G��-/'�jdg+�%!��FZ
����~�q��BI��/?i�K)������[���B%\=����yuo���Me�����.�f6^�X8�,���������J���~@,�je�F�E����}l�����ssz��?J��J����A+�
����H]���`t}=�Vd�K�&r^g���d�'�xGt��YO���F��d����S(XfC-R#6|���������,��?����~FT'�x������go���j�c��7�Z����<����B�x��������&N
y1���(�Z��������T���������D��Ybm3#<����.�heDqp������U������vFg1��|�n�F;#-)N��W�;�m�X8��P��V�:Y�A��MW�V�
����/�!�v7�p�X8�?d�-���h N����$a;U���0�r;t]�%�>m/�s6�l�.�F�a6!w#�>/{���L����45PI��V�1�v.Z�k%���J��$�C=����c�6?E�6v�*l��j��V���z6�%�p2pCNR	�|����t�;�	��Q���r�����g�����`R8��q��S�xI���CJ���S����,G1R�Wa�AD9pC}B+��8�Qq0���~2�-���i#�N���"�{�n`�p�������4P�@)���t���v7��F���&�h3�<\�pR�l~���jl����t|iQ
���D3#�)�-�P��X�A�:�r�UV���NX	�t
�����U�
�B$UF{O�pLJ����v�b���/H�y����&/�(�AF	�b�����]hf�R�e$���������B3+4���ME,�M�!�N���+$��Z�9���|�������A����P����lE_&�.�x�
�"��lB�b��{��)1��w��m���&�Z��g#�.w�����*d��r��6Vb��R�B��iBbJg�)�E�������OD�k(@����U���W,��\�����v�x%���������Y������{������
�;�R�N����~��^�a��>3	�88�O�z���N�vU�]��>�^���/W�w�����)D�K���^���4�3)�p6�3��.F,���M�I�G4����X��<�����n�I�$�n���g���������/�0��l��b��x~��06M�h[-�88�9P��9��"���=�"���I�@$���@����(=�K9��'����J���Kc��Q�nKie�a��S��b��\e�v2����l����fE,����R+�������/'���$��5�C3+�
��
�p�'�?����T�S����X8�`��d<��Mi��������l�c��1��:�_O��+R�^)7�u��]<|we�w�.������6��R|U?hw6��\�T����D�@����Qm��j=��gRg��j����_o=�V�dw�|��G�';;;�"��;R�W�d��4�����';�P����ol����&!����������y�Z������sD�����vA�^O���dL�}s������WTvR1��$���|�:O�@��;�{
��{�b��&%p_��th�%�[{zO~w���=s>�H���urgO�[�z�-h�=�)��d�b�{����ni�w�	��7����3
��?���#�#.�?9����������N�h��"v4w\���������K��/�
�7G~�������m(��W~�]~�o���X~��ow����T~s����6��>�o����������g��,�0eY������]��5:��v�����y�B�m1T���U�+	9���k�q����0�o�^������O���tf<��������^�"��M���|L�OvhL�ks-���d�E��������K���}�YSk����'3bqLl�T�rF���^;�(,���s��P�"��+��iyj2��(�3����Yam����#����3*���"g��h���������\a�
_aV�`�K��f�tt��t�W���Ug����\cl�k,O�_8�n�j��7���7�
^��n<J^���r���5�������C\b3��TL�	��Qz�S���D��<l��C���<���MhT>C�����5��gO��g'�s�8���8�1?��b3*p�����&�5���/y-:�.�.�����f����^���e��Z���*6��b�%C�^$k�:ky������ri����wi����4�`-��p�YK�`-��kY�Z��H����Hf�Z���n���ZcI���5TdF�52 ��vn�8A[u�t����h�_J`DmDm^����3����tZ��y�������c8Y�0I��������yY5����
Za�P�`�B����I�N��;a�|����&-kN�"0JG|��LQ������s�N��3/
c�`.���sI�\y2����\2���F���^:��y��t��(�=��]��[f�<��x����Q_:���IH��tB�0r���K�kSAt�]f���W��2���R�u�V�������iqG2S�����^�<��o�>���,�V�3��)|������8{:.�����v��d`�W���d��������2O<����qXEfT���2<H�4���&�$��*�jL�7�����1�c�<���.�Y*6���L�Kv1�eN���`/9��.*6�.Y����Ds�n�\A������P�
����d����f���l�m$]�*S�
*�D'���7�p�#��\]YGb��{���p���?��c�&��:�cY{>&"��
���������Ri�~�nsll�# 8���"��GX�`sRV���)V����}��I}i��%����g[77'5l7���
n]p�8���[���#]f�������GJH���_�=R~�0!���=�eV��F�v�����.#���e+&>/e���lE
q5� W�ehTN�P��\�\��S�j�>]�k��P"����yf��i�������?6(�c�L�2��UC�>^&S,�xFT
����R����`�O���������o��D�v�xI�`�Y���#e������������N8@��k�p���h�E��:�Es���@���L�V{/��eZ��W�C��@[�2�Y�IF�4E��ng�W�����%C���prR!���dJQg4��zx��ds���F���S�������)������<3Nb��Y����\:���zf]�R�:�%?4�e����Q����3��V�Gp9yY�LK9�������l��.�v��s��R����*��zi��N����NK���6����f~'J�fv'�`�k%�|-7�;-_)�������NfI�������G�C�rZ���oF��� W��=A�>:
%��M��t�fu�v\�7�]f=��t�y���|f�����Z�pv^Eg���f
��]�:��*:��
~�>B����������_?t~m,�y��,_��lf����c]m�*����,�j�5�w�����CP3v�d�+"0�������[�E�d3d���C�cs���2�eX�!Jis�a6�~
���0
�qe@�f��-�{`�p[16��"�c�q�/+x���x4�����F�f<dD�f|A����-��G`�0�&6�;2�N[������9�5h��V]����?
�0Wl��[�1�	��D-��5Z������R�������r�����-�{i`��8PlF7���Pm7���k����VG���n>LBC�G��2�78��]'�f4���m���9oG�k�������Ws���-���`�0EIlF}
�������t�F��?_�������\�exy���&q�|z�������Hl)7�V����5�)'�P���e�\HCg�����fC���f��d~�R{�c���+��
KY�]��8��[;�2o[j��[�*�
�����,�{�-�p�{�4t��g:�t]�*:�.&�y���-CzlF��n��@[�:��*:��h*��w=���,�|�9Dw��2J��h>�B��U��!
RC����C���._+�|���|���-�(���f�.8�z5�|m�|My�=TlYb)��B����|m�|M��&�f4;~!�����k��k��k��k��?��b3�~@��a����^�Pp��n��k����|�![������/rA��O����f���2�c�e�#�c��(�:B7�fu��:�[��k��>�1�pU=6��LS�\��h�m�U���|z��J���{��l�M��<3���Y�4�_f]�R":�<��u�u���;6:j"r��

�y�F'�4�::��
��#*6���:f2�'�f6�z��/�
���X7�3�����woh������r��V����V����V����V�����T���q7�8s
��Mn
]�|q�*:�Q�*6�y�Tl�c�Ulfc�w�._;7�c
]�|1�*:�1�*6�1�*6�1�*6�1���[��,�����W�W}7_�b3I���|����l�m������k��k����������U����U����U����-�����K�������M�|��\���OV�����f�a+�N��'w"o���"�����mnX]hPN
/����������<�U�e����e�`C�2<zz3r�B��D�F��
��2�y?���������*6�f������*6��b=W?�:��=K*6�^3�y����������gI�f�k�b3�������k[��7�%��G��;Ut���TlY�	�{���.�|�
9�s��2J�-���B�m���C���._�6��n
]�����G���N[�q�	�e�^�����5�s8���3�C�����B/����������c]�GW`��Xn!�6I��`��._#7��#�|��'�Ul����2�=�[�yU
��I:@��4t�������N��u~y�16DPE�Hv�����p�o�!�k���I��z09\�&3{"S9\��}����_��Vh+������7�[����e���zA�W l�[�e�-�����a�Q�C�a�0���Z��_e��1�������
&S0��eo���egJ����:����y$]/�L2]&_e�h*�l��m���������w�r�hG&��0i��4���s�o��o�7�L�w.��Q����;_����!���&-C�n~����}��� ��}�j�}�5��s�DQ\���tF7gSPh�QD� Z���g�����k������������+i�����a3��a3~S��-�h����w!�0J��3o�j��GSk����k���Rj����j�����a3z�S���[�������G��jn�{��	D�O������+D�����g0��6cs���uPX�n�H
��|�������eq-�}o�R����	����\�h����3�3yH��#�d����s������Utf����3Y�	E���gK�>�h�����3��	�1����7e�?�������5n�}����lJ��c��|���3+�0�\xwA����\�����v=i��(��0&,�1�b@��`����\�en�&i��GL�������������_��a3~s����������(xn�s�)����b3�W�f<%���|�����66�W�h��_s�a��*�`>�f���|V����g�0j[c�����v	WB5��T���MB�Q������������g��(�g/���9~/��w���s��Q�������d���s�
����.8M�i��4�=�*:�14��4���lHR����&7^�C���lM6���Z�kPuc{e��6�����f#i2��,C�c(|cR{=v
����������a�����x��lDM&��1����^k ���{����{�Hli�v�6(�+�1�b�B���`�B
X{r
)���w���1���1���1[��26�Ac*6�Ac*����
�[��x�3��b3o���������������f>hL�f>hL��a�X�����������Ci�o�kCz����rJ��"���vfV]64��F��fl�4���Mc��+3����n�������7��k?����g|����D�f�3�
��E�mH^���l �1�1X3�1o�����2g�j��f5���`5��O��W�1��
�1���7e�?�%����45v�	���~�����N�9aQ��=��
�����}����mY�M��1�9b`M�`���<�e~w1����Q�������G�i��_��a3~��-����e}�[�y���YW�ut��b�����QGg<VLCg�2F
���5l^����d����YC��V��(R~a?L����T��V ]�����G����^��>�����lLk6�Z���	N����g��(�g���i������U7op��2��~p<F:/7b�;S0���~���2o����[pW��r�L�^��%��|��I�^7��<�L�<<��o����7��������uA��!�|eV���q?D��'�"?�K_EbKyH���6*�+�9�b�@�Z$�`��X�r
#���K���K
��x1
��x1]���	��S��S�e.Vp���.d��=5t���4t�mb]�b*��>���S��S�e.�wt���>�)��
�j���"�C��ng�W���G3�]����I����)��u��?�$
�jr�����%
:�&c��N���e�L^E�!_�@r
���������������'3�{�(}r���2�]UC�G�j����c(xM�k��5��5���p^S�5����I���Uk2Lu��Y�fd����,����
]���^T���vA���t"���W����t�B��p\tc6Ew���w�nX�{7^e|�����g�*6��D�f>�C�f>�E�f��8
����4l�������?�����)�|����|�����+@�f>'�����q6���i����a���8_N ��.��@��5�:'�~V��Fq_@`*'P�nEy����(�(�l�1�	6f
s��39�� �@�v�G�0�,��������\^�[Km�6�F����/��7��O�7s[0��G�9�`��y���:@��EVj��FVn>��t��H�P0���L�<�5S��3S����f�+�l�e.���W�5M������njPv������e4|u��vA��r��J�Fc8 �O'"��l����2���������l�u
4j��
�'���3�Q���a3/LTl�c85l�c85l�c85l�c85l�c85l�c8�[�\����pj���pj����*6�1�6�1�6�1�6�1���c8}w��%�����U
$�f���Zg�(!��'+���e��3F_�f����R(
�:�7"q6���?0
��Cf��8��I:��y����4tF�r{(Lf3R�\��2�q�|U�7�=.S�2����I���'����`��p�����'���������.�|��W�m��.�;���V��r�U$��Q#���Z.�9���uL��w6-����G�2���tt�����|8���|������r6�W�i��_-�a3}�\�y�`���4t�c5t��*:�W�i��_-�a3~������r��������!�o�y��/Tp0����}9r��Zc�*.0����l^g������'G��^��=��Y�sw5���� ���u�A�WW�Z�����N���1��+���.���9�l��|G�8�]
��DeujWQ ����.�\������J.Jq�����ZO�������^���W{�����Z�����qw<����������H�^�����o���{�u����t7�����t��],����+�n��'��L�n����t��P.2P��E�������6<s��}�l�
E�&��������O��OQ1��S�������}2�PbL�	����=�Yr�r7�f[T+���������	���<2c�����Sp�O<�o����)o����S	At������:<��x,�]��!<��O3#�JbF"�H�����FG����t���g0|�|��)�.�@1m����~�qI����t�K�7��M�>V�]�Y��C4Z
���P8��U���~^J=!YT��?����#��*��2����� {�}U0(6�W���_J���y��B%	uB��*^�O�H�J%A��(lM�R)=�v�C%sM�S�f�-�J����q�0J\r�i�+�#�%�I�H�l5�F�����4]e��M�"H��!�HKQ����pY-P��b��M��!�&����O�>i������|t��� �05`Y|�����X�a����4��1��B��%�i�P�����()q��2y�����b}�h3��*�W��VS,�B-,��B-�ZV�8�w{�=�N��%��S^���1�A������_J���3%�G\�~�:���&�^o�,'�hR�hR�hR��4� �4%�4%�4%�t���D�Z���������m��)
��PB	��Z�n��$*�'*�'���9���������(B�p��������IU�6)U9W��Dm�uB�zu���t�p��F�oeV�Q���1n�#6
�'3b�#�$|K�+5�<�N@�N1��#!�n����S�4�F��<1.���K��nv��E�� v�u����i���&K]=��>&V��j8�)F5���j��� ���sP�/�*&�����^=��<�V
���y���{�Ig��g��x�#�@B���.��q\��r����z����Xu������C��C���
�����v���������9�X�3����]{>��Rr��V�<V1
�+���s9�.���sY�Y�Oy��~.������������u[k�ll�;�o�P���^�f���ceZ�����(�,&�n�1ho�F��	��(�y�:��:1����=�>N���?a�g[����h2�{���!� �u@����?q�xPl��;9~w��U ���%������"�%���+Rbs-�g~K�����/�JE6u0�[i��T��;��'�[{D;��:6��ET6)���3�#J��[�j��;�x'���<#�md�;:=����]�p�FF�G��FCY���1���.�y���+��=��\"��g�g�]�o}�m �9����v-���oC��������H~������D~���������+�������Q~�$�}������=K4��(�jNc��9��weZ����w�Z�x�4��I����R����Mu������Y�7�(��U��c������!O�U���"(�y��K�.4���u{�������I��8b�6�/
����D��;���v�
��%Y�%��*�����J��������:"�����|�8�+���p'tKgZ�����8,�j�:������GsI�(�n����.]l�� #�f	$�8�Lf��p0��q=reS=o��+�����������K��Bd}<��
=����SGG�J�m,?��_��dd��3��FCI0�~������-g�:)����r�?���X5�_�2��(~>���,9�x�1O;�@B%��V&�esy��y�
!u�F���eI������!��7�3��(~���cY��&�3��& �N&�esC�,���`���������$[���WP�g��2��(�L��Sh$b
�a�%X{�,�(������H0��zcee�0�bXL7�����f��^�/������}<���LX{s�B��P�Y*�t�t����{(i���d:	��.�2R;8��3��h([13�/��^�f'��$�a�t4���:�%��%lh�r�\�Uem'�*Y���K�ee����,AfU�t@`��V��V#�"�_�pz����7)���y<R�jd�
���Ay�BzA[�T�����I��"��{��~)(OV�u����}�PX+�%&=������7^��	=���L�x�\,����;Z��$����=�j!*V;�$�7�C7��}xr��Fie������"��+��S��l(��(��k[}{��.���VBPu�R���A�T�A��R�O�x�
$<������x9='c����?�\�"w��L�I2��
g]x����k�-6�$�C���gG �����=9�E�cL��z(k�0e�1�:~w~tvA;��d�~��0�}�?V������k�q�����o������y�����,�������1g�w�g7��m	4e��5<��;��U_�v�G3�]�v���L1g��[�5��ou+=�h��B�0!�l���B�j�iy��)��c�����=��F�tF�7a{�"��ek�ml
5�	��[H��������Pk�e��IZ�9�r��Q�����:��SBR^Y���k���N%oF��Z���a�p�������H���T����EJd�u���a]�9�4L�
s����{�0��������$�KD�7d3l��#�o�()����b���.���M�e5"�9���%�QnshS���������(c<�z�����	�[�������5�n�[���s��[=@��a����Bx]��/���L�J]���c��qF��cT�R�Z�m1���s[������0s��|��V'��k4)�IE����/:��U�^G���V����9��m�qv�������G������H���x������&�3H:�;tlW84Ck'K���;�n�v��3���u��a}��4%��0�c8����x N��p�8��
G�ej��<;*��42A���C��h��Hx`5��
�7
�������Z��j%���A	g�AT�[bJ[I�����R������������dsM���Rmv�{RB�Ia���:�>�CB���c���Y��P�U���+..����"b��pt��'�Gf�������2�xBGnJyfB������dW
M���������j�`���;�(�L<k�������Oc���c�o��P���K���~��t=��x���^���>tzT���z���{I�b4���V�m7y������~��Hm8�%1V�U�;������lx��}B>qt��+��
�V��,�5��|G�c�G3d���v]�����9 ����9�I�����h.�(6Qo���?��y"����5%7�����-��]*D8��!
�yA�:��u��3��a�L�7��g�'9cj��G��M!�:�����K�j�)��6�����
X`�o�}E�}�(A����0J8X[p�K"�����KOCO��N\����a�L'�\��z�I��P$�oI���b-���7��l*����C��p_���u�Q�(�o��Q���7��V�RM��eK~3�\����j��>~���������(�~��SS���
����,���"�)��u?��X�[Z"�>�&�L�Q�+�4h��J�v�*���N��Z����uj[�Lm��$�4��P����3*/x���4R��p�FpJ����.�yI$Dn�1��Fi�I������������O0��t�w$��y��}�	�$�2���Z���oT��k6�����_E�v"�>�T�<�7����*���4��hsin�U
7�R��^6���y�&�He:����Y-��^���&q���d��V��Y��Jr�A#������|Y��$�Mft)����������w�!������p#0	�����q�n�;��
xx5D��=��
~o3J��d
�XU���]��g
����lx�j?�gs{4�'�v���R�2�����p�	k+x���9��a?��Hy25��p�"�+�;P����m�����(%�6�����x�*-P���@���UZ�����khb��	}:�D��E�[����\��C�������s��0����|������3&�T������^��7��4`���x\]9���F�&�g3�4������z�2�%�^�=���jU��f�:�����|=s�:�RZXL��Z��z#��5�e�Xu>�����s�[����q8��r�
��l��N�L�["����G'����� =3j��V_�O�B���7HbMNr!�V�������T\�^aM���!H�G�B{t;�E�����$%{�������}��-�����:P�W����6��,�j�t:���Ln6���PR.�e�r����__��$����������$Rr`�P;%<�}6j\,�MHke����Y1El#]%N�$��l4�X8���U�Ko��Hk5�~�����[0Sl���2�v���$Sl�p>����L�/������1"���r��e!�W�=��^0���F�zRr>3�g0�Q�������a�J;�NFKk�:�jZ��oC_�+
����KwB�;,�&3��PP��z2�&w���7�2�����vf=�����s*�))Q��
>�]�����0��Afg�,dI�"H�2�����6'Q����D+3s�i�N>-oF��GAvi�|V��&�V��/��]�8�B!$7_�@)��G.���C�F�H7�����H�usD��	���i�8)��6W-u�<�����1T�B_�2��Zy)��-��-����o��� ��_�*l�/M�We��T��Z�-���r6W5�����"�
[��B��Y+/e������Zy�B��A�dP��B�-���!�����*[�B�������D-�r����������yb��C
[([���z��j2�����*���C�-�[��O�� ���P�KC�-%���R="�\a�o��mi=�0�j2���������#
O(l�u�B�c��y���$�:��P�KC�-%��R=�@����2�YAf���j�P2���������#:�Z�B������R����� Z*�_:9��R�PaE	!�Q
�G�����BS{�+�OXnc
�x�i�i���^����eJl
�vB����0��N��X�#J�����X&��d���`�ElU�C�U���"�������P�V�VnT����p=�E�U�j�pT�T*PR��
�|
��=T�@E�������s�Gd�=^����.���_���E�&� L/��T.Y]%��������1J���r)�fE4�����M\g��m1y)0"���ON�W�8����������}M��oz0���g�����<x���0���p<to�f�-�Ab�����V��3b�����pLg���c��vg�;�u>�Q<�`���2[��U��`8���\r�R�'c��{��n�R��*�p<p>������~c0���T�U�;p>���������U����+u�cU���������}�L�l2�Gd<���?&W�S���j4��:eB�e3B���' �i8��3��^}��
xq����*{��Z��t��U2`M|�������N�8����E^��F��|�N���jr$�N��D��v��?�^�G���E�R40_�3��S.��8�]b�� �%i	����F�f����3��~Jf%�qn����[�����j�
������l�,������4,��>���)���	/���^It7�J�=!O���*m#=�m��
��3v��!��&2�Z���_���X�>�G�%�@���� �����hOK ��)Q�\!������^����'��>'�?����O���NF#����s��3�zR�3���"�w������rb[����6��Iu�OT&w��$W�MV���pr�����P���'=��"Z�^�3�jzk���K5w�B��,��D{�D�z�{Z����+��d|]��O�R��������U	����T�9~��������ER?���bG����� ��qOG��%"�E@������a6�S���D_&W6��L�>�������y�v�P�C�Gm����\W��h�r��)���s��<'���G�~�*���	][C4��O(?����3rc�TS"��`�:�AB@���g�����{+?��������7=e�Kn��\������z�e����l���.��	'#�/:b�����	F�mA\�������~7�Q�R,�M_v�9�:�@Y��k�����g���{��d16�P����2�u;~H�F"�;��g��-V����f#������lvq����2�b���m�E�YN~���)�7Ru�D�_N�2�f;%:�.�A^C	J�����K�X�Nt�D�\=�@	���Y
<��������@RO�'��$k�A����_���=,��c�eR!�%�	�;4S���~�l:�L��YKuKc�,��((�6[�v��";�3�4m4�4/J!Mi�Z�6��t��2���i*�J�����4�E�jg�h"����cv�|dZ��y��~���
����8�)}�mo�`�����I����r]��,�,�����g��3��L�"�H#II�;�uRN- �������c����X�_����c����|4�~�K�o�)������7����	��}9Q�H
�r���,�41PL(�
i7�����+
�C��D��?S���L�h(���x���~&b5�z�����V-�L�j��,�&�&{t
<�aXo���7�{�,�p(�^y ];]$le������R�X������5��u�6�P=��,<p�~�`V\��^���~�V�t��~c��_0M�/���F�� ;�3�j�A[�����@]O}b{^R
y�G{�`���.�}�V���������VP������4��������YeA=�Y)����s��=d���$�v5�4��8� Y�c��01���l2�8aU�}��:��eg��W�W�U�T�d2�1v>s�J��}5��,V]���h���P�pA4XIk�h))������X��H���h,hF���uY�	���������9 Oe�v/�x���#`��W�s^���W�ftW�����
7���z�l��#[�^��l������
k)Pw566�����
/�uU6���_:\���5W����LW��|`��9$'�p.y����2��=�Ic/��d���:�M�V��7�z�^�d�0SY
���n1a�>���/�B����.p���=f-�S��Gg?+���G��d�!���|�3d`HjO� =���-#����6k+���i�R���mC"n�4��W����@W�n �m7��S�A$�/#�"'�I���h%<a�"��
�C���?�9:��v�?�����f�F�P�;z9u�����<-J
�/kp�������U�
�N�yi-��=�i��W��5���>�����K��+p���N�	_j~�,s�7��j�P�M���A(+�1m��iT��J��3e�������'���fGw;r�/�7�
�jst9_�n��]�����	�A����E7#cf��(B���4Bk�Fh���j���&�Ff��Y-��+t!����&����Uym��&�Y�p�U�o��4��
(��~6����2��{���3X}R��J�Xy���h�'O����������i
[����B��{���Z����{�X
b;A��;m��>�������o��K�����a���p�^��������::��9�����]`~O0Az���O(�������a���B��2�<
;�I(%��H�J�5��g�@���d�3�t�j����	'�*�&��[���3)��vYMmJP�B�n�=�v���-,�&J�P�"���p����2���d@���e��j#T��])�����$O"g�f�����-�������?���rN�$��Q����l��0z
���� �O�m���U9�h!P9��pNB��)2�U4;��.�&�<�c��]
2�a��T����c���+��Y]g�B)o�.�(�0�h�p��OQ|�\Q����1��-�Rwi���������l��.�������6�C+���&�x�3hq,���Znv�i��+��������n��%��@��z	W�d4jM���5�;�����U����v{w�3�C��en�����
Xr��_}��O?�$�xk]�Q������'�z)a��������w�sB�Wg�
����p�3����p�4���>V�L��ie�k��/�Y�p�U�o�]���j,����\l|�M������+��Q�|����j��������Q��xyn)8��U���j��V�U_�R��	���v�y��gR������]���W�������_�����m�����^-@>~#2e;3�.����*�KIH(�
T^�5��;�f���q��6P��;]���G;�����;���d����v
Q��sQ����[-*j�����n}Q# �5�K���4���?cNb}��B����	/�/��+�aS��R�w_�u�=���[T{o�M��o#����������Ah-X����k}N(���Opb����,�����3�0^�:P�rbk�OHX� �oF�+��H{���!�VJ�����W!��X�#T�,w!�e-&���#�(b��+N�=tC���,����MLo5�����s�opVv�,�a
��Y�a��_���u���p��x�=m��cA�������g��+����V�^���1^;!����B�gZo�F����9q��^Rd;k���e�V�7���VR���5�W}1�7�7�
�'d��N�{�I�h�{9��{���H[��_|�O�����P�w��.z$��_)�<���[��OX[��u��Xb�\Q��_�3W|������|e���tEL���yrByk�N����(����y5��j�jW��]�5��H$�$"�r�Gi ���CLF�'d6��]���+\��*���v���b���,c����hri���i,�u�5�0e��s=u\�����9���L8=�_��:2���8I��T���2Q����Etj���*���~"/�����k�J��G��MF�D��Z�����c��Dx|�aAoeh�Y��eu�_��!��	{������!����YF��'_��I��b�Z	��d�|"��oA �5�Vp��W�5���Nc�K������E'��C��^��2m��Y�';��[J���e����p:_��';G�9z
�j����'��r�i8��"A���`�"��	��Ork�������d�O���s=K��u�ZZk�V�~��V!C���n���_���^(@j�F��c>��F�����s9�.Y�?��-�7X2�{y6!gG?���������+��#/g)
1�|G�v����=d{�9�!��R�:���EUg��n��`�n������[zv�>��c�>�q�>���
��u�������c�>n���}L���W��d�>\�1cs���}|b���������]�����7vr����Q����}C��nh�|%{>�L�J��{��E<�V|+%x�`�9���������O������G���l�	.P:�drE��]�����_���L�n��:����������
T����p��h�X�]l�8d�<T?�

������I	�=i����w�L��lP�����	s�{8p=�'���%�O���B�KC*��dH�6���������A�����C6g�h��:��<������yH��[�e��M'���1�����z�o9�TB��l�8�X��0 d0q\t�Q���1 X�/m2/5�������C���/�����V�HdN_u��k;�E�����1����\v�P��3*s��zc���[��9�L����N/��uDvv�1����j���n/[6�Sg�&�EJ�'e�*�<X;b�+�B��$�:�]���������7xs<�9��e�����!T���pC�[1]�]h	2�������
Q���@��_0����R�[!k�t[����[O��|=�."���S�A`fNQ��V��A����<�I"�U���L�6��HM�z���B�oY��(�
6�~6�V;�]�k��BQz0R������Y��!8ias(K���VR��R��������J�&&cb>��&���r���J���Q�z(�B��fF�m)e�G�Nh���!�C�u\2����E!�h4��xF#�Rlt�)U��l���eODY�W����J""[q�b���Z��+��F\{����C���y�����u�%M�>����2�_x��Lf�0<�
"�9�]���Fr;��qIia��!�k<�Ta�1��(F:�V-��'�"����.�����)m�ltO����F&�g����
�"(��SWC)�&��s������H,g�`=�7���M�����@:���Jf�������K�UM�^�,6�\b���Z2������l^1)'��� ��%����+X��
��Qe_TY�Z2Pf�����G^!���q(�v�m�����3+�S8��v���r�PN"�"�5�O�t����=��>�\m����`4����g�����	0��������j�(y�x�p��]l6j8nQ�����L�.Yb��c;�E|'P-X�*zz��o����|���@�?�fv�
��v�RLu�_���G?N�VM�q
U������%KU-�i/����VXj��R�T���)%�#�L�W����2<��&���Z]�8���KF����Z*�f�I�oF�H�n�j4���*�f$>%���imX��"��	f<Q�{i,W@A9����h��O�Ui��r}��h�|��9}h��i'=��pgV
A[���`?5�'T=���K�����%T�,��G��J�k���m�����������,�����4	m�V1mbrM(!x62�����G[HifH���9J��EP����`��R�L��R��o�R7b#���_y�KNRc&)a#1<I���I1���&Y�*�>����\{=��$�b�dp( �2��:������,~hYL�J��@`|B�,dq 0�:�~����=G��d#+����5,��e��=`L��	����8�X��T�:Y%���n�w��U\uB�W�`����MB�w�>����+�r�b_���tNk��w�?|�d��xB�s�NtJkv>(L���bh���x�|a5x��v3t1;��w\�ow��8���N~O>��+1u��^�� J��?��)��z�����Wa-���z��
O���5��9���C{"�\��[��=��+�*�����Z����
o��O�'�;�^��d������#U���H6X.^��'��v���
8��j�,28/�8>d	��Y�K6�H�l��0�a������4�Bi�pOt����\@"�k�-�,mz�r�O.P��$�?�f4��`,+|+������]�"wspw����*�!|��Y����b0����r+�����|����
'=.�oKA��V����R��S��F9x;d�\H�v�_Q;	�W����c��X,�Q�Fz��0o@N4��h���(���)�y�	��<��i�2���l�R���!�)��+w���`b��-�
q[�
�5*����-G�T�S���)1�	��b�?h�.�e!��v���=���	�^�n�q_��QRCeo�WJ�����Z�_����{�@���UZ�JTi�*-P�N�#&�T����~�����\OZ�������t���uB�!��U��7�Od�����x���os���`�����2�od�`2~6#0O#�N��+�������}I����������K�����o�%s�Tuj����`�P��z��(b�7|�:C����s���`Z�n�|N�.K@�j�7�Y����%b��	}�q2�����=3j��V_�k]$�Qv@+��kx�$��$g�m��p(#��SQaMB��kwtA|tx|�=����tD�XR��=t�[Ap���s����v�M�?(c����,��$���j�K3��-8A�e��\�q�'����/�AkgAbM\G��k2���Q.��
27.patch.gzapplication/x-tar; name=27.patch.gzDownload
��CNS27.patch�]�r�F��M>��k;�DR��,%��$��-EV6'��X 0�Pm+)?��</�/�;�=���E����l��������� ��N��M�q[�t�����u�w��@o�{F������z�V�|>�]��}���?���7��������������]�O��z�5��g�z��c?q���<�u�����f�5U�������P�
/��;f����c�[�y�i9w,����{��1���~��;�1��o�����jDAww�Z��L����g�c��	�$|���{���_���k�N���D�����a��g��&7���3�5���0.���=�3w�������r"p?��������; P.��d���;�~d��������}���]?����2���g�i��I����vK� �n�]���Ki�����kVow������fpk�?����Kvq����������~y~4�=������,��L����t�p�N�J�f�T<�
"����{�0�k�l���f.�&�������55�\g��NuGhn�y��Rz��Z�������������1�a�
vFe��>��k�&����o�Y�����,E��.]��	�<u��1���2��xI.�����������q&X�7p4_��Cn���Rj������Yl�!#a	�y�SGK;(�%+������e%��Dh��u��E~��Cb�!QT�
$�}��o���&�uP�!_��!ZDA�����+!�\���:	��Z������+n]7�Gx����������!|����9��8�������77������xD\�&Ll�?����A��PV���?��C��c���q0�U���5��������S�5t{��c#�C/��9����mkj90.j�t�1w�����K"�L�D�%D���20���N-����f�&z�4���`DC��f`�0�~0I�68�T���m�
]W
]��
�H�s!B�UE��V�!��l��?,���&g�P�!i4���
ZdT��L ��?K�D}*����V���a&��o��]p!�]����>��-���%pC�>���N�D�}~R:: �	����|@����X��|X�����!�6X���"� ��T�@`���sOY];��TdTou{���r�"����L�h_��\���@�F\���)������Rf��<v��	"#�#E��#G��_~��*�RE��
�[��7��@���~�N�L�e����6oVfN����6%���W�%x��P��+ S
]�[��ys#@@v�8�}��������d�f�X���sR�7@�R�|��fz�K�<�(��Qy1s�r�+��d���lL2�T ��������2f���3�(s�{|4�����G`!���XP���(FK����N�sH�d�{����T�H<�wm��k>%Cs�����>S+����B,��U#k]���_��{���0��?��l���H�
��{��F�Q-�A��
|k'#��`aQ�� ��IL �~0
�������u#��-���[}d[>�����xV�&L����S����K������
O�|��*&��|�����/Fy�\���������P:z}�jX�F�)��|:�*��p�V{Pk��a���u�g���>D�����s��;f�@A���Zc�?8�|�J��g"#}H�.���G�^��t~�����A������Lw�g����9�!-�<��%�G,-m�H|-�$?�K�|��!�t1s@L�CL��*��M��� ��j��9�,A�/��80��P�E�V����D���8^c�g04��4d�:V����iA>T�s\&��}y��O�F����(sC7�i��3��Q&Sb�;eZ5"p2�����p0jsH�D�,���J h
v	�V*�^+U���i����1�`��
���m
���H�WEL���K%��>���n��Ec|��PP��l/���;7�X�������c��������`��i&c+���~	8�S?�	zQ���L��Y�d$�l�e������S�o���2f���8���9�f�����}Em������^�Q�X�$��"�OqPK�D���
��~�JU+����=���3��h�g�	6�"<H�Jg\2����'�a
��z�����BV�?$�����Ba��(�@��� �����K�hl B�n;���_]?��Y�Q��/�d��IO��kup����{�Ng��'Ki��'[#�\��A��
�&{������N~����39�DYIq)���G�a	lE���Q��(�;$�H��;���fU������w���q<2�\@I�^`<q��)o]�����/�,���j!�t��Hkr>.W}�$��$����wu�4ur�<Fr8�t7�|r��)z_�M��r�������Y�]H�?n���`�33k�=�<DuHJ�;�9�"�Ll
�Uuzh��h�SS��:iu����0;c0��G�<Z�q4�6!i�Cs������8��_~)�������P��o�Q���pE�&&Ex���[���S���A�U6��%���$]!����~���
3��w��Is:���������E���>�s>�V!;��a�Xb�z�H�5�x��D��cLg��n�Uh]�Rc�*NT�&�P�*���L^*�N�����(�[YTG�=�����R�l�<���H"�f��jEL������p:%WR��o�G���D���*����p�`��-����Z������YZ-�����#!)~�u	�\�GF#@D\(�SY�"��?�)c�-R�e.:J6�;����m��t�@t����%�����R��0����9����RWf�X5q_���h��������bJ�O�X�
�dC��4���W�dU���	o�8o4��i���(+�auZ���Z�����B�����$�%��!��0�	�eem3��0�]���S+��s���J@8���px9o��E�8\�(���p����CC����GL^3��6�[9�
wk�
�Zt��n���.{��z2�3��(*V��no.V���7U��w���T�F������U���VO��+�����Z����e��i�3�8W���.��^���X;W�pr[;F��t%V�q���L�`4uM���������`asD�,��Jm�p��lr�ziB�����\���o$�F�/_G�{j����g\_��lxw2O)��nT,nO$�~�J~9f�>�o����4�-�WR>.�N�^�����I`xB��/�1���42i����w�(Vsj���h~�o^r�r�%VhurkS��T���I�#�#�Sk�]T���Q����5c>h����"��GY�Ek���])#��5��=���2K	O�3BJZa��)����d#�AD���V��X'�Nnr��jd$����������w7��s`
��o9>��u�#��������h���y��T�Z���G���	�=��$�}���6����P[i����n���v�����&\��r�.�^Sy�C\�%������x(�9����9*Z���@��y�A�UDo�;�	��e��Q
-�"T&Y]�&��8D�(�\��������(U
�/R!�������G��	��N��h�[�e�@�PUD�@�7��x|kX���a�{bB���hn���%[��
te��<��Z�)�<U-�j�9�D��D_��F/_�xyq~��
��`���Qmx��6�|s�#������[hN[���G%D����N ����Kg'	K��V�M���������V����Y����Z���w5��R���]�1��w5?�w�2 �������VStv�X}�2�/�����R���
�=���5�/��m�_�#B��
0��u9<�.|[a
#�.5�lU��>�A���=��j8���%p��_�@�%c��#�+���w]�� Sv�&�;��x��B�:D��<g!�V�3�@�#;�*���!T��*Q�0�>��|[������)B����m������� .���`���j��0y���'����b@~k��^��qY���R�6n�	W��h�b��6�2`y��8v���*���pG�_B�/��1������%M,
���C��������z[l��D�Yc��F�KA��}��J����������je{Y�jQ(�{� gK�W�|	Hd���������Q(���l�9Sx�ZHH�Z�e�H>���K�C����
�`�D�}������G��8����yB��H�Z*�%�V9��S|����s)��y?��v�]u�K����65�6��Y�$
{�{9Qo3��R�D�%Kb�-�����c��UKy[s��>���u�+63��h�w/�P��A��|�y��2������E'I�f���q���{�F����N��%\xz�m*v�"c����$�<��n��b��'�z��_��hNr��b|��S�}j����-��5�~c_�S����X�����������i��n���N�u�v����_�������P����	���E�
�#}���)�*Nd�E��G�	��d( L��/������k�9VY����"���7�X�����g��)�8vw�9�r�c|��C��������1���[���U ���!2,���f6�������.�n����}���_�����I��G���6��G��x�����+�/@������x6m�^�����3%|~Uc��%��ZN��u}����$�t��)�m�ZT�)�
�6�����<=[I���:�!����O��Qm������fO,���
�IM,���� ;
�����[�H�����@-�����*7q� XS�E�d��5������y��>��w�����#N�ScQ��p���m�>��)���H�iL���u���Cy-��i�n'=���7��,��A�{�${���G\;�������V�������!��[�u�
g*��?�Y�Nk/�6^or�B&�y<�[��x�7���7���ar���&�3u������P^�A�������b7	�����f=�����=�3���
��v�vh�u1���{�&#�#��'<��T��{`^�m���y�N|,g���dC��4���h����j�WD ��:S�1�5
�����-yFRS^�|����L�;8���Q��Mgn�XP�O����=!�oD
��%$-v�����R���K���2�������d�.A�!�u���G�3����.?"s�������;*���������=uY]B=��LZ��82�H4]?��y�~l;��#6��=�*
���0��>�"=�fQF�C+��4c�1����a/L6zq3�&��w��&Fg�v�
y	���DS��"7e�����f�+����������>Y1�y���E�gC^1��jx^��2��>I�P�,����(WcS����a@n}o����&���>����M���N���z�'���<J�tW[��=D�d��Y��1�I)������)�EQ#���B�����S�rX�~����.�w#�q��)��!������:��n|6:�-� q�������<
_h�j�����4o�0|����SF���V�=r�0�N�U�����Ov�j�A��0��d7L%�����X�K����Yz|J|����;g�9b��1������������>V1�{�BI���
�j���E]�D�I��6��`��'��I'�b��{�$O��E��D7k���O�b5Q_M�R`Z��vA(�����z�}#�7+ ���'`�\��S���)������j|��w��k6CPp)��/��A�17�O���;��h��a��t��n`���)1����/�2��E"$�7��)��
9?u�:9Y�]y��������;|='
.��<�v�T~�Y[6�kn���E|s<�g�}W<<_�,{�~O�Q��0o����D'0�|%�=Sf.���@Sz�Z��s�v[���)�=�N��`B�i��]���������L����i�����������u2�H�����(9���X<�&D��+Qf�w�b	�o�],vER���pnY8��x<�����UL�fk�e�p���<J� Zqc��Aa;ef�������ww�n�l1�6C�O��k���4�C�5:�R./�	5�TQni��ei��YXZ�������f���<�&�����
�Y�����0�
�Bc(�E����U]tBE�pb��#QT%��q��R�?���t��X�����:v��
$	��s���cR!^0�h9�c&�������#zt�V�����t8�����K��=N������w8��>��7�U�92���HEM�-<]Pzl�KF�����#
�������S��y��ID�6Q^J?��{���?o��IN�n]��.T�%�	�B�����
y��+E�������e��*�:��|O�:�C��^	�����C��o��e+�K�A8"��~��@���'��?*8�F����/��5	����]�o���n�1*�R����_��1����Z�e���,����U��u�[\���t��*c��K���`��	�vQ����������0����n�d���O���^��`�g_��������X��=.�,�P:#�_����1dFz#����i	����D���Es��*��h,�z�qM��|�^(���dp]���<��������>wP���k�YI{�<��9���{�a_�l��8�����sOv	����g�J��^��s\�k�6/v���P�]��F%�����m�0t)N�s/8=�e����{��/85��I��V�2:�`��M�#�_����
���"�XCQ27��8�-k��3��I�����������)�}!�4s,���b�0�U�8��,/�����?r������ �(���+�����Fy�����R�����7�����F�V���LG�0��L=�n�\�����p���7�T�A��'�u����9D'��P�Ev�
<�Uv�~��l	��X�{R����~$h����%uO
����|G)��i��r��a�<�*��6�����4�}W��)�P�+�bw��S?�������)j�S�
h�!�j�"�r��A>����D:�c�f��
r�g�TS�!02�*���=�f�UQ?5#�Pz��2&�Zj����9h��9����T�m��
�~&��
�L��J���;������^�����Y�$T��b~	k�@r��*��K��q%b5��J�V^Pul���6��ed���A%�/��o������$��x>�-k:��P��h;m���������pT���H�w.��xv7e������3�~Y�OD'�s����jI����Li�z��f)�����h�V��)�G:g�|�V1+�7_.�� ��r�K!!OT�b<,2��7�^����!"���'7�5$ Z�����4])}�m��F���z��	���A�`�J<��&3}�TPVWME[��"��O���EY� ���{q���Q��b�f�YD^�}����������R���5�
m5�Z���f+��I�d����:���X\v�����J'����o3t]���*���6��d�%���g��j��|]����,#�,V(B"�1��M�V�Qgo7��F)�&h�NC1����F��I��AP@�w>�����.�;�����MDxfa���Dv2�������	���+!_�A��J����w���<��e�����q��r�U3�n�!c�M������|��fa#!��mg�$�������������n*��-v�	������g`l$T.���V�Jc��@I6;��fe�g_��`�g���Ta]o��m�7�������`�\�R�m���~3��
�?G���!�.c�]y>��C���}D=����_M��I}Q	��K���>TBI�]���W4���R������&��J��]��n���u����L�<1�F�P9���q�'�L�������a����e��Oq�s��	��g�&,���=J�t��$Z:������Z+P	�M��h�������(k�o^)Lw�]
-y)���f��B��Z�w�f������o���O�tM�ld3"}W�1���:�����2q��U�r�~��P�m
q�|@��I|�"��2���u�����8���h���>��Q�EU���m�����f�,�Hk]�i*-�y+����5�����Ft(E]%.u��/�e�����w�*i���gbW��r���+�#�z}�����n����`�w	���]���e�-]S������Sl{�l����!�N^ YCe��>
*#o!b������e������2
�**�h����Z<������*cP����r~t%�J��l^���v���]�Y�P	_f�!�����O/���B��\��YQZ0d� ����!Dt/t�U-{U����QtOX���7�a;6`b�������h�_����e��N
�C�*���"����������Q��a2��\Oy8��h�Y�=���_N����V������A���e����N����T�,���^�v��������/�w���2wE�>�Z��F��������G�Q���'�[JO6nPU�Y*jJ�"z3(�O3���pX��&��>�"���8�C^@y@(������V�<��b���$��3HH{�q�o���oh6�����2�
M�%��
M �Mh
���
�X���I�Y;���:LYH�vi�����.c������������D^0��<�M��h�?s�����Ms��\���S���w�h�K��]�����y��s��<�p�
����X��w���c�;{��'X'g�>��S���yo���4�S%s�mf���g���C6,�}�]��c�lW�`8�Xg�"(�lVD�y�t, ���Tm\��e�t|�~%���We����|\)��Y5�hQ���U�/�>�$��C���*���#���*bb��������%�vtT����"D-����x�_���L����
�i�+�[)��,S������s!�4Z��s�Y_���K��>B���
���L5{�4�����t����Y0�2�Nso)li����f���:�R������a������,���CHv�&�� ��1��=��T��P�m]D���	��Q]�\^�8��	b�{�Cw'���}���%>��
28.patch.gzapplication/x-tar; name=28.patch.gzDownload
29.patch.gzapplication/x-tar; name=29.patch.gzDownload
30.patch.gzapplication/x-tar; name=30.patch.gzDownload
31.patch.gzapplication/x-tar; name=31.patch.gzDownload
In reply to: Boszormenyi Zoltan (#111)
Re: ECPG FETCH readahead

2014-04-16 10:54 keltez�ssel, Boszormenyi Zoltan �rta:

2014-01-18 18:08 keltez�ssel, Boszormenyi Zoltan �rta:

Hi,

Alvaro Herrera wrote:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I hope Thunderbird did the right thing and didn't include the reference
message ID when I told it to "edit as new". So supposedly this is a new
thread but with all the cc: addresses kept.

I have rebased all remaining patches and kept the numbering.
All the patches from 18 to 25 that were previously in the
"ECPG infrastructure" CF link are included here.

There is no functional change.

Because of the recent bugfixes in the ECPG area, the patchset
didn't apply cleanly anymore. Rebased with no functional change.

The patches themselves are a little bigger though. It's because the
patches are generated with 10 lines of context, this was set in my
$HOME/.gitconfig:

[diff]
context = 10

Best regards,
Zolt�n B�sz�rm�nyi

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

#113Antonin Houska
antonin.houska@gmail.com
In reply to: Boszormenyi Zoltan (#111)
Review: ECPG FETCH readahead

I haven't been too familiar with the ECPG internals so far but tried to
do my best.

Generic criteria
----------------

* Does it follow the project coding guidelines?

Yes.

* Are there portability issues?

Shouldn't be. I even noticed the code tries to avoid platform-specific
behaviour of standard library function - see comment about strtoll() in
Linux in 25.patch. (I personally don't know how that function works
elsewhere but that shouldn't matter.)

* Are the comments sufficient and accurate?

Yes, mostly. Just a few improvements recommended below.

* Does it do what it says, correctly?
IMO, yes.

* Does it produce compiler warnings?
No.

* Can you make it crash?
No.

Only some of the parts deserve comments:

23.patch
--------

Reviewed earlier as a component of the relate patch
(/messages/by-id/52A1E61A.7010100@gmail.com)
and minimum changes done since that time. Nevertheless, a few more comments:

* How about a regression test for the new ECPGcursor_dml() function?

* ECPGtrans() - arguments are explained, but the return (bool) value
should be as well.

* line breaks (pgindent might help):

static void
output_cursor_name(struct cursor *ptr)
{

instead of

static void output_cursor_name(struct cursor *ptr)
{

* confused messages in src/interfaces/ecpg/test/sql/cursorsubxact.pgc,
starting at 100:

exec sql open :curname;
if (sqlca.sqlcode < 0)
printf("open %s (case sensitive) failed with SQLSTATE
%5s\n", curname, sqlca.sqlstate);
else
printf("close %s (case sensitive) succeeded\n", curname);

I suppose both should be "open".

26.patch (the READAHEAD feature itself)
---------------------------------------

I tried to understand the code but couldn't find any obvious error. The
coding style looks clean. Maybe just the arguments and return value of
the ecpglib functinons (ECPGopen, ECPGopen, ECPGfetch, ...) deserve a
bit more attention.

As for tests, I find them comprehensive and almost everything they do is
clear to me. Just the following was worth questions:

* sql-cursor-ra-fetch.stderr

[NO_PID]: ecpg_execute on line 169: query: move forward all in
scroll_cur; with 0 parameter(s) on connection regress1
...
[NO_PID]: ecpg_execute on line 169: query: move relative -3 in
scroll_cur; with 0 parameter(s) on

As the first iteration is special anyway, wouldn't "move absolute -3" be
more efficient than the existing 2 commands?

The following test (also FETCH RELATIVE) uses "move absolute":

[NO_PID]: ecpg_execute on line 186: query: move absolute -20 in
scroll_cur; with 0 parameter(s) on connection regress1

Other than this, I had an idea to improve the behaviour if READAHEAD is
smaller than the actual step, but then realized that 29.patch actually
does fix that :-)

* cursor-ra-move.pgc

What's the relevant difference between unspec_cur1 and unspec_cur2
cursors? There's no difference in scrollability or ordering. And the
tests seem to be identical.

* cursor-ra-swdir.pgc

No questions

* cursorsubxact.pgc

This appears to be the test we discussed earlier:
/messages/by-id/52A1CAB6.9020600@cybertec.at

The only difference I see is minor change of log message of DECLARE
command. Therefore I didn't have to recheck the logic of the test.

28.patch
--------

* ecpg_cursor_do_move_absolute() and ecpg_cursor_do_move_all() should
better be declared in 26.patch. Just a pedantic comment - all the parts
will probably be applied all at once.

Other
-----

Besides the individual parts I propose some typo fixes and
improvements in wording:

* doc/src/sgml/ecpg.sgml

462c462
< ECPG does cursor accounting in its runtime library and this makes
possible
---

ECPG does cursor accounting in its runtime library and this makes

it possible
504c504
< recommended to recompile using option <option>-r
readahead=number</option>
---

recommended to recompile it using option <option>-r

readahead=number</option>

* src/interfaces/ecpg/ecpglib/extern.h

97c97
< * The cursor was created in this level of * (sub-)transaction.
---

* The cursor was created at this level of (sub-)transaction.

* src/interfaces/ecpg/ecpglib/README.cursor+subxact

4c4
< Contents of tuples returned by a cursor always reflect the data present at
---

Contents of tuples returned by a cursor always reflects the data

present at
29c29
< needs two operations. If the next command issued by the application spills
---

need two operations. If the next command issued by the application spills

32c32
< kinds of commands as is after 3 cache misses. FETCH FORWARD/BACKWARD
allows
---

kinds of commands "as is" after 3 cache misses. FETCH FORWARD/BACKWARD

allows
81c81
< I can also be negative (but also 1-based) if the application started with
---

It can also be negative (but also 1-based) if the application started with

132c132
< is that (sub-)transactions are also needed to be tracked. These two are
---

is that (sub-)transactions also need to be tracked. These two are

148c148
< and he issued command may be executed without an error, causing unwanted
---

and the issued command may be executed without an error, causing unwanted

In addition, please consider the following stuff in
src/interfaces/ecpg/ecpglib/README.cursor+subxact - it can't be
expressed as diff because I'm not 100% sure about the intended meaning

"either implicitly propagated" - I'd expect "either ... or ...". Or
remove no "either" at all?

"Committing a transaction or releasing a subtransaction make cursors ..."
->
"Committing a transaction or releasing a subtransaction propagates the
cursor(s) ... "
?

"The idea behind cursor readahead is to move one tuple less than asked
by the application ..."

My understanding of sql-cursor-ra-fetch.stderr is that the application
does not have to do MOVE explicitly. Maybe

"... to move to the adjacent lower / upper tuple of the supposed
beginning of the result set and then have ecpglib perform FETCH FORWARD
/ BACKWARD N respectively ..."

Consider it just a tentative proposal, I can easily be wrong :-)

That's it for my review.

// Tony

On 04/16/2014 10:54 AM, Boszormenyi Zoltan wrote:

2014-01-18 18:08 keltez�ssel, Boszormenyi Zoltan �rta:

Hi,

Alvaro Herrera wrote:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I hope Thunderbird did the right thing and didn't include the reference
message ID when I told it to "edit as new". So supposedly this is a new
thread but with all the cc: addresses kept.

I have rebased all remaining patches and kept the numbering.
All the patches from 18 to 25 that were previously in the
"ECPG infrastructure" CF link are included here.

There is no functional change.

Because of the recent bugfixes in the ECPG area, the patchset
didn't apply cleanly anymore. Rebased with no functional change.

Best regards,
Zolt�n B�sz�rm�nyi

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

#114Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Antonin Houska (#113)
Re: Review: ECPG FETCH readahead

Antonin Houska wrote:

I haven't been too familiar with the ECPG internals so far but tried to
do my best.

I'm afraid we're stuck on this patch until Michael has time to review
it, or some other committer wants to acquire maintainership rights in
the ECPG code.

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

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

In reply to: Antonin Houska (#113)
Re: Review: ECPG FETCH readahead

Hi,

thanks for the review.

2014-04-23 17:20 keltez�ssel, Antonin Houska �rta:

I haven't been too familiar with the ECPG internals so far but tried to
do my best.

Generic criteria
----------------

* Does it follow the project coding guidelines?

Yes.

* Are there portability issues?

Shouldn't be. I even noticed the code tries to avoid platform-specific
behaviour of standard library function - see comment about strtoll() in
Linux in 25.patch. (I personally don't know how that function works
elsewhere but that shouldn't matter.)

* Are the comments sufficient and accurate?

Yes, mostly. Just a few improvements recommended below.

* Does it do what it says, correctly?
IMO, yes.

* Does it produce compiler warnings?
No.

* Can you make it crash?
No.

Only some of the parts deserve comments:

23.patch
--------

Reviewed earlier as a component of the relate patch
(/messages/by-id/52A1E61A.7010100@gmail.com)
and minimum changes done since that time. Nevertheless, a few more comments:

* How about a regression test for the new ECPGcursor_dml() function?

It makes sense to add one.

* ECPGtrans() - arguments are explained, but the return (bool) value
should be as well.

All exported ECPG functions returns bool. IIRC the code generated by
"EXEC SQL WHENEVER <something-else-than-CONTINUE>" makes use
of the returned value.

* line breaks (pgindent might help):

static void
output_cursor_name(struct cursor *ptr)
{

instead of

static void output_cursor_name(struct cursor *ptr)
{

OK.

* confused messages in src/interfaces/ecpg/test/sql/cursorsubxact.pgc,
starting at 100:

exec sql open :curname;
if (sqlca.sqlcode < 0)
printf("open %s (case sensitive) failed with SQLSTATE
%5s\n", curname, sqlca.sqlstate);
else
printf("close %s (case sensitive) succeeded\n", curname);

I suppose both should be "open".

Yes, oversight.

26.patch (the READAHEAD feature itself)
---------------------------------------

I tried to understand the code but couldn't find any obvious error. The
coding style looks clean. Maybe just the arguments and return value of
the ecpglib functinons (ECPGopen, ECPGopen, ECPGfetch, ...) deserve a
bit more attention.

What do you mean exactly?

As for tests, I find them comprehensive and almost everything they do is
clear to me. Just the following was worth questions:

* sql-cursor-ra-fetch.stderr

[NO_PID]: ecpg_execute on line 169: query: move forward all in
scroll_cur; with 0 parameter(s) on connection regress1
...
[NO_PID]: ecpg_execute on line 169: query: move relative -3 in
scroll_cur; with 0 parameter(s) on

As the first iteration is special anyway, wouldn't "move absolute -3" be
more efficient than the existing 2 commands?

The caching code tries to do the correct thing whichever direction
the cursor is scanned. AFAIR this one explicitly tests invalidating
the readahead window if you fall off it by using MOVE FORWARD ALL.

The following test (also FETCH RELATIVE) uses "move absolute":

[NO_PID]: ecpg_execute on line 186: query: move absolute -20 in
scroll_cur; with 0 parameter(s) on connection regress1

Other than this, I had an idea to improve the behaviour if READAHEAD is
smaller than the actual step, but then realized that 29.patch actually
does fix that :-)

B-)

* cursor-ra-move.pgc

What's the relevant difference between unspec_cur1 and unspec_cur2
cursors? There's no difference in scrollability or ordering. And the
tests seem to be identical.

Oh. Erm. That is a leftover from a previous incarnation when
I thought it's a good idea to let the server return the actual
scrollability flag because the server can actually know.
The simple query when running in psql is implicitly scrollable
but the query with the join is not. That idea was shot down
with prejudice but I forgot to adjust the test and remove
one of these cursors. Now all queries where scrollability is
not specified are explicitly modified (behind the application's
back) to have NO SCROLL. ( Please, don't revise your previous
opinion, Tom Lane included... ;-) )

* cursor-ra-swdir.pgc

No questions

* cursorsubxact.pgc

This appears to be the test we discussed earlier:
/messages/by-id/52A1CAB6.9020600@cybertec.at

The only difference I see is minor change of log message of DECLARE
command. Therefore I didn't have to recheck the logic of the test.

28.patch
--------

* ecpg_cursor_do_move_absolute() and ecpg_cursor_do_move_all() should
better be declared in 26.patch. Just a pedantic comment - all the parts
will probably be applied all at once.

When I re-roll the patchset, I will move this chunk to 26.

Other
-----

Besides the individual parts I propose some typo fixes and
improvements in wording:

* doc/src/sgml/ecpg.sgml

462c462
< ECPG does cursor accounting in its runtime library and this makes
possible
---

ECPG does cursor accounting in its runtime library and this makes

it possible
504c504
< recommended to recompile using option <option>-r
readahead=number</option>
---

recommended to recompile it using option <option>-r

readahead=number</option>

* src/interfaces/ecpg/ecpglib/extern.h

97c97
< * The cursor was created in this level of * (sub-)transaction.
---

* The cursor was created at this level of (sub-)transaction.

* src/interfaces/ecpg/ecpglib/README.cursor+subxact

4c4
< Contents of tuples returned by a cursor always reflect the data present at
---

Contents of tuples returned by a cursor always reflects the data

present at

Contents of tuples ... reflect ...

Plural. The verb is correct as is. :-)

29c29
< needs two operations. If the next command issued by the application spills
---

need two operations. If the next command issued by the application spills

I'll re-read and see what context "need" is in. Hey, a context diff
would have made it more obvious. ;-)

32c32
< kinds of commands as is after 3 cache misses. FETCH FORWARD/BACKWARD
allows
---

kinds of commands "as is" after 3 cache misses. FETCH FORWARD/BACKWARD

allows
81c81
< I can also be negative (but also 1-based) if the application started with
---

It can also be negative (but also 1-based) if the application started with

Sure. This sentence is not about "I" but it's true either way. :-D

132c132
< is that (sub-)transactions are also needed to be tracked. These two are
---

is that (sub-)transactions also need to be tracked. These two are

148c148
< and he issued command may be executed without an error, causing unwanted
---

and the issued command may be executed without an error, causing unwanted

I will fix these.

In addition, please consider the following stuff in
src/interfaces/ecpg/ecpglib/README.cursor+subxact - it can't be
expressed as diff because I'm not 100% sure about the intended meaning

"either implicitly propagated" - I'd expect "either ... or ...". Or
remove no "either" at all?

"Committing a transaction or releasing a subtransaction make cursors ..."
->
"Committing a transaction or releasing a subtransaction propagates the
cursor(s) ... "
?

"The idea behind cursor readahead is to move one tuple less than asked
by the application ..."

My understanding of sql-cursor-ra-fetch.stderr is that the application
does not have to do MOVE explicitly. Maybe

"... to move to the adjacent lower / upper tuple of the supposed
beginning of the result set and then have ecpglib perform FETCH FORWARD
/ BACKWARD N respectively ..."

Consider it just a tentative proposal, I can easily be wrong :-)

I will read your comments again with fresh eyes.

That's it for my review.

Thank you very much.

// Tony

On 04/16/2014 10:54 AM, Boszormenyi Zoltan wrote:

2014-01-18 18:08 keltez�ssel, Boszormenyi Zoltan �rta:

Hi,

Alvaro Herrera wrote:

Boszormenyi Zoltan escribi�:

Rebased patches after the regression test and other details were fixed
in the infrastructure part.

This thread started in 2010, and various pieces have been applied
already and some others have changed in nature. Would you please post a
new patchset, containing rebased patches that still need application, in
a new email thread to be linked in the commitfest entry?

I hope Thunderbird did the right thing and didn't include the reference
message ID when I told it to "edit as new". So supposedly this is a new
thread but with all the cc: addresses kept.

I have rebased all remaining patches and kept the numbering.
All the patches from 18 to 25 that were previously in the
"ECPG infrastructure" CF link are included here.

There is no functional change.

Because of the recent bugfixes in the ECPG area, the patchset
didn't apply cleanly anymore. Rebased with no functional change.

Best regards,
Zolt�n B�sz�rm�nyi

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

#116Antonin Houska
antonin.houska@gmail.com
In reply to: Boszormenyi Zoltan (#115)
Re: Review: ECPG FETCH readahead

[Now I'm only replying where my explanation seems useful. If you expect
anything else, please remind me.]

On 04/23/2014 06:41 PM, Boszormenyi Zoltan wrote:

All exported ECPG functions returns bool. IIRC the code generated by
"EXEC SQL WHENEVER <something-else-than-CONTINUE>" makes use
of the returned value.

ok

26.patch (the READAHEAD feature itself)
---------------------------------------
Maybe just the arguments and return value of
the ecpglib functinons (ECPGopen, ECPGopen, ECPGfetch, ...) deserve a
bit more attention.

What do you mean exactly?

Basically the missing description of return type was most blatant, but
you explained it above. Now that I see some of the existing library
functions, the descriptions of parameters are neither too eloquent. So
ignore this remark.

* sql-cursor-ra-fetch.stderr

[NO_PID]: ecpg_execute on line 169: query: move forward all in
scroll_cur; with 0 parameter(s) on connection regress1
...
[NO_PID]: ecpg_execute on line 169: query: move relative -3 in
scroll_cur; with 0 parameter(s) on

As the first iteration is special anyway, wouldn't "move absolute -3" be
more efficient than the existing 2 commands?

The caching code tries to do the correct thing whichever direction
the cursor is scanned. AFAIR this one explicitly tests invalidating
the readahead window if you fall off it by using MOVE FORWARD ALL.

I have no doubt about correctness of the logic, just suspect that a
single MOVE command could do the action. Perhaps consider it my paranoia
and let committer judge if it's worth a change (especially if the
related amount of coding would seem inadequate).

Other
-----

Besides the individual parts I propose some typo fixes and
improvements in wording:

* doc/src/sgml/ecpg.sgml

In general, I'm not English native speaker, can be wrong in some cases.
Just pointed out what I thought is worth checking.

// Tony

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

#117Antonin Houska
antonin.houska@gmail.com
In reply to: Alvaro Herrera (#114)
Re: Review: ECPG FETCH readahead

On 04/23/2014 05:24 PM, Alvaro Herrera wrote:

Antonin Houska wrote:

I haven't been too familiar with the ECPG internals so far but tried to
do my best.

I'm afraid we're stuck on this patch until Michael has time to review
it, or some other committer wants to acquire maintainership rights in
the ECPG code.

Committer availability might well be the issue, but missing review
probably too.

Whether this review is enough to move the patch to "ready for committer"
- I tend to let the next CFM decide. (I don't find it productive to
ignite another round of discussion about kinds of reviews - already saw
some.)

// Tony

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

#118Noah Misch
noah@leadboat.com
In reply to: Antonin Houska (#117)
Re: Review: ECPG FETCH readahead

On Thu, Apr 24, 2014 at 12:15:41AM +0200, Antonin Houska wrote:

Whether this review is enough to move the patch to "ready for committer"
- I tend to let the next CFM decide. (I don't find it productive to
ignite another round of discussion about kinds of reviews - already saw
some.)

In today's CF process, we trust reviewers to make that decision. When all
unambiguous defects known to you have been resolved, please mark the patch
Ready for Committer. Your review covered more ground than the average review,
so don't worry about it being too cursory to qualify.

Thanks,
nm

--
Noah Misch
EnterpriseDB http://www.enterprisedb.com

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

#119Michael Meskes
meskes@postgresql.org
In reply to: Antonin Houska (#117)
Re: Review: ECPG FETCH readahead

Thanks an awful lot Antonin.

Committer availability might well be the issue, but missing review
probably too.

Yes, you're right. If my taks is mostly one last glance and a commit I will make time for that.

Whether this review is enough to move the patch to "ready for committer"
- I tend to let the next CFM decide. (I don't find it productive to
ignite another round of discussion about kinds of reviews - already saw
some.)

I saw some remarks in your review that Zoltan wants to address. Once I got the
updated version I'll have a look at it.

Zoltan, could you send a new version by end of day tomorrow? I'll be sitting on
a plane for a longer time again on Saturday. :)

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at gmail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL

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

In reply to: Michael Meskes (#119)
Re: Review: ECPG FETCH readahead

2014-04-24 14:50 keltezéssel, Michael Meskes írta:

Thanks an awful lot Antonin.

Committer availability might well be the issue, but missing review
probably too.

Yes, you're right. If my taks is mostly one last glance and a commit I will make time for that.

Whether this review is enough to move the patch to "ready for committer"
- I tend to let the next CFM decide. (I don't find it productive to
ignite another round of discussion about kinds of reviews - already saw
some.)

I saw some remarks in your review that Zoltan wants to address. Once I got the
updated version I'll have a look at it.

Zoltan, could you send a new version by end of day tomorrow? I'll be sitting on
a plane for a longer time again on Saturday. :)

I will try to.

Thanks in advance,
Zoltán

Michael

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

#121Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Boszormenyi Zoltan (#120)
Re: Review: ECPG FETCH readahead

Just a quickie: I remember noticing earlier that a few comments on
functions would probably get mangled badly by pgindent. You probably
want to wrap them in /*----- */ to avoid this. In a very quick glance
now I saw them in ecpg_get_data, ecpg_cursor_next_pos, ECPGfetch.
Perhaps you want to run pgindent on the files you modify, review the
changes, and apply tweaks to avoid unwanted ones. (I don't mean to
submit pgindented files, because they will be fixed later on anyway; I
only suggest tweaking things that would be damaged.)

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

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

In reply to: Boszormenyi Zoltan (#120)
Re: Review: ECPG FETCH readahead

2014-04-24 15:19 keltezéssel, Boszormenyi Zoltan írta:

2014-04-24 14:50 keltezéssel, Michael Meskes írta:

Thanks an awful lot Antonin.

Committer availability might well be the issue, but missing review
probably too.

Yes, you're right. If my taks is mostly one last glance and a commit I will make time
for that.

Whether this review is enough to move the patch to "ready for committer"
- I tend to let the next CFM decide. (I don't find it productive to
ignite another round of discussion about kinds of reviews - already saw
some.)

I saw some remarks in your review that Zoltan wants to address. Once I got the
updated version I'll have a look at it.

Zoltan, could you send a new version by end of day tomorrow? I'll be sitting on
a plane for a longer time again on Saturday. :)

I will try to.

Unfortunately, I won't make the deadline because of life
(I had to attend a funeral today) and because Antonin has
opened a can of worms with this comment:

* How about a regression test for the new ECPGcursor_dml() function?

There are some aspects that may need a new discussion.

The SQL standard wants an "updatable cursor" for positioned DML
(i.e. UPDATE/DELETE with the WHERE CURRENT OF clause)
This means passing FOR UPDATE in the query.

FOR UPDATE + SCROLL cursor is an impossible combination,
ERROR is thrown when DECLARE is executed. This combination can
(and should?) be detected in the ECPG preprocessor and it would
prevent runtime errors. It's not implemented at the moment.

Fortunately, a previous discussion resulted in explicitly passing
NO SCROLL for cursors where SCROLL is not specified, it's in 25.patch

I intend to extend it a little for SQL standard compliance with
embedded SQL. FOR UPDATE should also implicitly mean NO SCROLL.
Both the FOR UPDATE + explicit SCROLL and the explicit SCROLL +
usage of positioned DML can be detected in the preprocessor and
they should throw an error. Then the regression test would really make
sense.

But these checks in ECPG would still leave a big hole, and it's the other
DECLARE variant with the query passed in a prepared statement with
"EXEC SQL PREPARE prep_stmt FROM :query_string;"

Plugging this hole would require adding a simplified syntax checker to
libecpg that only checks the SelectStmt or re-adding the backend code
to tell the application the cursor's scrollable (and perhaps the updatable)
property.

I must have forgotten but surely this was the reason for changing the
DECLARE command tag in the first place which was shot down already.
So, only the other choice remains, the syntax checker in ecpglib.

I think implementing it would make the caching code miss 9.4, since
it adds a whole new set of code but the Perl magic for the ECPG syntax
checker may be mostly reusable here.

Best regards,
Zoltán Böszörményi

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