copy-processed-rows-simple2.patch
application/octet-stream
Filename: copy-processed-rows-simple2.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| doc/src/sgml/spi.sgml | 4 | 0 |
| src/backend/executor/spi.c | 12 | 0 |
| src/test/regress/input/copy.source | 14 | 0 |
| src/test/regress/output/copy.source | 15 | 0 |
*** a/doc/src/sgml/spi.sgml
--- b/doc/src/sgml/spi.sgml
***************
*** 397,403 **** typedef struct
<structfield>tupdesc</> is a row descriptor which you can pass to
SPI functions dealing with rows. <structfield>tuptabcxt</>,
<structfield>alloced</>, and <structfield>free</> are internal
! fields not intended for use by SPI callers.
</para>
<para>
--- 397,406 ----
<structfield>tupdesc</> is a row descriptor which you can pass to
SPI functions dealing with rows. <structfield>tuptabcxt</>,
<structfield>alloced</>, and <structfield>free</> are internal
! fields not intended for use by SPI callers. <varname>SPI_processed</varname>
! can be non zero, althoug <varname>SPI_tuptable</varname> is NULL. It is
! possible when <command>CREATE TABLE AS SELECT</command> or <command>COPY</command>
! statements was executed.
</para>
<para>
*** a/src/backend/executor/spi.c
--- b/src/backend/executor/spi.c
***************
*** 1922,1934 **** _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
_SPI_current->processed = _SPI_current->tuptable->alloced -
_SPI_current->tuptable->free;
! /*
! * CREATE TABLE AS is a messy special case for historical
! * reasons. We must set _SPI_current->processed even though
! * the tuples weren't returned to the caller, and we must
! * return a special result code if the statement was spelled
! * SELECT INTO.
! */
if (IsA(stmt, CreateTableAsStmt))
{
Assert(strncmp(completionTag, "SELECT ", 7) == 0);
--- 1922,1928 ----
_SPI_current->processed = _SPI_current->tuptable->alloced -
_SPI_current->tuptable->free;
! /* Update "processed" when stmt doesn't returns tuples */
if (IsA(stmt, CreateTableAsStmt))
{
Assert(strncmp(completionTag, "SELECT ", 7) == 0);
***************
*** 1939,1944 **** _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
--- 1933,1949 ----
else
res = SPI_OK_UTILITY;
}
+ else if (IsA(stmt, CopyStmt))
+ {
+ /*
+ * usually utility statements doesn't return a number
+ * of processed rows, but COPY does it.
+ */
+ Assert(strncmp(completionTag, "COPY ", 5) == 0);
+ _SPI_current->processed = strtoul(completionTag + 5,
+ NULL, 10);
+ res = SPI_OK_UTILITY;
+ }
else
res = SPI_OK_UTILITY;
}
*** a/src/test/regress/input/copy.source
--- b/src/test/regress/input/copy.source
***************
*** 106,108 **** this is just a line full of junk that would error out if parsed
--- 106,122 ----
\.
copy copytest3 to stdout csv header;
+
+ -- test of taking number of processed rows via SPI interface
+ do $$
+ declare r int;
+ begin
+ copy copytest2 to '@abs_builddir@/results/copytest.csv' csv;
+ get diagnostics r = row_count;
+ raise notice 'exported % rows', r;
+ truncate copytest2;
+ copy copytest2 from '@abs_builddir@/results/copytest.csv' csv;
+ get diagnostics r = row_count;
+ raise notice 'imported % rows', r;
+ end;
+ $$ language plpgsql;
*** a/src/test/regress/output/copy.source
--- b/src/test/regress/output/copy.source
***************
*** 71,73 **** copy copytest3 to stdout csv header;
--- 71,88 ----
c1,"col with , comma","col with "" quote"
1,a,1
2,b,2
+ -- test of taking number of processed rows via SPI interface
+ do $$
+ declare r int;
+ begin
+ copy copytest2 to '@abs_builddir@/results/copytest.csv' csv;
+ get diagnostics r = row_count;
+ raise notice 'exported % rows', r;
+ truncate copytest2;
+ copy copytest2 from '@abs_builddir@/results/copytest.csv' csv;
+ get diagnostics r = row_count;
+ raise notice 'imported % rows', r;
+ end;
+ $$ language plpgsql;
+ NOTICE: exported 4 rows
+ NOTICE: imported 4 rows