Re: [GENERAL] Postgres Database size

2007-03-18 Thread Naz Gassiep




I have been looking for such a function. Having Just upgraded to 8.2,
this function is a very welcome addition to my arsenal of tools.
Many thanks!
- Naz.

Reece Hart wrote:

  On Sun, 2007-03-18 at 00:40 +0530, Mageshwaran wrote:
  
  
how to find the size of a particular database in postgres...

  
  
The old way was to use du or similar. Recent versions (I believe >=8.1,
but check the release notes to be sure) provide several useful functions
for this:
 pg_column_size
 pg_database_size
 pg_relation_size
 pg_size_pretty
 pg_tablespace_size
 pg_total_relation_size


For example:

[EMAIL PROTECTED]> select datname,pg_size_pretty(pg_database_size(oid)) from
pg_database ;
   datname   | pg_size_pretty 
-+
 postgres| 3905 kB
 csb | 113 GB
 template0   | 3840 kB
 csb-dev | 124 GB
 csb-dev-snapshot-2007-03-08 | 123 GB
 csb_02_02_2007  | 121 GB
 template1   | 3840 kB


  





Re: [GENERAL] Shell script to determine if PostgreSQL is accepting connections?

2007-03-18 Thread Reid Thompson
On 10:44 Sun 18 Mar , Jeff Ross wrote:
> Hi,
>
> Is there a simple way to determine with a shell script if PostgreSQL is
> ready to accept connections?
>
> PostgreSQL is started and controlled by daemontools.  This shell script
> is called by the /etc/netstart script  as a part of bringing up the
> first interface.  Unfortunately, it will never exit the loop.
>
> #!/bin/sh
> /bin/csh -cf '/command/svscanboot &'
> until [ -S /tmp/.s.PGSQL.5432 ] ; do
> /bin/echo "Waiting for PostgreSQL to start..."
> /bin/sleep 1
> done
>
> Because this is happening at startup before I get a login prompt I'm not
> sure I know how to figure out why it never exits the loop.
>
> The purpose of this is that I'm running pglogd, a daemon that uses a
> custom log format and a fifo to stuff Apache web logs into a table.  The
> pglogd daemon must start after PostgreSQL and before Apache.  I can do
> this in /etc/rc.local, but OpenBSD's /etc/rc wants to start Apache
> before rc.local is parsed.  Once I know that PostgreSQL is up and
> accepting connections I can then start pglogd and then it's ready to go
> when Apache starts.
>
> As a side note, the original creator and maintainer of pglogd has EOLed
> the project but it works well for me under 8.2.3.  I intend to fix a few
> of its problems (it does fine until the backend goes away ;-) and
> re-release it.
>
> Thanks,
>
> Jeff Ross
>
> P.S.  Apologies to the owner of the list--I inadvertently sent this to
> the wrong address first.
>
> ---(end of broadcast)---
> TIP 3: Have you checked our extensive FAQ?
>
>   http://www.postgresql.org/docs/faq

variants on the following might be useful...

$ psql -U postgres -t  -c "select pg_postmaster_start_time()" postgres`
  2007-03-18 16:51:55.239342-04

so ...

start loop
response=`psql -U postgres -t  -c "select pg_postmaster_start_time()" 
postgres`
or
response=`psql -U postgres -t  -c "select now()" postgres`

if [ $? == 0 ]; then
parse/evaluate response to make determination of whether db is up
( or, base decision on evaluation of $? )
break loop if db is up or other criteria are met ( taking too
long, etc )
else
   query failed, backend not ready, continue loop
fi
end loop


---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] PostgreSQL 8.2.3 VACUUM Timings/Performance

2007-03-18 Thread Martijn van Oosterhout
On Fri, Mar 16, 2007 at 07:06:57PM -, Bruce McAlister wrote:
> Okay, I'm getting a little further now. I'm about to create entries in the 
> pg_autovacuum system tables. However, I'm a little confused as to how I go 
> about finding out the OID value of the tables. The pg_autovacuum table 
> requires the OID of the table you want to create settings for (vacrelid). 
> Can anyone shed some light on how I can extract the OID of the table? Also, 
> what happens if you create a table without OID's, are you still able to add 
> it's details in the pg_autovacuum table if there is no OID associated with a 
> table?

The easiest would seem to be to be:

SELECT 'mytable'::regclass;

That will get you the OID without you having to look it up yourself.

Have a nice day,
-- 
Martijn van Oosterhout  http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to 
> litigate.


signature.asc
Description: Digital signature


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Tom Lane
Stefan Berglund <[EMAIL PROTECTED]> writes:
> I tried this:

> create or replace function foo(plist TEXT)
>   RETURNS SETOF Show_Entries as $$

>   SELECT *
>   FROM Show_Entries
>   WHERE Show_ID = 1250 AND Show_Number IN ($1);

> $$ LANGUAGE sql;

> When I use select * from foo('101,110,115,120'); I get no results.  When
> I use select * from foo(101,110,115,120); I get the correct results.

Just for the record, the reason that didn't work is that Postgres saw it
as a comparison to a single scalar IN-list item.  What you had was
effectively

   WHERE Show_ID = 1250 AND Show_Number::text IN ('101,110,115,120');

which of course will fail to find any rows.

In recent releases (8.2 for sure, don't remember if 8.1 can do this
efficiently) you could instead do

create or replace function foo(plist int[])
  RETURNS SETOF Show_Entries as $$

  SELECT *
  FROM Show_Entries
  WHERE Show_ID = 1250 AND Show_Number IN ($1);

$$ LANGUAGE sql;

select * from foo(array[101,110,115,120]);

regards, tom lane

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


[GENERAL] Shell script to determine if PostgreSQL is accepting connections?

2007-03-18 Thread Jeff Ross

Hi,

Is there a simple way to determine with a shell script if PostgreSQL is 
ready to accept connections?


PostgreSQL is started and controlled by daemontools.  This shell script 
is called by the /etc/netstart script  as a part of bringing up the 
first interface.  Unfortunately, it will never exit the loop.


#!/bin/sh
/bin/csh -cf '/command/svscanboot &'
until [ -S /tmp/.s.PGSQL.5432 ] ; do
/bin/echo "Waiting for PostgreSQL to start..."
/bin/sleep 1
done

Because this is happening at startup before I get a login prompt I'm not 
sure I know how to figure out why it never exits the loop.


The purpose of this is that I'm running pglogd, a daemon that uses a 
custom log format and a fifo to stuff Apache web logs into a table.  The 
pglogd daemon must start after PostgreSQL and before Apache.  I can do 
this in /etc/rc.local, but OpenBSD's /etc/rc wants to start Apache 
before rc.local is parsed.  Once I know that PostgreSQL is up and 
accepting connections I can then start pglogd and then it's ready to go 
when Apache starts.


As a side note, the original creator and maintainer of pglogd has EOLed 
the project but it works well for me under 8.2.3.  I intend to fix a few 
of its problems (it does fine until the backend goes away ;-) and 
re-release it.


Thanks,

Jeff Ross

P.S.  Apologies to the owner of the list--I inadvertently sent this to 
the wrong address first.


---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


[GENERAL] phpPgAdmin - prior version available?

2007-03-18 Thread Bob Hartung

Hi all,
  I have been struggling with phpPgAdmin 4.1 - login failures.  There 
does not yet seem to be a fix.  Where can I find a prior version for FC6 
- rpm, tar.gz etc.


Thanks,

Bob

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


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Martijn van Oosterhout
On Thu, Mar 15, 2007 at 10:26:48AM -0700, Stefan Berglund wrote:
> that PostgreSQL would allow a substitutable parameter in the IN clause. 
> However, it seems that it can't be done in this fashion without using
> dynamic SQL unless I'm missing something.

The substitutable list has to be an array, not a text value. So
if the parameter is specified as ARRAY OF INTEGER, you can call it
like:

SELECT foo(ARRAY[1,2,3,45]);
SELECT foo('{1,2,3,4,56}');

Hope this helps,
-- 
Martijn van Oosterhout  http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to 
> litigate.


signature.asc
Description: Digital signature


Re: [GENERAL] Design / Implementation problem

2007-03-18 Thread Ted Byers

Naz

First, there is nothing you can do about the computational load except make 
your code as efficient as possible.  Get it right and then make it fast. 
But there is only so much you can do.  If a "calculation" requires an 
integer sum and an integer difference, you inevitably have two integer 
operations per "calculation".  For a given complex calculation, you 
generally have to resort to a little algebra to put the calculation into a 
form that requires the least number of atomic operations (think of a mean 
and variance, for a simple example where a brute force approach will be 
correct but much more expensive than one based on a little algebraic 
manipulation.  That leaves making your application appear to be more 
responsive by distributing the computational load differently.  This time 
think of some basic data structures and the work required to obtain sorted 
output.  Considering the standard C++ STL, one could use a  vector, with 
contents in random order, and sort that, or one could use a map and have 
sorted output at any time without an explicit sort operation before getting 
it.  But think what has happened.  Element access, including especially 
inserts or additions and reading container elements, will be very fast with 
the vector, faster than with a map.  But all the computational load for 
obtaining sorted output is carried at the moment the request for such output 
is made.  On the other hand, getting sorted output from the map will appear 
to be blindingly fast relative to getting the same output from the vector. 
Why?  Because getting sorted output requires a certain number of 
comparisons.  This can not be avoided.  But with the map, these are done on 
insert, so your data is actually stored sorted.  The price of the sort is 
paid in both the case of using a vector and in the case of using the map, 
but the user may not notice that cost in the case of a map where he would in 
the case of the vector (if the dataset is large).  I suspect you are aware 
of some of this already, but I say it just to make certain of it.


I say all the above so that you don't get too distracted by your 
calculations of the potential costs of supporting your program.  You need to 
have an idea of how expensive it wll be, and how you might distribute the 
costs, but if you have millions of clients, and each operation requires a 
hald a dozen basic operations, there is no avoiding that.  You reduce as 
much as possible, but you will always get to a point where it can not be 
reduced further.  At that point, all you can do is throw more iron at the 
application.


Now, an option to consider.  Create two tables, one for points accrued and 
one for points used.  In each case, you'll have fields to identify the 
customer, his transactions, etc., but the important fields will be one for 
the number of points (acquired or used) on a given day, and the date.  It 
may also be prudent to have a field to represent expiry date since how long 
points can be stored before they have to be used is a policy decision, one 
that could change at any time, and ought therefore be a data item stored 
rather than hardcoded into your code.  The points acquired table will need a 
field to represent the points acquired on that date that remain to be used, 
so that transactions using points can use the oldest points acquired by the 
customer before using new ones.  You may well want this for auditing 
purposes in addition to the core functionality you're after.  Now add a 
third which keeps track of the number of points available at a given time. 
Again, you'll have fields to identify the customer, the number of available 
points, and maybe the date (it depends on how you want to do it and what 
else your database needs to support).  Now, update the points acquired table 
and the summary table in each transaction in which the customer can gain 
points, and update the points used table and summary table in each 
transaction where the customer can use points.  And you can update all three 
in transactions where a customer can use points for part of the transaction 
and other resources for the rest.  At least until your unit testing is done, 
I'd suggest an extra table or two that allows you to store information about 
which points a customer is using for a given transaction, just to make 
absolutely certain that in fact your customer is using the oldest points 
that he has, in a given transaction, before the ones he acquired today. 
Finally, you may want to create archive tables and a scheduled task that 
moves records dealing with expired points from the table you're always 
working with to the archive tables (in enough detail that you can 
reconstruct precisely how and when points were acquired and used by each 
customer), but you might need extra code to bring them back should a policy 
make decide that points can have a three year lifespan instead of one.  I'd 
put all the required code to support all of this into a suite of store

Re: [GENERAL] cannot get build (initdb) to work after trying for a week

2007-03-18 Thread Magnus Hagander
Eric wrote:
> I am getting truly desperate!  I am trying to build any version of
> Postgres on Windows from source.  First experience with Postgres
> source.  I have struggled for days trying to solve a problem. Would be
> willing to pay for the solution!!!
> 
> The following error occurred when issuing a vanilla initdb command on
> my Windows system.
> 
> 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.
> 
> I built this from 8.1.8 source under msys/mingw.  Also tried 8.2.2.
> Everything builds fine but initdb always reports the above error and
> quits.

This could happen if the timezone files aren't properly installed. This
should normally happen when you do "make install", but verify that they
are actually present (in share/timezone).

> I also had to create a typedef int ssize_t in a couple of files to get
> the compile finished.  Maybe this is related.  Other than that, have
> not touched any code.

I don't think that's related, but it's a clear indicator that something
in your environment is broken. Because it should build without any such
changes.

//Magnus

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [GENERAL] cannot get build (initdb) to work after trying for a week

2007-03-18 Thread Alvaro Herrera
Eric wrote:
> I am getting truly desperate!  I am trying to build any version of
> Postgres on Windows from source.  First experience with Postgres
> source.  I have struggled for days trying to solve a problem. Would be
> willing to pay for the solution!!!
> 
> The following error occurred when issuing a vanilla initdb command on
> my Windows system.
> 
> 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.

Try specifying a timezone in postgresql.conf.  For initdb, I'd try
specifying it in the TZ environment variable.

-- 
Alvaro Herrerahttp://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

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


[GENERAL] cannot get build (initdb) to work after trying for a week

2007-03-18 Thread Eric
I am getting truly desperate!  I am trying to build any version of
Postgres on Windows from source.  First experience with Postgres
source.  I have struggled for days trying to solve a problem. Would be
willing to pay for the solution!!!

The following error occurred when issuing a vanilla initdb command on
my Windows system.

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.

I built this from 8.1.8 source under msys/mingw.  Also tried 8.2.2.
Everything builds fine but initdb always reports the above error and
quits.

I was able to run successfully from 8.1.5 binaries on the same
system.  This would lead me to believe that it is a simple compiler
switch somewhere that would alleviate this problem.

I have tried variations of configure, including and not including
mingw includes and libs.

I also had to create a typedef int ssize_t in a couple of files to get
the compile finished.  Maybe this is related.  Other than that, have
not touched any code.

Given that an 8.1.5 binary dist worked for me, what flags were
provided to build that version?  Simply configure, then make?


---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [GENERAL] PgSql on Vista?

2007-03-18 Thread [EMAIL PROTECTED]

Ok thanks i've fixed.
The problem is with 8.2.3 installer, i tried 8.1.8 and I had no problem.

Thanks

On 3/15/07, Dave Page <[EMAIL PROTECTED]> wrote:



> --- Original Message ---
> From: Alvaro Herrera <[EMAIL PROTECTED]>
> To: Dave Page <[EMAIL PROTECTED]>
> Sent: 15/03/07, 22:32:50
> Subject: Re: [GENERAL] PgSql on Vista?
>
> Dave Page escribió:
> > Paul Lambert wrote:
> >
> > >After install completes you can turn it back on... if you want -
> > >personally I leave it off, it's an incredibly annoying "feature".
> >
> > Doesn't the security center keep popping up to point out that it's
> > turned off?
>
> You mean, like this?
>
> 
http://images.apple.com/movies/us/apple/getamac/apple-getamac-security_480x376.mov
>

I haven't watched yet as I'm on my pda, but would it seem a little ironic if I 
pointed out that the Windows distribution of PostgreSQL is built on a Macbook 
Pro these days?

/D




--
(¯`·._)
XF86Config ne sa MOLTE più del diavolo. O forse serve ad evocare il
diavolo stesso, non ho capito bene.
(¯`·._)

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


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Stefan Berglund
On Sat, 10 Mar 2007 08:26:32 +0300 (MSK), oleg@sai.msu.su (Oleg
Bartunov) wrote:
 in <[EMAIL PROTECTED]> 

>I don't know if you could change your schema. but I'd consider your
>problem as a overlapping arrays task and use contrib/intarray for that.

That's a nice piece of work, Oleg, and extremely quick.  I played with
it and pored over the docs but it just seems to keep coming back to the
fact that all of the array type manipulations are column based as
opposed to row based.  In fact, this from section 8.10.5 of the docs
confirms it:

Tip
Arrays are not sets; searching for specific array elements may be a sign
of database misdesign. Consider using a separate table with a row for
each item that would be an array element. This will be easier to search,
and is likely to scale up better to large numbers of elements. 

I was able to clean up the function I originally posted removing the
extraneous LOOP and I'm more than happy with the performance.  What's
funny is that the function as it now stands is what I initially obtained
by googling, but I mistakenly added the extra loop.  :-)

What I finally came up with is here:
<[EMAIL PROTECTED]> 

---
Stefan Berglund

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


Re: [GENERAL] issue with SELECT settval(..);

2007-03-18 Thread Alain Roger

thanks a lot Christian.

On 3/18/07, Christian Schröder <[EMAIL PROTECTED]> wrote:


Alain Roger wrote:
> insert into immense.statususer (statususer_id, statususer_type) values
> (SELECT nextval( 'statususer_statususer_id_seq' ),'customer');
The correct syntax would be:

insert into immense.statususer (statususer_id, statususer_type) values
((SELECT nextval( 'statususer_statususer_id_seq' )),'customer');

The sub-select must be put in parentheses. However, the much simpler
statement

insert into immense.statususer (statususer_id, statususer_type) values
(nextval( 'statususer_statususer_id_seq' ),'customer');

will do the same without a sub-select.

Regards
Christian

--
Deriva GmbH Tel.: +49 551 489500-42
Financial IT and Consulting Fax:  +49 551 489500-91
Hans-Böckler-Straße 2  http://www.deriva.de
D-37079 Göttingen

Deriva CA Certificate: http://www.deriva.de/deriva-ca.cer


---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly





--
Alain

Windows XP SP2
PostgreSQL 8.1.4
Apache 2.0.58
PHP 5


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Stefan Berglund
On Fri, 16 Mar 2007 09:38:52 -0300, [EMAIL PROTECTED] (Jorge Godoy)
wrote:
 in <[EMAIL PROTECTED]> 

>Tino Wildenhain <[EMAIL PROTECTED]> writes:
>
>> Show me a user which really clicks on 1000 or more checkboxes on a
>> webpage or similar ;)
>> I'd think around 20 values is plenty.
>
>On the other hand, show me a page with 1000 or more checkboxes to be clicked
>at once and I'd show a developer / designer that needs a new career... :-)

Just to allay your fears, a fairly typical scenario might have the user
presented with a list of from twenty to fifty names of horse trainers
depending on the size of the show.  Since each trainer can have anywhere
from one to thirty or forty horses in their barn you can do the math to
see that the list of IDs passed from the app to the database can be
anywhere from a single ID up to possibly thousands of IDs.

---
Stefan Berglund

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Stefan Berglund
On Thu, 15 Mar 2007 15:46:33 -0500, [EMAIL PROTECTED] (Bruno Wolff III)
wrote:
 in <[EMAIL PROTECTED]> 

>On Mon, Mar 12, 2007 at 11:15:01 -0700,
>  Stefan Berglund <[EMAIL PROTECTED]> wrote:
>> 
>> I have an app where the user makes multiple selections from a list.  I
>> can either construct a huge WHERE clause such as SELECT blah blah FROM
>> foo WHERE (ID = 53016 OR ID = 27 OR ID = 292 OR ID = 512) or I could
>> alternatively pass the string of IDs ('53016,27,292,512') to a table
>> returning function which TABLE is then JOINed with the table I wish to
>> query instead of using the unwieldy WHERE clause.  The latter strikes me
>> as a far more scalable method since it eliminates having to use dynamic
>> SQL to construct the ridiculously long WHERE clause which will no doubt
>> ultimately bump up against parser length restrictions or some such.
>
>How big is huge?
>If the list of IDs is in the 1000s or higher, then it may be better to
>load the data into a temp table and ANALYSE it before running your query.
>Otherwise, for smaller lists the IN suggestion should work well in recent
>versions.

Sorry, huge was an exaggeration.  I doubt it would ever approach 1000 -
more like a couple hundred.  I'll look at it a little closer.

---
Stefan Berglund

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


[GENERAL] Own messages for constraints?

2007-03-18 Thread Kacper Chrapa
Hi !

Is it possible in postgres to define own message for some constraint?

Example:
If i create check constraint on zip_code column , i want to get
a message: "Zip code is invalid.Please,input code in format: nn-nnn"
and I want to send this message to the end user.
It will be much better(in my case) than "violates constraint 
zip_code_check" :-) .

I can make this validation in trigger (and send msg to application by 
notice or raise),but in this case  i will duplicate validation
rules (in trigger and in constraint).Effect: Lower performance(i think) 
and rules in two places...


Best regards and thanks for help,
Kacper Chrapa


Fantastyczna promocja w RUCHu! Rób zakupy, wysyłaj SMSy 
i codziennie wygrywaj bony pieniężne! 
W finale do wygrania Nissan NOTE. 
Sprawdź: http://klik.wp.pl/?adr=www.loteriaruch.pl&sid=1062



---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] Is This A Set Based Solution?

2007-03-18 Thread Stefan Berglund
On Thu, 15 Mar 2007 09:47:27 -0500, [EMAIL PROTECTED] (George Weaver)
wrote:
 in <[EMAIL PROTECTED]> 

>
>Stefan Berglund wrote:
>
>> foo WHERE (ID = 53016 OR ID = 27 OR ID = 292 OR ID = 512) or I could
>> alternatively pass the string of IDs ('53016,27,292,512') to a table
>> returning function which TABLE is then JOINed with the table I wish to
>
>The user selections will be in some sort of list.  Could you not use WHERE 
>ID IN (the list)?

Coming from SQL Server where that is not allowed, it didn't occur to me
that PostgreSQL would allow a substitutable parameter in the IN clause. 
However, it seems that it can't be done in this fashion without using
dynamic SQL unless I'm missing something.

I tried this:

create or replace function foo(plist TEXT)
  RETURNS SETOF Show_Entries as $$

  SELECT *
  FROM Show_Entries
  WHERE Show_ID = 1250 AND Show_Number IN ($1);

$$ LANGUAGE sql;

When I use select * from foo('101,110,115,120'); I get no results.  When
I use select * from foo(101,110,115,120); I get the correct results.

At any rate, I'm happy with what I've come up with and so far
performance is excellent:

CREATE TABLE test_table (
  id int not null,
  tname varchar(50) not null);

INSERT INTO test_table
  SELECT 1, 'Adams'
UNION SELECT 2, 'Baker'
UNION SELECT 3, 'Chrysler'
UNION SELECT 4, 'Douglas'
UNION SELECT 5, 'Everyman';

CREATE OR REPLACE FUNCTION foo (
  pList TEXT) RETURNS SETOF INTEGER AS $foo$

DECLARE
  v_arr text[];

BEGIN
  v_arr := string_to_array($1, ',');
  FOR i IN array_lower(v_arr, 1)..array_upper(v_arr, 1) LOOP
RETURN NEXT v_arr[i]::int;
  END LOOP;
RETURN;
END;
$foo$ LANGUAGE plpgsql;

SELECT *
FROM
  foo('5,1,3') SL INNER JOIN
  test_table T ON SL=T.ID;

SELECT * FROM foo('52001,17,22,42,47') ORDER BY foo;

---
Stefan Berglund

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


Re: [GENERAL] Design / Implementation problem

2007-03-18 Thread Jorge Godoy
Naz Gassiep <[EMAIL PROTECTED]> writes:

> that calculating the point
> balance on the fly is not an unfeasibly heavy duty calculation to be done at
> every page view?

One alternative to calculate it everytime is calculating it once a day.  If
there are calculations for today, then just read the calculated value.
Otherwise calculate it. 

If the user earns more points, make an entry at the raw table (for the
expiration process) and increments today points.  Do the same for points
spent. 



-- 
Jorge Godoy  <[EMAIL PROTECTED]>

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [GENERAL] Design / Implementation problem

2007-03-18 Thread Naz Gassiep

Here it is again with more sensible wrapping:


*** The Scenario ***

We are running a customer loyalty program whereby customers earn points
for purchasing products. Each product has a value of points that are
earned by purchasing it, and a value of points required to redeem it.

In order to prevent customers from stockpiling points, we want to place
an expiry date on points so that unused points expire and are lost if
they are not redeemed within a certain period of time. This will be
calculated on a FIFO basis, I.e., the oldest points will expire first.

We will assume the expiry period is 12 months.


*** The Problem ***

Ascertaining which points to expire is fairly conceptually simple. At any
given point in time, the points expired is simply the balance on hand at
the start of the period, less redemptions in that period. If the
redemptions is less than the balance at open, not all points that were
available on that date were used, and the difference is the expiry.

This can be done periodically, say, at the start of every month. However
there are a few problems with doing it periodically

1. The runs are likely to be too large to be manageable. A DB with tens of
thousands of customers and many hundreds of thousands or even millions of
sales in the records tables will require several queries and some
application calculation to compute. If it takes 2 seconds to compute
each balance of a 20,000 strong customer base, that's over 11 hours of
heavy lifting in the DB, which will likely result in severely degraded
performance during those hours. This problem can only get worse as time
goes on, and hardware upgrade requirements just to accommodate a 12 hour
window once a month is the sign of an app not designed to scale well.

2. Calculating the balance on the fly would be more effective, as it is
unlikley that many customers will check their balance on a regular basis.
It is likely that a small fraction of customers will check their balance
in a given month, meaning that calculating it on the fly would both spread
the load over time as well as reduce the total load, even if on the fly
calculation results in significantly higher per-customer calculation time.

3. The app is a web app, and it would be preferable to contain business
logic within the database itself or the current app codebase. Spreading
application logic into an external mechanism such as cron or an external
daemon would be undesirable unless there was no other way.


*** A Possible Solution ***

Calculating the balance on the fly can be done easily if it is done at the
time the customer seeks to redeem a voucher. Expired points are only
relevant at these times, and so the expired points would be calculated
with an application function that did the following:

1. Get the balance as it was 12 months ago by getting total points earned
less redemptions and expiries up to that date.
2. Subtract from it redemptions and expiries since then. The value
obtained, if it is positive, is the value of points to expire.
3. Log the expiry entry, and then calculate the balance of points to the
current date by subtracting total points redeemed and expired from total
points earned.

This procedure has a few practical problems, however:
1. Customers, when they view their running total, will not be aware that
some of the points included in it will have expired, as the expiry will
only happen when the application attempts to log a redemption.
2. A customer may attempt to redeem a product they do not have enoughh
points for, and be told at the last minute that they do not have enough
points, leading to acrimony.

The solution is then to calculate it on only on redemptions, but also
whenever the customer attempts to view their balance. This will ensure
that expired points will never be shown in the current balance of
available points. This, however, means the calculation may be done many
times by each customer in a single catalog browsing session.


*** The Question ***

Is there a way to design the DB schema as well as the query in such a
manner that calculating the point balance on the fly is not an unfeasibly
heavy duty calculation to be done at every page view?

This problem does not appear to be solved comprehensively by anyone. When
I log into my credit card company web site to check my points, I get a
message "please come back in an hour, and your points will be calculated"
if I haven't logged in for over a week. So obviously they calculate the
balance and put it in a table that acts as a "cached balance".

Emirates has a different solution, they do bi-annual runs, so points
expire every March and September for them.

Neither of these solutions appeals, and there must be A Better Way(tm).

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

  http://archives.postgresql.org/


[GENERAL] Design / Implementation problem

2007-03-18 Thread Naz Gassiep
This is possibly not a DB only problem, the solution may involve 
application logic as well. But PG users

are the smartest bunch I know. Ass kissing aside, here are the details:

*** The Scenario ***

We are running a customer loyalty program whereby customers earn points 
for purchasing products. Each
product has a value of points that are earned by purchasing it, and a 
value of points required to

redeem it.

In order to prevent customers from stockpiling points, we want to place 
an expiry date on points so
that unused points expire and are lost if they are not redeemed within a 
certain period of time. This
will be calculated on a FIFO basis, I.e., the oldest points will expire 
first.


We will assume the expiry period is 12 months.

*** The Problem ***

Ascertaining which points to expire is fairly conceptually simple. At 
any given point in time, the
points expired is simply the balance on hand at the start of the period, 
less redemptions in that
period. If the redemptions is less than the balance at open, not all 
points that were available on

that date were used, and the difference is the expiry.

This can be done periodically, say, at the start of every month. However 
there are a few problems

with doing it periodically

1. The runs are likely to be too large to be manageable. A DB with tens 
of thousands of customers
  and many hundreds of thousands or even millions of sales in the 
records tables will require several
  queries and some application calculation to compute. If it takes 2 
seconds to compute each balance
  of a 20,000 strong customer base, that's over 11 hours of heavy 
lifting in the DB, which will
  likely result in severely degraded performance during those hours. 
This problem can only get
  worse as time goes on, and hardware upgrade requirements just to 
accommodate a 12 hour window

  once a month is the sign of an app not designed to scale well.

2. Calculating the balance on the fly would be more effective, as it is 
unlikley that many customers
  will check their balance on a regular basis. It is likely that a 
small fraction of customers will
  check their balance in a given month, meaning that calculating it on 
the fly would both spread
  the load over time as well as reduce the total load, even if on the 
fly calculation results in

  significantly higher per-customer calculation time.

3. The app is a web app, and it would be preferable to contain business 
logic within the database
  itself or the current app codebase. Spreading application logic into 
an external mechanism such
  as cron or an external daemon would be undesirable unless there was 
no other way.


*** A Possible Solution ***

Calculating the balance on the fly can be done easily if it is done at 
the time the customer seeks
to redeem a voucher. Expired points are only relevant at these times, 
and so the expired points

would be calculated with an application function that did the following:

1. Get the balance as it was 12 months ago by getting total points 
earned less redemptions and expiries

  up to that date.
2. Subtract from it redemptions and expiries since then. The value 
obtained, if it is positive, is the

  value of points to expire.
3. Log the expiry entry, and then calculate the balance of points to the 
current date by subtracting

  total points redeemed and expired from total points earned.

This procedure has a few practical problems, however:
1. Customers, when they view their running total, will not be aware that 
some of the points included
  in it will have expired, as the expiry will only happen when the 
application attempts to log a

  redemption.
2. A customer may attempt to redeem a product they do not have enoughh 
points for, and be told at

  the last minute that they do not have enough points, leading to acrimony.

The solution is then to calculate it on only on redemptions, but also 
whenever the customer attempts
to view their balance. This will ensure that expired points will never 
be shown in the current balance
of available points. This, however, means the calculation may be done 
many times by each customer in

a single catalog browsing session.

*** The Question ***

Is there a way to design the DB schema as well as the query in such a 
manner that calculating the point
balance on the fly is not an unfeasibly heavy duty calculation to be 
done at every page view?


This problem does not appear to be solved comprehensively by anyone. 
When I log into my credit card
company web site to check my points, I get a message "please come back 
in an hour, and your points
will be calculated" if I haven't logged in for over a week. So obviously 
they calculate the balance

and put it in a table that acts as a "cached balance".

Emirates has a different solution, they do bi-annual runs, so points 
expire every March and September

for them.

Neither of these solutions appeals to me, and there must be A Better 
Way(tm).


---(end of broadcast)-

Re: [GENERAL] Creation of a read-only role.

2007-03-18 Thread Dmitry Koterov

Oh, sorry for the previous question - I can create a
scheme-changes-disallowed role by revoking the "CREATE" permission from all
the database schemas.
The issue seems to be closed now, thanks.

On 3/18/07, Dmitry Koterov <[EMAIL PROTECTED]> wrote:


> actually - you dont need the read-only role, if this is only for slave
> nodes. slony takes care about the issue and doesn't allow any writes
> on slaves.
Great!

But what about a role which can modify the data, but cannot modify the
database schema?

On 3/17/07, hubert depesz lubaczewski <[EMAIL PROTECTED]> wrote:
>
> On 3/16/07, Dmitry Koterov <[EMAIL PROTECTED]> wrote:
> > Overall, we need 3 roles:
> > 1. Administrator: can do anything with a database (by default this
> user is
> > already exists - "postgres").
> > 2. Read-only: can only read. Runs on all slave nodes.
>
> actually - you dont need the read-only role, if this is only for slave
> nodes. slony takes care about the issue and doesn't allow any writes
> on slaves.
>
> depesz
>
> ---(end of broadcast)---
> TIP 2: Don't 'kill -9' the postmaster
>




Re: [GENERAL] Creation of a read-only role.

2007-03-18 Thread Dmitry Koterov

actually - you dont need the read-only role, if this is only for slave
nodes. slony takes care about the issue and doesn't allow any writes
on slaves.

Great!

But what about a role which can modify the data, but cannot modify the
database schema?

On 3/17/07, hubert depesz lubaczewski <[EMAIL PROTECTED]> wrote:


On 3/16/07, Dmitry Koterov <[EMAIL PROTECTED]> wrote:
> Overall, we need 3 roles:
> 1. Administrator: can do anything with a database (by default this user
is
> already exists - "postgres").
> 2. Read-only: can only read. Runs on all slave nodes.

actually - you dont need the read-only role, if this is only for slave
nodes. slony takes care about the issue and doesn't allow any writes
on slaves.

depesz

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster