Tuesday, June 24, 2008

Re: [ADMIN] Functions

Hello,

There a some differences from MySQL to PostgreSQL. In PostgreSQL we use Functions, what you called "Store Procedures", that do the same thing.
In Postgres you can combine the Functions with "Triggers".
Triggers are procedures that will be done when you do some U, I or D, you have to specific the operation.
In the Functions you can work with some languages: plpgsql (the best, in my oppinion), SQL, C, Ruby, Perl, Python, and so on.
So, you have to create a function that does the operation you want, and then you call that function using "select * from [function]".


About the $n, you can create an alias for the variable, using clause "DECLARE":
DECLARE
  vardocid alias for $1;

An example:
CREATE OR REPLACE FUNCTION test (integer) RETURNS integer AS
$BODY$
DECLARE
  vardocid alias for $1;
BEGIN
  update docs
  set
    posted = -1
  where
    docid = vardocid;

  RETURN 1;
END
$BODY$
LANGUAGE 'plpgsql';

select test (2);

2008/6/24 C K <shreeseva.it@gmail.com>:
Dear Members,
I am switching our ERP and other under development applications from MySQL to PostgreSQL. While working on this, I got some problems while creating store procedures. As PG does not support procedures, rather it uses Functions. While creating a function from MySQL as

CREATE DEFINER=`root`@`localhost` PROCEDURE `postdoc`(vardocid int)
    MODIFIES SQL DATA
UPDATE docs        SET posted = -1        WHERE docid = vardocid;

on PG, it gave me error for using variable in where condition. Other things are properly defined thru' PGAdmin. Does PG do no support to use variables or variable names in the functions? As per manual for 8.3, I understood to use $1, $2...$n for the input parameter reference, but it is difficult to mark them correclty in a big function having many parameters.
How could I use varibles in the functions?
Plesae help and give the details on above issue.

Thanks

CPK
--
Keep your Environment clean and green.

Re: [GENERAL] what are rules for?

Martijn van Oosterhout <kleptog@svana.org> writes:
> On Tue, Jun 24, 2008 at 10:28:00AM -0500, Michael Shulman wrote:
>> My question was, what else *can* you do with a rule that you *can't*
>> do with a trigger? Are rules only a way to speed up things that could
>> also be done with triggers?

> Well, views for one.

To expand on that: it's pretty hard to see how update or delete triggers
on a view would work. Insert is easy, because if left to its own
devices the system would in fact try to insert a tuple into the view
relation, and that action could fire a trigger which could redirect the
insertion someplace else. But updates and deletes require a
pre-existing target tuple, and there just aren't any of those in a view
relation. (Another way to say it is that update/delete require a CTID
column, which a view hasn't got.)

So view update/delete appear to require a transformational-rule kind
of approach instead of an actions-on-physical-tuples kind of approach.

If you've got a better idea we're all ears ...

regards, tom lane

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

[COMMITTERS] pgsql: TODO item done: < o Prevent pg_dump/pg_restore from being

Log Message:
-----------
TODO item done:

< o Prevent pg_dump/pg_restore from being affected by
> o -Prevent pg_dump/pg_restore from being affected by

Modified Files:
--------------
pgsql/doc:
TODO (r1.2472 -> r1.2473)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/TODO?r1=1.2472&r2=1.2473)
pgsql/doc/src/FAQ:
TODO.html (r1.978 -> r1.979)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/FAQ/TODO.html?r1=1.978&r2=1.979)

--
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] [HACKERS] Patch for Prevent pg_dump/pg_restore from being affected by statement_timeout

Joshua D. Drake wrote:
> Alex Hunsaker wrote:
> > On Mon, Jun 23, 2008 at 4:51 PM, Bruce Momjian <bruce@momjian.us> wrote:
> >> I would like to get do this without adding a new --use-statement-timeout
> >> flag. Is anyone going to want to honor statement_timeout during
> >> pg_dump/pg_restore? I thought we were just going to disable it.
> >
> > I believe so. This was when not everyone was convinced. Im fairly
> > certain Josh original patch is in the commit fest. So feel free to
> > drop this one.
> >
>
> My patch has been committed.

Ah, I see, but with no switch. Thanks.

--
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: [ADMIN] plpgsql function seems to be leaking memory

Guillaume Lelarge <guillaume@lelarge.info> writes:
> Tom Lane a écrit :
>> What do you have shared_buffers set to? I think you might be getting
>> fooled by top's treatment of shared memory (ie, it starts to count
>> shared pages after the process touches them for the first time).

> That's what I thought at first when I saw Marc's email. I tried his
> example many times, with different values for shared_buffers. RSS column
> climbs until it reaches more or less the shared_buffers configuration.
> But, if I launch another psql, this process will have a much lower value
> on the RSS column. Shouldn't it get the RSS at the same value, even when
> the process starts ?

No, that's exactly the point. Linux top includes in a process's
reported size its actual private space, plus however many pages of
shared memory that process has physically accessed so far. So any PG
backend that's doing a material amount of table access is going to show
an RSS that starts low and creeps up to roughly the size of your shared
memory block, quite independently of what its actual private space usage
is. It's just a matter of how many buffers it has had occasion to use.

This is all pretty OS-dependent. Some systems don't count shared memory
at all (HPUX seems not to), and some other ones report a separate total
for shared memory so that you can mentally subtract it.

regards, tom lane

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

Re: [ADMIN] plpgsql function seems to be leaking memory

Tom Lane a écrit :
> Marc Cousin <mcousin@sigma.fr> writes:
>> I'm having a problem with plpgsql functions leaking memory.
>
> Your example shows absolutely no memory leak here, in either 8.3.3
> or CVS HEAD.
>
>> I see the postgresql process growing from 8MB to about 400 MB during this
>> run...
>
> What do you have shared_buffers set to? I think you might be getting
> fooled by top's treatment of shared memory (ie, it starts to count
> shared pages after the process touches them for the first time).
>

That's what I thought at first when I saw Marc's email. I tried his
example many times, with different values for shared_buffers. RSS column
climbs until it reaches more or less the shared_buffers configuration.
But, if I launch another psql, this process will have a much lower value
on the RSS column. Shouldn't it get the RSS at the same value, even when
the process starts ?

I'm a bit puzzled by this column, anyone has a URL where I can find more
info?

Regards.


--
Guillaume.

http://www.postgresqlfr.org

http://dalibo.com

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

Re: [ADMIN] plpgsql function seems to be leaking memory

On Tuesday 24 June 2008 16:56:10 Tom Lane wrote:
> Marc Cousin <mcousin@sigma.fr> writes:
> > I'm having a problem with plpgsql functions leaking memory.
>
> Your example shows absolutely no memory leak here, in either 8.3.3
> or CVS HEAD.
>
> > I see the postgresql process growing from 8MB to about 400 MB during this
> > run...
>
> What do you have shared_buffers set to? I think you might be getting
> fooled by top's treatment of shared memory (ie, it starts to count
> shared pages after the process touches them for the first time).
>
> regards, tom lane


I'm seeing this with ps aux, you're (almost) right... And I've been wasting your time.

At the begining :
postgres 23305 39.2 0.8 1275484 31208 ? Rs 17:07 0:18 postgres: postgres test [local] idle in transaction


Then after a few seconds :
postgres 23305 39.2 0.8 1275484 31208 ? Rs 17:07 0:18 postgres: postgres test [local] idle in transaction

The RSS column is growing ... Here it is only a test, but I've been having
it get to more that 500MB on the real use case, and it got me worried...

shared_buffers is at 1GB...

So in fact, the problem is linked to RSS containing some shared memory...
And that this growing memory is because the process has put all those
modified blocks in the shared buffers... I've confirmed that with doing the
inserts out of plpgsql, and it's also the same if I select the process...
And I never noticed it before ...

It all started with a plperl procedure and I was afraid I had a leak in it ... :)


Sorry to have wasted your time and thanks a lot ...

Regards.

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

Re: [HACKERS] Git Repository for WITH RECURSIVE and others

David Fetter wrote:
> On Tue, Jun 24, 2008 at 09:52:22AM +0200, Magnus Hagander wrote:
>> David Fetter wrote:
>>> Folks,
>>>
>>> With lots of help from Greg Sabino Mullane, I've set up a git
>>> repository for the WITH RECURSIVE patches on
>>> <http://git.postgresql.org/>.
>>>
>>> What other patches would people like to try maintaining this way
>>> until commitfest?
>>>
>>> It looks like gitosis is a good way to grant write access to git
>>> repositories, but it's not yet packaged for FreeBSD. Any ideas
>>> about how to handle this?
>> As you were answered the last time you asked about it, people are
>> already working on this.
>
> Which people, and what are they doing? The silence here has been
> deafening.

Peter is in charge of the GIT repository, and I've offered to make the
changes once we've agreed exactly on what should be done.


>> Unfortunately, the requirements have also been raised a bit (such as
>> allowing a user to delegate access to another user)
>
> Who raised those requirements, and where did that discussion take
> place?

Peter did.


> I don't recall any decision to do any of this by star chamber
> and secret cabal, and frankly, moving the goalposts on this is a great
> way to have it never actually happen. Is that your intention?

Not mine :-) My suggestion is to fix what we have now, and then add more
stuff later.


>> which means it will take longer.
>>
>> Now, if you can give us a step-by-step on how to set it up, that
>> would certainly help ;-)
>
> Gitosis does not, as far as I can tell, have that delegation
> capability, but I've come up with a way to do this:
>
> 1. Use git-shell. Yes, this does involve creating one shell account
> for each project, but git-shell is, by design, very short on
> exploitable capability.
>
> 2. Make the .ssh directory a git repository.
>
> 3. Edit .ssh/authorized_keys and push via git.

I was looking into being able to do it using gitosis, with an interface
on top of it's existing GIT repository for being able to delegate this.
I think it can be done without modifying gitosis itself, by just writing
some simple frontend script on top of it. What do you think of this idea?

//Magnus

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

[SQL] Verify Execute

Hello
 
Is there a way to find out if the EXECUTE of a UPDATE, INSERT has been completed successfully?
 
Here is an example of what I do:
 
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Form_Store_PSQL"
 
Set oRs = Server.CreateObject("ADODB.Recordset" )
strSQL = "INSERT INTO TABLE_TEMP (ID) VALUES ('1')"
conn.Execute strSQL
 
Thank you
 
Shavonne Wijesinghe

[GENERAL] could not select a suitable default timezone on Initdb, 8.3.3, Windows 2008 x64

Initdb throws "could not select a suitable default timezone" on PostgreSQL
8.3.3
and Windows x64.

We'd like to use those settings --lc-collate=C --lc-ctype=French_Canada
pginstaller does initdb properly but not with the parameters we want.

We want upper, lower, regex, ... to process acccented characters properly
but don't care
about the collating sequence of those accented characters.

We have many indexes of varchar columns and want to avoid having both
regular indexes
and index with *_pattern_ops.

we first install PostgreSQL with pgInstaller and no initdb

we then issue:
initdb -d --pgdata="C:/Program Files (x86)/PostgreSQL/8.3/data"
--encoding=WIN1252 --lc-collate=C --lc-ctype=French_Canada --pwprompt -L
"C:/Program Files (x86)/PostgreSQL/8.3/share"

creating template1 database in C:/Program Files
(x86)/PostgreSQL/8.3/data/base/1 ...
DEBUG: TZ "US/Eastern" matches Windows timezone "Eastern Daylight Time"
LOG: could not open directory "/share/timezone": No such file or directory
LOG: could not open directory "/share/timezone": No such file or directory
FATAL: could not select a suitable default timezone
DETAIL: It appears that your GMT time zone uses leap seconds. PostgreSQL
does not support leap seconds.
DEBUG: proc_exit(1)
DEBUG: shmem_exit(1)
DEBUG: exit(1)
child process exited with exit code 1

We tried putting a copy of C:/Program Files (x86)/PostgreSQL/8.3/share in
c:/share
to get a little bit further and got this fatal error:

creating conversions ...
FATAL: could not access file "$libdir/ascii_and_mic": No such file or
directory
STATEMENT: CREATE OR REPLACE FUNCTION ascii_to_mic (INTEGER, INTEGER,
CSTRING, INTERNAL, INTEGER)
RETURNS VOID AS '$libdir/ascii_and_mic', 'ascii_to_mic' LANGUAGE C STRICT;
child process exited with exit code 1

The file ascii_and_mic.dll does exist in C:/Program Files
(x86)/PostgreSQL/8.3/lib

Thanks,
Jean-Pierre Pelletier
e-djuster

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

Re: [PATCHES] variadic function support

*** ./doc/src/sgml/ref/create_function.sgml.orig 2008-06-24 16:46:47.000000000 +0200
--- ./doc/src/sgml/ref/create_function.sgml 2008-06-24 16:47:46.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-06-24 16:53:58.000000000 +0200
--- ./doc/src/sgml/xfunc.sgml 2008-06-24 16:59:42.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-06-24 11:24:34.000000000 +0200
--- ./src/backend/catalog/namespace.c 2008-06-24 13:58:31.000000000 +0200
***************
*** 570,576 ****
* identical entries in later namespaces.
*/
FuncCandidateList
! FuncnameGetCandidates(List *names, int nargs)
{
FuncCandidateList resultList = NULL;
char *schemaname;
--- 570,576 ----
* 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))
--- 606,655 ----
int pronargs = procform->pronargs;
int pathpos = 0;
FuncCandidateList newResult;
+ Oid va_oid = InvalidOid;
+ bool variadic = false;
+ 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))
***************
*** 691,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;
}

--- 732,772 ----
/*
* Okay to add it to result list
*/
! 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)
{
--- 821,827 ----

visible = false;

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

for (; clist; clist = clist->next)
{
*** ./src/backend/catalog/pg_aggregate.c.orig 2008-06-24 14:17:42.000000000 +0200
--- ./src/backend/catalog/pg_aggregate.c 2008-06-24 15:58:27.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("aggregate function has variadic argument %d %d", nvargs, va_oid)));
+
/*
* 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-06-24 10:36:44.000000000 +0200
--- ./src/backend/commands/functioncmds.c 2008-06-24 12:37:26.000000000 +0200
***************
*** 173,178 ****
--- 173,179 ----
Datum *paramNames;
int outCount = 0;
bool have_names = false;
+ int varCount = 0;
ListCell *x;
int i;

***************
*** 227,241 ****
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);
--- 228,270 ----
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 argument isn't last function's argument")));
+ }

! 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 arguments")));
+
+ /* 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 argument isn't array")));
+ }
+ }
+
allTypes[i] = ObjectIdGetDatum(toid);

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

! if (outCount > 0)
{
*allParameterTypes = construct_array(allTypes, parameterCount, OIDOID,
sizeof(Oid), true, 'i');
--- 281,287 ----
/* 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/parser/gram.y.orig 2008-06-24 10:30:01.000000000 +0200
--- ./src/backend/parser/gram.y 2008-06-24 10:32:36.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; }
;

/*
*** ./src/backend/parser/keywords.c.orig 2008-06-24 10:29:58.000000000 +0200
--- ./src/backend/parser/keywords.c 2008-06-24 10:30:50.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_func.c.orig 2008-06-24 13:09:17.000000000 +0200
--- ./src/backend/parser/parse_func.c 2008-06-24 15:58:44.000000000 +0200
***************
*** 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
***************
*** 158,164 ****
*/
fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types,
&funcid, &rettype, &retset,
! &declared_arg_types);
if (fdresult == FUNCDETAIL_COERCION)
{
/*
--- 160,167 ----
*/
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 ****
--- 232,279 ----
}

/*
+ * 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;
+
+ if (nvargs < nargs)
+ {
+ 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
+ {
+ /* array from all argumenst */
+ n->elements = fargs;
+ tn= transformExpr(pstate, (Node *) n);
+ fargs = list_make1(tn);
+ }
+
+ /*
+ * 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;
+ actual_arg_types[nargs - 1] = ((ArrayExpr *) tn)->array_typeid;
+ 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
--- 742,756 ----
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 ****
--- 834,841 ----
*rettype = targetType;
*retset = false;
*true_typeids = argtypes;
+ *nvargs = 0;
+ *va_oid = InvalidOid;
return FUNCDETAIL_COERCION;
}
}
***************
*** 836,841 ****
--- 885,892 ----

*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)
{
--- 1240,1246 ----
{
FuncCandidateList clist;

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

while (clist)
{
*** ./src/backend/utils/adt/regproc.c.orig 2008-06-24 13:12:03.000000000 +0200
--- ./src/backend/utils/adt/regproc.c 2008-06-24 13:12:53.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-06-24 14:37:19.000000000 +0200
--- ./src/backend/utils/adt/ruleutils.c 2008-06-24 14:38:28.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-06-24 16:18:51.000000000 +0200
--- ./src/backend/utils/fmgr/funcapi.c 2008-06-24 16:21:54.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-06-24 15:05:21.000000000 +0200
--- ./src/bin/pg_dump/pg_dump.c 2008-06-24 15:09:08.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-06-24 15:17:23.000000000 +0200
--- ./src/bin/psql/describe.c 2008-06-24 15:18:26.000000000 +0200
***************
*** 187,192 ****
--- 187,193 ----
" 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-06-24 12:48:23.000000000 +0200
--- ./src/include/catalog/namespace.h 2008-06-24 12:59:36.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-06-24 13:33:45.000000000 +0200
--- ./src/include/catalog/pg_proc.h 2008-06-24 13:33:24.000000000 +0200
***************
*** 4466,4470 ****
--- 4466,4471 ----
#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-06-24 10:35:02.000000000 +0200
--- ./src/include/nodes/parsenodes.h 2008-06-24 10:35:09.000000000 +0200
***************
*** 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
--- 1568,1575 ----
/* 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-06-24 14:16:40.000000000 +0200
--- ./src/include/parser/parse_func.h 2008-06-24 14:17:13.000000000 +0200
***************
*** 49,55 ****
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,
--- 49,56 ----
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-24 11:12:00.000000000 +0200
--- ./src/interfaces/ecpg/preproc/preproc.y 2008-06-24 11:13:52.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

***************
*** 6668,6673 ****
--- 6668,6674 ----
| 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-06-24 16:23:47.000000000 +0200
--- ./src/pl/plpgsql/src/pl_comp.c 2008-06-24 16:25:53.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-06-24 16:33:20.000000000 +0200
--- ./src/test/regress/expected/plpgsql.out 2008-06-24 16:32:32.000000000 +0200
***************
*** 3544,3546 ****
--- 3544,3611 ----

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)
+
+ drop function pleast(numeric[]);
*** ./src/test/regress/expected/polymorphism.out.orig 2008-06-24 16:10:52.000000000 +0200
--- ./src/test/regress/expected/polymorphism.out 2008-06-24 16:07:12.000000000 +0200
***************
*** 613,615 ****
--- 613,658 ----
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)
+
+ -- 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-06-24 16:01:55.000000000 +0200
--- ./src/test/regress/sql/plpgsql.sql 2008-06-24 16:30:50.000000000 +0200
***************
*** 2878,2880 ****
--- 2878,2913 ----

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);
+
+ drop function pleast(numeric[]);
*** ./src/test/regress/sql/polymorphism.sql.orig 2008-06-24 16:01:52.000000000 +0200
--- ./src/test/regress/sql/polymorphism.sql 2008-06-24 16:04:16.000000000 +0200
***************
*** 426,428 ****
--- 426,453 ----
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);
+ -- 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 implements syntax based on argmodes.


CREATE FUNCTION mleast(variadic numeric[]) RETURNS numeric AS $$
SELECT min($1[i])
FROM generate_subscripts($1,1) g(i);
$$ LANGUAGE SQL;

Regards
Pavel Stehule

2008/6/24 Tom Lane <tgl@sss.pgh.pa.us>:
> Andrew Dunstan <andrew@dunslane.net> writes:
>> But if I have
>> foo( a text, b int[])
>> it looks odd if both these calls are legal:
>> foo('a',1,2,3,)
>> foo('a',ARRAY[1,2,3])
>> which I understand would be the case with the current patch.
>
> Maybe I misunderstand what is supposed to happen, but I believe that
> if the function is marked VARIADIC then the second case would in fact
> be rejected: the signature of the function for parameter-matching
> purposes is text followed by one or more ints, never text and int[].
>
>> I'm also still curious to know how the following would be handled:
>> foo(a text[], b text[])
>
> I think a is just text[], full stop. Only the last parameter is
> interpreted differently for variadic.
>
> Your point about the syntax is good though. It would be better if
> the syntax were like
>
> create function foo (a text, variadic b int[])
>
> or maybe even better
>
> create function foo (a text, variadic b int)
>
> since (a) this makes it much more obvious to the reader what the
> function might match, and (b) it leaves the door open for marking
> multiple parameters as variadic, if we can figure out what that means.
>
> regards, tom lane
>

Re: [GENERAL] backslashes in 8.3.3

"Brandon Metcalf" <bmetcalf@nortel.com> writes:
> t == tgl@sss.pgh.pa.us writes:
> t> See standard_conforming_strings and escape_string_warning.

> Excellent. I had missed the standard_conforming_strings and will turn
> this on. Hold on. Yes, that did it. Thanks so much.

Well, if your intent is to replicate 8.1's behavior, you should instead
frob the other switch.

regards, tom lane

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

[pgsql-es-ayuda] slony u otro similar para postgresql 8.3. en windows

Hola que tal,
 
quisiera saber si existe alguna version de slony para postgresql 8.3 o informacion sobre otro software que haga replicas de base de datos y que funcione sobre postgresql 8.3 y en windows xp o superior
 
Gracias de antemano por la ayuda,
saludos.

Re: [ADMIN] plpgsql function seems to be leaking memory

Marc Cousin <mcousin@sigma.fr> writes:
> I'm having a problem with plpgsql functions leaking memory.

Your example shows absolutely no memory leak here, in either 8.3.3
or CVS HEAD.

> I see the postgresql process growing from 8MB to about 400 MB during this
> run...

What do you have shared_buffers set to? I think you might be getting
fooled by top's treatment of shared memory (ie, it starts to count
shared pages after the process touches them for the first time).

regards, tom lane

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

Re: [HACKERS] Git Repository for WITH RECURSIVE and others

On Tue, Jun 24, 2008 at 03:26:36PM +0900, Yoshiyuki Asaba wrote:
> Hi,
>
> From: David Fetter <david@fetter.org>
> Subject: [HACKERS] Git Repository for WITH RECURSIVE and others
> Date: Mon, 23 Jun 2008 21:38:11 -0700
>
> > With lots of help from Greg Sabino Mullane, I've set up a git
> > repository for the WITH RECURSIVE patches on
> > <http://git.postgresql.org/>.
>
> Thank you very much.
>
> I tried git-clone, but I could not access the repository.
>
> % git-clone git://git.postgresql.org/git/~davidfetter/postgresql/.git
> Initialized empty Git repository in /home/y-asaba/x/postgresql/.git/
> fatal: The remote end hung up unexpectedly
> fetch-pack from 'git://git.postgresql.org/git/~davidfetter/postgresql/.git' failed.

I ran git-update-server-info on the server, and it should work now. :)

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: [GENERAL] what are rules for?

Adam Rich wrote:

> One interesting example is having rules and triggers watching for
> deletes or updates on a table. If many rows are modified, rules
> can be faster. Take this statement:
>
> DELETE FROM mydata WHERE idval BETWEEN 10000 and 20000;
>
> Say this statement deletes 10,000 rows. The delete trigger would
> get called 10,000 times whereas the rule is essentially executed
> once, since it can share the WHERE clause of the user's query.

This is a use case we should be able to better implement using FOR EACH
STATEMENT triggers, it seems. We just need to be able to pass the list
of affected tuples to the trigger function, which until now has remained
unimplemented.

--
Alvaro Herrera

http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

--
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] backslashes in 8.3.3

t == tgl@sss.pgh.pa.us writes:

t> "Brandon Metcalf" <bmetcalf@nortel.com> writes:
t> > I just upgraded to 8.3.3 from 8.1.5 and noticed that backslashes are
t> > handled completely differently now. For example,

t> See standard_conforming_strings and escape_string_warning.


Excellent. I had missed the standard_conforming_strings and will turn
this on. Hold on. Yes, that did it. Thanks so much.


--
Brandon

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

Re: [HACKERS] Dept of ugly hacks: eliminating padding space in system indexes

Teodor Sigaev <teodor@sigaev.ru> writes:
>> dead easy to implement this: effectively, we just decree that the
>> index column storage type for NAME is always CSTRING. Because the

> Isn't it a reason to add STORAGE option of CREATE OPERATOR CLASS to BTree? as
> it's done for GiST and GIN indexes.

Hmm ... I don't see a point in exposing that as a user-level facility,
unless you can point to other use-cases besides NAME. But it would be
cute to implement the hack by changing the initial contents of
pg_opclass instead of inserting code in the backend. I'll give that
a try.

regards, tom lane

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

[pgsql-it-generale] == Postgres Weekly News - 22 giugno 2008 ==

Nuovo Sondaggio: Quale TODO vi piace di più?
http://www.postgresql.org/community/

== Offerte di lavoro legate a PostgreSQL per il mese di Giugno ==

http://archives.postgresql.org/pgsql-jobs/2008-06/threads.php


== PostgreSQL news locali ==

Il primo meeting del TorontoPUG ci sarà il 23 giugno al Rhino.
http://pugs.postgresql.org/blog/159

L'Oklahoma PUG terrà il suo primo meeting il 23 giugno dalle 19:00
alle 21:00 presso Coach's, Norman, OK.
http://pugs.postgresql.org/node/408

Il meeting di preparazione al PgDay italiano ci sarà mercoledi 25
giugno alle ore 2130 CET via IRC.
irc://irc.freenode.net/pgday-it

Il pgDay di Portland ci sarà il 20 luglio. Poco prima di OSCON.
http://pugs.postgresql.org/node/400

Il PGCon Brasile 2008 ci sara' il 26 e 27 settembre 2008 a Unicamp, Campinas.
http://pgcon.postgresql.org.br/index.en.html

Il PGDay.IT 2008 ci sarà il 17 e 18 ottobre a Prato.
http://www.pgday.org/it/

== News su PostgreSQL ==

Planet PostgreSQL: http://www.planetpostgresql.org/

General Bits, archivi e nuovi articoli occasionali:
http://www.varlena.com/GeneralBits/

PostgreSQL Weekly News è stato spedito questa settimana grazie a David
Fetter e Josh Berkus.

Per segnalare news e annunci invia un email in inglese entro le ore 15,
fuso orario della costa orientale degli U.S.A, di domenica.

Per segnalazioni in inglese david@fetter.org, per segnalazioni in
Tedesco pwn@pgug.de, per segnalazioni in italiano pwn@itpug.org


== Patch applicate ==
Tom Lane committed:

- Clean up a number of bogosities around pltcl's handling of the Tcl
"result": 1. Directly reading interp->result is deprecated in Tcl
8.0 and later; you're supposed to use Tcl_GetStringResult. This
code finally broke with Tcl 8.5, because Tcl_GetVar can now have
side-effects on interp->result even though it preserves the logical
state of the result. (There's arguably a Tcl issue here, because
Tcl_GetVar could invalidate the pointer result of a just-preceding
Tcl_GetStringResult, but I doubt the Tcl guys will see it as a bug.)
2. We were being sloppy about the encoding of the result: some
places would push database-encoding data into the Tcl result, which
should not happen, and we were assuming that any error result coming
back from Tcl was in the database encoding, which is not a good
assumption. 3. There were a lot of calls of Tcl_SetResult that
uselessly specified TCL_VOLATILE for constant strings. This is only
a minor performance issue, but I fixed it in passing since I had to
look at all the calls anyway. #2 is a live bug regardless of which
Tcl version you are interested in, so back-patch even to branches
that are unlikely to be used with Tcl 8.5. I went back as far as
8.0, which is as far as the patch applied easily; 7.4 was using a
different error processing scheme that has got its own problems :-(

- In pgsql/src/backend/optimizer/plan/setrefs.c, fix the code that
adds regclass constants to a plan's list of relation OIDs that it
depends on for replan-forcing purposes. We need to consider plain
OID constants too, because eval_const_expressions folds a
RelabelType atop a Const to just a Const. This change could result
in OID values that aren't really for tables getting added to the
dependency list, but the worst-case consequence would be occasional
useless replans. Per report from Gabriele Messineo.

- Clean up some problems with redundant cross-type arithmetic
operators. Add int2-and-int8 implementations of the basic
arithmetic operators +, -, *, /. This doesn't really add any new
functionality, but it avoids "operator is not unique" failures that
formerly occurred in these cases because the parser couldn't decide
whether to promote the int2 to int4 or int8. We could alternatively
have removed the existing cross-type operators, but experimentation
shows that the cost of an additional type coercion expression node
is noticeable compared to such cheap operators; so let's not give up
any performance here. On the other hand, I removed the
int2-and-int4 modulo (%) operators since they didn't seem as
important from a performance standpoint. Per a complaint last
January from ykhuang.

- In pgsql/src/backend/storage/ipc/sinvaladt.c, remove freeBackends
counter from the sinval shared memory area. We used to use it to
help enforce superuser_reserved_backends, but since 8.1 it's just
been dead weight.

- Improve error reporting for problems in text search configuration
files by installing an error context subroutine that will provide
the file name and line number for all errors detected while reading
a config file. Some of the reader routines were already doing that
in an ad-hoc way for errors detected directly in the reader, but it
didn't help for problems detected in subroutines, such as encoding
violations. Back-patch to 8.3 because 8.3 is where people will be
trying to debug configuration files.

- In pgsql/src/backend/utils/mb/mbutils.c, fix compiler warning
introduced by recent patch. Tsk tsk.

- Fix a few places that were non-multibyte-safe in tsearch
configuration file parsing. Per bug #4253 from Giorgio Valoti.

- Rewrite the sinval messaging mechanism to reduce contention and
avoid unnecessary cache resets. The major changes are: 1. When the
queue overflows, we only issue a cache reset to the specific backend
or backends that still haven't read the oldest message, rather than
resetting everyone as in the original coding. 2. When we observe
backend(s) falling well behind, we signal SIGUSR1 to only one
backend, the one that is furthest behind and doesn't already have a
signal outstanding for it. When it finishes catching up, it will in
turn signal SIGUSR1 to the next-furthest-back guy, if there is one
that is far enough behind to justify a signal. The
PMSIGNAL_WAKEN_CHILDREN mechanism is removed. 3. We don't attempt
to clean out dead messages after every message-receipt operation;
rather, we do it on the insertion side, and only when the queue
fullness passes certain thresholds. 4. Split SInvalLock into
SInvalReadLock and SInvalWriteLock so that readers don't block
writers nor vice versa (except during the infrequent queue cleanout
operations). 5. Transfer multiple sinval messages for each
acquisition of a read or write lock.

- In pgsql/src/backend/storage/ipc/sinvaladt.c, seems I was too
optimistic in supposing that sinval's maxMsgNum could be read and
written without a lock. The value itself is atomic, sure, but on
processors with weak memory ordering it's possible for a reader to
see the value change before it sees the associated message written
into the buffer array. Fix by introducing a spinlock that's used
just to read and write maxMsgNum. (We could do this with less
overhead if we recognized a concept of "memory access barrier"; is
it worth introducing such a thing? At the moment probably not --- I
can't measure any clear slowdown from adding the spinlock, so this
solution is probably fine.) Per buildfarm results.

Bruce Momjian committed:

- Move USE_WIDE_UPPER_LOWER define to c.h, and remove TS_USE_WIDE and
use USE_WIDE_UPPER_LOWER instead.

- In pgsql/src/backend/utils/mb/README, add URL for introduction to
multibyte programming in C.

- Move wchar2char() and char2wchar() from tsearch into /mb to be
easier to use for other modules; also move pnstrdup(). Clean up
code slightly.

- Add URL for TODO: "Allow pg_hba.conf to specify host names along
with IP addresses."

Neil Conway committed:

- In pgsql/doc/src/sgml/monitoring.sgml, fix a few typos in the DTrace
docs. Patch from Euler Taveira de Oliveira, along with an
additional typo I noticed along the way.

Alvaro Herrera committed:

- Improve our #include situation by moving pointer types away from the
corresponding struct definitions. This allows other headers to
avoid including certain highly-loaded headers such as rel.h and
relscan.h, instead using just relcache.h, heapam.h or genam.h, which
are more lightweight and thus cause less unnecessary dependencies.

== Patch rigettate (per ora) ==
Nessuno è stato scontentato questa settimana ;)

== Patch in attesa ==
Zoltan Boszormenyi sent in another revision of his POSIX fadvise
patch.

Simon Riggs sent in a patch to improve performance via hint bits for
write I/O.

--
(all opinions expressed are my own)
Federico Campoli
PostgreSQL Consulting -> PGHost http://www.pghost.eu

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

[GENERAL] Probably been asked a hundred times before.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Which disto is best for running a Postgres server?
I just installed OpenSuse and downloaded and compiled the latest version
of Postgres. It isn't that big of a hassle but I noticed that almost
none of the big distros keep all that up to date with Postgres as far as
what they have in their repositories.

I was wondering if anybody has made an Postgres centric distro? Just a
nice stripped down server Distro that is ideal for running a database
server on?

More just curious since I already got mine installed and compiled.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3-nr1 (Windows XP)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQEVAwUBSGEE9uLnn4qAcbUGAQJpkQf/VkeYeG9aCklcybj6qFPAgNRxT7foIiqt
sbjQI/Geik1qDX3WwD7o9bbPR7V8VmZqcY8JhXjsxD8ggNA9qi92YI5Sx/l7Nmaq
yhCPUPZfaexyGynI5DgUxx7glgZP4iPZfYcbjoy0nyaZPLXXDR11i3q8CXvdPhoE
oTGQBT07CijtGPN6y4h2ymlgePUQKoN0NPT9JQ5KQOc8PECpqJsFDUuIon0BtbeN
S+TB1lwAgiceINQBys6wYpw1epbYb3LV2zuN6GjEx41SQQO+8vF1tBpJTvkXBHZI
G3j457pL4NaRgbZtGC0aAz90G2QFFV1MJ9ocMX4Im6HYL2SYOBbDyQ==
=n84g
-----END PGP SIGNATURE-----

--
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] backslashes in 8.3.3

"Brandon Metcalf" <bmetcalf@nortel.com> writes:
> I just upgraded to 8.3.3 from 8.1.5 and noticed that backslashes are
> handled completely differently now. For example,

See standard_conforming_strings and escape_string_warning.

regards, tom lane

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

[GENERAL] backslashes in 8.3.3

I just upgraded to 8.3.3 from 8.1.5 and noticed that backslashes are
handled completely differently now. For example,

db=# insert into junk (cifs) values ('\\foooo\bar');
WARNING: nonstandard use of \\ in a string literal
LINE 1: insert into junk (cifs) values ('\\foooo\bar');
^
HINT: Use the escape string syntax for backslashes, e.g., E'\\'.
INSERT 0 1
db=# select * from junk;
cifs
--------------
\foooo\x08ar
(1 row)

Is there anyway to disable this behavior or fix this on the server
side? I really don't want to have to rework all of our code that
inserts or queries data.

It seems this works,

db=# insert into junk (cifs) values (E'\\\\foobar\\bar');
INSERT 0 1

--
Brandon

--
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] Bulk load data from one table to another

Nikola <XLPizza@gmail.com> writes:
> Currently, I truncate the destination table, drop the indexes,
> execute:
> "INSERT INTO destination SELECT * FROM source_partition"
> and recreate indexes.

> This loads about 66.5 million rows into the destination table in about
> 1 hour. Recreating of indexes (4 of them) takes additional 2 hours. Is
> there a more efficient way to perform this procedure?

Do you have maintenance_work_mem set to a suitable value for building
the indexes?

regards, tom lane

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

Re: [HACKERS] stat() vs cygwin

Andrew Dunstan wrote:
>
>
> Magnus Hagander wrote:
>> Kenneth Marshall wrote:
>>
>>> One motivation for keeping it working on Cygwin, is that in some
>>> environments it is not allowed to install native Windows apps but
>>> they allow the use of the Cygwin environment. Of course if it takes
>>> too many resources to support, then dropping support would be an
>>> option. I would check this for you, but I am in the middle of moving
>>> and my Windows/Cygwin box is not available right now.
>>>
>>
>> Does anybody seriously have such a broken policy? I know a lot of places
>> who have inverse policy, where they don't allow cygwin, but I've never
>> heard of anybody refusing native programs and only allowing cygwin. Just
>> like I've heard of no linux shops requiring that you run your database
>> under wine...
>>
>>
>>
>
> This whole argument is pointless, ISTM. We are not in the business of
> telling people what environment to use Postgres in.

Well, agreed, the argument was that it should be dropped *IF* it turns
into a maintenance burden. Which it hasn't yet done.


> More to the point: I thought this had been tested. I will test it today
> so we can put this whole thread to rest.

IIRC it was only tested insofar that it doesn't actually break. Not if
it returns proper results.

Buf if my memory isn't completely off, there are other such cases as
well around the code, where we've done proper fixes for native win32 and
left cygwin alone. The argument being that for a developer system, it
doesn't really matter if things aren't entirely reliable, and that
nobody should be using cygwin for a production server. (I have nothing
against using it for a dev box, though I wouldn't do it myself)

//Magnus

--
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] stat() vs cygwin

Magnus Hagander wrote:
> Kenneth Marshall wrote:
>
>> One motivation for keeping it working on Cygwin, is that in some
>> environments it is not allowed to install native Windows apps but
>> they allow the use of the Cygwin environment. Of course if it takes
>> too many resources to support, then dropping support would be an
>> option. I would check this for you, but I am in the middle of moving
>> and my Windows/Cygwin box is not available right now.
>>
>
> Does anybody seriously have such a broken policy? I know a lot of places
> who have inverse policy, where they don't allow cygwin, but I've never
> heard of anybody refusing native programs and only allowing cygwin. Just
> like I've heard of no linux shops requiring that you run your database
> under wine...
>
>
>

This whole argument is pointless, ISTM. We are not in the business of
telling people what environment to use Postgres in.

Using Cygwin is still the best way I know of to use psql on Windows, and
it works just fine as a development environment.

By contrast, setting up a development environment for the native build
in either supported flavor is distinctly non-trivial.

(And yes I know about the problems Cygwin causes if you put it in the
System PATH. Don't do that.)

More to the point: I thought this had been tested. I will test it today
so we can put this whole thread to rest.

cheers

andrew

--
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] A GUC variable to replace PGBE_ACTIVITY_SIZE

I'd like to see some quick testing of this thing mentioned in the comments:

> /*
> * XXX if pgstat_track_activity_query_size is really large,
> * it might be best to use strcpy not memcpy for copying the
> * activity string?
> */

If we make it a GUC, there will be people running with "really large"
pgstat_track_activity_query_size settings. In fact I wouldn't be
surprised if people routinely cranked it up to the 10-100 KB range, just
in case.

It's going to be platform-dependent, for sure, but some quick
micro-benchmarks of where the break-even point between memcpy and strcpy
lies would be nice.

--
Heikki Linnakangas
EnterpriseDB

http://www.enterprisedb.com

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

Re: [pgsql-es-ayuda] Ayuda con una funcion SQL

Gracias, me funcionó utilizando el UNION ALL y además de la forma que
calabazas me envió como ejemplo.

Gracias una vez más.


----- Original Message -----
From: "Calabaza" <calalinux@gmail.com>
To: <pgsql-es-ayuda@postgresql.org>
Sent: Monday, June 23, 2008 1:12 PM
Subject: Re: [pgsql-es-ayuda] Ayuda con una funcion SQL


2008/6/20 Juan Carlos Badillo Goy <badillo@cav.desoft.cu>:
> Ahora estoy tratando de hacer que una función me retorne lo siguiente: (la
> suma o union por asi decirlo de rs_tabla_1 y rs_tabla_2 )

Eso lo puedes hacer con una vista:

> CREATE OR REPLACE FUNCTION "public"."funct_resultante" (aid_usuario
> integer)
> RETURNS SETOF "public"."tabla_1" AS
> $body$
> declare rs_tabla_1 tabla_1%rowtype;
> declare rs_tabla_2 tabla_1%rowtype;
> begin
>
> for rs_tabla_1 in
> select * from rs_tabla_1 where propietario = aid_usuario and
> (tipo = 2 or tipo = 7)
> loop
> return next rs_tabla_1;
> end loop;
>
> for rs_tabla_2 in
> select * from rs_tabla_2 where propietario = aid_usuario and
> tipo
> = 9
> loop
> return next rs_tabla_2;
> end loop;
>
> return;
> end;
> $body$
> LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

Imagino que las columnas que devuelven ambas tablas son de igual
cantidad y del mismo tipo :

Prueba esto:


Select * from
(
select * from rs_tabla_1 where propietario = 777 and (tipo = 2 or tipo = 7)
) as a
union
(
select * from rs_tabla_2 where propietario = 777 and tipo = 9
) as b

777 = tu identificador de usuario...

Date una vuelta por:
http://www.postgresql.org/docs/8.3/interactive/sql-select.html#SQL-UNION

Un abrazo...
--
§~^Calabaza^~§ from Villa Elisa, Paraguay
----------------
A hendu hína: 1864 - 1949 RICHARD STRAUSS - op.28, Till Eulenspiegels
lustige Striche
http://foxytunes.com/artist/1864+-+1949+richard+strauss/track/op.28%2c+till+eulenspiegels+lustige+striche
--
TIP 6: ¿Has buscado en los archivos de nuestra lista de correo?

http://archives.postgresql.org/pgsql-es-ayuda


--
TIP 10: no uses HTML en tu pregunta, seguro que quien responda no podrá leerlo

[COMMITTERS] pgsnap - pgsnap: Bugfix : check that the js directory exists before

Log Message:
-----------
Bugfix : check that the js directory exists before trying to empty it, per a report from
Claude Castello.

Modified Files:
--------------
pgsnap/pgsnap:
ChangeLog (r1.65 -> r1.66)
(http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/pgsnap/pgsnap/pgsnap/ChangeLog.diff?r1=1.65&r2=1.66)
pgsnap/pgsnap/lib:
reports.php (r1.6 -> r1.7)
(http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/pgsnap/pgsnap/pgsnap/lib/reports.php.diff?r1=1.6&r2=1.7)

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

[GENERAL] Problem by adding libpq++

 

Hallo fellows

i am new user of postgresql and need ur help to understand it.I am now using postgresql 3.0 with Microsoft Visual C++ 2005 express edition.But i can't connect MV C++ with postgresql.There is always library failure.

Pls help me. I have installed all on window XP.

salman



Gesendet von Yahoo! Mail.
Dem pfiffigeren Posteingang.

Re: [PERFORM] Postgresql is very slow

>> Not necessarily, the 'cost' depends on
>> seq_page_cost and there might be
>> other value than 1 (which is the default). A better
>> approach is
>>
>> SELECT relpages, reltuples FROM pg_class WHERE relname =
>> 'users';
>>
>> which reads the values from system catalogue.
>>
> The Output of query on the Slow Server
>
> SELECT relpages, reltuples FROM pg_class WHERE relname ='users';
> relpages | reltuples
> ----------+-----------
> 54063 | 2307
> (1 row)
>
> The Output of query on the old server which is fast
>
> relpages | reltuples
> ----------+-----------
> 42 | 1637
>
>

This definitely confirms the suspicion about dead tuples etc. On the old
server the table has 1637 tuples and occupies just 42 pages (i.e. 330kB
with 8k pages), which gives about 0.025 of a page (0.2kB per) per row.

Let's suppose the characteristics of data (row sizes, etc.) are the same
on both servers - in that case the 2307 rows should occuppy about 58
pages, but as you can see from the first output it occupies 54063, i.e.
400MB instead of 450kB.

>> > Definitely need a vacuum full on this table, likely
>> followed by a reindex.
>>
>
> The Slow server load increases whenever i run a simple query, is it the
> good idea to run VACUUM full on the live server's database now or it
> should be run when the traffic is very low may be in weekend.

The load increases because with the queries you've sent the database has
to read the whole table (sequential scan) and may be spread through the
disk (thus the disk has to seek).

I'd recommend running CLUSTER instead of VACUUM - that should be much
faster in this case. It will lock the table, but the performance already
sucks, so I'd probably prefer a short downtime with a much faster
processing after that.

>
>> Yes, that's true. I guess the table holds a lot of dead
>> tuples. I'm not
>> sure why this happens on one server (the new one) and not
>> on the other
>> one. I guess the original one uses some automatic vacuuming
>> (autovacuum,
>> cron job, or something like that).
>
> There was nothing related to VACUUM of database in the crontab.

In that case there's something running vacuum - maybe autovacuum (see
postgresql.conf), or so.

>> As someone already posted, clustering the table (by primary
>> key for
>> example) should be much faster than vacuuming and give
>> better performance
>> in the end. See
>>
>> http://www.postgresql.org/docs/8.3/interactive/sql-cluster.html
>>
>> The plain reindex won't help here - it won't remove
>> dead tuples.
>>
> I am new to Postgres database, i didnt understand the "indexing" part. Is
> it related to PRIMARY_KEY column of the table?

Not sure what you mean by the 'nd

Principle of clustering is quite simple - by sorting the table according
to an index (by the columns in the index) you may get better performance
when using the index. Another 'bonus' is that it compacts the table on the
disk, so disk seeking is less frequent. These two effects may mean a
serious increase of performance. You may cluster according to any index on
the table, not just by primary key - just choose the most frequently used
index.

Sure, there are some drawbacks - it locks the table, so you may not use it
when the command is running. It's not an incremental operation, the order
is not enforced when modifying the table - when you modify a row the new
version won't respect the order and you have to run the CLUSTER command
from time to time. And it's possible to cluster by one index only.

>
> Should i have to run:- CLUSTER USERS using 'username';

I guess 'username' is a column, so it won't work. You have to choose an
index (I'd recommend the primary key index, i.e. the one with _pk at the
end).

Tomas


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

[GENERAL] Query

Hello there

Can anyone please tell me how to make a column uneditable….

Plz  give me some output

thans

Re: [PERFORM] Postgresql is very slow

2008/6/24 Scott Marlowe <scott.marlowe@gmail.com>:
> On Mon, Jun 23, 2008 at 11:48 PM, bijayant kumar <bijayant4u@yahoo.com> wrote:
(...)
>> The output of EXPLAIN query;
>>
>> select * from USERS where email like '%bijayant.kumar%';
>> This simplest query tooks 10 minutes and server loads goes from 0.35 to 16.94.
>>
>> EXPLAIN select * from USERS where email like '%bijayant.kumar%';
>> QUERY PLAN
>> --------------------------------------------------------------
>> Seq Scan on USERS (cost=0.00..54091.84 rows=1 width=161)
>> Filter: ((email)::text ~~ '%bijayant.kumar%'::text)
>> (2 rows)
>
> You're scanning ~ 54094 sequential pages to retrieve 1 row. Note
> that explain analyze is generally a better choice, it gives more data
> useful for troubleshooting.
>
> Definitely need a vacuum full on this table, likely followed by a reindex.

This is a LIKE query with a wildcard at the start of the string to
match, reindexing won't help much.


Ian Barwick

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

Re: [PERFORM] Postgresql is very slow

--- On Tue, 24/6/08, tv@fuzzy.cz <tv@fuzzy.cz> wrote:

> From: tv@fuzzy.cz <tv@fuzzy.cz>
> Subject: Re: [PERFORM] Postgresql is very slow
> To: "Scott Marlowe" <scott.marlowe@gmail.com>
> Cc: bijayant4u@yahoo.com, tv@fuzzy.cz, pgsql-performance@postgresql.org
> Date: Tuesday, 24 June, 2008, 1:47 PM
> >> I was not aware of the VACUUM functionality
> earlier, but some times back
> >> i read and run this on the server but i did not
> achieve anything in
> >> terms of performance. The server is running from 1
> to 1.5 years and we
> >> have done VACUUM only once.
> >
> > vacuuming isn't so much about performance as about
> maintenance. You
> > don't change the oil in your car to make it go
> faster, you do it to
> > keep it running smoothly. Don't change it for 1.5
> years and you could
> > have problems. sludge build up / dead tuple build up.
> Kinda similar.
> >
>
> I have to disagree - the VACUUM is a maintenance task, but
> with a direct
> impact on performance. The point is that Postgresql holds
> dead rows (old
> versions, deleted, etc.) until freed by vacuum, and these
> rows need to be
> checked every time (are they still visible to the
> transaction?). So on a
> heavily modified table you may easily end up with most of
> the tuples being
> dead and table consisting of mostly dead tuples.
>
> >> The output of EXPLAIN query;
> >>
> >> select * from USERS where email like
> '%bijayant.kumar%';
> >> This simplest query tooks 10 minutes and server
> loads goes from 0.35 to
> >> 16.94.
> >>
> >> EXPLAIN select * from USERS where email like
> '%bijayant.kumar%';
> >> QUERY PLAN
> >>
> --------------------------------------------------------------
> >> Seq Scan on USERS (cost=0.00..54091.84 rows=1
> width=161)
> >> Filter: ((email)::text ~~
> '%bijayant.kumar%'::text)
> >> (2 rows)
> >
> > You're scanning ~ 54094 sequential pages to
> retrieve 1 row. Note
> > that explain analyze is generally a better choice, it
> gives more data
> > useful for troubleshooting.
>
> Not necessarily, the 'cost' depends on
> seq_page_cost and there might be
> other value than 1 (which is the default). A better
> approach is
>
> SELECT relpages, reltuples FROM pg_class WHERE relname =
> 'users';
>
> which reads the values from system catalogue.
>
The Output of query on the Slow Server

SELECT relpages, reltuples FROM pg_class WHERE relname ='users';
relpages | reltuples
----------+-----------
54063 | 2307
(1 row)

The Output of query on the old server which is fast

relpages | reltuples
----------+-----------
42 | 1637


> > Definitely need a vacuum full on this table, likely
> followed by a reindex.
>

The Slow server load increases whenever i run a simple query, is it the good idea to run VACUUM full on the live server's database now or it should be run when the traffic is very low may be in weekend.

> Yes, that's true. I guess the table holds a lot of dead
> tuples. I'm not
> sure why this happens on one server (the new one) and not
> on the other
> one. I guess the original one uses some automatic vacuuming
> (autovacuum,
> cron job, or something like that).

There was nothing related to VACUUM of database in the crontab.
>
> As someone already posted, clustering the table (by primary
> key for
> example) should be much faster than vacuuming and give
> better performance
> in the end. See
>
> http://www.postgresql.org/docs/8.3/interactive/sql-cluster.html
>
> The plain reindex won't help here - it won't remove
> dead tuples.
>
I am new to Postgres database, i didnt understand the "indexing" part. Is it related to PRIMARY_KEY column of the table?

Should i have to run:- CLUSTER USERS using 'username';

> Tomas

Send instant messages to your online friends http://uk.messenger.yahoo.com

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

Re: [HACKERS] Git Repository for WITH RECURSIVE and others

David Fetter wrote:
> Folks,
>
> With lots of help from Greg Sabino Mullane, I've set up a git
> repository for the WITH RECURSIVE patches on
> <http://git.postgresql.org/>.
>
> What other patches would people like to try maintaining this way until
> commitfest?
>
> It looks like gitosis is a good way to grant write access to git
> repositories, but it's not yet packaged for FreeBSD. Any ideas about
> how to handle this?

As you were answered the last time you asked about it, people are
already working on this. Unfortunately, the requirements have also been
raised a bit (such as allowing a user to delegate access to another
user) which means it will take longer.

Now, if you can give us a step-by-step on how to set it up, that would
certainly help ;-)

//Magnus

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

Re: [PERFORM] Postgresql is very slow

On Mon, Jun 23, 2008 at 11:48 PM, bijayant kumar <bijayant4u@yahoo.com> wrote:

OK, you don't have a ton of updates each day, but they add up over time.

> I was not aware of the VACUUM functionality earlier, but some times back i read and run this on the server but i did not achieve anything in terms of performance. The server is running from 1 to 1.5 years and we have done VACUUM only once.

vacuuming isn't so much about performance as about maintenance. You
don't change the oil in your car to make it go faster, you do it to
keep it running smoothly. Don't change it for 1.5 years and you could
have problems. sludge build up / dead tuple build up. Kinda similar.

> Is this the problem of slow database? One more thing if i recreate the database, will it help?

Most likely. What does

vacuum verbose;

on the main database say?

> The output of ANALYZE
>
> ANALYZE verbose USERS;
> INFO: analyzing "public.USERS"
> INFO: "USERS": scanned 3000 of 54063 pages, containing 128 live rows and 1 dead rows; 128 rows in sample, 2307 estimated total rows
> ANALYZE

So, 54963 pages hold 128 live database rows. A page is 8k. that
means you're storing 128 live rows in approximately a 400+ megabyte
file.

> The output of EXPLAIN query;
>
> select * from USERS where email like '%bijayant.kumar%';
> This simplest query tooks 10 minutes and server loads goes from 0.35 to 16.94.
>
> EXPLAIN select * from USERS where email like '%bijayant.kumar%';
> QUERY PLAN
> --------------------------------------------------------------
> Seq Scan on USERS (cost=0.00..54091.84 rows=1 width=161)
> Filter: ((email)::text ~~ '%bijayant.kumar%'::text)
> (2 rows)

You're scanning ~ 54094 sequential pages to retrieve 1 row. Note
that explain analyze is generally a better choice, it gives more data
useful for troubleshooting.

Definitely need a vacuum full on this table, likely followed by a reindex.

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