Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-27 Thread Pavel Stehule
Hello

I reduced this patch as just plpgsql (SPI) problem solution.

Correct generic solution needs a discussion about enhancing our libpq
interface - we can take a number of returned rows, but we should to
get number of processed rows too. A users should to parse this number
from completationTag, but this problem is not too hot and usually is
not blocker, because anybody can process completationTag usually.

So this issue is primary for PL/pgSQL, where this information is not
possible. There is precedent - CREATE AS SELECT (thanks for sample
:)), and COPY should to have same impact on ROW_COUNT like this
statement (last patch implements it).

Regards

Pavel



2012/9/21 Amit Kapila amit.kap...@huawei.com:
 On Friday, September 21, 2012 1:23 AM Pavel Stehule wrote:

 Basic stuff:
 
 - Patch applies OK. but offset difference in line numbers.
 - Compiles with errors in contrib [pg_stat_statements, sepgsql] modules
 - Regression failed; one test-case in COPY due to incomplete test-case
 attached patch. – same as reported by Heikki

fixed patch is in attachment

 After modifications:
 ---
 - Patch applies OK
 - Compiles cleanly without any errors/warnings
 - Regression tests pass.


 What it does:
 --
 Modification to get the number of processed rows evaluated via SPI. The
 changes are to add extra parameter in ProcessUtility to get the number of
 rows processed by COPY command.

 Code Review Comments:
 -
 1. New parameter is added to ProcessUtility_hook_type function
but the functions which get assigned to these functions like
sepgsql_utility_command, pgss_ProcessUtility, prototype  definition is
 not modified.

 Functionality is not fixed correctly for hook functions, In function 
 pgss_ProcessUtility
 for bellow snippet of code processed parameter is passed NULL, as well as not 
 initialized.
 because of this when pg_stat_statements extention is utilized COPY command 
 is giving garbage values.
 if (prev_ProcessUtility)
 prev_ProcessUtility(parsetree, queryString, params,
 dest, completionTag, 
 context, NULL);
 else
 standard_ProcessUtility(parsetree, queryString, params,
 dest, completionTag, 
 context, NULL);

 Testcase is attached.
 In this testcase table has only 1000 records but it show garbage value.
 postgres=# show shared_preload_libraries ;
  shared_preload_libraries
 --
  pg_stat_statements
 (1 row)
 postgres=# CREATE TABLE tbl (a int);
 CREATE TABLE
 postgres=# INSERT INTO tbl VALUES(generate_series(1,1000));
 INSERT 0 1000
 postgres=# do $$
 declare r int;
 begin
   copy tbl to '/home/kiran/copytest.csv' csv;
   get diagnostics r = row_count;
   raise notice 'exported % rows', r;
   truncate tbl;
   copy tbl from '/home/kiran/copytest.csv' csv;
   get diagnostics r = row_count;
   raise notice 'imported % rows', r;
 end;
 $$ language plpgsql;
 postgres$#
 NOTICE:  exported 13281616 rows
 NOTICE:  imported 13281616 rows
 DO


 2. Why to add the new parameter if completionTag hold the number of
 processed tuple information; can be extracted

from it as follows:
 _SPI_current-processed = strtoul(completionTag + 7,
 NULL, 10);

this is basic question. I prefer a natural type for counter - uint64
instead text. And there are no simply way to get offset (7 in this
case)

 I agree with your point, but currently in few other places we are parsing 
 the completion tag for getting number of tuples processed. So may be in 
 future we can change those places as well. For example

yes, this step can be done in future - together with libpq enhancing.
Is not adequate change API (and break lot of extensions) for this
isolated problem. So I propose fix plpgsql issue, and add to ToDo -
enhance libpq to return a number of processed rows as number - but
this change breaking compatibility.

Pavel


 pgss_ProcessUtility
 {
 ..

 /* parse command tag to retrieve the number of affected rows. */
 if (completionTag 
 sscanf(completionTag, COPY  UINT64_FORMAT, rows) != 1)
 rows = 0;

 }

 _SPI_execute_plan
 {
 ..
 ..
 if (IsA(stmt, CreateTableAsStmt))
 {
 Assert(strncmp(completionTag, SELECT , 7) == 0);
 _SPI_current-processed = strtoul(completionTag + 7,
   
 NULL, 10);

 ..
 }


 With Regards,
 Amit Kapila.



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


copy-processed-rows-simple.patch
Description: 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-27 Thread Amit Kapila
 On Friday, September 28, 2012 2:28 AM Pavel Stehule wrote:
 Hello
 
 I reduced this patch as just plpgsql (SPI) problem solution.
 
 Correct generic solution needs a discussion about enhancing our libpq
 interface - we can take a number of returned rows, but we should to get
 number of processed rows too. A users should to parse this number from
 completationTag, but this problem is not too hot and usually is not
 blocker, because anybody can process completationTag usually.
 
 So this issue is primary for PL/pgSQL, where this information is not
 possible. There is precedent - CREATE AS SELECT (thanks for sample :)),
 and COPY should to have same impact on ROW_COUNT like this statement
 (last patch implements it).

IMO now this patch is okay. I have marked it as Ready For Committer.

With Regards,
Amit Kapila.


 
 
 2012/9/21 Amit Kapila amit.kap...@huawei.com:
  On Friday, September 21, 2012 1:23 AM Pavel Stehule wrote:
 
  Basic stuff:
  
  - Patch applies OK. but offset difference in line numbers.
  - Compiles with errors in contrib [pg_stat_statements, sepgsql]
  modules
  - Regression failed; one test-case in COPY due to incomplete
  test-case attached patch. – same as reported by Heikki
 
 fixed patch is in attachment
 
  After modifications:
  ---
  - Patch applies OK
  - Compiles cleanly without any errors/warnings
  - Regression tests pass.
 
 
  What it does:
  --
  Modification to get the number of processed rows evaluated via SPI.
  The changes are to add extra parameter in ProcessUtility to get the
  number of rows processed by COPY command.
 
  Code Review Comments:
  -
  1. New parameter is added to ProcessUtility_hook_type function
 but the functions which get assigned to these functions like
 sepgsql_utility_command, pgss_ProcessUtility, prototype 
  definition is not modified.
 
  Functionality is not fixed correctly for hook functions, In function
  pgss_ProcessUtility for bellow snippet of code processed parameter is
 passed NULL, as well as not initialized.
  because of this when pg_stat_statements extention is utilized COPY
 command is giving garbage values.
  if (prev_ProcessUtility)
  prev_ProcessUtility(parsetree, queryString, params,
  dest,
 completionTag, context, NULL);
  else
  standard_ProcessUtility(parsetree, queryString,
 params,
  dest,
  completionTag, context, NULL);
 
  Testcase is attached.
  In this testcase table has only 1000 records but it show garbage
 value.
  postgres=# show shared_preload_libraries ;
   shared_preload_libraries
  --
   pg_stat_statements
  (1 row)
  postgres=# CREATE TABLE tbl (a int);
  CREATE TABLE
  postgres=# INSERT INTO tbl VALUES(generate_series(1,1000));
  INSERT 0 1000
  postgres=# do $$
  declare r int;
  begin
copy tbl to '/home/kiran/copytest.csv' csv;
get diagnostics r = row_count;
raise notice 'exported % rows', r;
truncate tbl;
copy tbl from '/home/kiran/copytest.csv' csv;
get diagnostics r = row_count;
raise notice 'imported % rows', r;
  end;
  $$ language plpgsql;
  postgres$#
  NOTICE:  exported 13281616 rows
  NOTICE:  imported 13281616 rows
  DO
 
 
  2. Why to add the new parameter if completionTag hold the number of
  processed tuple information; can be extracted
 
 from it as follows:
  _SPI_current-processed = strtoul(completionTag
  + 7, NULL, 10);
 
 this is basic question. I prefer a natural type for counter - uint64
 instead text. And there are no simply way to get offset (7 in this
 case)
 
  I agree with your point, but currently in few other places we are
  parsing the completion tag for getting number of tuples processed. So
  may be in future we can change those places as well. For example
 
 yes, this step can be done in future - together with libpq enhancing.
 Is not adequate change API (and break lot of extensions) for this
 isolated problem. So I propose fix plpgsql issue, and add to ToDo -
 enhance libpq to return a number of processed rows as number - but
 this change breaking compatibility.
 
 Pavel
 
 
  pgss_ProcessUtility
  {
  ..
 
  /* parse command tag to retrieve the number of affected rows. */ if
  (completionTag 
  sscanf(completionTag, COPY  UINT64_FORMAT, rows) != 1)
  rows = 0;
 
  }
 
  _SPI_execute_plan
  {
  ..
  ..
  if (IsA(stmt, CreateTableAsStmt))
  {
  Assert(strncmp(completionTag, SELECT , 7) == 0);
  _SPI_current-processed = strtoul(completionTag + 7,
 
  NULL, 10);
 
  ..
  }
 
 
  With Regards,
  Amit Kapila.
 
 
 
  --
 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-27 Thread Pavel Stehule
2012/9/28 Amit Kapila amit.kap...@huawei.com:
 On Friday, September 28, 2012 2:28 AM Pavel Stehule wrote:
 Hello

 I reduced this patch as just plpgsql (SPI) problem solution.

 Correct generic solution needs a discussion about enhancing our libpq
 interface - we can take a number of returned rows, but we should to get
 number of processed rows too. A users should to parse this number from
 completationTag, but this problem is not too hot and usually is not
 blocker, because anybody can process completationTag usually.

 So this issue is primary for PL/pgSQL, where this information is not
 possible. There is precedent - CREATE AS SELECT (thanks for sample :)),
 and COPY should to have same impact on ROW_COUNT like this statement
 (last patch implements it).

 IMO now this patch is okay. I have marked it as Ready For Committer.

Thank you very much for review

Regards

Pavel


 With Regards,
 Amit Kapila.




 2012/9/21 Amit Kapila amit.kap...@huawei.com:
  On Friday, September 21, 2012 1:23 AM Pavel Stehule wrote:
 
  Basic stuff:
  
  - Patch applies OK. but offset difference in line numbers.
  - Compiles with errors in contrib [pg_stat_statements, sepgsql]
  modules
  - Regression failed; one test-case in COPY due to incomplete
  test-case attached patch. – same as reported by Heikki
 
 fixed patch is in attachment
 
  After modifications:
  ---
  - Patch applies OK
  - Compiles cleanly without any errors/warnings
  - Regression tests pass.
 
 
  What it does:
  --
  Modification to get the number of processed rows evaluated via SPI.
  The changes are to add extra parameter in ProcessUtility to get the
  number of rows processed by COPY command.
 
  Code Review Comments:
  -
  1. New parameter is added to ProcessUtility_hook_type function
 but the functions which get assigned to these functions like
 sepgsql_utility_command, pgss_ProcessUtility, prototype 
  definition is not modified.
 
  Functionality is not fixed correctly for hook functions, In function
  pgss_ProcessUtility for bellow snippet of code processed parameter is
 passed NULL, as well as not initialized.
  because of this when pg_stat_statements extention is utilized COPY
 command is giving garbage values.
  if (prev_ProcessUtility)
  prev_ProcessUtility(parsetree, queryString, params,
  dest,
 completionTag, context, NULL);
  else
  standard_ProcessUtility(parsetree, queryString,
 params,
  dest,
  completionTag, context, NULL);
 
  Testcase is attached.
  In this testcase table has only 1000 records but it show garbage
 value.
  postgres=# show shared_preload_libraries ;
   shared_preload_libraries
  --
   pg_stat_statements
  (1 row)
  postgres=# CREATE TABLE tbl (a int);
  CREATE TABLE
  postgres=# INSERT INTO tbl VALUES(generate_series(1,1000));
  INSERT 0 1000
  postgres=# do $$
  declare r int;
  begin
copy tbl to '/home/kiran/copytest.csv' csv;
get diagnostics r = row_count;
raise notice 'exported % rows', r;
truncate tbl;
copy tbl from '/home/kiran/copytest.csv' csv;
get diagnostics r = row_count;
raise notice 'imported % rows', r;
  end;
  $$ language plpgsql;
  postgres$#
  NOTICE:  exported 13281616 rows
  NOTICE:  imported 13281616 rows
  DO
 
 
  2. Why to add the new parameter if completionTag hold the number of
  processed tuple information; can be extracted
 
 from it as follows:
  _SPI_current-processed = strtoul(completionTag
  + 7, NULL, 10);
 
 this is basic question. I prefer a natural type for counter - uint64
 instead text. And there are no simply way to get offset (7 in this
 case)
 
  I agree with your point, but currently in few other places we are
  parsing the completion tag for getting number of tuples processed. So
  may be in future we can change those places as well. For example

 yes, this step can be done in future - together with libpq enhancing.
 Is not adequate change API (and break lot of extensions) for this
 isolated problem. So I propose fix plpgsql issue, and add to ToDo -
 enhance libpq to return a number of processed rows as number - but
 this change breaking compatibility.

 Pavel

 
  pgss_ProcessUtility
  {
  ..
 
  /* parse command tag to retrieve the number of affected rows. */ if
  (completionTag 
  sscanf(completionTag, COPY  UINT64_FORMAT, rows) != 1)
  rows = 0;
 
  }
 
  _SPI_execute_plan
  {
  ..
  ..
  if (IsA(stmt, CreateTableAsStmt))
  {
  Assert(strncmp(completionTag, SELECT , 7) == 0);
  _SPI_current-processed = 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-21 Thread Amit Kapila
On Friday, September 21, 2012 1:23 AM Pavel Stehule wrote:

 Basic stuff: 
  
 - Patch applies OK. but offset difference in line numbers. 
 - Compiles with errors in contrib [pg_stat_statements, sepgsql] modules 
 - Regression failed; one test-case in COPY due to incomplete test-case 
 attached patch. – same as reported by Heikki 
 
fixed patch is in attachment 

After modifications: 
--- 
- Patch applies OK 
- Compiles cleanly without any errors/warnings 
- Regression tests pass. 

 
 What it does: 
 -- 
 Modification to get the number of processed rows evaluated via SPI. The 
 changes are to add extra parameter in ProcessUtility to get the number of 
 rows processed by COPY command. 
 
 Code Review Comments: 
 - 
 1. New parameter is added to ProcessUtility_hook_type function 
but the functions which get assigned to these functions like 
sepgsql_utility_command, pgss_ProcessUtility, prototype  definition is 
 not modified. 

Functionality is not fixed correctly for hook functions, In function 
pgss_ProcessUtility 
for bellow snippet of code processed parameter is passed NULL, as well as not 
initialized. 
because of this when pg_stat_statements extention is utilized COPY command is 
giving garbage values. 
if (prev_ProcessUtility) 
prev_ProcessUtility(parsetree, queryString, params, 
dest, completionTag, 
context, NULL); 
else 
standard_ProcessUtility(parsetree, queryString, params, 
dest, completionTag, 
context, NULL); 

Testcase is attached. 
In this testcase table has only 1000 records but it show garbage value. 
postgres=# show shared_preload_libraries ;   
 shared_preload_libraries 
--   
 pg_stat_statements 
(1 row) 
postgres=# CREATE TABLE tbl (a int); 
CREATE TABLE 
postgres=# INSERT INTO tbl VALUES(generate_series(1,1000)); 
INSERT 0 1000 
postgres=# do $$ 
declare r int; 
begin 
  copy tbl to '/home/kiran/copytest.csv' csv; 
  get diagnostics r = row_count; 
  raise notice 'exported % rows', r; 
  truncate tbl; 
  copy tbl from '/home/kiran/copytest.csv' csv; 
  get diagnostics r = row_count; 
  raise notice 'imported % rows', r; 
end; 
$$ language plpgsql; 
postgres$# 
NOTICE:  exported 13281616 rows 
NOTICE:  imported 13281616 rows 
DO 

   
 2. Why to add the new parameter if completionTag hold the number of 
 processed tuple information; can be extracted 
   
from it as follows: 
 _SPI_current-processed = strtoul(completionTag + 7, 
 NULL, 10); 
   
this is basic question. I prefer a natural type for counter - uint64 
instead text. And there are no simply way to get offset (7 in this 
case)   

I agree with your point, but currently in few other places we are parsing 
the completion tag for getting number of tuples processed. So may be in future 
we can change those places as well. For example

pgss_ProcessUtility 
{
..

/* parse command tag to retrieve the number of affected rows. */ 
if (completionTag  
sscanf(completionTag, COPY  UINT64_FORMAT, rows) != 1)   
rows = 0;

}

_SPI_execute_plan
{
..
..
if (IsA(stmt, CreateTableAsStmt)) 
{ 
Assert(strncmp(completionTag, SELECT , 7) == 0); 
_SPI_current-processed = strtoul(completionTag + 7, 
  NULL, 
10);

..
}


With Regards,
Amit Kapila.



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


Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-20 Thread Amit Kapila
On 16.08.2012 14:43, Pavel Stehule wrote:

 Hello

 

 here is updated patch

 

[Review of Patch]

 

Basic stuff: 
 
- Patch applies OK. but offset difference in line numbers. 
- Compiles with errors in contrib [pg_stat_statements, sepgsql] modules 
- Regression failed; one test-case in COPY due to incomplete test-case
attached patch. – same as reported by Heikki


Details of compilation errors and regression failure: 
-- 
PATH : postgres/src/contrib/pg_stat_statements 
gcc -g -ggdb3 -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute
-Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I.
-I../../src/include -D_GNU_SOURCE   -c -o pg_stat_statements.o
pg_stat_statements.c 
pg_stat_statements.c: In function â_PG_initâ: 
pg_stat_statements.c:363: warning: assignment from incompatible pointer type

pg_stat_statements.c: In function âpgss_ProcessUtilityâ: 
pg_stat_statements.c:823: error: too few arguments to function
âprev_ProcessUtilityâ 
pg_stat_statements.c:826: error: too few arguments to function
âstandard_ProcessUtilityâ 
pg_stat_statements.c:884: error: too few arguments to function
âprev_ProcessUtilityâ 
pg_stat_statements.c:887: error: too few arguments to function
âstandard_ProcessUtilityâ 
make: *** [pg_stat_statements.o] Error 1 

PATH : postgres/src/contrib/sepgsql 
gcc -g -ggdb3 -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute
-Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I.
-I../../src/include -D_GNU_SOURCE   -c -o hooks.o hooks.c 
In file included from hooks.c:26: 
sepgsql.h:17:29: error: selinux/selinux.h: No such file or directory 
sepgsql.h:18:25: error: selinux/avc.h: No such file or directory 
In file included from hooks.c:26: 
sepgsql.h:239: warning: âstruct av_decisionâ declared inside parameter list 
sepgsql.h:239: warning: its scope is only this definition or declaration,
which is probably not what you want 
hooks.c: In function âsepgsql_utility_commandâ: 
hooks.c:331: error: too few arguments to function ânext_ProcessUtility_hookâ

hooks.c:334: error: too few arguments to function âstandard_ProcessUtilityâ 
hooks.c: In function â_PG_initâ: 
hooks.c:365: warning: implicit declaration of function âis_selinux_enabledâ 
hooks.c:426: warning: assignment from incompatible pointer type 
make: *** [hooks.o] Error 1 

REGRESSION TEST: 
-- 
make installcheck 
test copy ... FAILED 
 
 1 of 132 tests failed. 
 
~/postgres/src/test/regress cat regression.diffs 
*** /home/postgres/code/src/test/regress/expected/copy.out 2012-09-18
19:57:02.0 +0530 
--- /home/postgres/code/src/test/regress/results/copy.out  2012-09-18
19:57:18.0 +0530 
*** 
*** 71,73  
--- 71,80  
  c1,col with , comma,col with  quote 
  1,a,1 
  2,b,2 
+ -- copy should to return processed rows 
+ do $$ 
+ 
+ ERROR:  unterminated dollar-quoted string at or near $$ 
+
+ LINE 1: do $$ 
+^ 


What it does: 
-- 
Modification to get the number of processed rows evaluated via SPI. The
changes are to add extra parameter in ProcessUtility to get the number of
rows processed by COPY command. 



Code Review Comments: 
- 
1. New parameter is added to ProcessUtility_hook_type function 
   but the functions which get assigned to these functions like 
   sepgsql_utility_command, pgss_ProcessUtility, prototype  definition is
not modified. 

2. Why to add the new parameter if completionTag hold the number of
processed tuple information; can be extracted 

   from it as follows: 
_SPI_current-processed = strtoul(completionTag + 7,
NULL, 10); 

3. Why new variable added in portal [portal-processed] this is not used in
code ?


Testing: 
 
The following test is carried out on the patch. 
1. Normal SQL command COPY FROM / TO is tested. 
2. SQL command COPY FROM / TO is tested from plpgsql. 

Test cases are attached in Testcases_Copy_Processed.txt 



 

With Regards,

Amit Kapila.



--1) Normal SQL command COPY FROM and TO functionalities.
CREATE TABLE tbl (a int);
INSERT INTO tbl VALUES(generate_series(1,1000));
COPY tbl TO '/home/kiran/tbl.txt';
CREATE TABLE tbl1 (a int);
COPY tbl1 FROM '/home/kiran/tbl.txt';
DELETE FROM tbl1;
DROP TABLE tbl;
DROP TABLE tbl1;


--2) In side SPI [plpgsql function], SQL command COPY FROM and TO 
functionalities.
CREATE TABLE tbl (a int);
INSERT INTO tbl VALUES(generate_series(1,1000));
CREATE OR REPLACE FUNCTION public.copy_to_tbl() RETURNS integer
LANGUAGE plpgsql
AS $function$
DECLARE r int;
BEGIN
COPY tbl TO '/home/kiran/tbl.txt';
get diagnostics r = row_count;
RETURN r;
end;
$function$;

SELECT copy_to_tbl();
CREATE TABLE tbl1 (a int);
CREATE OR REPLACE FUNCTION public.copy_from_tbl() RETURNS 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement [Review of Patch]

2012-09-20 Thread Pavel Stehule
Hello



 Basic stuff:
 
 - Patch applies OK. but offset difference in line numbers.
 - Compiles with errors in contrib [pg_stat_statements, sepgsql] modules
 - Regression failed; one test-case in COPY due to incomplete test-case
 attached patch. – same as reported by Heikki

fixed patch is in attachment



 Details of compilation errors and regression failure:
 --
 PATH : postgres/src/contrib/pg_stat_statements
 gcc -g -ggdb3 -Wall -Wmissing-prototypes -Wpointer-arith
 -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute
 -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I.
 -I../../src/include -D_GNU_SOURCE   -c -o pg_stat_statements.o
 pg_stat_statements.c
 pg_stat_statements.c: In function â_PG_initâ:
 pg_stat_statements.c:363: warning: assignment from incompatible pointer type
 pg_stat_statements.c: In function âpgss_ProcessUtilityâ:
 pg_stat_statements.c:823: error: too few arguments to function
 âprev_ProcessUtilityâ
 pg_stat_statements.c:826: error: too few arguments to function
 âstandard_ProcessUtilityâ
 pg_stat_statements.c:884: error: too few arguments to function
 âprev_ProcessUtilityâ
 pg_stat_statements.c:887: error: too few arguments to function
 âstandard_ProcessUtilityâ
 make: *** [pg_stat_statements.o] Error 1

 PATH : postgres/src/contrib/sepgsql
 gcc -g -ggdb3 -Wall -Wmissing-prototypes -Wpointer-arith
 -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute
 -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I.
 -I../../src/include -D_GNU_SOURCE   -c -o hooks.o hooks.c
 In file included from hooks.c:26:
 sepgsql.h:17:29: error: selinux/selinux.h: No such file or directory
 sepgsql.h:18:25: error: selinux/avc.h: No such file or directory
 In file included from hooks.c:26:
 sepgsql.h:239: warning: âstruct av_decisionâ declared inside parameter list
 sepgsql.h:239: warning: its scope is only this definition or declaration,
 which is probably not what you want
 hooks.c: In function âsepgsql_utility_commandâ:
 hooks.c:331: error: too few arguments to function ânext_ProcessUtility_hookâ
 hooks.c:334: error: too few arguments to function âstandard_ProcessUtilityâ
 hooks.c: In function â_PG_initâ:
 hooks.c:365: warning: implicit declaration of function âis_selinux_enabledâ
 hooks.c:426: warning: assignment from incompatible pointer type
 make: *** [hooks.o] Error 1

 REGRESSION TEST:
 --
 make installcheck
 test copy ... FAILED
 
  1 of 132 tests failed.
 
 ~/postgres/src/test/regress cat regression.diffs
 *** /home/postgres/code/src/test/regress/expected/copy.out 2012-09-18
 19:57:02.0 +0530
 --- /home/postgres/code/src/test/regress/results/copy.out  2012-09-18
 19:57:18.0 +0530
 ***
 *** 71,73 
 --- 71,80 
   c1,col with , comma,col with  quote
   1,a,1
   2,b,2
 + -- copy should to return processed rows
 + do $$
 +
 + ERROR:  unterminated dollar-quoted string at or near $$
 +   
 + LINE 1: do $$
 +^


fixed


 What it does:
 --
 Modification to get the number of processed rows evaluated via SPI. The
 changes are to add extra parameter in ProcessUtility to get the number of
 rows processed by COPY command.



 Code Review Comments:
 -
 1. New parameter is added to ProcessUtility_hook_type function
but the functions which get assigned to these functions like
sepgsql_utility_command, pgss_ProcessUtility, prototype  definition is
 not modified.

 2. Why to add the new parameter if completionTag hold the number of
 processed tuple information; can be extracted

from it as follows:
 _SPI_current-processed = strtoul(completionTag + 7,
 NULL, 10);

this is basic question. I prefer a natural type for counter - uint64
instead text. And there are no simply way to get offset (7 in this
case)


 3. Why new variable added in portal [portal-processed] this is not used in
 code ?

This value can be used anywhere instead parsing completionTag to get
returned numbers



 Testing:
 
 The following test is carried out on the patch.
 1. Normal SQL command COPY FROM / TO is tested.
 2. SQL command COPY FROM / TO is tested from plpgsql.

 Test cases are attached in Testcases_Copy_Processed.txt


Regards

Pavel



 With Regards,

 Amit Kapila.



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



copy-processed-rows.diff
Description: Binary data

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


Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2012-09-19 Thread Heikki Linnakangas

On 16.08.2012 14:43, Pavel Stehule wrote:

Hello

here is updated patch


The patch seems to be truncated, it ends with:

*** 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,112 
  \.

  copy copytest3 to stdout csv header;
+
+ -- copy should to return processed rows
+ do $$
+

I believe the code changes are OK, but regression test changes are 
missing. Can you resend the full patch, please?


- Heikki


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


Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2012-08-16 Thread Pavel Stehule
Hello

here is updated patch

postgres=# copy omega to '/tmp/xxx';
COPY 60
postgres=# do $$ declare r int;
begin
   copy omega from '/tmp/xxx'; get diagnostics r = row_count; raise
notice ' %', r;
end;
$$ language plpgsql;
NOTICE:   60
DO

Regards

Pavel

2012/8/16 Bruce Momjian br...@momjian.us:

 What ever happened to this patch?  I don't see it on any of the
 commit-fests, though someone was asked for it to be added:

 http://archives.postgresql.org/pgsql-hackers/2011-10/msg00381.php

 ---

 On Tue, Oct  4, 2011 at 12:22:19PM +0200, Pavel Stehule wrote:
 Hello

 There is not possible to get a number of processed rows when COPY is
 evaluated via SPI. Client can use a tag, but SPI doesn't use a tag.

 I propose a small change a ProcessUtility to return a processed rows.

 Note: I found a small inconsistency between SPI and Utility interface.
 SPI still use a 4 byte unsign int for storing a number of processed
 rows. Utility use a 8bytes unsign int.

 Motivation:

  postgres=# \sf fx
 CREATE OR REPLACE FUNCTION public.fx(tablename text, filename text)
  RETURNS integer
  LANGUAGE plpgsql
 AS $function$
 declare r int;
 begin
   execute format('COPY %s FROM %s', quote_ident(tablename),
 quote_literal(filename));
   get diagnostics r = row_count;
   return r;
 end;
 $function$

 Regards

 Pavel Stehule

 diff --git a/src/backend/executor/functions.c 
 b/src/backend/executor/functions.c
 index 398bc40..a7c2b8f 100644
 --- a/src/backend/executor/functions.c
 +++ b/src/backend/executor/functions.c
 @@ -600,6 +600,7 @@ postquel_getnext(execution_state *es, 
 SQLFunctionCachePtr fcache)
  es-qd-params,
  false,   /* not top level */
  es-qd-dest,
 +NULL,
  NULL);
   result = true;  /* never stops early */
   }
 diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
 index 688279c..21cabcc 100644
 --- a/src/backend/executor/spi.c
 +++ b/src/backend/executor/spi.c
 @@ -1838,6 +1838,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   Node   *stmt = (Node *) lfirst(lc2);
   boolcanSetTag;
 + boolisCopyStmt = false;
   DestReceiver *dest;

   _SPI_current-processed = 0;
 @@ -1857,6 +1858,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   CopyStmt   *cstmt = (CopyStmt *) stmt;

 + isCopyStmt = true;
   if (cstmt-filename == NULL)
   {
   my_res = SPI_ERROR_COPY;
 @@ -1911,16 +1913,23 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   }
   else
   {
 + uint32 processed;
 +
   ProcessUtility(stmt,
  
 plansource-query_string,
  paramLI,
  false,   /* not 
 top level */
  dest,
 -NULL);
 +NULL,
 +processed);
   /* Update processed if stmt returned tuples 
 */
 +
   if (_SPI_current-tuptable)
   _SPI_current-processed = 
 _SPI_current-tuptable-alloced -
   _SPI_current-tuptable-free;
 + else if (canSetTag  isCopyStmt)
 + _SPI_current-processed = processed;
 +
   res = SPI_OK_UTILITY;
   }

 diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
 index 466727b..1a861ee 100644
 --- a/src/backend/tcop/pquery.c
 +++ b/src/backend/tcop/pquery.c
 @@ -1184,7 +1184,8 @@ PortalRunUtility(Portal portal, Node *utilityStmt, 
 bool isTopLevel,
  portal-portalParams,
  isTopLevel,
  dest,
 -completionTag);
 +completionTag,
 +NULL);

   /* Some utility statements may change context on us */
   MemoryContextSwitchTo(PortalGetHeapMemory(portal));
 diff 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2012-08-15 Thread Bruce Momjian

What ever happened to this patch?  I don't see it on any of the
commit-fests, though someone was asked for it to be added:

http://archives.postgresql.org/pgsql-hackers/2011-10/msg00381.php

---

On Tue, Oct  4, 2011 at 12:22:19PM +0200, Pavel Stehule wrote:
 Hello
 
 There is not possible to get a number of processed rows when COPY is
 evaluated via SPI. Client can use a tag, but SPI doesn't use a tag.
 
 I propose a small change a ProcessUtility to return a processed rows.
 
 Note: I found a small inconsistency between SPI and Utility interface.
 SPI still use a 4 byte unsign int for storing a number of processed
 rows. Utility use a 8bytes unsign int.
 
 Motivation:
 
  postgres=# \sf fx
 CREATE OR REPLACE FUNCTION public.fx(tablename text, filename text)
  RETURNS integer
  LANGUAGE plpgsql
 AS $function$
 declare r int;
 begin
   execute format('COPY %s FROM %s', quote_ident(tablename),
 quote_literal(filename));
   get diagnostics r = row_count;
   return r;
 end;
 $function$
 
 Regards
 
 Pavel Stehule

 diff --git a/src/backend/executor/functions.c 
 b/src/backend/executor/functions.c
 index 398bc40..a7c2b8f 100644
 --- a/src/backend/executor/functions.c
 +++ b/src/backend/executor/functions.c
 @@ -600,6 +600,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr 
 fcache)
  es-qd-params,
  false,   /* not top level */
  es-qd-dest,
 +NULL,
  NULL);
   result = true;  /* never stops early */
   }
 diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
 index 688279c..21cabcc 100644
 --- a/src/backend/executor/spi.c
 +++ b/src/backend/executor/spi.c
 @@ -1838,6 +1838,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   Node   *stmt = (Node *) lfirst(lc2);
   boolcanSetTag;
 + boolisCopyStmt = false;
   DestReceiver *dest;
  
   _SPI_current-processed = 0;
 @@ -1857,6 +1858,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   CopyStmt   *cstmt = (CopyStmt *) stmt;
  
 + isCopyStmt = true;
   if (cstmt-filename == NULL)
   {
   my_res = SPI_ERROR_COPY;
 @@ -1911,16 +1913,23 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   }
   else
   {
 + uint32 processed;
 +
   ProcessUtility(stmt,
  
 plansource-query_string,
  paramLI,
  false,   /* not 
 top level */
  dest,
 -NULL);
 +NULL,
 +processed);
   /* Update processed if stmt returned tuples */
 +
   if (_SPI_current-tuptable)
   _SPI_current-processed = 
 _SPI_current-tuptable-alloced -
   _SPI_current-tuptable-free;
 + else if (canSetTag  isCopyStmt)
 + _SPI_current-processed = processed;
 +
   res = SPI_OK_UTILITY;
   }
  
 diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
 index 466727b..1a861ee 100644
 --- a/src/backend/tcop/pquery.c
 +++ b/src/backend/tcop/pquery.c
 @@ -1184,7 +1184,8 @@ PortalRunUtility(Portal portal, Node *utilityStmt, bool 
 isTopLevel,
  portal-portalParams,
  isTopLevel,
  dest,
 -completionTag);
 +completionTag,
 +NULL);
  
   /* Some utility statements may change context on us */
   MemoryContextSwitchTo(PortalGetHeapMemory(portal));
 diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
 index 0749227..35db28c 100644
 --- a/src/backend/tcop/utility.c
 +++ b/src/backend/tcop/utility.c
 @@ -319,6 +319,9 @@ CheckRestrictedOperation(const char *cmdname)
   * completionTag is only set nonempty if we want to return a 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2012-08-15 Thread Pavel Stehule
Hello

I can reassign it again

Regards

Pavel

2012/8/16 Bruce Momjian br...@momjian.us:

 What ever happened to this patch?  I don't see it on any of the
 commit-fests, though someone was asked for it to be added:

 http://archives.postgresql.org/pgsql-hackers/2011-10/msg00381.php

 ---

 On Tue, Oct  4, 2011 at 12:22:19PM +0200, Pavel Stehule wrote:
 Hello

 There is not possible to get a number of processed rows when COPY is
 evaluated via SPI. Client can use a tag, but SPI doesn't use a tag.

 I propose a small change a ProcessUtility to return a processed rows.

 Note: I found a small inconsistency between SPI and Utility interface.
 SPI still use a 4 byte unsign int for storing a number of processed
 rows. Utility use a 8bytes unsign int.

 Motivation:

  postgres=# \sf fx
 CREATE OR REPLACE FUNCTION public.fx(tablename text, filename text)
  RETURNS integer
  LANGUAGE plpgsql
 AS $function$
 declare r int;
 begin
   execute format('COPY %s FROM %s', quote_ident(tablename),
 quote_literal(filename));
   get diagnostics r = row_count;
   return r;
 end;
 $function$

 Regards

 Pavel Stehule

 diff --git a/src/backend/executor/functions.c 
 b/src/backend/executor/functions.c
 index 398bc40..a7c2b8f 100644
 --- a/src/backend/executor/functions.c
 +++ b/src/backend/executor/functions.c
 @@ -600,6 +600,7 @@ postquel_getnext(execution_state *es, 
 SQLFunctionCachePtr fcache)
  es-qd-params,
  false,   /* not top level */
  es-qd-dest,
 +NULL,
  NULL);
   result = true;  /* never stops early */
   }
 diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
 index 688279c..21cabcc 100644
 --- a/src/backend/executor/spi.c
 +++ b/src/backend/executor/spi.c
 @@ -1838,6 +1838,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   Node   *stmt = (Node *) lfirst(lc2);
   boolcanSetTag;
 + boolisCopyStmt = false;
   DestReceiver *dest;

   _SPI_current-processed = 0;
 @@ -1857,6 +1858,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   {
   CopyStmt   *cstmt = (CopyStmt *) stmt;

 + isCopyStmt = true;
   if (cstmt-filename == NULL)
   {
   my_res = SPI_ERROR_COPY;
 @@ -1911,16 +1913,23 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo 
 paramLI,
   }
   else
   {
 + uint32 processed;
 +
   ProcessUtility(stmt,
  
 plansource-query_string,
  paramLI,
  false,   /* not 
 top level */
  dest,
 -NULL);
 +NULL,
 +processed);
   /* Update processed if stmt returned tuples 
 */
 +
   if (_SPI_current-tuptable)
   _SPI_current-processed = 
 _SPI_current-tuptable-alloced -
   _SPI_current-tuptable-free;
 + else if (canSetTag  isCopyStmt)
 + _SPI_current-processed = processed;
 +
   res = SPI_OK_UTILITY;
   }

 diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
 index 466727b..1a861ee 100644
 --- a/src/backend/tcop/pquery.c
 +++ b/src/backend/tcop/pquery.c
 @@ -1184,7 +1184,8 @@ PortalRunUtility(Portal portal, Node *utilityStmt, 
 bool isTopLevel,
  portal-portalParams,
  isTopLevel,
  dest,
 -completionTag);
 +completionTag,
 +NULL);

   /* Some utility statements may change context on us */
   MemoryContextSwitchTo(PortalGetHeapMemory(portal));
 diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
 index 0749227..35db28c 100644
 --- a/src/backend/tcop/utility.c
 +++ b/src/backend/tcop/utility.c
 @@ -319,6 +319,9 @@ 

Re: [HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2011-10-07 Thread Kevin Grittner
Pavel Stehule pavel.steh...@gmail.com wrote:
 
 There is not possible to get a number of processed rows when COPY
 is evaluated via SPI. Client can use a tag, but SPI doesn't use a
 tag.
 
 I propose a small change a ProcessUtility to return a processed
 rows.
 
Please add this to the open CommitFest:
 
https://commitfest.postgresql.org/action/commitfest_view/open
 
-Kevin

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


[HACKERS] ToDo: allow to get a number of processed rows by COPY statement

2011-10-04 Thread Pavel Stehule
Hello

There is not possible to get a number of processed rows when COPY is
evaluated via SPI. Client can use a tag, but SPI doesn't use a tag.

I propose a small change a ProcessUtility to return a processed rows.

Note: I found a small inconsistency between SPI and Utility interface.
SPI still use a 4 byte unsign int for storing a number of processed
rows. Utility use a 8bytes unsign int.

Motivation:

 postgres=# \sf fx
CREATE OR REPLACE FUNCTION public.fx(tablename text, filename text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
declare r int;
begin
  execute format('COPY %s FROM %s', quote_ident(tablename),
quote_literal(filename));
  get diagnostics r = row_count;
  return r;
end;
$function$

Regards

Pavel Stehule
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 398bc40..a7c2b8f 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -600,6 +600,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
 	   es-qd-params,
 	   false,	/* not top level */
 	   es-qd-dest,
+	   NULL,
 	   NULL);
 		result = true;			/* never stops early */
 	}
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 688279c..21cabcc 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -1838,6 +1838,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 		{
 			Node	   *stmt = (Node *) lfirst(lc2);
 			bool		canSetTag;
+			bool		isCopyStmt = false;
 			DestReceiver *dest;
 
 			_SPI_current-processed = 0;
@@ -1857,6 +1858,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 {
 	CopyStmt   *cstmt = (CopyStmt *) stmt;
 
+	isCopyStmt = true;
 	if (cstmt-filename == NULL)
 	{
 		my_res = SPI_ERROR_COPY;
@@ -1911,16 +1913,23 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 			}
 			else
 			{
+uint32 processed;
+
 ProcessUtility(stmt,
 			   plansource-query_string,
 			   paramLI,
 			   false,	/* not top level */
 			   dest,
-			   NULL);
+			   NULL,
+			   processed);
 /* Update processed if stmt returned tuples */
+
 if (_SPI_current-tuptable)
 	_SPI_current-processed = _SPI_current-tuptable-alloced -
 		_SPI_current-tuptable-free;
+else if (canSetTag  isCopyStmt)
+	_SPI_current-processed = processed;
+
 res = SPI_OK_UTILITY;
 			}
 
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 466727b..1a861ee 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -1184,7 +1184,8 @@ PortalRunUtility(Portal portal, Node *utilityStmt, bool isTopLevel,
    portal-portalParams,
    isTopLevel,
    dest,
-   completionTag);
+   completionTag,
+   NULL);
 
 	/* Some utility statements may change context on us */
 	MemoryContextSwitchTo(PortalGetHeapMemory(portal));
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 0749227..35db28c 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -319,6 +319,9 @@ CheckRestrictedOperation(const char *cmdname)
  * completionTag is only set nonempty if we want to return a nondefault status.
  *
  * completionTag may be NULL if caller doesn't want a status string.
+ *
+ * processed may be NULL if caller doesn't want a number of processed rows 
+ * by COPY statement
  */
 void
 ProcessUtility(Node *parsetree,
@@ -326,7 +329,8 @@ ProcessUtility(Node *parsetree,
 			   ParamListInfo params,
 			   bool isTopLevel,
 			   DestReceiver *dest,
-			   char *completionTag)
+			   char *completionTag,
+			   uint32 *processed)
 {
 	Assert(queryString != NULL);	/* required as of 8.4 */
 
@@ -337,10 +341,10 @@ ProcessUtility(Node *parsetree,
 	 */
 	if (ProcessUtility_hook)
 		(*ProcessUtility_hook) (parsetree, queryString, params,
-isTopLevel, dest, completionTag);
+isTopLevel, dest, completionTag, processed);
 	else
 		standard_ProcessUtility(parsetree, queryString, params,
-isTopLevel, dest, completionTag);
+isTopLevel, dest, completionTag, processed);
 }
 
 void
@@ -349,7 +353,8 @@ standard_ProcessUtility(Node *parsetree,
 		ParamListInfo params,
 		bool isTopLevel,
 		DestReceiver *dest,
-		char *completionTag)
+		char *completionTag,
+		uint32 *processed)
 {
 	check_xact_readonly(parsetree);
 
@@ -571,6 +576,7 @@ standard_ProcessUtility(Node *parsetree,
 	   params,
 	   false,
 	   None_Receiver,
+	   NULL,
 	   NULL);
 	}
 
@@ -716,12 +722,14 @@ standard_ProcessUtility(Node *parsetree,
 
 		case T_CopyStmt:
 			{
-uint64		processed;
+uint64		_processed;
 
-processed = DoCopy((CopyStmt *) parsetree, queryString);
+_processed = DoCopy((CopyStmt *) parsetree, queryString);
 if (completionTag)
 	snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
-			 COPY  UINT64_FORMAT, processed);
+			 COPY  UINT64_FORMAT,