[SQL] Triggers & Conditional Assignment

2005-09-15 Thread Neil Saunders
Hi,

I've run in to a small problem when writing a trigger.

For simplicities sake lets say that I have 2 tables – 'bookings' and
'unavailable_periods'. Both have columns 'start_date','end_date', and
'property_id'.

I have written a trigger that is fired on inserts and updates for both
tables that simply ensures that no intervals (defined by start_date
and end_date) overlap for the same property across both tables.

It works simply by doing a SELECT using the OVERLAP keyword on
NEW.start_date, and NEW.end_date for both tables (Ignoring the record
being modified). This works fine on inserts (Where both start_date and
end_date are specified), and updates that modify both start_date and
end_date, but for updates where I only update 'start_date', for
example, the trigger fails because NEW.end_date is empty.

Whats the best way around this?

I've tried to write something along the lines of the following:

DECLARE
sdate DATE;
edate DATE;

BEGIN
sdate = (NEW.start_date IS NOT NULL) ? NEW.start_date : OLD.start_date;
edate = (NEW.end_date IS NOT NULL) ? NEW.end_date : OLD.end_date;
…

But conditional assignment doesn't seem to be catered for. The next
best thing is a series of IF THEN ELSIF ELSE statements to assign
sdate and edate, or is there another technique that I've missed
entirely?

Kind Regards,

Neil Saunders.

---(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


[SQL] Difference from average

2005-10-11 Thread Neil Saunders
Hi all,

I'm developing a property rental database. One of the tables tracks
the price per week for different properties:

CREATE TABLE "public"."prices" (
  "id" SERIAL,
  "property_id" INTEGER,
  "start_date" TIMESTAMP WITHOUT TIME ZONE,
  "end_date" TIMESTAMP WITHOUT TIME ZONE,
  "price" DOUBLE PRECISION NOT NULL
) WITH OIDS;

CREATE INDEX "prices_idx" ON "public"."prices"
  USING btree ("property_id");

I'd like to display the prices per property in a table, with each row
coloured different shades; darker shades representing the more
expensive periods for that property. To do this, I propose to
calculate the percentage difference of each rows price from the
average for that property, so if for example I have two rows, one for
price=200 and one for price=300, i'd like to retrieve both records
along with the calculated field indicating that the rows are -20%,
+20% from the average, respectively.

I've started with the following query, but since I'm still learning
how PostgreSQL works, I'm confused as to the efficiency of the
following statement:

SELECT *, (price - (SELECT avg(price) from prices)) as diff FROM prices;

EXPLAIN reveals (albeit not a real test, as only the two rows above)

Seq Scan on prices  (cost=1.03..2.05 rows=2 width=32)
  InitPlan
->  Aggregate  (cost=1.03..1.03 rows=1 width=8)
  ->  Seq Scan on prices  (cost=0.00..1.02 rows=2 width=8)

Does this mean that I'll be performing a nested table scan every time
I run this query? Also, I haven't yet calculated the percentage
difference for this, which in my eyes means another instance of
"SELECT avg(price) from prices". Is this the best way of doing this?
Can I optimize this away by re-writing this as a function and storing
"SELECT avg(price) from prices)" in a variable?

All opinions gratefully received.

Kind Regards,

Neil

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


Re: [SQL] PGSQL encryption functions

2005-11-02 Thread Neil Saunders
OK, you're not really "breaking" md5. If the attacker already knows
the information being encrypted, then all you're testing is the
concatenation order- Surely the information is more important than the
order? md5 is a one way hash function, and so using an alternate
algorithm will provide no benefit whatsoever; you're just running
through 9 permutations.

Kind Regards,

Neil.

On 11/2/05, Mark R. Dingee <[EMAIL PROTECTED]> wrote:
> Mike & Tom,
>
> The script I'm using to "break" md5 presumes that the cracker knows the 3
> elements being concatenated together to form the plain-text sting which is
> then passed into md5.  The method I'm using then begins running through
> various permutations.  Do you believe that the methodology is appropriate or
> that I'm being a bit paranoid?
>
> Thanks
>
> On Tuesday 01 November 2005 05:13 pm, Tom Lane wrote:
> > "Mark R. Dingee" <[EMAIL PROTECTED]> writes:
> > > md5 works, but I've been able to
> > > brute-force crack it very quickly,
> >
> > Really?  Where's your publication of this remarkable breakthrough?
> >
> >   regards, tom lane
> >
> > ---(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
>
> On Wednesday 02 November 2005 04:26 am, Mario Splivalo wrote:
> > On Tue, 2005-11-01 at 17:13 -0500, Tom Lane wrote:
> > > "Mark R. Dingee" <[EMAIL PROTECTED]> writes:
> > > > md5 works, but I've been able to
> > > > brute-force crack it very quickly,
> > >
> > > Really?  Where's your publication of this remarkable breakthrough?
> >
> > I'd say you can't bruteforce md5, unless you're extremley lucky.
> > However, md5 is easily broken, you just need to know how to construct
> > the hashes.
> >
> > One could switch to SHA for 'increaased' security.
> >
> > Although I don't think he'd be having problems using MD5 as he described
> > it. I'd also lilke to see he's example of brute-force 'cracking' the MD5
> > digest.
> >
> >   Mike
>
> ---(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
>

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


Re: [SQL] Foreign key to 2 tables problem

2005-11-22 Thread Neil Saunders
As far as I'm aware, not without using an intermediatary table (id,
cust_id, supplier_id) . Otherwise, how would you know which table the
foreign key was referencing?

That said, an intermediatary table isn't a very clean solution; What
problem are you trying to solve, exactly?

Kind Regards,

Neil.

On 11/22/05, Joost Kraaijeveld <[EMAIL PROTECTED]> wrote:
> Hi,
>
> Is there a way to create a foreign key to 2 tables: e.g. a bankaccount
> table that has a column "owner", that must point to a record in either
> the customer or the supplier table?
>
>
> TIA
>
> --
> Groeten,
>
> Joost Kraaijeveld
> Askesis B.V.
> Molukkenstraat 14
> 6524NB Nijmegen
> tel: 024-3888063 / 06-51855277
> fax: 024-3608416
> e-mail: [EMAIL PROTECTED]
> web: www.askesis.nl
>
>
>
> ---(end of broadcast)---
> TIP 3: Have you checked our extensive FAQ?
>
>   http://www.postgresql.org/docs/faq
>

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

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


Re: [SQL] Triggers

2005-11-22 Thread Neil Saunders
Try:

create or replace function update_last_edit() returns trigger as
$$
begin
new.last_edit=now();
return new;
end;
$$ language plpgsql;

On 11/22/05, Leif B. Kristensen <[EMAIL PROTECTED]> wrote:
> On Tuesday 22 November 2005 17:25, Achilleus Mantzios wrote:
> >O Leif B. Kristensen έγραψε στις Nov 22, 2005 :
> >> I'm trying to understand triggers. I have read the documentation in
> >> the manual as well as the few pages in the Douglas book about the
> >> subject, but I don't see how to implement a trigger that simply
> >> updates a 'last_edit' date field in my 'persons' table whenever I do
> >> an insert or update into my 'participants' table; that is a trigger
> >> that basically does an "UPDATE persons SET 'last_edit' = NOW() WHERE
> >> persons.person_id = participants.person_fk". Is that even possible?
> >
> >smth like:
> >foodb=# CREATE or REPLACE FUNCTION upd_dad() RETURNS "trigger" AS '
> >foodb'# BEGIN
> >foodb'# UPDATE dad set lastedit=now() where id=new.dadid;
> >foodb'# RETURN new;
> >foodb'# END;
> >foodb'# '
> >foodb-# LANGUAGE plpgsql;
> >CREATE FUNCTION
> >foodb=# CREATE TRIGGER upd_dad_tg AFTER INSERT OR UPDATE ON kid FOR
> > EACH ROW EXECUTE PROCEDURE upd_dad();
>
> leif=> create or replace function update_last_edit() returns trigger as
> $$
> leif$> begin
> leif$> update persons set last_edit=now() where person_id=new.person_fk;
> leif$> return new;
> leif$> end;
> leif$> $$ language plpgsql;
> CREATE FUNCTION
> leif=> create trigger update_last_edit after insert or update on
> participants
> leif-> for each row execute procedure update_last_edit();
> CREATE TRIGGER
> leif=> insert into participants (participant_id,person_fk) values (1,1);
> ERROR:  record "new" has no field "last_edit"
> CONTEXT:  PL/pgSQL function "process_last_edited" line 2 at assignment
> leif=>
>
> What am I missing?
> --
> Leif Biberg Kristensen | Registered Linux User #338009
> http://solumslekt.org/ | Cruising with Gentoo/KDE
>
> ---(end of broadcast)---
> TIP 2: Don't 'kill -9' the postmaster
>

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


Re: [SQL] Triggers

2005-11-22 Thread Neil Saunders
And change AFER INSERT to BEFORE INSERT

On 11/22/05, Achilleus Mantzios <[EMAIL PROTECTED]> wrote:
> O Leif B. Kristensen έγραψε στις Nov 22, 2005 :
>
> > On Tuesday 22 November 2005 17:25, Achilleus Mantzios wrote:
> > >O Leif B. Kristensen έγραψε στις Nov 22, 2005 :
> > >> I'm trying to understand triggers. I have read the documentation in
> > >> the manual as well as the few pages in the Douglas book about the
> > >> subject, but I don't see how to implement a trigger that simply
> > >> updates a 'last_edit' date field in my 'persons' table whenever I do
> > >> an insert or update into my 'participants' table; that is a trigger
> > >> that basically does an "UPDATE persons SET 'last_edit' = NOW() WHERE
> > >> persons.person_id = participants.person_fk". Is that even possible?
> > >
> > >smth like:
> > >foodb=# CREATE or REPLACE FUNCTION upd_dad() RETURNS "trigger" AS '
> > >foodb'# BEGIN
> > >foodb'# UPDATE dad set lastedit=now() where id=new.dadid;
> > >foodb'# RETURN new;
> > >foodb'# END;
> > >foodb'# '
> > >foodb-# LANGUAGE plpgsql;
> > >CREATE FUNCTION
> > >foodb=# CREATE TRIGGER upd_dad_tg AFTER INSERT OR UPDATE ON kid FOR
> > > EACH ROW EXECUTE PROCEDURE upd_dad();
> >
> > leif=> create or replace function update_last_edit() returns trigger as
> > $$
> > leif$> begin
> > leif$> update persons set last_edit=now() where person_id=new.person_fk;
> > leif$> return new;
> > leif$> end;
> > leif$> $$ language plpgsql;
> > CREATE FUNCTION
> > leif=> create trigger update_last_edit after insert or update on
> > participants
> > leif-> for each row execute procedure update_last_edit();
> > CREATE TRIGGER
> > leif=> insert into participants (participant_id,person_fk) values (1,1);
> > ERROR:  record "new" has no field "last_edit"
> > CONTEXT:  PL/pgSQL function "process_last_edited" line 2 at assignment
>  ^
>
> > leif=>
> >
> > What am I missing?
> >
>
> apparently some forgotten process_last_edited() function.
>
> --
> -Achilleus
>
>
> ---(end of broadcast)---
> TIP 4: Have you searched our list archives?
>
>   http://archives.postgresql.org
>

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


[SQL] Archives site down?

2005-11-30 Thread Neil Saunders
Apologies if this has been mentioned on announce (I'm not subscribed),
but the mailing list archive site appears to have a problem (403
Forbidden):

http://archives.postgresql.org/

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


Re: [SQL] LinkedList

2006-04-27 Thread Neil Saunders
Ray,

There's a good introductory article on Sitepoint for doing this kind of thing:

http://www.sitepoint.com/article/hierarchical-data-database

The "Modified Preorder Tree Traversal" is quite a nice method that I
would expect  to be a magnitude faster than recursive joins, although
does have some drawbacks.

Kind Regards,

Neil.


On 4/27/06, Jim C. Nasby <[EMAIL PROTECTED]> wrote:
> decibel=# select * from t;
>  a | b
> ---+---
>  1 | 0
>  3 | 1
>  5 | 3
>  7 | 5
>  2 | 0
>  4 | 2
>  6 | 4
>  8 | 6
> (8 rows)
>
> decibel=# select * from t x join t y on(x.a=y.b) where y.a=7;
>  a | b | a | b
> ---+---+---+---
>  5 | 3 | 7 | 5
> (1 row)
>
> decibel=# select * from t x join t y on(x.a=y.b) where y.a=8;
>  a | b | a | b
> ---+---+---+---
>  6 | 4 | 8 | 6
> (1 row)
>
> decibel=#
>
> As you can see, it selects the right data, but you'll need to step
> through it somehow. You might be able to do it with a generate_series(),
> or you can use a function. If we get WITH support/recursion in 8.2 you'd
> use that.
>
> I think that "SQL For Smarties" by Joe Celko might have an example of
> how to do this without using a function. Even if it doesn't it's a book
> any serious database developer should own.
>
> On Wed, Apr 26, 2006 at 10:35:15AM -0700, Ray Madigan wrote:
> > Scott,
> >
> > Thanks for your reply,  I tried what you said, worked around a few things
> > but I am still stuck.  The main reason is I didn't do an adequate job of
> > explaining the situation.  The table implements many linked lists and I want
> > to traverse one of them given the end of the list.
> >
> > Say the table contains
> >
> > h | v | j
> > 1   0   100
> > 3   1   300
> > 5   3   500
> > 7   5   700
> >
> > 2   0   200
> > 4   2   400
> > 6   4   600
> > 8   6   800
> >
> > If I specify t.h = 8 I want to traverse the even part of the table
> > If I specify t.h = 7 I want to traverse the odd part of the table
> >
> > If you can send me to a book to read I am willing
> >
> > Thanks
> >
> > -Original Message-
> > From: [EMAIL PROTECTED]
> > [mailto:[EMAIL PROTECTED] Behalf Of Scott Marlowe
> > Sent: Wednesday, April 26, 2006 8:59 AM
> > To: Ray Madigan
> > Cc: pgsql-sql@postgresql.org
> > Subject: Re: [SQL] LinkedList
> >
> >
> > On Wed, 2006-04-26 at 11:09, Ray Madigan wrote:
> > > I have a table that I created that implements a linked list.  I am not an
> > > expert SQL developer and was wondering if there are known ways to traverse
> > > the linked lists.  Any information that can point me in the direction to
> > > figure this out would be appreciated.  The table contains many linked
> > lists
> > > based upon the head of the list and I need to extract all of the nodes
> > that
> > > make up a list.  The lists are simple with a item and a link to the
> > history
> > > item so it goes kind of like:
> > >
> > > 1, 0
> > > 3, 1
> > > 7, 3
> > > 9, 7
> > > ...
> > >
> > > Any suggestions would be helpful, or I will have to implement the table
> > > differently.
> >
> > You should be able to do this with a fairly simple self-join...
> >
> > select a.id, b.aid, a.field1, b.field1
> > from mytable a
> > join mytable b
> > on (a.id=b.aid)
> >
> > Or something like that.
> >
> > ---(end of broadcast)---
> > TIP 2: Don't 'kill -9' the postmaster
> >
> >
> > ---(end of broadcast)---
> > TIP 6: explain analyze is your friend
> >
>
> --
> Jim C. Nasby, Sr. Engineering Consultant  [EMAIL PROTECTED]
> Pervasive Software  http://pervasive.comwork: 512-231-6117
> vcard: http://jim.nasby.net/pervasive.vcf   cell: 512-569-9461
>
> ---(end of broadcast)---
> TIP 2: Don't 'kill -9' the postmaster
>

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