Re: [HACKERS] pl/python quoting functions

2011-02-23 Thread Jan Urbański
On 22/02/11 22:48, Peter Eisentraut wrote:
 Committed this, with two changes:  Changed some things around with the
 way const char * is propagated.  Just casting it away is not nice.  Also
 dropped the error tests in the _quote.sql regression test.  This
 generates three different wordings of error messages from Python with
 2.6, 3.1, and 3.2, which I don't care to maintain.  Maybe one day we'll
 have a better solution for this.

Thanks.

One thing: you removed the conditional pfree from PLy_quote_ident, which
makes this function leak memory if the actual quoting took place, no? Is
that leak too small to worry about?

Cheers,
Jan

-- 
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] pl/python quoting functions

2011-02-23 Thread Peter Eisentraut
On ons, 2011-02-23 at 11:26 +0100, Jan Urbański wrote:
 One thing: you removed the conditional pfree from PLy_quote_ident,
 which makes this function leak memory if the actual quoting took
 place, no? Is that leak too small to worry about?

Many functions in PostgreSQL leak memory in this way.  It's not worth
worrying about, and certainly not worth violating a called function's
API for it.



-- 
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] pl/python quoting functions

2011-02-22 Thread Peter Eisentraut
Committed this, with two changes:  Changed some things around with the
way const char * is propagated.  Just casting it away is not nice.  Also
dropped the error tests in the _quote.sql regression test.  This
generates three different wordings of error messages from Python with
2.6, 3.1, and 3.2, which I don't care to maintain.  Maybe one day we'll
have a better solution for this.





-- 
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] pl/python quoting functions

2011-02-06 Thread Jan Urbański
On 04/02/11 18:10, Hitoshi Harada wrote:
 2011/1/11 Jan Urbański wulc...@wulczer.org:
 Here's a patch that adds a few PL/Python functions for quoting strings.
 It's an incremental patch on top of the plpython-refactor patch sent in
 http://archives.postgresql.org/message-id/4d135170.3080...@wulczer.org.

 Git branch for this patch:
 https://github.com/wulczer/postgres/tree/functions

 The new functions are plpy.quote_literal, plpy.quote_nullable and
 plpy.quote_ident, and work just like their sql or plperl equivalents.

 
 I reviewed this.
 
 The patch applies and compiles cleanly and all the tests are passed.
 The patch adds 3 functions which works as the corresponding SQL
 functions. The test is enough, without any additional docs. No
 feature/performance issues found.
 
 I mark this Reader for Committer.

Thanks!

I guess a short paragraph in the Utility Functions section of the
PL/Python docs would be in order, I'll try to add it today.

Jan

-- 
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] pl/python quoting functions

2011-02-06 Thread Jan Urbański
On 06/02/11 10:54, Jan Urbański wrote:
 On 04/02/11 18:10, Hitoshi Harada wrote:
 2011/1/11 Jan Urbański wulc...@wulczer.org:
 Here's a patch that adds a few PL/Python functions for quoting strings.
 It's an incremental patch on top of the plpython-refactor patch sent in
 http://archives.postgresql.org/message-id/4d135170.3080...@wulczer.org.

 Git branch for this patch:
 https://github.com/wulczer/postgres/tree/functions

 The new functions are plpy.quote_literal, plpy.quote_nullable and
 plpy.quote_ident, and work just like their sql or plperl equivalents.


 I reviewed this.

 The patch applies and compiles cleanly and all the tests are passed.
 The patch adds 3 functions which works as the corresponding SQL
 functions. The test is enough, without any additional docs. No
 feature/performance issues found.

 I mark this Reader for Committer.
 
 Thanks!
 
 I guess a short paragraph in the Utility Functions section of the
 PL/Python docs would be in order, I'll try to add it today.

Added docs and merged with master.
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
index e05c293..8a995b2 100644
*** a/doc/src/sgml/plpython.sgml
--- b/doc/src/sgml/plpython.sgml
*** $$ LANGUAGE plpythonu;
*** 997,1002 
--- 997,1018 
 xref linkend=guc-client-min-messages configuration
 variables. See xref linkend=runtime-config for more information.
/para
+   para
+Another set of utility functions
+are literalplpy.quote_literal(replaceablestring/)/literal,
+literalplpy.quote_nullable(replaceablestring/)/literal
+and literalplpy.quote_ident(replaceablestring/)/literal. They are
+equivalent to the builtin quoting functions described
+in xref linkend=functions-string. They are useful when constructing
+ad-hoc queries. A PL/Python equivalent of dynamic SQL
+from xref linkend=plpgsql-quote-literal-example would be:
+ programlisting
+ plpy.execute(UPDATE tbl SET %s = %s where key = %s % (
+ plpy.quote_ident(colname),
+ plpy.quote_nullable(newvalue),
+ plpy.quote_literal(keyvalue)))
+ /programlisting
+   /para
   /sect1
  
   sect1 id=plpython-envar
diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile
index 16d78ae..292e360 100644
*** a/src/pl/plpython/Makefile
--- b/src/pl/plpython/Makefile
*** REGRESS = \
*** 79,84 
--- 79,85 
  	plpython_types \
  	plpython_error \
  	plpython_unicode \
+ 	plpython_quote \
  	plpython_drop
  # where to find psql for running the tests
  PSQLDIR = $(bindir)
diff --git a/src/pl/plpython/expected/plpython_quote.out b/src/pl/plpython/expected/plpython_quote.out
index ...b33ee3f .
*** a/src/pl/plpython/expected/plpython_quote.out
--- b/src/pl/plpython/expected/plpython_quote.out
***
*** 0 
--- 1,87 
+ -- test quoting functions
+ CREATE FUNCTION quote(t text, how text) RETURNS text AS $$
+ if how == literal:
+ return plpy.quote_literal(t)
+ elif how == nullable:
+ return plpy.quote_nullable(t)
+ elif how == ident:
+ return plpy.quote_ident(t)
+ else:
+ raise plpy.Error(unrecognized quote type %s % how)
+ $$ LANGUAGE plpythonu;
+ SELECT quote(t, 'literal') FROM (VALUES
+('abc'),
+('a''bc'),
+('''abc'''),
+(''),
+(),
+('xyzv')) AS v(t);
+quote   
+ ---
+  'abc'
+  'a''bc'
+  '''abc'''
+  ''
+  
+  'xyzv'
+ (6 rows)
+ 
+ SELECT quote(t, 'nullable') FROM (VALUES
+('abc'),
+('a''bc'),
+('''abc'''),
+(''),
+(),
+(NULL)) AS v(t);
+quote   
+ ---
+  'abc'
+  'a''bc'
+  '''abc'''
+  ''
+  
+  NULL
+ (6 rows)
+ 
+ SELECT quote(t, 'ident') FROM (VALUES
+('abc'),
+('a b c'),
+('a  ''abc''')) AS v(t);
+ quote 
+ --
+  abc
+  a b c
+  a  'abc'
+ (3 rows)
+ 
+ -- test errors
+ SELECT quote(NULL::text, 'literal');
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python function quote
+ SELECT quote(NULL::text, 'ident');
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python function quote
+ SELECT quote('abc', 'random');
+ ERROR:  plpy.Error: unrecognized quote type random
+ CONTEXT:  PL/Python function quote
+ DO $$ plpy.quote_literal(3) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not int
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal(None) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal({'a': 'b'}) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not dict
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal() $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: function takes exactly 1 argument (0 given)
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal(1, 2) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: 

Re: [HACKERS] pl/python quoting functions

2011-02-04 Thread Hitoshi Harada
2011/1/11 Jan Urbański wulc...@wulczer.org:
 Here's a patch that adds a few PL/Python functions for quoting strings.
 It's an incremental patch on top of the plpython-refactor patch sent in
 http://archives.postgresql.org/message-id/4d135170.3080...@wulczer.org.

 Git branch for this patch:
 https://github.com/wulczer/postgres/tree/functions

 The new functions are plpy.quote_literal, plpy.quote_nullable and
 plpy.quote_ident, and work just like their sql or plperl equivalents.


I reviewed this.

The patch applies and compiles cleanly and all the tests are passed.
The patch adds 3 functions which works as the corresponding SQL
functions. The test is enough, without any additional docs. No
feature/performance issues found.

I mark this Reader for Committer.

Regards,


-- 
Hitoshi Harada

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


[HACKERS] pl/python quoting functions

2011-01-10 Thread Jan Urbański
Here's a patch that adds a few PL/Python functions for quoting strings.
It's an incremental patch on top of the plpython-refactor patch sent in
http://archives.postgresql.org/message-id/4d135170.3080...@wulczer.org.

Git branch for this patch:
https://github.com/wulczer/postgres/tree/functions

The new functions are plpy.quote_literal, plpy.quote_nullable and
plpy.quote_ident, and work just like their sql or plperl equivalents.

Cheers,
Jan
diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile
index 16d78ae..292e360 100644
*** a/src/pl/plpython/Makefile
--- b/src/pl/plpython/Makefile
*** REGRESS = \
*** 79,84 
--- 79,85 
  	plpython_types \
  	plpython_error \
  	plpython_unicode \
+ 	plpython_quote \
  	plpython_drop
  # where to find psql for running the tests
  PSQLDIR = $(bindir)
diff --git a/src/pl/plpython/expected/plpython_quote.out b/src/pl/plpython/expected/plpython_quote.out
index ...b33ee3f .
*** a/src/pl/plpython/expected/plpython_quote.out
--- b/src/pl/plpython/expected/plpython_quote.out
***
*** 0 
--- 1,87 
+ -- test quoting functions
+ CREATE FUNCTION quote(t text, how text) RETURNS text AS $$
+ if how == literal:
+ return plpy.quote_literal(t)
+ elif how == nullable:
+ return plpy.quote_nullable(t)
+ elif how == ident:
+ return plpy.quote_ident(t)
+ else:
+ raise plpy.Error(unrecognized quote type %s % how)
+ $$ LANGUAGE plpythonu;
+ SELECT quote(t, 'literal') FROM (VALUES
+('abc'),
+('a''bc'),
+('''abc'''),
+(''),
+(),
+('xyzv')) AS v(t);
+quote   
+ ---
+  'abc'
+  'a''bc'
+  '''abc'''
+  ''
+  
+  'xyzv'
+ (6 rows)
+ 
+ SELECT quote(t, 'nullable') FROM (VALUES
+('abc'),
+('a''bc'),
+('''abc'''),
+(''),
+(),
+(NULL)) AS v(t);
+quote   
+ ---
+  'abc'
+  'a''bc'
+  '''abc'''
+  ''
+  
+  NULL
+ (6 rows)
+ 
+ SELECT quote(t, 'ident') FROM (VALUES
+('abc'),
+('a b c'),
+('a  ''abc''')) AS v(t);
+ quote 
+ --
+  abc
+  a b c
+  a  'abc'
+ (3 rows)
+ 
+ -- test errors
+ SELECT quote(NULL::text, 'literal');
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python function quote
+ SELECT quote(NULL::text, 'ident');
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python function quote
+ SELECT quote('abc', 'random');
+ ERROR:  plpy.Error: unrecognized quote type random
+ CONTEXT:  PL/Python function quote
+ DO $$ plpy.quote_literal(3) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not int
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal(None) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not None
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal({'a': 'b'}) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not dict
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal() $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: function takes exactly 1 argument (0 given)
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_literal(1, 2) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: function takes exactly 1 argument (2 given)
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_nullable([1, 2]) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string or None, not list
+ CONTEXT:  PL/Python anonymous code block
+ DO $$ plpy.quote_ident(1.5) $$ LANGUAGE plpythonu;
+ ERROR:  TypeError: argument 1 must be string, not float
+ CONTEXT:  PL/Python anonymous code block
diff --git a/src/pl/plpython/expected/plpython_test.out b/src/pl/plpython/expected/plpython_test.out
index d92c987..961f6c0 100644
*** a/src/pl/plpython/expected/plpython_test.out
--- b/src/pl/plpython/expected/plpython_test.out
*** contents.sort()
*** 43,51 
  return , .join(contents)
  $$ LANGUAGE plpythonu;
  select module_contents();
!   module_contents  
! ---
!  Error, Fatal, SPIError, debug, error, execute, fatal, info, log, notice, prepare, warning
  (1 row)
  
  CREATE FUNCTION elog_test() RETURNS void
--- 43,51 
  return , .join(contents)
  $$ LANGUAGE plpythonu;
  select module_contents();
! module_contents
! ---
!  Error, Fatal, SPIError, debug, error, execute, fatal, info, log, notice, prepare, quote_ident, quote_literal, quote_nullable, warning
  (1 row)
  
  CREATE FUNCTION elog_test() RETURNS void
diff --git a/src/pl/plpython/plpython.c