Commit 7ae18159 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Return the number of rows processed when COPY is executed through SPI.

You can now get the number of rows processed by a COPY statement in a
PL/pgSQL function with "GET DIAGNOSTICS x = ROW_COUNT".

Pavel Stehule, reviewed by Amit Kapila, with some editing by me.
parent bc1229c8
...@@ -377,7 +377,10 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5); ...@@ -377,7 +377,10 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
global pointer <literal>SPITupleTable *SPI_tuptable</literal> to global pointer <literal>SPITupleTable *SPI_tuptable</literal> to
access the result rows. Some utility commands (such as access the result rows. Some utility commands (such as
<command>EXPLAIN</>) also return row sets, and <literal>SPI_tuptable</> <command>EXPLAIN</>) also return row sets, and <literal>SPI_tuptable</>
will contain the result in these cases too. will contain the result in these cases too. Some utility commands
(<command>COPY</>, <command>CREATE TABLE AS</>) don't return a row set, so
<literal>SPI_tuptable</> is NULL, but they still return the number of
rows processed in <varname>SPI_processed</>.
</para> </para>
<para> <para>
......
...@@ -1922,25 +1922,31 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, ...@@ -1922,25 +1922,31 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
_SPI_current->processed = _SPI_current->tuptable->alloced - _SPI_current->processed = _SPI_current->tuptable->alloced -
_SPI_current->tuptable->free; _SPI_current->tuptable->free;
res = SPI_OK_UTILITY;
/* /*
* CREATE TABLE AS is a messy special case for historical * Some utility statements return a row count, even though the
* reasons. We must set _SPI_current->processed even though * tuples are not returned to the caller.
* 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)) if (IsA(stmt, CreateTableAsStmt))
{ {
Assert(strncmp(completionTag, "SELECT ", 7) == 0); Assert(strncmp(completionTag, "SELECT ", 7) == 0);
_SPI_current->processed = strtoul(completionTag + 7, _SPI_current->processed = strtoul(completionTag + 7,
NULL, 10); NULL, 10);
/*
* For historical reasons, if CREATE TABLE AS was spelled
* as SELECT INTO, return a special return code.
*/
if (((CreateTableAsStmt *) stmt)->is_select_into) if (((CreateTableAsStmt *) stmt)->is_select_into)
res = SPI_OK_SELINTO; res = SPI_OK_SELINTO;
else
res = SPI_OK_UTILITY;
} }
else else if (IsA(stmt, CopyStmt))
res = SPI_OK_UTILITY; {
Assert(strncmp(completionTag, "COPY ", 5) == 0);
_SPI_current->processed = strtoul(completionTag + 5,
NULL, 10);
}
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment