Monday, July 14, 2008

Re: [SQL] how to perform minus (-) operation in a dynamic query

Hai all,

 Thanks to all , I got the answer,  actualy I am write the function in openoffice.org and paste it to a .sql file that is the reason for the error.

thanks
Anoop









On Mon, Jul 14, 2008 at 7:32 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
"Anoop G" <anoopmadavoor@gmail.com> writes:
> ERROR:  syntax error at or near "\226" at character 18
> QUERY:  SELECT mf,sf,(mf \226 mf * comm /100) \226 (sf \226 sf * comm/100) as
> flt_claim
> CONTEXT:  PL/pgSQL function "test_perc" line 7 at for over execute statement
> LINE 1: SELECT mf,sf,(mf \226 mf * comm /100) \226 (sf \226 sf * comm/100) as...

I'm not sure what character \226 is, but it's not a minus sign ...

                       regards, tom lane

Re: [PERFORM] 3ware vs Areca

On Fri, 11 Jul 2008, Jeffrey Baker wrote:

> Their firmware is, frankly, garbage. In more than one instance we
> have had the card panic when a disk fails, which is obviously counter
> to the entire purpose of a RAID. We finally removed the Areca
> controllers from our database server and replaced them with HP P800s.

Can you give a bit more detail here? If what you mean is that the driver
for the card generated an OS panic when a drive failed, that's not
necessarily the firmware at all. I know I had problems with the Areca
cards under Linux until their driver went into the mainline kernel in
2.6.19, all kinds of panics under normal conditions. Haven't seen
anything like that with later Linux kernels or under Solaris 10, but then
again I haven't had a disk failure yet either.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

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

Re: [GENERAL] FAQ correction for Windows 2000/XP

Bruce Momjian escribió:
> Dan Dascalescu wrote:
> > I'd like to submit a correction for question "2.1) How do I setup a
> > datasource?" in the FAQ. The existing text reads:
> >
> > "For Windows, use the ODBC Administrator in Control Panel. Here you
> > can add, modify, or delete data sources."
> >
> > On Windows XP, however, there is no Control Panel applet for ODBC
> > management. The answer should read:
> >
> > "Go to Programs -> Administrative Tools -> Data Sources and Add the
> > PostgreSQL Unicode driver".
>
> Uh, I am not sure where you saw this FAQ but this is not an FAQ we
> manage. Where did you see it?

http://psqlodbc.projects.postgresql.org/faq.html#2.1

--
Alvaro Herrera

http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

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

Re: [GENERAL] FAQ correction for Windows 2000/XP

Dan Dascalescu wrote:
> I'd like to submit a correction for question "2.1) How do I setup a
> datasource?" in the FAQ. The existing text reads:
>
> "For Windows, use the ODBC Administrator in Control Panel. Here you
> can add, modify, or delete data sources."
>
> On Windows XP, however, there is no Control Panel applet for ODBC
> management. The answer should read:
>
> "Go to Programs -> Administrative Tools -> Data Sources and Add the
> PostgreSQL Unicode driver".

Uh, I am not sure where you saw this FAQ but this is not an FAQ we
manage. Where did you see it?

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

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

Re: [pgsql-es-ayuda] Plan de ejecución de una consulta con OR

El lun, 14-07-2008 a las 10:51 -0400, Alvaro Herrera escribió:
> Sebastián Villalba escribió:
> > Hola Marcos.
> >
> > On Mon, 14 Jul 2008 10:22:07 -0400, Marcos Saldivar wrote
> > > Estimados tengo la siguiente duda, para una consulta como esta:
> > >
> > > select * from foo where foo.permiso = 'todos' or 1950 in (select
> > > miembro from miembros_grupos)
> > >
> > > Al cumplirse la condición "foo.permiso = 'todos'" es valido pensar
> > > que la sub consulta jamas se ejecutara ????
> >
> > Muy válido. Saludos!
>
> No necesariamente ... me parece que SQL no garantiza que las condiciones
> se evalúan de izquierda a derecha ...
>
> Supongo que es posible que por una cosa de rendimiento la condición que
> involucra la constante sea ejecutada antes que la otra, y que el motor
> se tome la libertad de eliminar el subselect. Por otro lado supongo que
> si el subselect incluyera cosas como una funcion volátil, no podría hacerlo.

Pero acaso el explain no entrega pistas acerca de como resuelve la
consulta ?.
Si no recuerdo mal, las SQL se leen de abajo hacia arriba y de izquierda
a derecha.

Saludos,

-- Mauro

--
TIP 9: visita nuestro canal de IRC #postgresql-es en irc.freenode.net

Re: [HACKERS] DROP ROLE dependency tracking ...

Alvaro Herrera wrote:
> Hans-Juergen Schoenig wrote:
>
> > when thinking of REASSIGNED OWNED people tend to think about tables
> > rather than about CONNECT rights.
> > i would suggest to make DROP ROLE just kill the role unless there is a
> > real object depending on it.
> > i would not see a permission to be an object. what do you think?
>
> Yes, this might make some sense. (Keep in mind that db CONNECT
> privileges were invented after REASSIGN OWNED). Perhaps we could make
> exceptions -- in which case it would be good to investigate which
> exceptions we need (i.e. for all object types that we support, which
> ones we should be caring about and which ones we should ignore).
>
> I'm stuck in Canuckistan for a week still, so I expect your detailed
> proposal by when I get back home ;-)

Where are we on this issue? The original issue was CONNECT priviledges
prevented the role from being dropped.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
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 item: Have psql show current values for a sequence

Index: src/bin/psql/describe.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.179
diff -c -c -r1.179 describe.c
*** src/bin/psql/describe.c 14 Jul 2008 23:13:04 -0000 1.179
--- src/bin/psql/describe.c 15 Jul 2008 03:06:24 -0000
***************
*** 811,817 ****
printTableContent cont;
int i;
char *view_def = NULL;
! char *headers[5];
char **modifiers = NULL;
char **ptr;
PQExpBufferData title;
--- 811,818 ----
printTableContent cont;
int i;
char *view_def = NULL;
! char *headers[6];
! char **seq_values = NULL;
char **modifiers = NULL;
char **ptr;
PQExpBufferData title;
***************
*** 869,874 ****
--- 870,904 ----
tableinfo.tablespace = (pset.sversion >= 80000) ?
atooid(PQgetvalue(res, 0, 6)) : 0;
PQclear(res);
+
+ /*
+ * This is used to get the values of a sequence and store it in an
+ * array that will be used later.
+ */
+ if (tableinfo.relkind == 'S')
+ {
+ PGresult *result;
+
+ #define SEQ_NUM_COLS 10
+ printfPQExpBuffer(&buf,
+ "SELECT sequence_name, last_value, \n"
+ " start_value, increment_by, \n"
+ " max_value, min_value, cache_value, \n"
+ " log_cnt, is_cycled, is_called \n"
+ "FROM \"%s\"",
+ relationname);
+
+ result = PSQLexec(buf.data, false);
+ if (!result)
+ goto error_return;
+
+ seq_values = pg_malloc_zero((SEQ_NUM_COLS+1) * sizeof(*seq_values));
+
+ for (i = 0; i < SEQ_NUM_COLS; i++)
+ seq_values[i] = pg_strdup(PQgetvalue(result, 0, i));
+
+ PQclear(result);
+ }

/* Get column info (index requires additional checks) */
printfPQExpBuffer(&buf, "SELECT a.attname,");
***************
*** 932,938 ****
}

/* Set the number of columns, and their names */
! cols = 2;
headers[0] = gettext_noop("Column");
headers[1] = gettext_noop("Type");

--- 962,968 ----
}

/* Set the number of columns, and their names */
! cols += 2;
headers[0] = gettext_noop("Column");
headers[1] = gettext_noop("Type");

***************
*** 943,948 ****
--- 973,981 ----
modifiers = pg_malloc_zero((numrows + 1) * sizeof(*modifiers));
}

+ if (tableinfo.relkind == 'S')
+ headers[cols++] = gettext_noop("Value");
+
if (verbose)
{
headers[cols++] = gettext_noop("Storage");
***************
*** 980,986 ****

/* Type */
printTableAddCell(&cont, PQgetvalue(res, i, 1), false);
!
/* Extra: not null and default */
if (show_modifiers)
{
--- 1013,1023 ----

/* Type */
printTableAddCell(&cont, PQgetvalue(res, i, 1), false);
!
! /* A special 'Value' column for sequences */
! if (tableinfo.relkind == 'S')
! printTableAddCell(&cont, seq_values[i], false);
!
/* Extra: not null and default */
if (show_modifiers)
{
***************
*** 1543,1549 ****
termPQExpBuffer(&buf);
termPQExpBuffer(&title);
termPQExpBuffer(&tmpbuf);
!
if (show_modifiers)
{
for (ptr = modifiers; *ptr; ptr++)
--- 1580,1593 ----
termPQExpBuffer(&buf);
termPQExpBuffer(&title);
termPQExpBuffer(&tmpbuf);
!
! if (tableinfo.relkind == 'S')
! {
! for (ptr = seq_values; *ptr; ptr++)
! free(*ptr);
! free(seq_values);
! }
!
if (show_modifiers)
{
for (ptr = modifiers; *ptr; ptr++)
Wow. I adjusted the patch slightly and applied it; the updated version
is attached. We have been waiting for this to be done for quite some
time. Thanks.

---------------------------------------------------------------------------


Dickson S. Guedes wrote:
> Hi all,
>
> These patch implements the TODO item: Have psql show current values
> for a sequence.
> Comments are welcome.
>
> * Credits
>
> The original patch were developed by Euler Taveira de Oliveira
> <euler@timbira.com>
> but how he is a little busy, he sends it to me and I made some changes
> to satisfy
> the TODO item above.
>
> * Discussions
>
> http://archives.postgresql.org/pgsql-hackers/2007-12/msg00102.php
> http://archives.postgresql.org/pgsql-hackers/2007-12/msg00605.php
>
> * Outputs
>
> # \d foo_bar_seq
> Sequence "public.foo_bar_seq"
> +---------------+---------+---------------------+
> | Column | Type | Value |
> +---------------+---------+---------------------+
> | sequence_name | name | foo_bar_seq |
> | last_value | bigint | 11 |
> | start_value | bigint | 1 |
> | increment_by | bigint | 1 |
> | max_value | bigint | 9223372036854775807 |
> | min_value | bigint | 1 |
> | cache_value | bigint | 1 |
> | log_cnt | bigint | 31 |
> | is_cycled | boolean | f |
> | is_called | boolean | t |
> +---------------+---------+---------------------+
>
> # \d+ foo_bar_seq
> Sequence "public.foo_bar_seq"
> +---------------+---------+---------------------+-------------+
> | Column | Type | Value | Description |
> +---------------+---------+---------------------+-------------+
> | sequence_name | name | foo_bar_seq | |
> | last_value | bigint | 11 | |
> | start_value | bigint | 1 | |
> | increment_by | bigint | 1 | |
> | max_value | bigint | 9223372036854775807 | |
> | min_value | bigint | 1 | |
> | cache_value | bigint | 1 | |
> | log_cnt | bigint | 31 | |
> | is_cycled | boolean | f | |
> | is_called | boolean | t | |
> +---------------+---------+---------------------+-------------+
>
> --
> []s
> Dickson S. Guedes
> --------------------------------------
> Projeto Colmeia - Curitiba - PR
> +55 (41) 3254-7130 ramal: 27
> http://makeall.wordpress.com/
> http://pgcon.postgresql.org.br/
> http://planeta.postgresql.org.br/

[ Attachment, skipping... ]

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

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

[COMMITTERS] pgsql: Done: > o -Have psql show current values for a sequence

Log Message:
-----------
Done:

> o -Have psql show current values for a sequence

Modified Files:
--------------
pgsql/doc:
TODO (r1.2485 -> r1.2486)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/TODO?r1=1.2485&r2=1.2486)
pgsql/doc/src/FAQ:
TODO.html (r1.991 -> r1.992)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/FAQ/TODO.html?r1=1.991&r2=1.992)

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

[COMMITTERS] pgsql: Have psql \d show the value of sequence columns.

Log Message:
-----------
Have psql \d show the value of sequence columns.

Dickson S. Guedes

Modified Files:
--------------
pgsql/src/bin/psql:
describe.c (r1.179 -> r1.180)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/bin/psql/describe.c?r1=1.179&r2=1.180)

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

[GENERAL] 8.3.3 Complie issue

Hi All,

Compile issue I was hoping someone might have a suggestion for:

Did

./configure --prefix /removeExt2/pgsql8.3
make

make[3]: Entering directory `/removeExt2/postgresql-8.3.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_jis_2004'
make[3]: *** No rule to make target `utf8_and_euc_jis_2004.o', needed by `libutf8_and_euc_jis_2004.so.0.0'. Stop.
make[3]: Leaving directory `/removeExt2/postgresql-8.3.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_jis_2004'

Allan


The material contained in this email may be confidential, privileged or copyrighted. If you are not the intended recipient, use, disclosure or copying of this information is prohibited. If you have received this document in error, please advise the sender and delete the document. Neither OneSteel nor the sender accept responsibility for any viruses contained in this email or any attachments.

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

Re: [SQL] Rollback in Postgres

On Mon, Jul 14, 2008 at 9:18 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Kaare Rasmussen <kaare@jasonic.dk> writes:
>> But yes, it has to be enabled, and yes it has to have a performance cost
>> somehow, but people are requesting it, and somehow I don't think Oracle
>> developed the feature just for fun.
>
> No, they developed it for marketing.

No, they developed it because it was needed. In addition to knowing
quite a bit about the design and implementation of this feature, I've
been a production Oracle DBA and can speak from experience.

In fact, one of the primary reasons for creating this feature was for
the very purpose of why the original poster needed it, human-induced
disasters/mistakes. While flashback does give you the ability to
perform temporal-related queries, it was designed to allow recovery of
individual database objects (or the entire database itself) to a
certain point in time, thereby giving DBAs the ability to undo changes
(intentional or otherwise).

> Keep in mind that Oracle has six thousand full-time developers and an
> already extremely mature database.

True.

> Stuff that they see fit to add is not necessarily going to be on our radar
> screen in the foreseeable future.

Agreed.

--
Jonah H. Harris, Sr. Software Architect | phone: 732.331.1324
EnterpriseDB Corporation | fax: 732.331.1301
499 Thornall Street, 2nd Floor | jonah.harris@enterprisedb.com
Edison, NJ 08837 | http://www.enterprisedb.com/

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

[DOCS] triggers on views?

We had a doc comment come in noting that the second paragraph seems to be
incorrect on

http://www.postgresql.org/docs/8.3/interactive/rules-triggers.html,

specifically the part that says "On the other hand, a trigger that is fired
on INSERT on a view can do the same as a rule". I'm not sure if this is
supposed to just be taken as a conceptual argument, but it is confusing
because you can't put insert triggers on views... so just what is it getting
at? This exists in several versions back, not sure how folks feel about
updating existing versions, but seems like it could use some rewording...
thoughts?

--
Robert Treat
Build A Brighter LAMP :: Linux Apache {middleware} PostgreSQL

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

Re: [pgsql-es-ayuda] Hora del Servidor

2008/7/14 Alvaro Herrera <alvherre@commandprompt.com>:

> Puedes usar ALTER DATABASE o ALTER USER para cambiarla. Eso rige para
> todos quienes se conecten a esa base de datos, o para ese usuario todas
> las veces que se conecte, respectivamente.
>
>
> --
> Alvaro Herrera

http://www.CommandPrompt.com/
> The PostgreSQL Company - Command Prompt, Inc.
>

Excelente Alvaro!!! Funciono !!! Eso era lo que realmente estaba
buscando !!! Gracias!!!
Con esto cierro el hilo de esta duda.-
--
TIP 8: explain analyze es tu amigo

Re: [BUGS] BUG #4191: Include hint for Windows-like locals in documentation

Index: doc/src/sgml/charset.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v
retrieving revision 2.85
diff -c -c -r2.85 charset.sgml
*** doc/src/sgml/charset.sgml 6 Mar 2008 15:37:56 -0000 2.85
--- doc/src/sgml/charset.sgml 15 Jul 2008 01:15:44 -0000
***************
*** 65,79 ****
</para>

<para>
! This example sets the locale to Swedish (<literal>sv</>) as spoken
in Sweden (<literal>SE</>). Other possibilities might be
<literal>en_US</> (U.S. English) and <literal>fr_CA</> (French
Canadian). If more than one character set can be useful for a
locale then the specifications look like this:
<literal>cs_CZ.ISO8859-2</>. What locales are available under what
names on your system depends on what was provided by the operating
! system vendor and what was installed. (On most systems, the command
! <literal>locale -a</> will provide a list of available locales.)
</para>

<para>
--- 65,81 ----
</para>

<para>
! This example for Unix systems sets the locale to Swedish
! (<literal>sv</>) as spoken
in Sweden (<literal>SE</>). Other possibilities might be
<literal>en_US</> (U.S. English) and <literal>fr_CA</> (French
Canadian). If more than one character set can be useful for a
locale then the specifications look like this:
<literal>cs_CZ.ISO8859-2</>. What locales are available under what
names on your system depends on what was provided by the operating
! system vendor and what was installed. On most Unix systems, the command
! <literal>locale -a</> will provide a list of available locales.
! Windows uses more verbose names, such as <literal>German_Germany</>.
</para>

<para>
Martin Saschek wrote:
>
> The following bug has been logged online:
>
> Bug reference: 4191
> Logged by: Martin Saschek
> Email address: m.saschek@automationwr.de
> PostgreSQL version: 8.2.7; 8.3.1
> Operating system: Windows XP
> Description: Include hint for Windows-like locals in documentation
> Details:
>
> include a hint on the Windows-like encoding of locale settings in "Chapter
> 21. Localization".
>
> Only by chance and after several hours (!) I found out that on Windows I
> should use "German_Germany" rather than "de_DE".

Yep. I have improved the documentation with the attached patch.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

[COMMITTERS] pgsql: Clarify that locale names on Windows are more verbose.

Log Message:
-----------
Clarify that locale names on Windows are more verbose.

Report from Martin Saschek

Modified Files:
--------------
pgsql/doc/src/sgml:
charset.sgml (r2.85 -> r2.86)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/charset.sgml?r1=2.85&r2=2.86)

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

Re: [pgsql-es-ayuda] Hora del Servidor

Hugo César escribió:
> 2008/7/10 Alvaro Herrera <alvherre@commandprompt.com>:
>
> > No, una variable de Postgres (la misma que configuras en
> > postgresql.conf, pero esta vez la cambias directamente via la interfaz
> > SQL, y rige solamente para esa sesion).
>
> Y no hay una forma, manera, comando o algo que se le parezca para establecerla
> de manera global sin necesidad de modificar el archivo "Postgresql.conf" ?? Para
> evitar que solamente afecte a una sesion y sea mas dinamico ??

Puedes usar ALTER DATABASE o ALTER USER para cambiarla. Eso rige para
todos quienes se conecten a esa base de datos, o para ese usuario todas
las veces que se conecte, respectivamente.


--
Alvaro Herrera

http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
--
TIP 8: explain analyze es tu amigo

Re: [pgsql-es-ayuda] Hora del Servidor

2008/7/10 Alvaro Herrera <alvherre@commandprompt.com>:

> No, una variable de Postgres (la misma que configuras en
> postgresql.conf, pero esta vez la cambias directamente via la interfaz
> SQL, y rige solamente para esa sesion).
>

Y no hay una forma, manera, comando o algo que se le parezca para establecerla
de manera global sin necesidad de modificar el archivo "Postgresql.conf" ?? Para
evitar que solamente afecte a una sesion y sea mas dinamico ??

Gracias Miguel por tu aporte, en ocasiones es bueno salir de las dudas respecto
a nuestro idioma, en este caso con el "huso horario" jejejeje
--
TIP 8: explain analyze es tu amigo

Re: [SQL] Rollback in Postgres

Kaare Rasmussen <kaare@jasonic.dk> writes:
> But yes, it has to be enabled, and yes it has to have a performance cost
> somehow, but people are requesting it, and somehow I don't think Oracle
> developed the feature just for fun.

No, they developed it for marketing.

Keep in mind that Oracle has six thousand full-time developers and an
already extremely mature database. Stuff that they see fit to add is
not necessarily going to be on our radar screen in the foreseeable
future.

regards, tom lane

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

Re: [GENERAL] Cause of error message?

Bayless Kirtley wrote:
> An old app is giving a new error message. I query a table and make one
> update. Later I come back to query the table again and get this error:
>
> ERROR: current transaction is aborted, commands ignored until end of
> transaction block
>
> The error only occurs after I have made an update. As long as no
> updates, I can query multiple times. Can anyone give me an idea of
> what sort of actions or errors usually cause this error?
>
>
It means that you have an open transaction and the statement before you
get this message failed.

e.g.
postgres=# begin;
BEGIN
postgres=# update bob set abc=1;
ERROR: relation "bob" does not exist
postgres=# select version();
ERROR: current transaction is aborted, commands ignored until end of
transaction block
postgres=#

You need to find which statement failed first and fix it or rollback and
have your app deal with the failure. The postgres log is a good place
to start looking.

klint.

--
Klint Gore
Database Manager
Sheep CRC
A.G.B.U.
University of New England
Armidale NSW 2350

Ph: 02 6773 3789
Fax: 02 6773 3266
EMail: kgore4@une.edu.au


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

Re: [GENERAL] Cause of error message?

On Mon, 2008-07-14 at 19:44 -0500, Bayless Kirtley wrote:
> An old app is giving a new error message. I query a table and make one
> update. Later I come back to query the table again and get this error:
>
> ERROR: current transaction is aborted, commands ignored until end of
> transaction block
>
> The error only occurs after I have made an update. As long as no
> updates, I can query multiple times. Can anyone give me an idea of
> what sort of actions or errors usually cause this error?
>
> Thanks,
> Bayless
>

I believe that this might be caused by a syntax error. Do you have any
error handling code that might be hiding the error from you?

-Mark


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

Re: [pgus-board] [Fwd: US PostreSQL]

On Mon, 2008-07-14 at 10:57 -0400, Michael Alan Brewer wrote:
> I've modified the two .DOC files to include the revised terms for the
> initial board members (standing for re-election in '09, taking office
> in '10 [instead of '10/'11, respectively]) and the correct membership
> fees (and to correct one typo of a misspelled two-letter word and
> adding "of" before "financial institution [???] Oregon"). I did not
> define "student" in the document, figuring that we can do that via
> separate motion (and not necessarily be encoded specifically in the
> bylaws at this point). Let me know if I missed anything.

I think they look great and I approve, +1, now request that we get
consent unless someone has objections. I would like everyone to print,
sign (at notary) and return!

Thanks for your work on these Michael!

Joshua D. Drake

>
> ---Michael Brewer
> mbrewer@gmail.com
--
The PostgreSQL Company since 1997: http://www.commandprompt.com/

PostgreSQL Community Conference: http://www.postgresqlconference.org/
United States PostgreSQL Association: http://www.postgresql.us/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate


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

Re: [pgus-board] [Fwd: US PostreSQL]

On Mon, 2008-07-14 at 10:57 -0400, Michael Alan Brewer wrote:
> I've modified the two .DOC files to include the revised terms for the
> initial board members (standing for re-election in '09, taking office
> in '10 [instead of '10/'11, respectively]) and the correct membership
> fees (and to correct one typo of a misspelled two-letter word and
> adding "of" before "financial institution [???] Oregon"). I did not
> define "student" in the document, figuring that we can do that via
> separate motion (and not necessarily be encoded specifically in the
> bylaws at this point). Let me know if I missed anything.

Financial Institution is Sterling Savings Bank.

Joshua D. Drake

>
> ---Michael Brewer
> mbrewer@gmail.com
--
The PostgreSQL Company since 1997: http://www.commandprompt.com/

PostgreSQL Community Conference: http://www.postgresqlconference.org/
United States PostgreSQL Association: http://www.postgresql.us/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate


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

Re: [pgus-board] [Fwd: US PostreSQL]

On Mon, 2008-07-14 at 10:57 -0400, Michael Alan Brewer wrote:
> I've modified the two .DOC files to include the revised terms for the
> initial board members (standing for re-election in '09, taking office
> in '10 [instead of '10/'11, respectively]) and the correct membership
> fees (and to correct one typo of a misspelled two-letter word and
> adding "of" before "financial institution [???] Oregon"). I did not
> define "student" in the document, figuring that we can do that via
> separate motion (and not necessarily be encoded specifically in the
> bylaws at this point). Let me know if I missed anything.

Right I assumed you would submit a motion.

Joshua D. Drake

>
> ---Michael Brewer
> mbrewer@gmail.com
--
The PostgreSQL Company since 1997: http://www.commandprompt.com/

PostgreSQL Community Conference: http://www.postgresqlconference.org/
United States PostgreSQL Association: http://www.postgresql.us/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate


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

[GENERAL] Cause of error message?

An old app is giving a new error message. I query a table and make one update. Later I come back to query the table again and get this error:
 
ERROR: current transaction is aborted, commands ignored until end of transaction block
 
The error only occurs after I have made an update. As long as no updates, I can query multiple times. Can anyone give me an idea of what sort of actions or errors usually cause this error?
 
Thanks,
Bayless
 

Re: [HACKERS] Postgres-R source code release

On 15/07/2008, David E. Wheeler <david@kineticode.com> wrote:
> > > Of course, I am personally happy with SVN but hey :P
> >
> > You can't have tried a merge in SVN if that's so :P :P
>
> Those of us who have been doing it for years, in CVS and in SVN, aren't too
> worried about it.
>

Follow the sandal! :D

--
Please don't top post, and don't use HTML e-Mail :} Make your quotes concise.

http://www.american.edu/econ/notes/htmlmail.htm

--
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] Postgres-R source code release

On Jul 14, 2008, at 16:54, David Fetter wrote:

>> Of course, I am personally happy with SVN but hey :P
>
> You can't have tried a merge in SVN if that's so :P :P

Those of us who have been doing it for years, in CVS and in SVN,
aren't too worried about it.

Best,

David

--
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] Postgres-R source code release

On Mon, Jul 14, 2008 at 04:22:47PM -0700, Joshua D. Drake wrote:
> On Mon, 2008-07-14 at 14:41 -0700, David Fetter wrote:
> > On Mon, Jul 14, 2008 at 05:35:28PM -0400, Alvaro Herrera wrote:
> > > David Fetter wrote:
> > > > On Mon, Jul 14, 2008 at 05:42:21PM +0200, Markus Wanner wrote:
> > >
> > > > Would you mind if I were to make a git branch for it on
> > > > <http://git.postgresql.org/> ?
> > >
> > > That's very likely wasted effort, since obviously Markus has got
> > > a Monotone tree somewhere ...
> >
> > I'm curious as to your motive behind continual deriding any effort
> > to get git going on branches. Do you have some other alternative
> > in mind?
>
> Obviously monotone, but I think the point is, Git gives them nothing
> Monotone doesn't.

Apart from being able to interoperate with CVS, you mean? ;)

> Of course, I am personally happy with SVN but hey :P

You can't have tried a merge in SVN if that's so :P :P

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

--
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] Postgres-R source code release

On Mon, 2008-07-14 at 14:41 -0700, David Fetter wrote:
> On Mon, Jul 14, 2008 at 05:35:28PM -0400, Alvaro Herrera wrote:
> > David Fetter wrote:
> > > On Mon, Jul 14, 2008 at 05:42:21PM +0200, Markus Wanner wrote:
> >
> > > Would you mind if I were to make a git branch for it on
> > > <http://git.postgresql.org/> ?
> >
> > That's very likely wasted effort, since obviously Markus has got a
> > Monotone tree somewhere ...
>
> I'm curious as to your motive behind continual deriding any effort to
> get git going on branches. Do you have some other alternative in mind?

Obviously monotone, but I think the point is, Git gives them nothing
Monotone doesn't. Of course, I am personally happy with SVN but hey :P

Joshua D. Drake

--
The PostgreSQL Company since 1997: http://www.commandprompt.com/

PostgreSQL Community Conference: http://www.postgresqlconference.org/
United States PostgreSQL Association: http://www.postgresql.us/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate


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

Re: [pgsql-es-ayuda] Plan de ejecución de una consulta con OR

2008/7/14 Alvaro Herrera <alvherre@commandprompt.com>:
>
> Por otro lado supongo que si el subselect incluyera cosas como una funcion volátil, no podría
> hacerlo.
>

Desde la 8.2, IIRC, si ve una funcion volatil no hace ningun intento
de optimizar la subconsulta (al menos en lo referente a bajarla un
nivel o subirla un nivel)...

--
Atentamente,
Jaime Casanova
Soporte y capacitación de PostgreSQL
Guayaquil - Ecuador
Cel. (593) 87171157
--
TIP 7: no olvides aumentar la configuración del "free space map"

[COMMITTERS] pgsql: Add comment about literal strings in our syntax not being

Log Message:
-----------
Add comment about literal strings in our syntax not being translated in
psql.

Modified Files:
--------------
pgsql/src/bin/psql:
describe.c (r1.178 -> r1.179)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/bin/psql/describe.c?r1=1.178&r2=1.179)

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

Re: [PATCHES] \d+ should display the storage options for columns

Alvaro Herrera wrote:
> Bruce Momjian wrote:
>
> > Update patch applied; I also adjusted some translation function calls.
> > The new output of psql \d+ is:
> >
> > test=> \d+ test
> > Table "public.test"
> > Column | Type | Modifiers | Storage | Description
> > --------+---------+-----------+---------+-------------
> > x | integer | | plain |
> > Has OIDs: no
>
> Thanks for fixing the header problem.
>
> This patch introduces other strings, "plain", "main" and so on that are
> not gettext_noop()ed. Should we mark those for translation too? I
> admit I am not sure, if only because the untranslated strings are what
> gets passed to ALTER TABLE ... SET STORAGE. But if that's the
> decision, then it oughtta be commented in the code ...

I thought about that, but those strings are literal used in our syntax,
so translating them seemed wrong.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

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

Re: [PATCHES] [HACKERS] WITH RECURSIVE updated to CVS TIP

On Tue, Jul 08, 2008 at 06:01:05PM +0900, Tatsuo Ishii wrote:
> Here is the patches he made against CVS HEAD (as of today).
>
> According to him followings are fixed with the patches:
>
> - fix crush with DISTINCT
> - fix creating VIEW
> - fix the case when recursion plan has another recursion plan under it
> - fix WITH RECURSIVE ...(..) SELECT ...WHERE.. returns wrong result
> - fix inifinit recursion with OUTER JOIN

Great!

I've patched psql for some partial support of WITH [RECURSIVE].

http://git.postgresql.org/?p=~davidfetter/postgresql/.git;a=commit;h=da63f9a82b9e902b5542f788b2e6e6bc95221793

> Not yet fixed:
>
> - detect certain queries those are not valid acroding to the standard
> - sort query names acording to the dependency

Is there something in the standard on how to do this? How to sort the
nodes other ways?

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

--
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] Exposing quals

On Tue, Jul 08, 2008 at 02:41:45PM -0400, Jan Wieck wrote:
> Here,
>
> I talked to my supervisor here in Toronto (that's where I am this week)
> and Afilias actually sees enough value in this for me to go and spend
> time officially on it.

Yay!

> The ideas I have so far are as follows:
>
> Down in the exec nodes like SeqScan or IndexScan, there are several
> parts available that are important.
>
> - Scanned relation
> - Targetlist
> - Filter (for SeqScan)
> - IndexQual (for IndexScan)
>
> These pieces are available at least in the scans Init function and
> actually can be converted back into some SQL statement that effectively
> represents this one single table scan. However, parsing it back at that
> point is nonsense, as we cannot expect everything out there to actually
> be an SQL database.
>
> Also, both the qualification as well as the targetlist can contain
> things like user defined function calls. We neither want to deny nor
> require that this sort of construct is actually handed over to the
> external data source, so the interface needs to be more flexible.
> Therefore it is best to divide the functionality into several user exit
> functions.

Right :)

> The several functions that implement a scan type inside of the
> executor very much resemble opening a cursor for a single table
> query, fetching rows from it, eventually (in the case of a nested
> loop for example) close and reopen the cursor with different key
> values from the outer tuple, close the cursor. So it makes total
> sense to actually require an implementation of an external data
> source to provide functions to open a cursor, fetch rows, close the
> cursor.

That's not unreasonable, given that the simplest kind of external data
source would likely be along the lines of fopen().

> There will be some connection and transaction handling around all
> this that I have in mind but think it would distract from the
> problem to be solved right here, so more about that another time.

Maybe something like a way of setting, for each relation, what kind
(if any) of transactions are available?

> The C implementation for open cursor would be called with a scan
> handle, containing the connection, the relname, the targetlist and
> the qualification subtrees. These are modified from the real ones
> in the scan node so that all Var's have varno=1 and that all OUTER
> Var's have been replaced with a Const that reflects the current
> outer tuples values. From here there are several support functions
> available to "dumb down" each of those to whatever the external
> data source may support. In case of the targetlist, this could mean
> to filter out a unique list of Var nodes only, removing all
> expressions from it. In case of the qualification, this could mean
> remove everything that isn't a standard operator (=, <>, ...), or
> remove everything that isn't Postgres builtin. Finally, there is a
> support function that will build a SQL statement according to
> what's left inside that scan handle.

Interesting.

> The scan handle would track which modifications have been done to the
> various pieces so that the outer support framework knows if it gets back
> the originally requested targetlist, or if it has to run the projection
> on the returned unique list of Var's. And if it has to recheck the
> returned tuples for qualification, because some of the qual's had been
> removed.
>
> In order to allow the user exits to be written in PL's, I can think of
> makiing a complex data type containing the scan handle. The subtrees
> could be accessed by the PL via support functions that return them in
> nodeToString() or other formats.
>
> I'll try to write up a more complete proposal until end of next week.

Yay!

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

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

[COMMITTERS] pgsql: Add to TODO: > * Improve ability to modify views via ALTER TABLE

Log Message:
-----------
Add to TODO:

> * Improve ability to modify views via ALTER TABLE
>
>

http://archives.postgresql.org/pgsql-hackers/2008-05/msg00691.php

Modified Files:
--------------
pgsql/doc:
TODO (r1.2484 -> r1.2485)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/TODO?r1=1.2484&r2=1.2485)
pgsql/doc/src/FAQ:
TODO.html (r1.990 -> r1.991)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/FAQ/TODO.html?r1=1.990&r2=1.991)

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

Re: [PATCHES] \d+ should display the storage options for columns

Bruce Momjian wrote:

> Update patch applied; I also adjusted some translation function calls.
> The new output of psql \d+ is:
>
> test=> \d+ test
> Table "public.test"
> Column | Type | Modifiers | Storage | Description
> --------+---------+-----------+---------+-------------
> x | integer | | plain |
> Has OIDs: no

Thanks for fixing the header problem.

This patch introduces other strings, "plain", "main" and so on that are
not gettext_noop()ed. Should we mark those for translation too? I
admit I am not sure, if only because the untranslated strings are what
gets passed to ALTER TABLE ... SET STORAGE. But if that's the
decision, then it oughtta be commented in the code ...

--
Alvaro Herrera

http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

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

Re: [HACKERS] idea: storing view source in system catalogs

Added to TODO:

* Improve ability to modify views via ALTER TABLE

http://archives.postgresql.org/pgsql-hackers/2008-05/msg00691.php


---------------------------------------------------------------------------

Robert Haas wrote:
> I think the real problem here is that PostgreSQL is very finicky about
> what operations you can perform on a view. If I have a table foo and
> I define a view bar that uses foo and a view baz that uses bar, I can
> add a column to foo without a problem, and, similarly, I can also drop
> or alter a column in foo that is not used by bar. But the same is not
> true of bar. I can't make any changes at all to bar without dropping
> and recreating it, and that means I have to drop and recreate baz as
> well. If there are only two views involved, this is not so bad, but
> frequently there are a whole slough of views baz1, baz2, ..., bazn
> that all depend on bar, and I have to drop and recreate every single
> one of them.
>
> I could understand the need to do this if I were (for example)
> changing the type of some column that was used by all of these views,
> but that's usually not the case. Normally I'm just adding new columns
> to foo and bar, and none of the other views are changing... but they
> have to be recreated anyway.
>
> As a side note, handling this problem gracefully would go a long way
> to solving the original poster's concern about *-expansion. If
> updating to the latest version of "*" just required re-executing
> CREATE OR REPLACE VIEW ..., it would be relatively simple. As things
> stand now, it requires DROP VIEW ... CASCADE; CREATE OR REPLACE VIEW
> ...; followed by recreating all of the dependent objects.
>
> ...Robert
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

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

Re: [PATCHES] \d+ should display the storage options for columns

Index: src/bin/psql/describe.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.177
diff -c -c -r1.177 describe.c
*** src/bin/psql/describe.c 14 Jul 2008 22:00:04 -0000 1.177
--- src/bin/psql/describe.c 14 Jul 2008 22:50:32 -0000
***************
*** 811,817 ****
printTableContent cont;
int i;
char *view_def = NULL;
! char *headers[4];
char **modifiers = NULL;
char **ptr;
PQExpBufferData title;
--- 811,817 ----
printTableContent cont;
int i;
char *view_def = NULL;
! char *headers[5];
char **modifiers = NULL;
char **ptr;
PQExpBufferData title;
***************
*** 878,884 ****
"\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
"\n a.attnotnull, a.attnum");
if (verbose)
! appendPQExpBuffer(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum)");
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_attribute a");
if (tableinfo.relkind == 'i')
appendPQExpBuffer(&buf, ", pg_catalog.pg_index i");
--- 878,884 ----
"\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
"\n a.attnotnull, a.attnum");
if (verbose)
! appendPQExpBuffer(&buf, ", a.attstorage, pg_catalog.col_description(a.attrelid, a.attnum)");
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_attribute a");
if (tableinfo.relkind == 'i')
appendPQExpBuffer(&buf, ", pg_catalog.pg_index i");
***************
*** 933,951 ****

/* Set the number of columns, and their names */
cols = 2;
! headers[0] = "Column";
! headers[1] = "Type";

if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v')
{
show_modifiers = true;
! headers[cols++] = "Modifiers";
modifiers = pg_malloc_zero((numrows + 1) * sizeof(*modifiers));
}

if (verbose)
! headers[cols++] = "Description";
!
printTableInit(&cont, &myopt, title.data, cols, numrows);

for (i = 0; i < cols; i++)
--- 933,954 ----

/* Set the number of columns, and their names */
cols = 2;
! headers[0] = gettext_noop("Column");
! headers[1] = gettext_noop("Type");

if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v')
{
show_modifiers = true;
! headers[cols++] = gettext_noop("Modifiers");
modifiers = pg_malloc_zero((numrows + 1) * sizeof(*modifiers));
}

if (verbose)
! {
! headers[cols++] = gettext_noop("Storage");
! headers[cols++] = gettext_noop("Description");
! }
!
printTableInit(&cont, &myopt, title.data, cols, numrows);

for (i = 0; i < cols; i++)
***************
*** 1000,1008 ****
printTableAddCell(&cont, modifiers[i], false);
}

! /* Description */
if (verbose)
! printTableAddCell(&cont, PQgetvalue(res, i, 5), false);
}

/* Make footers */
--- 1003,1020 ----
printTableAddCell(&cont, modifiers[i], false);
}

! /* Storage and Description */
if (verbose)
! {
! char *storage = PQgetvalue(res, i, 5);
! printTableAddCell(&cont, (storage[0]=='p' ? "plain" :
! (storage[0]=='m' ? "main" :
! (storage[0]=='x' ? "extended" :
! (storage[0]=='e' ? "external" :
! "???")))),
! false);
! printTableAddCell(&cont, PQgetvalue(res, i, 6), false);
! }
}

/* Make footers */
Gregory Stark wrote:
> "Alvaro Herrera" <alvherre@commandprompt.com> writes:
>
> > This seems to be against an older version of psql ... with the
> > printTable API stuff, we reworked this -- in particular the mbvalidate()
> > call that's only on WIN32 is gone (actually it's the lack of it that's
> > gone.)
>
> Sorry. Here's a patch against a current sync of HEAD.
>
> Incidentally how can this new API work? Calling _() on a function parameter
> would work but how would the translation tools know what strings need to be
> translated?

Update patch applied; I also adjusted some translation function calls.
The new output of psql \d+ is:

test=> \d+ test
Table "public.test"
Column | Type | Modifiers | Storage | Description
--------+---------+-----------+---------+-------------
x | integer | | plain |
Has OIDs: no

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

[COMMITTERS] pgsql: Add column storage type to psql \d+ display.

Log Message:
-----------
Add column storage type to psql \d+ display.

Gregory Stark

Modified Files:
--------------
pgsql/src/bin/psql:
describe.c (r1.177 -> r1.178)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/bin/psql/describe.c?r1=1.177&r2=1.178)

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

Re: [PATCHES] variadic function support

*** ./doc/src/sgml/ref/create_function.sgml.orig 2008-07-14 09:11:54.000000000 +0200
--- ./doc/src/sgml/ref/create_function.sgml 2008-07-14 09:14:37.000000000 +0200
***************
*** 102,108 ****
<listitem>
<para>
The mode of an argument: either <literal>IN</>, <literal>OUT</>,
! or <literal>INOUT</>. If omitted, the default is <literal>IN</>.
</para>
</listitem>
</varlistentry>
--- 102,109 ----
<listitem>
<para>
The mode of an argument: either <literal>IN</>, <literal>OUT</>,
! <literal>INOUT</> or <literal>VARIADIC</literal>. If omitted,
! the default is <literal>IN</>.
</para>
</listitem>
</varlistentry>
*** ./doc/src/sgml/xfunc.sgml.orig 2008-07-14 09:12:00.000000000 +0200
--- ./doc/src/sgml/xfunc.sgml 2008-07-14 09:14:37.000000000 +0200
***************
*** 578,584 ****

<para>
Parameters can be marked as <literal>IN</> (the default),
! <literal>OUT</>, or <literal>INOUT</>. An <literal>INOUT</>
parameter serves as both an input parameter (part of the calling
argument list) and an output parameter (part of the result record type).
</para>
--- 578,585 ----

<para>
Parameters can be marked as <literal>IN</> (the default),
! <literal>OUT</>, <literal>INOUT</>, or <literal>VARIADIC</literal>.
! An <literal>INOUT</>
parameter serves as both an input parameter (part of the calling
argument list) and an output parameter (part of the result record type).
</para>
***************
*** 805,810 ****
--- 806,833 ----
</screen>
</para>
</sect2>
+
+ <sect2>
+ <title>Variadic <acronym>SQL</acronym> Functions</title>
+
+ <para>
+ <acronym>SQL</acronym> functions can be declared to accept
+ variable number of arguments.
+ <screen>
+ CREATE FUNCTION mleast(variadic numeric[]) RETURNS numeric AS $$
+ SELECT min($1[i])
+ FROM generate_subscripts($1,1) g(i);
+ $$ LANGUAGE SQL;
+
+ SELECT mleast(10, -1, 5, 4);
+ mleast
+ --------
+ -1
+ (1 row)
+ </screen>
+ </para>
+ </sect2>
+
</sect1>

<sect1 id="xfunc-overload">
*** ./src/backend/catalog/namespace.c.orig 2008-07-14 09:12:08.000000000 +0200
--- ./src/backend/catalog/namespace.c 2008-07-14 14:58:31.000000000 +0200
***************
*** 38,43 ****
--- 38,44 ----
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
+ #include "parser/parse_func.h"
#include "storage/backendid.h"
#include "storage/ipc.h"
#include "utils/acl.h"
***************
*** 570,576 ****
* identical entries in later namespaces.
*/
FuncCandidateList
! FuncnameGetCandidates(List *names, int nargs)
{
FuncCandidateList resultList = NULL;
char *schemaname;
--- 571,577 ----
* identical entries in later namespaces.
*/
FuncCandidateList
! FuncnameGetCandidates(List *names, int nargs, bool transform_variadic)
{
FuncCandidateList resultList = NULL;
char *schemaname;
***************
*** 606,614 ****
int pronargs = procform->pronargs;
int pathpos = 0;
FuncCandidateList newResult;

/* Ignore if it doesn't match requested argument count */
! if (nargs >= 0 && pronargs != nargs)
continue;

if (OidIsValid(namespaceId))
--- 607,656 ----
int pronargs = procform->pronargs;
int pathpos = 0;
FuncCandidateList newResult;
+ Oid va_oid = InvalidOid;
+ bool variadic = false; /* true when arglist contains PROARGMODE_VARIADIC parameter */
+ bool isnull;
+ Datum proargmodes;
+
+ /*
+ * Search type of variadic argument,
+ */
+ proargmodes = SysCacheGetAttr(PROCOID, proctup,
+ Anum_pg_proc_proargmodes, &isnull);
+ if (!isnull)
+ {
+ ArrayType *ar = DatumGetArrayTypeP(proargmodes);
+ char *argmodes;
+ int j;
+
+ argmodes = ARR_DATA_PTR(ar);
+ for (j = 0; j < ARR_DIMS(ar)[0]; j++)
+ if (argmodes[j] == PROARGMODE_VARIADIC)
+ {
+ variadic = true;
+ switch (procform->proargtypes.values[j])
+ {
+ case ANYOID:
+ va_oid = ANYOID;
+ break;
+ case ANYARRAYOID:
+ va_oid = ANYELEMENTOID;
+ break;
+ default:
+ va_oid = get_element_type(procform->proargtypes.values[j]);
+ Assert(OidIsValid(va_oid));
+ }
+
+ break;
+ }
+ }

/* Ignore if it doesn't match requested argument count */
! if (nargs >= 0 && pronargs != nargs && !variadic)
! continue;
!
! /* Ignore variadic function with less arguments */
! if (nargs >= 0 && pronargs > nargs && variadic)
continue;

if (OidIsValid(namespaceId))
***************
*** 676,683 ****
}
if (prevResult)
{
! /* We have a match with a previous result */
! Assert(pathpos != prevResult->pathpos);
if (pathpos > prevResult->pathpos)
continue; /* keep previous result */
/* replace previous result */
--- 718,734 ----
}
if (prevResult)
{
! /*
! * We have a match with a previous result. Variadic functions should
! * be not unique - foo(numeric), foo(variadic numeric[]).
! */
! if (pathpos == prevResult->pathpos)
! ereport(ERROR,
! (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! errmsg("function %s is not unique",
! func_signature_string(names, nargs,
! procform->proargtypes.values))));
!
if (pathpos > prevResult->pathpos)
continue; /* keep previous result */
/* replace previous result */
***************
*** 689,706 ****
}

/*
! * Okay to add it to result list
*/
! newResult = (FuncCandidateList)
! palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
! + pronargs * sizeof(Oid));
newResult->pathpos = pathpos;
newResult->oid = HeapTupleGetOid(proctup);
- newResult->nargs = pronargs;
- memcpy(newResult->args, procform->proargtypes.values,
- pronargs * sizeof(Oid));
-
newResult->next = resultList;
resultList = newResult;
}

--- 740,784 ----
}

/*
! * Okay to add it to result list - VARIADIC parameter isn't transformed when
! * we would show and work with function signature, etc pg_function_is_visible,
! * DROP FUNCTION (transform_variadic = false).
*/
! if (variadic && transform_variadic)
! {
! int i;
!
! Assert(nargs >= pronargs);
!
! newResult = (FuncCandidateList)
! palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
! + nargs * sizeof(Oid));
! newResult->nargs = nargs;
! newResult->nvargs = nargs - pronargs + 1;
! newResult->variadic_oid = va_oid;
! memcpy(newResult->args, procform->proargtypes.values,
! (pronargs - 1) * sizeof(Oid));
!
! /* Multiply variadic argument */
! for (i = pronargs - 1; i < nargs; i++)
! newResult->args[i] = va_oid;
! }
! else
! {
! newResult = (FuncCandidateList)
! palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
! + pronargs * sizeof(Oid));
! newResult->nargs = pronargs;
! newResult->nvargs = 0;
! newResult->variadic_oid = 0;
! memcpy(newResult->args, procform->proargtypes.values,
! pronargs * sizeof(Oid));
! }
!
newResult->pathpos = pathpos;
newResult->oid = HeapTupleGetOid(proctup);
newResult->next = resultList;
+
resultList = newResult;
}

***************
*** 755,761 ****

visible = false;

! clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs);

for (; clist; clist = clist->next)
{
--- 833,839 ----

visible = false;

! clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs, false);

for (; clist; clist = clist->next)
{
*** ./src/backend/catalog/pg_aggregate.c.orig 2008-07-14 09:12:15.000000000 +0200
--- ./src/backend/catalog/pg_aggregate.c 2008-07-14 13:10:59.000000000 +0200
***************
*** 297,302 ****
--- 297,304 ----
FuncDetailCode fdresult;
AclResult aclresult;
int i;
+ int nvargs;
+ Oid va_oid;

/*
* func_get_detail looks up the function in the catalogs, does
***************
*** 307,313 ****
*/
fdresult = func_get_detail(fnName, NIL, nargs, input_types,
&fnOid, rettype, &retset,
! &true_oid_array);

/* only valid case is a normal function not returning a set */
if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
--- 309,316 ----
*/
fdresult = func_get_detail(fnName, NIL, nargs, input_types,
&fnOid, rettype, &retset,
! &true_oid_array,
! &nvargs, &va_oid);

/* only valid case is a normal function not returning a set */
if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
***************
*** 321,326 ****
--- 324,334 ----
errmsg("function %s returns a set",
func_signature_string(fnName, nargs, input_types))));

+ if (nvargs > 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("variadic parameters not supported for aggregate functions")));
+
/*
* If there are any polymorphic types involved, enforce consistency, and
* possibly refine the result type. It's OK if the result is still
*** ./src/backend/commands/functioncmds.c.orig 2008-07-12 12:44:56.000000000 +0200
--- ./src/backend/commands/functioncmds.c 2008-07-14 14:10:18.000000000 +0200
***************
*** 174,179 ****
--- 174,180 ----
Datum *paramNames;
int outCount = 0;
bool have_names = false;
+ int varCount = 0;
ListCell *x;
int i;

***************
*** 228,242 ****
errmsg("functions cannot accept set arguments")));

if (fp->mode != FUNC_PARAM_OUT)
inTypes[inCount++] = toid;

! if (fp->mode != FUNC_PARAM_IN)
{
if (outCount == 0) /* save first OUT param's type */
*requiredResultType = toid;
outCount++;
}

allTypes[i] = ObjectIdGetDatum(toid);

paramModes[i] = CharGetDatum(fp->mode);
--- 229,271 ----
errmsg("functions cannot accept set arguments")));

if (fp->mode != FUNC_PARAM_OUT)
+ {
inTypes[inCount++] = toid;
+ /* check if variadic argument is last IN argument */
+ if (varCount > 0 && fp->mode != FUNC_PARAM_OUT)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+ errmsg("variadic parameter must be the last parameter to the function")));
+ }

! if (fp->mode != FUNC_PARAM_IN && fp->mode != FUNC_PARAM_VARIADIC)
{
if (outCount == 0) /* save first OUT param's type */
*requiredResultType = toid;
outCount++;
}

+ if (fp->mode == FUNC_PARAM_VARIADIC)
+ {
+ if (varCount++ > 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+ errmsg("function cannot accept two or more variadic parameters")));
+
+ /* check variadic parameter type */
+ switch (toid)
+ {
+ case ANYARRAYOID:
+ case ANYOID:
+ break;
+ default:
+ if (!OidIsValid(get_element_type(toid)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+ errmsg("variadic parameter must be an array")));
+ }
+ }
+
allTypes[i] = ObjectIdGetDatum(toid);

paramModes[i] = CharGetDatum(fp->mode);
***************
*** 253,259 ****
/* Now construct the proper outputs as needed */
*parameterTypes = buildoidvector(inTypes, inCount);

! if (outCount > 0)
{
*allParameterTypes = construct_array(allTypes, parameterCount, OIDOID,
sizeof(Oid), true, 'i');
--- 282,288 ----
/* Now construct the proper outputs as needed */
*parameterTypes = buildoidvector(inTypes, inCount);

! if (outCount > 0 || varCount > 0)
{
*allParameterTypes = construct_array(allTypes, parameterCount, OIDOID,
sizeof(Oid), true, 'i');
*** ./src/backend/nodes/copyfuncs.c.orig 2008-07-14 21:43:28.000000000 +0200
--- ./src/backend/nodes/copyfuncs.c 2008-07-14 21:49:49.000000000 +0200
***************
*** 1652,1657 ****
--- 1652,1658 ----
COPY_SCALAR_FIELD(agg_star);
COPY_SCALAR_FIELD(agg_distinct);
COPY_SCALAR_FIELD(location);
+ COPY_SCALAR_FIELD(variadic_expr);

return newnode;
}
*** ./src/backend/nodes/equalfuncs.c.orig 2008-07-14 21:43:43.000000000 +0200
--- ./src/backend/nodes/equalfuncs.c 2008-07-14 21:49:57.000000000 +0200
***************
*** 1706,1711 ****
--- 1706,1712 ----
COMPARE_SCALAR_FIELD(agg_star);
COMPARE_SCALAR_FIELD(agg_distinct);
COMPARE_SCALAR_FIELD(location);
+ COMPARE_SCALAR_FIELD(variadic_expr);

return true;
}
*** ./src/backend/nodes/outfuncs.c.orig 2008-07-14 21:44:16.000000000 +0200
--- ./src/backend/nodes/outfuncs.c 2008-07-14 21:54:37.000000000 +0200
***************
*** 1611,1616 ****
--- 1611,1617 ----
WRITE_BOOL_FIELD(agg_star);
WRITE_BOOL_FIELD(agg_distinct);
WRITE_INT_FIELD(location);
+ WRITE_NODE_FIELD(variadic_expr);
}

static void
*** ./src/backend/parser/gram.y.orig 2008-07-14 09:12:28.000000000 +0200
--- ./src/backend/parser/gram.y 2008-07-14 22:14:22.000000000 +0200
***************
*** 444,450 ****
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USER USING

! VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
VERBOSE VERSION_P VIEW VOLATILE

WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
--- 444,450 ----
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USER USING

! VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
VERBOSE VERSION_P VIEW VOLATILE

WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
***************
*** 4204,4209 ****
--- 4204,4210 ----
| OUT_P { $$ = FUNC_PARAM_OUT; }
| INOUT { $$ = FUNC_PARAM_INOUT; }
| IN_P OUT_P { $$ = FUNC_PARAM_INOUT; }
+ | VARIADIC { $$ = FUNC_PARAM_VARIADIC; }
;

/*
***************
*** 7863,7868 ****
--- 7864,7870 ----
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->location = @1;
+ n->variadic_expr = NULL;
$$ = (Node *)n;
}
| func_name '(' expr_list ')'
***************
*** 7873,7878 ****
--- 7875,7903 ----
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->location = @1;
+ n->variadic_expr = NULL;
+ $$ = (Node *)n;
+ }
+ | func_name '(' VARIADIC a_expr ')'
+ {
+ FuncCall *n = makeNode(FuncCall);
+ n->funcname = $1;
+ n->args = NIL;
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ n->location = @1;
+ n->variadic_expr = $4;
+ $$ = (Node *)n;
+ }
+ | func_name '(' expr_list VARIADIC a_expr ')'
+ {
+ FuncCall *n = makeNode(FuncCall);
+ n->funcname = $1;
+ n->args = $3;
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ n->location = @1;
+ n->variadic_expr = $5;
$$ = (Node *)n;
}
| func_name '(' ALL expr_list ')'
***************
*** 7887,7892 ****
--- 7912,7918 ----
* for that in FuncCall at the moment.
*/
n->location = @1;
+ n->variadic_expr = NULL;
$$ = (Node *)n;
}
| func_name '(' DISTINCT expr_list ')'
***************
*** 7897,7902 ****
--- 7923,7929 ----
n->agg_star = FALSE;
n->agg_distinct = TRUE;
n->location = @1;
+ n->variadic_expr = NULL;
$$ = (Node *)n;
}
| func_name '(' '*' ')'
***************
*** 7917,7922 ****
--- 7944,7950 ----
n->agg_star = TRUE;
n->agg_distinct = FALSE;
n->location = @1;
+ n->variadic_expr = NULL;
$$ = (Node *)n;
}
| CURRENT_DATE
*** ./src/backend/parser/keywords.c.orig 2008-07-14 09:12:34.000000000 +0200
--- ./src/backend/parser/keywords.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 393,398 ****
--- 393,399 ----
{"value", VALUE_P, UNRESERVED_KEYWORD},
{"values", VALUES, COL_NAME_KEYWORD},
{"varchar", VARCHAR, COL_NAME_KEYWORD},
+ {"variadic", VARIADIC, UNRESERVED_KEYWORD},
{"varying", VARYING, UNRESERVED_KEYWORD},
{"verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD},
{"version", VERSION_P, UNRESERVED_KEYWORD},
*** ./src/backend/parser/parse_expr.c.orig 2008-07-14 22:17:06.000000000 +0200
--- ./src/backend/parser/parse_expr.c 2008-07-14 23:01:35.000000000 +0200
***************
*** 359,365 ****
list_make1(n),
list_make1(result),
false, false, true,
! -1);
}
}
/* process trailing subscripts, if any */
--- 359,365 ----
list_make1(n),
list_make1(result),
false, false, true,
! -1, NULL);
}
}
/* process trailing subscripts, if any */
***************
*** 482,488 ****
list_make1(makeString(name2)),
list_make1(node),
false, false, true,
! cref->location);
}
break;
}
--- 482,489 ----
list_make1(makeString(name2)),
list_make1(node),
false, false, true,
! cref->location,
! NULL);
}
break;
}
***************
*** 512,518 ****
list_make1(makeString(name3)),
list_make1(node),
false, false, true,
! cref->location);
}
break;
}
--- 513,520 ----
list_make1(makeString(name3)),
list_make1(node),
false, false, true,
! cref->location,
! NULL);
}
break;
}
***************
*** 553,559 ****
list_make1(makeString(name4)),
list_make1(node),
false, false, true,
! cref->location);
}
break;
}
--- 555,562 ----
list_make1(makeString(name4)),
list_make1(node),
false, false, true,
! cref->location,
! NULL);
}
break;
}
***************
*** 1017,1022 ****
--- 1020,1026 ----
{
List *targs;
ListCell *args;
+ Node *variadic_expr;

/*
* Transform the list of arguments. We use a shallow list copy and then
***************
*** 1031,1036 ****
--- 1035,1042 ----
lfirst(args) = transformExpr(pstate,
(Node *) lfirst(args));
}
+
+ variadic_expr = transformExpr(pstate, fn->variadic_expr);

return ParseFuncOrColumn(pstate,
fn->funcname,
***************
*** 1038,1044 ****
fn->agg_star,
fn->agg_distinct,
false,
! fn->location);
}

static Node *
--- 1044,1051 ----
fn->agg_star,
fn->agg_distinct,
false,
! fn->location,
! variadic_expr);
}

static Node *
*** ./src/backend/parser/parse_func.c.orig 2008-07-14 09:12:41.000000000 +0200
--- ./src/backend/parser/parse_func.c 2008-07-14 23:54:45.000000000 +0200
***************
*** 63,69 ****
Node *
ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
bool agg_star, bool agg_distinct, bool is_column,
! int location)
{
Oid rettype;
Oid funcid;
--- 63,69 ----
Node *
ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
bool agg_star, bool agg_distinct, bool is_column,
! int location, Node *variadic_expr)
{
Oid rettype;
Oid funcid;
***************
*** 76,81 ****
--- 76,83 ----
Node *retval;
bool retset;
FuncDetailCode fdresult;
+ int nvargs;
+ Oid va_oid;

/*
* Most of the rest of the parser just assumes that functions do not have
***************
*** 83,89 ****
* against array overruns, etc. Of course, this may not be a function,
* but the test doesn't hurt.
*/
! if (list_length(fargs) > FUNC_MAX_ARGS)
ereport(ERROR,
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("cannot pass more than %d arguments to a function",
--- 85,91 ----
* against array overruns, etc. Of course, this may not be a function,
* but the test doesn't hurt.
*/
! if (list_length(fargs) + (variadic_expr != 0 ? 1:0) > FUNC_MAX_ARGS)
ereport(ERROR,
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("cannot pass more than %d arguments to a function",
***************
*** 139,145 ****
--- 141,152 ----
first_arg,
location);
if (retval)
+ {
+ if (variadic_expr)
+ elog(ERROR, "column projection must not have variadic parameter");
+
return retval;
+ }

/*
* If ParseComplexProjection doesn't recognize it as a projection,
***************
*** 149,154 ****
--- 156,177 ----
}

/*
+ * Magic with variadic_expr
+ *
+ */
+ if (variadic_expr != NULL)
+ {
+ Oid va_el_oid = get_element_type(exprType(variadic_expr));
+
+ if (!OidIsValid(va_el_oid))
+ elog(ERROR, "variadic parameter must be an array");
+
+ /* For this moment I emulate one variadic argument. */
+ actual_arg_types[nargs++] = va_el_oid;
+ }
+
+
+ /*
* Okay, it's not a column projection, so it must really be a function.
* func_get_detail looks up the function in the catalogs, does
* disambiguation for polymorphic functions, handles inheritance, and
***************
*** 158,164 ****
*/
fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types,
&funcid, &rettype, &retset,
! &declared_arg_types);
if (fdresult == FUNCDETAIL_COERCION)
{
/*
--- 181,188 ----
*/
fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types,
&funcid, &rettype, &retset,
! &declared_arg_types,
! &nvargs, &va_oid);
if (fdresult == FUNCDETAIL_COERCION)
{
/*
***************
*** 229,234 ****
--- 253,337 ----
}

/*
+ * variadic_expr implicates variadic_function, check it!
+ */
+ if (variadic_expr != NULL)
+ {
+ if (nvargs == 0)
+ elog(ERROR, "using variadic call on non variadic function");
+
+ /*
+ * Executor hasn't enough information for unpacking
+ * variadic call arguments into variadic argumenents.
+ * So I have to prohibit this call.
+ */
+ if (va_oid == ANYOID)
+ elog(ERROR, "cannot unpack variadic call arguments to variadic any arguments");
+ }
+
+ /*
+ * Last nvargs arguments are transformed to array when function is
+ * non "any" variadic.
+ */
+ if (nvargs > 0 && va_oid != ANYOID)
+ {
+ A_ArrayExpr *n = makeNode(A_ArrayExpr);
+ Node *tn;
+
+ /*
+ * without variadic call argument transform
+ * arguments into variadic array parameter
+ */
+ if (nvargs < nargs)
+ {
+ if (variadic_expr == NULL)
+ {
+ int non_var_args = nargs - nvargs;
+ List *vargs;
+
+ vargs = list_copy_tail(fargs, non_var_args);
+ fargs = list_truncate(fargs, non_var_args);
+ n->elements = vargs;
+ tn = transformExpr(pstate, (Node *) n);
+ fargs = lappend(fargs, tn);
+ }
+ else
+ /* attach variadic call argument */
+ fargs = lappend(fargs, variadic_expr);
+ }
+ else
+ {
+ if (variadic_expr == NULL)
+ {
+ /* array from all arguments */
+ n->elements = fargs;
+ tn= transformExpr(pstate, (Node *) n);
+ fargs = list_make1(tn);
+ }
+ else
+ /* forward variadic call argument */
+ fargs = list_make1(variadic_expr);
+ }
+
+ /*
+ * Now we have to correct argument's metadata used in
+ * enforce_generic_type_consistency and make_fn_arguments. These
+ * functions needs actual values of nargs, actual_arg_types and
+ * real_arg_types.
+ */
+ nargs = nargs - nvargs + 1;
+ if (variadic_expr == NULL)
+ actual_arg_types[nargs - 1] = ((ArrayExpr *) tn)->array_typeid;
+ else
+ actual_arg_types[nargs - 1] = exprType(variadic_expr);
+
+ if (va_oid != ANYELEMENTOID)
+ declared_arg_types[nargs - 1] = get_array_type(va_oid);
+ else
+ declared_arg_types[nargs - 1] = ANYARRAYOID;
+ }
+
+ /*
* enforce consistency with polymorphic argument and return types,
* possibly adjusting return type or declared_arg_types (which will be
* used as the cast destination by make_fn_arguments)
***************
*** 697,709 ****
Oid *funcid, /* return value */
Oid *rettype, /* return value */
bool *retset, /* return value */
! Oid **true_typeids) /* return value */
{
FuncCandidateList raw_candidates;
FuncCandidateList best_candidate;

/* Get list of possible candidates from namespace search */
! raw_candidates = FuncnameGetCandidates(funcname, nargs);

/*
* Quickly check if there is an exact match to the input datatypes (there
--- 800,814 ----
Oid *funcid, /* return value */
Oid *rettype, /* return value */
bool *retset, /* return value */
! Oid **true_typeids, /* return value */
! int *nvargs, /* return value */
! Oid *va_oid) /* return value */
{
FuncCandidateList raw_candidates;
FuncCandidateList best_candidate;

/* Get list of possible candidates from namespace search */
! raw_candidates = FuncnameGetCandidates(funcname, nargs, true);

/*
* Quickly check if there is an exact match to the input datatypes (there
***************
*** 787,792 ****
--- 892,899 ----
*rettype = targetType;
*retset = false;
*true_typeids = argtypes;
+ *nvargs = 0;
+ *va_oid = InvalidOid;
return FUNCDETAIL_COERCION;
}
}
***************
*** 836,841 ****
--- 943,950 ----

*funcid = best_candidate->oid;
*true_typeids = best_candidate->args;
+ *nvargs = best_candidate->nvargs;
+ *va_oid = best_candidate->variadic_oid;

ftup = SearchSysCache(PROCOID,
ObjectIdGetDatum(best_candidate->oid),
***************
*** 1189,1195 ****
{
FuncCandidateList clist;

! clist = FuncnameGetCandidates(funcname, nargs);

while (clist)
{
--- 1298,1304 ----
{
FuncCandidateList clist;

! clist = FuncnameGetCandidates(funcname, nargs, false);

while (clist)
{
*** ./src/backend/utils/adt/regproc.c.orig 2008-07-14 09:12:47.000000000 +0200
--- ./src/backend/utils/adt/regproc.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 131,137 ****
* pg_proc entries in the current search path.
*/
names = stringToQualifiedNameList(pro_name_or_oid);
! clist = FuncnameGetCandidates(names, -1);

if (clist == NULL)
ereport(ERROR,
--- 131,137 ----
* pg_proc entries in the current search path.
*/
names = stringToQualifiedNameList(pro_name_or_oid);
! clist = FuncnameGetCandidates(names, -1, false);

if (clist == NULL)
ereport(ERROR,
***************
*** 189,195 ****
* Would this proc be found (uniquely!) by regprocin? If not,
* qualify it.
*/
! clist = FuncnameGetCandidates(list_make1(makeString(proname)), -1);
if (clist != NULL && clist->next == NULL &&
clist->oid == proid)
nspname = NULL;
--- 189,195 ----
* Would this proc be found (uniquely!) by regprocin? If not,
* qualify it.
*/
! clist = FuncnameGetCandidates(list_make1(makeString(proname)), -1, false);
if (clist != NULL && clist->next == NULL &&
clist->oid == proid)
nspname = NULL;
***************
*** 276,282 ****
*/
parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes);

! clist = FuncnameGetCandidates(names, nargs);

for (; clist; clist = clist->next)
{
--- 276,282 ----
*/
parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes);

! clist = FuncnameGetCandidates(names, nargs, false);

for (; clist; clist = clist->next)
{
*** ./src/backend/utils/adt/ruleutils.c.orig 2008-07-14 09:12:55.000000000 +0200
--- ./src/backend/utils/adt/ruleutils.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 5344,5349 ****
--- 5344,5351 ----
Oid p_rettype;
bool p_retset;
Oid *p_true_typeids;
+ int nvargs;
+ Oid va_oid;

proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcid),
***************
*** 5362,5368 ****
p_result = func_get_detail(list_make1(makeString(proname)),
NIL, nargs, argtypes,
&p_funcid, &p_rettype,
! &p_retset, &p_true_typeids);
if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) &&
p_funcid == funcid)
nspname = NULL;
--- 5364,5371 ----
p_result = func_get_detail(list_make1(makeString(proname)),
NIL, nargs, argtypes,
&p_funcid, &p_rettype,
! &p_retset, &p_true_typeids,
! &nvargs, &va_oid);
if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) &&
p_funcid == funcid)
nspname = NULL;
*** ./src/backend/utils/fmgr/funcapi.c.orig 2008-07-14 09:13:01.000000000 +0200
--- ./src/backend/utils/fmgr/funcapi.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 844,850 ****
numoutargs = 0;
for (i = 0; i < numargs; i++)
{
! if (argmodes[i] == PROARGMODE_IN)
continue;
Assert(argmodes[i] == PROARGMODE_OUT ||
argmodes[i] == PROARGMODE_INOUT);
--- 844,850 ----
numoutargs = 0;
for (i = 0; i < numargs; i++)
{
! if (argmodes[i] == PROARGMODE_IN || argmodes[i] == PROARGMODE_VARIADIC)
continue;
Assert(argmodes[i] == PROARGMODE_OUT ||
argmodes[i] == PROARGMODE_INOUT);
***************
*** 994,1000 ****
{
char *pname;

! if (argmodes[i] == PROARGMODE_IN)
continue;
Assert(argmodes[i] == PROARGMODE_OUT ||
argmodes[i] == PROARGMODE_INOUT);
--- 994,1000 ----
{
char *pname;

! if (argmodes[i] == PROARGMODE_IN || argmodes[i] == PROARGMODE_VARIADIC)
continue;
Assert(argmodes[i] == PROARGMODE_OUT ||
argmodes[i] == PROARGMODE_INOUT);
*** ./src/bin/pg_dump/pg_dump.c.orig 2008-07-14 09:13:08.000000000 +0200
--- ./src/bin/pg_dump/pg_dump.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 6435,6449 ****
{
switch (argmodes[j][0])
{
! case 'i':
argmode = "";
break;
! case 'o':
argmode = "OUT ";
break;
! case 'b':
argmode = "INOUT ";
break;
default:
write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
argmode = "";
--- 6435,6452 ----
{
switch (argmodes[j][0])
{
! case PROARGMODE_IN:
argmode = "";
break;
! case PROARGMODE_OUT:
argmode = "OUT ";
break;
! case PROARGMODE_INOUT:
argmode = "INOUT ";
break;
+ case PROARGMODE_VARIADIC:
+ argmode = "VARIADIC ";
+ break;
default:
write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
argmode = "";
*** ./src/bin/psql/describe.c.orig 2008-07-12 12:44:56.000000000 +0200
--- ./src/bin/psql/describe.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 205,210 ****
--- 205,211 ----
" WHEN p.proargmodes[s.i] = 'i' THEN ''\n"
" WHEN p.proargmodes[s.i] = 'o' THEN 'OUT '\n"
" WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT '\n"
+ " WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC '\n"
" END ||\n"
" CASE\n"
" WHEN COALESCE(p.proargnames[s.i], '') = '' THEN ''\n"
*** ./src/include/catalog/namespace.h.orig 2008-07-14 09:13:21.000000000 +0200
--- ./src/include/catalog/namespace.h 2008-07-14 09:14:37.000000000 +0200
***************
*** 29,34 ****
--- 29,36 ----
int pathpos; /* for internal use of namespace lookup */
Oid oid; /* the function or operator's OID */
int nargs; /* number of arg types returned */
+ int nvargs; /* number of variadic arguments */
+ Oid variadic_oid; /* Oid of variadic argument */
Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */
} *FuncCandidateList; /* VARIABLE LENGTH STRUCT */

***************
*** 51,57 ****
extern Oid TypenameGetTypid(const char *typname);
extern bool TypeIsVisible(Oid typid);

! extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs);
extern bool FunctionIsVisible(Oid funcid);

extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright);
--- 53,60 ----
extern Oid TypenameGetTypid(const char *typname);
extern bool TypeIsVisible(Oid typid);

! extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs,
! bool transform_variadic);
extern bool FunctionIsVisible(Oid funcid);

extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright);
*** ./src/include/catalog/pg_proc.h.orig 2008-07-14 02:51:45.000000000 +0200
--- ./src/include/catalog/pg_proc.h 2008-07-14 09:14:37.000000000 +0200
***************
*** 4472,4476 ****
--- 4472,4477 ----
#define PROARGMODE_IN 'i'
#define PROARGMODE_OUT 'o'
#define PROARGMODE_INOUT 'b'
+ #define PROARGMODE_VARIADIC 'v'

#endif /* PG_PROC_H */
*** ./src/include/nodes/parsenodes.h.orig 2008-07-14 09:13:36.000000000 +0200
--- ./src/include/nodes/parsenodes.h 2008-07-14 21:57:18.000000000 +0200
***************
*** 262,267 ****
--- 262,268 ----
bool agg_star; /* argument was really '*' */
bool agg_distinct; /* arguments were labeled DISTINCT */
int location; /* token location, or -1 if unknown */
+ Node *variadic_expr; /* when last parameter is array of variadic arguments */
} FuncCall;

/*
***************
*** 1568,1574 ****
/* the assigned enum values appear in pg_proc, don't change 'em! */
FUNC_PARAM_IN = 'i', /* input only */
FUNC_PARAM_OUT = 'o', /* output only */
! FUNC_PARAM_INOUT = 'b' /* both */
} FunctionParameterMode;

typedef struct FunctionParameter
--- 1569,1576 ----
/* the assigned enum values appear in pg_proc, don't change 'em! */
FUNC_PARAM_IN = 'i', /* input only */
FUNC_PARAM_OUT = 'o', /* output only */
! FUNC_PARAM_INOUT = 'b', /* both */
! FUNC_PARAM_VARIADIC = 'v' /* variadic */
} FunctionParameterMode;

typedef struct FunctionParameter
*** ./src/include/parser/parse_func.h.orig 2008-07-14 09:13:43.000000000 +0200
--- ./src/include/parser/parse_func.h 2008-07-14 22:25:12.000000000 +0200
***************
*** 44,55 ****
extern Node *ParseFuncOrColumn(ParseState *pstate,
List *funcname, List *fargs,
bool agg_star, bool agg_distinct, bool is_column,
! int location);

extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
int nargs, Oid *argtypes,
Oid *funcid, Oid *rettype,
! bool *retset, Oid **true_typeids);

extern int func_match_argtypes(int nargs,
Oid *input_typeids,
--- 44,56 ----
extern Node *ParseFuncOrColumn(ParseState *pstate,
List *funcname, List *fargs,
bool agg_star, bool agg_distinct, bool is_column,
! int location, Node *variadic_expr);

extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
int nargs, Oid *argtypes,
Oid *funcid, Oid *rettype,
! bool *retset, Oid **true_typeids,
! int *nvargs, Oid *va_oid);

extern int func_match_argtypes(int nargs,
Oid *input_typeids,
*** ./src/interfaces/ecpg/preproc/preproc.y.orig 2008-06-26 10:04:05.000000000 +0200
--- ./src/interfaces/ecpg/preproc/preproc.y 2008-07-14 09:14:37.000000000 +0200
***************
*** 489,495 ****
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USER USING

! VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
VERBOSE VERSION_P VIEW VOLATILE
WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE

--- 489,495 ----
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USER USING

! VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
VERBOSE VERSION_P VIEW VOLATILE
WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE

***************
*** 6667,6672 ****
--- 6667,6673 ----
| VALIDATOR { $$ = make_str("validator"); }
| VALUE_P { $$ = make_str("value"); }
| VARYING { $$ = make_str("varying"); }
+ | VARIADIC { $$ = make_str("variadic"); }
| VERSION_P { $$ = make_str("version"); }
| VIEW { $$ = make_str("view"); }
| VOLATILE { $$ = make_str("volatile"); }
*** ./src/pl/plpgsql/src/pl_comp.c.orig 2008-07-14 09:13:56.000000000 +0200
--- ./src/pl/plpgsql/src/pl_comp.c 2008-07-14 09:14:37.000000000 +0200
***************
*** 426,432 ****
{
argitemtype = PLPGSQL_NSTYPE_VAR;
/* input argument vars are forced to be CONSTANT */
! if (argmode == PROARGMODE_IN)
((PLpgSQL_var *) argvariable)->isconst = true;
}
else
--- 426,432 ----
{
argitemtype = PLPGSQL_NSTYPE_VAR;
/* input argument vars are forced to be CONSTANT */
! if (argmode == PROARGMODE_IN || argmode == PROARGMODE_VARIADIC)
((PLpgSQL_var *) argvariable)->isconst = true;
}
else
***************
*** 436,442 ****
}

/* Remember arguments in appropriate arrays */
! if (argmode == PROARGMODE_IN || argmode == PROARGMODE_INOUT)
in_arg_varnos[num_in_args++] = argvariable->dno;
if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_INOUT)
out_arg_variables[num_out_args++] = argvariable;
--- 436,443 ----
}

/* Remember arguments in appropriate arrays */
! if (argmode == PROARGMODE_IN || argmode == PROARGMODE_INOUT
! || argmode == PROARGMODE_VARIADIC)
in_arg_varnos[num_in_args++] = argvariable->dno;
if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_INOUT)
out_arg_variables[num_out_args++] = argvariable;
*** ./src/test/regress/expected/plpgsql.out.orig 2008-07-14 09:14:03.000000000 +0200
--- ./src/test/regress/expected/plpgsql.out 2008-07-14 15:06:36.000000000 +0200
***************
*** 3544,3546 ****
--- 3544,3621 ----

drop function catch();
drop function case_test(bigint);
+ -- variadic fuction test
+ create or replace function vari(variadic int[])
+ returns void as $$
+ begin
+ for i in array_lower($1,1)..array_upper($1,1) loop
+ raise notice '%', $1[i];
+ end loop; end;
+ $$ language plpgsql;
+ select vari(1,2,3,4,5);
+ NOTICE: 1
+ NOTICE: 2
+ NOTICE: 3
+ NOTICE: 4
+ NOTICE: 5
+ vari
+ ------
+
+ (1 row)
+
+ select vari(3,4,5);
+ NOTICE: 3
+ NOTICE: 4
+ NOTICE: 5
+ vari
+ ------
+
+ (1 row)
+
+ drop function vari(int[]);
+ -- coerce test
+ create or replace function pleast(variadic numeric[])
+ returns numeric as $$
+ declare aux numeric = $1[array_lower($1,1)];
+ begin
+ for i in array_lower($1,1)+1..array_upper($1,1) loop
+ if $1[i] < aux then aux := $1[i]; end if;
+ end loop;
+ return aux;
+ end;
+ $$ language plpgsql immutable strict;
+ select pleast(10,1,2,3,-16);
+ pleast
+ --------
+ -16
+ (1 row)
+
+ select pleast(10.2,2.2,-1.1);
+ pleast
+ --------
+ -1.1
+ (1 row)
+
+ select pleast(10.2,10, -20);
+ pleast
+ --------
+ -20
+ (1 row)
+
+ select pleast(10,20, -1.0);
+ pleast
+ --------
+ -1.0
+ (1 row)
+
+ -- we can't call variadic function with not unique signature
+ create or replace function pleast(numeric)
+ returns numeric as $$
+ begin
+ return $1;
+ end;
+ $$ language plpgsql immutable strict;
+ select pleast(10);
+ ERROR: function pleast(numeric) is not unique
+ drop function pleast(numeric[]);
+ drop function pleast(numeric);
*** ./src/test/regress/expected/polymorphism.out.orig 2008-07-14 09:14:08.000000000 +0200
--- ./src/test/regress/expected/polymorphism.out 2008-07-15 00:03:30.000000000 +0200
***************
*** 613,615 ****
--- 613,678 ----
SFUNC = add_group,
STYPE = int8[]
);
+ --test for variadic polymorphic function
+ create function myleast(variadic anyarray)
+ returns anyelement as $$
+ select min($1[i])
+ from generate_subscripts($1,1) g(i)
+ $$ language sql immutable strict;
+ select myleast(10, 1, 20, 33);
+ myleast
+ ---------
+ 1
+ (1 row)
+
+ select myleast(1.1, 0.22, 0.55);
+ myleast
+ ---------
+ 0.22
+ (1 row)
+
+ -- test with variadic call parameter
+ select myleast(variadic array[1,2,3,4,-1]);
+ myleast
+ ---------
+ -1
+ (1 row)
+
+ select myleast(variadic array[1.1, -5.5]);
+ myleast
+ ---------
+ -5.5
+ (1 row)
+
+ --test with empty variadic call parameter
+ select myleast(variadic array[]::int[]);
+ myleast
+ ---------
+
+ (1 row)
+
+ -- visibility test
+ select pg_catalog.pg_function_is_visible('myleast(anyarray)'::regprocedure::int);
+ pg_function_is_visible
+ ------------------------
+ t
+ (1 row)
+
+ drop function myleast(anyarray);
+ create or replace function concat(varchar, variadic anyarray)
+ returns varchar as $$
+ select array_to_string($2, $1);
+ $$ language sql immutable strict;
+ select concat('%', 1, 2, 3, 4, 5);
+ concat
+ -----------
+ 1%2%3%4%5
+ (1 row)
+
+ select concat('|', 'a'::text, 'b', 'c');
+ concat
+ --------
+ a|b|c
+ (1 row)
+
+ drop function concat(varchar, anyarray);
*** ./src/test/regress/sql/plpgsql.sql.orig 2008-07-14 09:14:16.000000000 +0200
--- ./src/test/regress/sql/plpgsql.sql 2008-07-14 15:05:17.000000000 +0200
***************
*** 2878,2880 ****
--- 2878,2924 ----

drop function catch();
drop function case_test(bigint);
+
+ -- variadic fuction test
+ create or replace function vari(variadic int[])
+ returns void as $$
+ begin
+ for i in array_lower($1,1)..array_upper($1,1) loop
+ raise notice '%', $1[i];
+ end loop; end;
+ $$ language plpgsql;
+
+ select vari(1,2,3,4,5);
+ select vari(3,4,5);
+
+ drop function vari(int[]);
+
+ -- coerce test
+ create or replace function pleast(variadic numeric[])
+ returns numeric as $$
+ declare aux numeric = $1[array_lower($1,1)];
+ begin
+ for i in array_lower($1,1)+1..array_upper($1,1) loop
+ if $1[i] < aux then aux := $1[i]; end if;
+ end loop;
+ return aux;
+ end;
+ $$ language plpgsql immutable strict;
+
+ select pleast(10,1,2,3,-16);
+ select pleast(10.2,2.2,-1.1);
+ select pleast(10.2,10, -20);
+ select pleast(10,20, -1.0);
+
+ -- we can't call variadic function with not unique signature
+ create or replace function pleast(numeric)
+ returns numeric as $$
+ begin
+ return $1;
+ end;
+ $$ language plpgsql immutable strict;
+
+ select pleast(10);
+
+ drop function pleast(numeric[]);
+ drop function pleast(numeric);
*** ./src/test/regress/sql/polymorphism.sql.orig 2008-07-14 09:14:26.000000000 +0200
--- ./src/test/regress/sql/polymorphism.sql 2008-07-15 00:02:27.000000000 +0200
***************
*** 426,428 ****
--- 426,461 ----
SFUNC = add_group,
STYPE = int8[]
);
+
+ --test for variadic polymorphic function
+ create function myleast(variadic anyarray)
+ returns anyelement as $$
+ select min($1[i])
+ from generate_subscripts($1,1) g(i)
+ $$ language sql immutable strict;
+
+ select myleast(10, 1, 20, 33);
+ select myleast(1.1, 0.22, 0.55);
+
+ -- test with variadic call parameter
+ select myleast(variadic array[1,2,3,4,-1]);
+ select myleast(variadic array[1.1, -5.5]);
+
+ --test with empty variadic call parameter
+ select myleast(variadic array[]::int[]);
+
+ -- visibility test
+ select pg_catalog.pg_function_is_visible('myleast(anyarray)'::regprocedure::int);
+
+ drop function myleast(anyarray);
+
+ create or replace function concat(varchar, variadic anyarray)
+ returns varchar as $$
+ select array_to_string($2, $1);
+ $$ language sql immutable strict;
+
+ select concat('%', 1, 2, 3, 4, 5);
+ select concat('|', 'a'::text, 'b', 'c');
+
+ drop function concat(varchar, anyarray);
+
Hello

this version is WIP - I have to clean comments, and will do some
documentation. But I am sure, I am not able explain this feature in
english well. Please, can some body help me with documentation? So
now, plpgsql is more/less ruby :)

postgres=# select myleast(variadic array[1,2,3,4,-1]);
myleast
---------
-1
(1 row)

postgres=# select myleast(variadic array[1.1, -5.5]);
myleast
---------
-5.5
(1 row)

postgres=# --test with empty variadic call parameter
postgres=# select myleast(variadic array[]::int[]);
myleast
---------

(1 row)
postgres=# select myleast(1.1,-5.5);
myleast
---------
-5.5

regards
Pavel

2008/7/14 Pavel Stehule <pavel.stehule@gmail.com>:
> 2008/7/14 Tom Lane <tgl@sss.pgh.pa.us>:
>> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>>> 2008/7/14 Tom Lane <tgl@sss.pgh.pa.us>:
>>>> Are you intending to change this right now and resubmit, or is it
>>>> work for later?
>>
>>> I prefer separate it to other patch.
>>
>> It seems a fairly important part of the feature, especially given the
>> connection to the zero-argument issue.
>
> ok tomorrow I have some work, but I can do it to Friday.
>
> regards
> Pavel Stehule
>>
>> regards, tom lane
>>
>