[PATCHES] pgcrypto BYTE_ORDER fix for stable branches

2005-07-13 Thread Marko Kreen
Recently was uncovered that pgcrypto does not include
right header file to get BYTE_ORDER define on Cygwin
and MINGW, and the missing define does not result in
build failures, but random combinations of little and
big-endian code sections.

This patch adds missing sys/param.h include for md5.c,
sha1.c and rijndael.c plus also check to catch undefined
BYTE_ORDER.

The patch applies cleanly and is tested on branches
for versions 7.2, 7.3, 7.4 and 8.0.  There are also
no failures on buildfarm for HEAD, where this patch
is already included.

-- 
marko

Index: contrib/pgcrypto/md5.c
===
RCS file: /opt/arc/cvs2/pgsql/contrib/pgcrypto/md5.c,v
retrieving revision 1.9
diff -u -c -r1.9 md5.c
*** contrib/pgcrypto/md5.c  29 Nov 2001 19:40:37 -  1.9
--- contrib/pgcrypto/md5.c  13 Jul 2005 14:14:07 -
***
*** 31,40 
   */
  
  #include "postgres.h"
- #include "px.h"
  
  #include "md5.h"
  
  #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s
  
  #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
--- 31,47 
   */
  
  #include "postgres.h"
  
+ #include 
+ 
+ #include "px.h"
  #include "md5.h"
  
+ /* sanity check */
+ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != 
BIG_ENDIAN)
+ #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+ #endif
+ 
  #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s
  
  #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
Index: contrib/pgcrypto/rijndael.c
===
RCS file: /opt/arc/cvs2/pgsql/contrib/pgcrypto/rijndael.c,v
retrieving revision 1.9
diff -u -c -r1.9 rijndael.c
*** contrib/pgcrypto/rijndael.c 5 Sep 2002 21:08:26 -   1.9
--- contrib/pgcrypto/rijndael.c 13 Jul 2005 14:15:43 -
***
*** 38,48 
  
  */
  
! #include 
  #include "px.h"
  
  #include "rijndael.h"
  
  #define PRE_CALC_TABLES
  #define LARGE_TABLES
  
--- 38,56 
  
  */
  
! #include "postgres.h"
! 
! #include 
! 
  #include "px.h"
  
  #include "rijndael.h"
  
+ /* sanity check */
+ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != 
BIG_ENDIAN)
+ #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+ #endif
+ 
  #define PRE_CALC_TABLES
  #define LARGE_TABLES
  
Index: contrib/pgcrypto/sha1.c
===
RCS file: /opt/arc/cvs2/pgsql/contrib/pgcrypto/sha1.c,v
retrieving revision 1.11
diff -u -c -r1.11 sha1.c
*** contrib/pgcrypto/sha1.c 29 Nov 2001 19:40:37 -  1.11
--- contrib/pgcrypto/sha1.c 13 Jul 2005 14:15:05 -
***
*** 36,53 
   */
  
  #include "postgres.h"
  #include "px.h"
  
  #include "sha1.h"
  
  /* sanity check */
! #if BYTE_ORDER != BIG_ENDIAN
! #if BYTE_ORDER != LITTLE_ENDIAN
! #define unsupported 1
  #endif
- #endif
- 
- #ifndef unsupported
  
  /* constant table */
  static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
--- 36,52 
   */
  
  #include "postgres.h"
+ 
+ #include 
+ 
  #include "px.h"
  
  #include "sha1.h"
  
  /* sanity check */
! #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != 
BIG_ENDIAN)
! #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
  #endif
  
  /* constant table */
  static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
***
*** 347,350 
  #endif
  }
  
- #endif   /* unsupported */
--- 346,348 

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


[PATCHES] Final cleanup of SQL:1999 references

2005-07-13 Thread Simon Riggs

This doc patch replaces all inappropriate references to SQL:1999 when it
is used as if it were the latest (and/or still valid) SQL standard.

SQL:2003 is used in its place.

Best Regards, Simon Riggs
Index: array.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/array.sgml,v
retrieving revision 1.43
diff -c -c -r1.43 array.sgml
*** array.sgml	6 Feb 2005 20:59:30 -	1.43
--- array.sgml	12 Jul 2005 20:31:31 -
***
*** 63,69 
   
  
   
!   An alternative syntax, which conforms to the SQL:1999 standard, may
be used for one-dimensional arrays.
pay_by_quarter could have been defined
as:
--- 63,69 
   
  
   
!   An alternative syntax, which conforms to the SQL:2003 standard, may
be used for one-dimensional arrays.
pay_by_quarter could have been defined
as:
Index: ddl.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ddl.sgml,v
retrieving revision 1.41
diff -c -c -r1.41 ddl.sgml
*** ddl.sgml	13 Jun 2005 02:40:01 -	1.41
--- ddl.sgml	12 Jul 2005 20:31:33 -
***
*** 1122,1128 
 
   In previous versions of PostgreSQL, the
   default behavior was not to include child tables in queries. This was
!  found to be error prone and is also in violation of the SQL:1999
   standard. Under the old syntax, to get the sub-tables you append
   * to the table name.
   For example
--- 1122,1128 
 
   In previous versions of PostgreSQL, the
   default behavior was not to include child tables in queries. This was
!  found to be error prone and is also in violation of the SQL:2003
   standard. Under the old syntax, to get the sub-tables you append
   * to the table name.
   For example
Index: ecpg.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ecpg.sgml,v
retrieving revision 1.64
diff -c -c -r1.64 ecpg.sgml
*** ecpg.sgml	20 May 2005 12:36:48 -	1.64
--- ecpg.sgml	12 Jul 2005 20:31:35 -
***
*** 1146,1153 
  The fields sqlca.sqlstate and
  sqlca.sqlcode are two different schemes that
  provide error codes.  Both are specified in the SQL standard, but
! SQLCODE has been marked deprecated in the 1992
! edition of the standard and has been dropped in the 1999 edition.
  Therefore, new applications are strongly encouraged to use
  SQLSTATE.
 
--- 1146,1153 
  The fields sqlca.sqlstate and
  sqlca.sqlcode are two different schemes that
  provide error codes.  Both are specified in the SQL standard, but
! SQLCODE has been marked deprecated in SQL-92
! edition of the standard and has been dropped in later editions.
  Therefore, new applications are strongly encouraged to use
  SQLSTATE.
 
Index: errcodes.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/errcodes.sgml,v
retrieving revision 1.13
diff -c -c -r1.13 errcodes.sgml
*** errcodes.sgml	26 Jun 2005 19:16:04 -	1.13
--- errcodes.sgml	12 Jul 2005 20:31:36 -
***
*** 127,133 
  
  
  Class 02
! No Data — this is also a warning class per SQL:1999
  
  
  
--- 127,133 
  
  
  Class 02
! No Data — this is also a warning class per SQL:2003
  
  
  
Index: func.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.260
diff -c -c -r1.260 func.sgml
*** func.sgml	26 Jun 2005 22:05:35 -	1.260
--- func.sgml	12 Jul 2005 20:31:59 -
***
*** 2515,2522 
  There are three separate approaches to pattern matching provided
  by PostgreSQL: the traditional
  SQL LIKE operator, the
! more recent SIMILAR TO operator (added in
! SQL:1999), and POSIX-style regular expressions.
  Additionally, a pattern matching function,
  substring, is available, using either
  SIMILAR TO-style or POSIX-style regular
--- 2515,2522 
  There are three separate approaches to pattern matching provided
  by PostgreSQL: the traditional
  SQL LIKE operator, the
! more recent SIMILAR TO operator (part of 
! SQL:2003), and POSIX-style regular expressions.
  Additionally, a pattern matching function,
  substring, is available, using either
  SIMILAR TO-style or POSIX-style regular
Index: sql.sgml
===
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/sql.sgml,v
retrieving revision 1.36
diff -c -c -r1.36 sql.sgml
*** sql.sgml	28 Apr 2005 21:47:09 -	1.36
--- sql.sgml	12 Jul 2005 20:31:59 -
***
*** 98,105 
 is under development. It is planned to make SQL
 a Turing-complete
 language, i.e. all computable queries (e.g. recursive queries)

[PATCHES] PL/PGSQL: Dynamic Record Introspection

2005-07-13 Thread Titus von Boxberg

Hi all,

I needed introspection capabilities for record types to write more generic
trigger procedures in PL/PGSQL.

With the following patch it's possible to
- extract all field names of a record into an array
- extract field count of a record
- address a single field of a record with a variable
  containing the field name (additional to the usual record.fieldname
  notation where the fieldname is hardcoded).

The syntax is
- record%NFIELDS gives the number of fields in the record
- record%FIELDNAMES gives the array of the field names
- record%scalarvariable extracts the field whose name
  is equal to the contents of scalarvariable



The patch is nonintrusive in the sense that it only adds things
with one exception:
In function exec_eval_datum(), file pl_exec.c, line 3557 (after the patch)
I chose to convert the record field values to TEXT if the caller does
not require a certain type (expectedtypeid == InvalidOid).
Additionally, I cast the value from the record field type if
the destination Datum is of different type.

As far as I can see, this does no harm because in most cases
the expectedtypeid is correctly set. I just wanted to avoid that
if it is not set, the returned datum is of a more restrictive type
than TEXT.



The patch is against a HEAD checkout from 07/12/05
The output comes from difforig.

Test code for the patch can be extracted from an example I put into
plpgsql.sgml



Here is a summary of things that get patched by the file:
- add three new special parsing functions to pl_comp.c
  (plpgsql_parse_wordpercentword, plpgsql_parse_wordnfields,
  plpgsql_parse_wordfieldnames).
- modify PLpgSQL_recfield in plpgsql.h to either hold
  a conventional field name (record.fieldname) or a dno
  for the variable (record%variable).
- add two PLPGSQL_DTYPEs for the two new % notations
- modify "case PLPGSQL_DTYPE_RECFIELD:"
  in exec_eval_datum() and exec_assign_value()
  to deal with index strings from a variable
- add "case PLPGSQL_DTYPE_RECFIELDNAMES"
  and "case PLPGSQL_DTYPE_NRECFIELD"
  to exec_eval_datum() to evaluate  %FIELDNAMES
  and %NFIELDS expressions.
- update plpgsql.sgml in the docs directory



Please notify me if I can be of further assistance.

Regards
Titus
*** ./doc/src/sgml/plpgsql.sgml.origThu Jul 14 00:49:33 2005
--- ./doc/src/sgml/plpgsql.sgml Thu Jul 14 01:15:41 2005
***
*** 867,872 
--- 867,941 
 
  
 
+ To obtain the values of the fields the record is made up of,
+ the record variable can be qualified with the column or field
+ name. This can be done either literally with the usual dot notation
+ or the column name for indexing the record can be taken out of a scalar
+ variable. The syntax for this notation is Record_variable%IndexVariable.
+ To get information about the column fields, two special
+ notations exist that return all column names as an array 
(RecordVariable%FIELDNAMES)
+ and the count of fields stored in a record (RecordVariable%NFIELDS). 
+ Thus, the RECORD can be viewed
+ as an associative array that allows for introspection of it's contents.
+ This feature is especially useful for writing generic triggers that
+ operate on records with unknown structure.
+ Here is an example that operates on the predefined record NEW in 
+ a trigger procedure:
+ 
+ CREATE OR REPLACE FUNCTION show_associative_records() RETURNS TRIGGER AS 
$ztt_u$
+   DECLARE
+   wmsgTEXT;
+   column  TEXT;
+   colcontent  TEXT;
+   colnamesTEXT[];
+   colnINT4;
+   coliINT4;
+   testint8INT8;
+   BEGIN
+ -- get the number of fields
+   coln := NEW%NFIELDS;
+   RAISE NOTICE 'Record type has % fields', coln;
+ 
+ -- obtain an array with all field names of the record
+   colnames := NEW%FIELDNAMES;
+   RAISE NOTICE 'All column names of test record: %', colnames;
+ 
+ -- show field names and contents of record
+   coli := 1;
+   LOOP 
+   column := colnames[coli];
+   colcontent := NEW%column;
+   IF colcontent IS NULL
+   THEN
+   colcontent := '';
+   END IF;
+   RAISE NOTICE 'column name % of NEW: value %', column, 
colcontent;
+   coli := coli + 1;
+   EXIT WHEN coli > coln;
+   END LOOP;
+ 
+ -- get a single record field value indexed by the contents of the variable 
"column"
+ -- raises an error if the record does not have the field name from "column"
+   column := 'SomeFieldNameInYourRecord';
+ -- testint8 will contain NULL if the value of this column
+ -- has a different type and cannot be casted to int8!
+ -- use a TEXT

[PATCHES] A minor patch to mark xml/xslt functions immutable

2005-07-13 Thread Ilia Kantor

Immutability is obvious, because xml procession result depends on the
document and request solely.

Couldn't use it for indexes w/o that flag.



--- /root/pgxml.sql.in  Sat Jul  9 21:41:33 2005
+++
/usr/ports/databases/postgresql-contrib/work/postgresql-8.0.3/contrib/xml2/p
gxml.sql.in Sat Jul  9 21:41:36 2005
@@ -1,31 +1,31 @@
 --SQL for XML parser
 
-CREATE OR REPLACE FUNCTION xml_valid(text) RETURNS bool
+CREATE OR REPLACE FUNCTION xml_valid(text) RETURNS bool IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
-CREATE OR REPLACE FUNCTION xml_encode_special_chars(text) RETURNS text
+CREATE OR REPLACE FUNCTION xml_encode_special_chars(text) RETURNS text
IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
-CREATE OR REPLACE FUNCTION xpath_string(text,text) RETURNS text
+CREATE OR REPLACE FUNCTION xpath_string(text,text) RETURNS text IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
-CREATE OR REPLACE FUNCTION xpath_nodeset(text,text,text,text) RETURNS text
+CREATE OR REPLACE FUNCTION xpath_nodeset(text,text,text,text) RETURNS text
IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
-CREATE OR REPLACE FUNCTION xpath_number(text,text) RETURNS float4
+CREATE OR REPLACE FUNCTION xpath_number(text,text) RETURNS float4 IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
-CREATE OR REPLACE FUNCTION xpath_bool(text,text) RETURNS boolean
+CREATE OR REPLACE FUNCTION xpath_bool(text,text) RETURNS boolean IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
 -- List function
 
-CREATE OR REPLACE FUNCTION xpath_list(text,text,text) RETURNS text
+CREATE OR REPLACE FUNCTION xpath_list(text,text,text) RETURNS text
IMMUTABLE
AS 'MODULE_PATHNAME'
LANGUAGE 'c' WITH (isStrict);
 
 
-CREATE OR REPLACE FUNCTION xpath_list(text,text) RETURNS text 
+CREATE OR REPLACE FUNCTION xpath_list(text,text) RETURNS text IMMUTABLE
 AS 'SELECT xpath_list($1,$2,'','')' language 'SQL' WITH (isStrict);
 
 
@@ -33,16 +33,16 @@
 -- Wrapper functions for nodeset where no tags needed.
 
 
-CREATE OR REPLACE FUNCTION xpath_nodeset(text,text) RETURNS text AS
+CREATE OR REPLACE FUNCTION xpath_nodeset(text,text) RETURNS text IMMUTABLE
AS
 'SELECT xpath_nodeset($1,$2,,)' language 'SQL' WITH (isStrict);
 
 
-CREATE OR REPLACE FUNCTION xpath_nodeset(text,text,text) RETURNS text AS
+CREATE OR REPLACE FUNCTION xpath_nodeset(text,text,text) RETURNS text
IMMUTABLE AS
 'SELECT xpath_nodeset($1,$2,,$3)' language 'SQL' WITH (isStrict);
 
 -- Table function
 
-CREATE OR REPLACE FUNCTION xpath_table(text,text,text,text,text) RETURNS
setof record
+CREATE OR REPLACE FUNCTION xpath_table(text,text,text,text,text) RETURNS
setof record IMMUTABLE
AS 'MODULE_PATHNAME'
LANGUAGE 'c' WITH (isStrict);
 
@@ -51,10 +51,10 @@
 -- XSLT support.
 
 
-CREATE OR REPLACE FUNCTION xslt_process(text,text,text) RETURNS text 
+CREATE OR REPLACE FUNCTION xslt_process(text,text,text) RETURNS text
IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);
 
 -- the function checks for the correct argument count
 
-CREATE OR REPLACE FUNCTION xslt_process(text,text) RETURNS text 
+CREATE OR REPLACE FUNCTION xslt_process(text,text) RETURNS text IMMUTABLE
AS 'MODULE_PATHNAME' LANGUAGE 'c' WITH (isStrict);


---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PATCHES] PL/PGSQL: Dynamic Record Introspection

2005-07-13 Thread Neil Conway

Titus von Boxberg wrote:

With the following patch it's possible to
- extract all field names of a record into an array
- extract field count of a record
- address a single field of a record with a variable
  containing the field name (additional to the usual record.fieldname
  notation where the fieldname is hardcoded).


I wonder if this is the right syntax. record%identifier is doing 
something fundamentally different from record.identifier, but the syntax 
doesn't make that clear. I don't have any concrete suggestions for 
improvement, mind you... :)



Test code for the patch can be extracted from an example I put into
plpgsql.sgml


Can you supply some proper regression tests, please? i.e. patch 
sql/plpgsql.sql and expected/plpgsql.out in src/test/regress


A few minor comments from skimming the patch:


***
*** 995,1001 
  
  new = palloc(sizeof(PLpgSQL_recfield));

new->dtype = PLPGSQL_DTYPE_RECFIELD;
!   new->fieldname = pstrdup(cp[1]);
new->recparentno = ns->itemno;
  
  plpgsql_adddatum((PLpgSQL_datum *) new);

--- 995,1002 
  
  new = palloc(sizeof(PLpgSQL_recfield));

new->dtype = PLPGSQL_DTYPE_RECFIELD;
!   new->fieldindex.fieldname = strdup(cp[1]);
!   new->fieldindex_flag = RECFIELD_USE_FIELDNAME;
new->recparentno = ns->itemno;
  
  plpgsql_adddatum((PLpgSQL_datum *) new);


Should be pstrdup().


***
*** 1101,1107 
  
  new = palloc(sizeof(PLpgSQL_recfield));

new->dtype = PLPGSQL_DTYPE_RECFIELD;
!   new->fieldname = pstrdup(cp[2]);
new->recparentno = ns->itemno;
  
  plpgsql_adddatum((PLpgSQL_datum *) new);

--- 1102,1109 
  
  new = palloc(sizeof(PLpgSQL_recfield));

new->dtype = PLPGSQL_DTYPE_RECFIELD;
!   new->fieldindex.fieldname = strdup(cp[2]);
!   new->fieldindex_flag = RECFIELD_USE_FIELDNAME;
new->recparentno = ns->itemno;
  
  plpgsql_adddatum((PLpgSQL_datum *) new);


Ibid.


+   switch (ns1->itemtype)
+   {
+   case PLPGSQL_NSTYPE_REC:
+   {
+   PLpgSQL_recfieldproperties *new;
+ 
+ new = malloc(sizeof(PLpgSQL_recfieldproperties));

+   new->dtype = PLPGSQL_DTYPE_NRECFIELD;
+   new->recparentno = ns1->itemno;
+   plpgsql_adddatum((PLpgSQL_datum *) new);
+   plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
+   ret =  T_SCALAR;/* ??? */
+   break;


Should be palloc().


+   return ret;
+ } /* plpgsql_parse_wordnfields */


The Postgres convention is not to include comments like this.


+   case PLPGSQL_NSTYPE_REC:
+   {
+   PLpgSQL_recfieldproperties *new;
+ 
+ new = malloc(sizeof(PLpgSQL_recfieldproperties));

+   new->dtype = PLPGSQL_DTYPE_RECFIELDNAMES;
+   new->recparentno = ns1->itemno;
+   plpgsql_adddatum((PLpgSQL_datum *) new);
+   plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
+   ret =  T_SCALAR;/* ??? */
+   break;
+   }


Should be palloc().


!   /* construct_array copies data; free temp elem 
array */
! #if   0
!   for ( fc = 0; fc < tfc; ++fc )
!   pfree(DatumGetPointer(arrayelems[fc]);
!   pfree(arrayelems);
! #endif


Unexplained #if 0 blocks aren't good.

-Neil

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
  choose an index scan if your joining column's datatypes do not
  match


Re: [PATCHES] Final cleanup of SQL:1999 references

2005-07-13 Thread Neil Conway

Simon Riggs wrote:

This doc patch replaces all inappropriate references to SQL:1999 when it
is used as if it were the latest (and/or still valid) SQL standard.


Applied, thanks.

-Neil

---(end of broadcast)---
TIP 4: Have you searched our list archives?

  http://archives.postgresql.org


Re: [PATCHES] PL/PGSQL: Dynamic Record Introspection

2005-07-13 Thread Pavel Stehule
good idea. it's what can eliminate not neccessery using plperl. I would to 
see it in plpgsql.

regards
Pavel

On Thu, 14 Jul 2005, Titus von Boxberg wrote:

> Hi all,
> 
> I needed introspection capabilities for record types to write more generic
> trigger procedures in PL/PGSQL.
> 
> With the following patch it's possible to
> - extract all field names of a record into an array
> - extract field count of a record
> - address a single field of a record with a variable
>containing the field name (additional to the usual record.fieldname
>notation where the fieldname is hardcoded).
> 
> The syntax is
> - record%NFIELDS gives the number of fields in the record
> - record%FIELDNAMES gives the array of the field names
> - record%scalarvariable extracts the field whose name
>is equal to the contents of scalarvariable
> 
> 
> 
> The patch is nonintrusive in the sense that it only adds things
> with one exception:
> In function exec_eval_datum(), file pl_exec.c, line 3557 (after the patch)
> I chose to convert the record field values to TEXT if the caller does
> not require a certain type (expectedtypeid == InvalidOid).
> Additionally, I cast the value from the record field type if
> the destination Datum is of different type.
> 
> As far as I can see, this does no harm because in most cases
> the expectedtypeid is correctly set. I just wanted to avoid that
> if it is not set, the returned datum is of a more restrictive type
> than TEXT.
> 
> 
> 
> The patch is against a HEAD checkout from 07/12/05
> The output comes from difforig.
> 
> Test code for the patch can be extracted from an example I put into
> plpgsql.sgml
> 
> 
> 
> Here is a summary of things that get patched by the file:
> - add three new special parsing functions to pl_comp.c
>(plpgsql_parse_wordpercentword, plpgsql_parse_wordnfields,
>plpgsql_parse_wordfieldnames).
> - modify PLpgSQL_recfield in plpgsql.h to either hold
>a conventional field name (record.fieldname) or a dno
>for the variable (record%variable).
> - add two PLPGSQL_DTYPEs for the two new % notations
> - modify "case PLPGSQL_DTYPE_RECFIELD:"
>in exec_eval_datum() and exec_assign_value()
>to deal with index strings from a variable
> - add "case PLPGSQL_DTYPE_RECFIELDNAMES"
>and "case PLPGSQL_DTYPE_NRECFIELD"
>to exec_eval_datum() to evaluate  %FIELDNAMES
>and %NFIELDS expressions.
> - update plpgsql.sgml in the docs directory
> 
> 
> 
> Please notify me if I can be of further assistance.
> 
> Regards
> Titus
> 


---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] thousands comma numeric formatting in psql

2005-07-13 Thread Bruce Momjian

Thanks, fixed, and applied.  I also centralized the malloc into a
function.  We could use pg_malloc, but that doesn't export out to
/scripts, where this is shared.  We will fix that some day, but not
right now.

---

Eugen Nedelcu wrote:
> On Mon, Jul 11, 2005 at 11:37:17PM -0400, Bruce Momjian wrote:
> > 
> > Did you do a 'make clean' before testing?  I can't reproduce any failure
> > here.  Can you supply a number that is failing, like this:
> > 
> > SELECT 100;
> > 
> > ---
> > 
> 
> The bug is in the following code:
> 
> new_str = malloc(new_len) and every one of
> char *my_cell = malloc()
> 
> Ring a bell?
> 
> The corect form is:
> 
> new_str = malloc(new_len + 1),
> char *my_cell = malloc( + 1)
> 
> because of the null character that must terminate the string (\0)
> 
> The error apears of course randomly (more probably for a query which 
> returns many rows)
> 
> Regarding locale aproach, it is trivial to replace langinfo with
> localeconv:
> 
> struct lconv *l = localeconv();
> char *dec_point = l->decimal_point;
> 
> instead of:
> 
> #include langinfo.h
> char *dec_point = nl_langinfo(__DECIMAL_POINT);
> 
> I used langinfo because in linux libc it is considered
> "The Elegant and Fast Way" of using locale and conforms with
> X/Open portability guide that every modern Unix follows
> (Solaris, Linux, latest FreeBSD).
> 
> Regarding locale vs. \pset numericsep, for me it doesn't matter
> which one is used. I consider the patch very usefull, and I think 
> that other guys that use psql daily for working with financial data
> will appreciate it too.
> 
> With a quick setting like \pset numericsep ',' all my numeric fields
> will appear in easy readable form. I must underline that to_char is
> a backend function and we talk here about a little psql feature which
> makes life a little easier (for me at least).
> 

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  pgman@candle.pha.pa.us   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073
Index: src/bin/psql/print.c
===
RCS file: /cvsroot/pgsql/src/bin/psql/print.c,v
retrieving revision 1.63
diff -c -c -r1.63 print.c
*** src/bin/psql/print.c10 Jul 2005 15:53:42 -  1.63
--- src/bin/psql/print.c14 Jul 2005 06:44:10 -
***
*** 29,34 
--- 29,48 
  
  #include "mbprint.h"
  
+ static void *
+ pg_local_malloc(size_t size)
+ {
+   void   *tmp;
+ 
+   tmp = malloc(size);
+   if (!tmp)
+   {
+   psql_error("out of memory\n");
+   exit(EXIT_FAILURE);
+   }
+   return tmp;
+ }
+ 
  static int
  num_numericseps(const char *my_str)
  {
***
*** 46,51 
--- 60,66 
else
return int_len / 3 - 1; /* no leading separator */
  }
+ 
  static int
  len_with_numericsep(const char *my_str)
  {
***
*** 77,88 
if (digits_before_sep == 0)
new_len--;  /* no leading separator */
  
!   new_str = malloc(new_len);
!   if (!new_str)
!   {
!   fprintf(stderr, _("out of memory\n"));
!   exit(EXIT_FAILURE);
!   }
  
for (i=0, j=0; ; i++, j++)
{
--- 92,98 
if (digits_before_sep == 0)
new_len--;  /* no leading separator */
  
!   new_str = pg_local_malloc(new_len + 1);
  
for (i=0, j=0; ; i++, j++)
{
***
*** 167,179 
if ((opt_align[i % col_count] == 'r') && strlen(*ptr) > 0 &&
opt_numericsep != NULL && strlen(opt_numericsep) > 0)
{
!   char *my_cell = malloc(len_with_numericsep(*ptr));

-   if (!my_cell)
-   {
-   fprintf(stderr, _("out of memory\n"));
-   exit(EXIT_FAILURE);
-   }
strcpy(my_cell, *ptr);
format_numericsep(my_cell, opt_numericsep);
fputs(my_cell, fout);
--- 177,184 
if ((opt_align[i % col_count] == 'r') && strlen(*ptr) > 0 &&
opt_numericsep != NULL && strlen(opt_numericsep) > 0)
{
!   char *my_cell = 
pg_local_malloc(len_with_numericsep(*ptr) + 1);

strcpy(my_cell, *ptr);
format_numericsep(my_cell, opt_numericsep);
fputs(my_cell, fout);
***
*** 249,261 
if ((opt_align[i % col_count] == 'r') && strlen(*ptr) != 0 &&
opt_numeri