[SQL] summing tables

2003-07-15 Thread Erik Thiele
hi,

i have a table consisting of 4 integers.

seq is for making the table ordered. (ORDER BY SEQ ASC)
a,b,c maybe null


 seq | a  | b  | c 
-+++---
   0 |  1 |  2 | 3
   1 |  1 |  2 |  
   2 |  5 |  7 |  
   3 | -2 | -4 |  


i am needing a sql statement to do

c=a+b+"the c of the row with seq one less than myself"

this statement has to run over the whole table, in seq order.


how can this be acomplished???


cu&thanks
erik


-- 
Erik Thiele

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [SQL] summing tables

2003-07-15 Thread Viorel Dragomir
update table_name
set c = a + b + (select c from table_name as x where x.seq = seq-1)
where c is null;

additional checks are required if you want to update c when c is not null
if all the c are null then this query will do nothing

god help u
:)

- Original Message - 
From: "Erik Thiele" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, July 15, 2003 3:09 PM
Subject: [SQL] summing tables


> hi,
> 
> i have a table consisting of 4 integers.
> 
> seq is for making the table ordered. (ORDER BY SEQ ASC)
> a,b,c maybe null
> 
> 
>  seq | a  | b  | c 
> -+++---
>0 |  1 |  2 | 3
>1 |  1 |  2 |  
>2 |  5 |  7 |  
>3 | -2 | -4 |  
> 
> 
> i am needing a sql statement to do
> 
> c=a+b+"the c of the row with seq one less than myself"
> 
> this statement has to run over the whole table, in seq order.
> 
> 
> how can this be acomplished???
> 
> 
> cu&thanks
> erik
> 
> 
> -- 
> Erik Thiele
> 
> ---(end of broadcast)---
> TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

---(end of broadcast)---
TIP 3: 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: [SQL] summing tables

2003-07-15 Thread Dani Oderbolz
Erik Thiele wrote:

hi,

i have a table consisting of 4 integers.

seq is for making the table ordered. (ORDER BY SEQ ASC)
a,b,c maybe null
seq | a  | b  | c 
-+++---
  0 |  1 |  2 | 3
  1 |  1 |  2 |  
  2 |  5 |  7 |  
  3 | -2 | -4 |  

i am needing a sql statement to do

c=a+b+"the c of the row with seq one less than myself"

this statement has to run over the whole table, in seq order.

how can this be acomplished???

cu&thanks
erik
 

Hi Erik,
this should do the trick:
(I have not yet considered the NULLS though...)
UPDATE table t set c = a + b + (Select c from table tt where tt.seq = 
t.seq -1)

Cheers, Dani



---(end of broadcast)---
TIP 3: 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: [SQL] summing tables

2003-07-15 Thread Erik Thiele
On Tue, 15 Jul 2003 15:16:21 +0300
"Viorel Dragomir" <[EMAIL PROTECTED]> wrote:

> update table_name
> set c = a + b + (select c from table_name as x where x.seq = seq-1)
> where c is null;

hmmm. the query is run row by row, isn't it?
but it will have different results depending on the order of those rows.

look, the c value is set by one row-query
and read by the row-query of the row below.

does sql specify some "order is magically always as you expect it" rule?

still i am a little confused.


and i am sorry, i didn't initially specify that the "seq" are not gapless.
i.e. seq-1 does not always exist. but seq-13 could be the next lower one!

zeit=# select * from foo;
 seq | a  | b  | c 
-+++---
   0 |  1 |  2 | 3
   1 |  1 |  2 |  
   2 |  5 |  7 |  
   3 | -2 | -4 |  
   6 | -1 | -2 |  
   5 | -2 | -2 |  
   4 |  0 |  1 |  
(7 rows)

i created this (gapless for easiness) table and run your query:

zeit=# update foo set c = a + b + (select c from foo as x where x.seq = seq-1) where c 
is null;
UPDATE 6

 6 updates??? really???

zeit=# select * from foo;
 seq | a  | b  | c 
-+++---
   0 |  1 |  2 | 3
   1 |  1 |  2 |  
   2 |  5 |  7 |  
   3 | -2 | -4 |  
   6 | -1 | -2 |  
   5 | -2 | -2 |  
   4 |  0 |  1 |  
(7 rows)


h. let's try the statement of the other reply to my initial mail:

UPDATE foo t set c = a + b + (Select c from foo tt where tt.seq = t.seq -1)

zeit=# UPDATE foo t set c = a + b + (Select c from foo tt where tt.seq = t.seq -1);
ERROR:  parser: parse error at or near "t"

h

any clues?

cu & thx
erik

> additional checks are required if you want to update c when c is not null
> if all the c are null then this query will do nothing
> > i have a table consisting of 4 integers.
> > 
> > seq is for making the table ordered. (ORDER BY SEQ ASC)
> > a,b,c maybe null
> > 
> > 
> >  seq | a  | b  | c 
> > -+++---
> >0 |  1 |  2 | 3
> >1 |  1 |  2 |  
> >2 |  5 |  7 |  
> >3 | -2 | -4 |  
> > 
> > 
> > i am needing a sql statement to do
> > 
> > c=a+b+"the c of the row with seq one less than myself"
> > 
> > this statement has to run over the whole table, in seq order.

-- 
Erik Thiele

---(end of broadcast)---
TIP 3: 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] Non-Blocking Locks (i.e. Oracle NOWAIT)

2003-07-15 Thread Jan Bernhardt
Hi there,

though this question has been asked several times before (but never really
answered), I have to give it another try.

I have a multi-user application which synchronizes access to certain datasets
via the database itself. If a user has a project in that application open no
other user should be able to work on it too. When developing the application I
considered the database to be a place to handle the synchronization since
transactions are (normally) an integral part of a database system. When a user
opens a project the application firstly locks a corresponding row. But since I
don't want the application to block if that row is already locked I use the
Oracle "NOWAIT" feature (SELECT ... FOR UPDATE NOWAIT) which tries to receive
the lock on the specified row and if that row is already locked it returns
with an error without blocking and I can tell the user that the project is
already in use.

Now that the application is to be ported to PG I need a similar functionality.
Is there that an animal? If not, what would you recommend?

TIA,

- Jan.

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


[SQL] Cannot insert dup id in pk

2003-07-15 Thread Scott Cain
Hello,

I sent this question yesterday morning, but it was not allowed because I
wasn't subscribed to the list.  If it did make it through, I appologize
for the dup.

I am having strange behavior when I try to do an insert.  Postgres tells
me that it cannot insert a duplicate key into a primary key index, when
I am not trying to insert into it.  Can anyone shed light on why this is
happening, or point out the error of my ways?

Here are the details:
wormbase=> \d fdata
  Table "public.fdata"
Column |  Type  |   Modifiers  
   
---++--- 
-
 fid   | integer| not null default nextval('public.fdata 
_fid_seq'::text)
 fref  | character varying(100) | not null default ''
 fstart| integer| not null default '0'
 fstop | integer| not null default '0'
 fbin  | double precision   | not null default '0.00'
 ftypeid   | integer| not null default '0'
 fscore| double precision   |
 fstrand   | character varying(3)   |
 fphase| character varying(3)   |
 gid   | integer| not null default '0'
 ftarget_start | integer|
 ftarget_stop  | integer|
Indexes: pk_fdata primary key btree (fid),
 fdata_fref_idx btree (fref, fbin, fstart, fstop, ftypeid, gid),
 fdata_ftypeid_idx btree (ftypeid),
 fdata_gid_idx btree (gid)
Check constraints: "chk_fdata_fstrand" ((fstrand = '+'::character varying) OR (f 
strand = '-'::character varying))
   "chk_fdata_fphase" (((fphase = '0'::character varying) OR (fp hase 
= '1'::character varying)) OR (fphase = '2'::character varying))

Now a chunk from my query log:
Jul 14 12:48:47 localhost postgres[2998]: [107-1] LOG:  query: INSERT INTO fdata 
(fref,fstart,fstop,fbin,ftypeid,fscore,fstrand,fphase,gid,ftarget_start,ftarget_stop)
Jul 14 12:48:47 localhost postgres[2998]: [107-2] 
VALUES('XX',7327656,7327658,'1000.007327','41',NULL,'+',NULL,'12358',NULL,NULL)
Jul 14 12:48:47 localhost postgres[2998]: [108] ERROR:  Cannot insert a duplicate key 
into unique index pk_fdata

Note that I do not try to insert anything into fid, the primary key on
this table.  Why does Postgres think I am?

Thanks much,
Scott

-- 

Scott Cain, Ph. D. [EMAIL PROTECTED]
GMOD Coordinator (http://www.gmod.org/) 216-392-3087
Cold Spring Harbor Laboratory


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

   http://www.postgresql.org/docs/faqs/FAQ.html


[SQL] help with troublesome query

2003-07-15 Thread teknokrat
I have three tables customers which 1-many with requests which is 1-1 
with applications. all customers have at least one request but not all 
requests have an application.

I want a query to return all the customers and their application data if 
they have any ( or else null). So this is like a left join of customers 
 with applications but I do not want multiple rows of customers UNLESS 
they have an application.

thanks



---(end of broadcast)---
TIP 6: Have you searched our list archives?
  http://archives.postgresql.org


Re: [SQL] summing tables

2003-07-15 Thread Viorel Dragomir
Ok. I disregarded the complexity of this problem. :)
You may wish to do this thing from a programming language with every row at
a time [in php, asp...].

Anyway here is a function in plpgsql.
It solves your problem, i hope; but i don't recommend it.

create function update_nulls() returns int
as '
declare
 var1  integer;
 var2  integer;
begin
select into var1 count(*) from tab where c is null;
var2 := var1;
while var1 > 0 loop
 update table_name
 set c = a + b + (select x.c from table_name as x where x.seq =
table_name.seq-1)
 where c is null;

 var1 := var1 - 1;
end loop;
return var2;
end; '
language 'plpgsql';




- Original Message -
From: "Erik Thiele" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, July 15, 2003 3:39 PM
Subject: Re: [SQL] summing tables


> On Tue, 15 Jul 2003 15:16:21 +0300
> "Viorel Dragomir" <[EMAIL PROTECTED]> wrote:
>
> > update table_name
> > set c = a + b + (select c from table_name as x where x.seq = seq-1)
> > where c is null;
>
> hmmm. the query is run row by row, isn't it?
> but it will have different results depending on the order of those rows.
>
> look, the c value is set by one row-query
> and read by the row-query of the row below.
>
> does sql specify some "order is magically always as you expect it" rule?
>
> still i am a little confused.
>
>
> and i am sorry, i didn't initially specify that the "seq" are not gapless.
> i.e. seq-1 does not always exist. but seq-13 could be the next lower one!
>
> zeit=# select * from foo;
>  seq | a  | b  | c
> -+++---
>0 |  1 |  2 | 3
>1 |  1 |  2 |
>2 |  5 |  7 |
>3 | -2 | -4 |
>6 | -1 | -2 |
>5 | -2 | -2 |
>4 |  0 |  1 |
> (7 rows)
>
> i created this (gapless for easiness) table and run your query:
>
> zeit=# update foo set c = a + b + (select c from foo as x where x.seq =
seq-1) where c is null;
> UPDATE 6
>
>  6 updates??? really???
>
> zeit=# select * from foo;
>  seq | a  | b  | c
> -+++---
>0 |  1 |  2 | 3
>1 |  1 |  2 |
>2 |  5 |  7 |
>3 | -2 | -4 |
>6 | -1 | -2 |
>5 | -2 | -2 |
>4 |  0 |  1 |
> (7 rows)
>
>
> h. let's try the statement of the other reply to my initial mail:
>
> UPDATE foo t set c = a + b + (Select c from foo tt where tt.seq =
t.seq -1)
>
> zeit=# UPDATE foo t set c = a + b + (Select c from foo tt where tt.seq =
t.seq -1);
> ERROR:  parser: parse error at or near "t"
>
> h
>
> any clues?
>
> cu & thx
> erik
>
> > additional checks are required if you want to update c when c is not
null
> > if all the c are null then this query will do nothing
> > > i have a table consisting of 4 integers.
> > >
> > > seq is for making the table ordered. (ORDER BY SEQ ASC)
> > > a,b,c maybe null
> > >
> > >
> > >  seq | a  | b  | c
> > > -+++---
> > >0 |  1 |  2 | 3
> > >1 |  1 |  2 |
> > >2 |  5 |  7 |
> > >3 | -2 | -4 |
> > >
> > >
> > > i am needing a sql statement to do
> > >
> > > c=a+b+"the c of the row with seq one less than myself"
> > >
> > > this statement has to run over the whole table, in seq order.
>
> --
> Erik Thiele
>
> ---(end of broadcast)---
> TIP 3: 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 3: 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: [SQL] help with troublesome query

2003-07-15 Thread Bruno Wolff III
On Tue, Jul 15, 2003 at 14:26:16 +0100,
  teknokrat <[EMAIL PROTECTED]> wrote:
> I have three tables customers which 1-many with requests which is 1-1 
> with applications. all customers have at least one request but not all 
> requests have an application.
> 
> I want a query to return all the customers and their application data if 
> they have any ( or else null). So this is like a left join of customers 
>  with applications but I do not want multiple rows of customers UNLESS 
> they have an application.

I think you want to first do an inner join of requests and applications
and then left join the customers and the previous join.

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


[SQL] Count dates distinct within an interval

2003-07-15 Thread Dmitry Tkach
Hi, everybody!

I was trying to formulate a sql query, that I now think is impossible :-(
I just thought, I'd run it by you before I give up - perhaps, you guys 
would have some ideas...

Suppose, I have a table like this

create table test
(
  stuff int,
  stamp timestamp
);
Now, I want to count the occurences of each value of stuff in the table, 
but so that entries within 24 hours from each other count as one...
The closest I could think of is:

select stuff, count (distinct date_trunc ('day', stamp)) from test group 
by stuff;

This doesn't do exactly what I need though - for example, if one entry 
is one minute before midnight, and the other one is two minutes later, 
they'd get counted  as 2, and what I am looking for is the way to get 
them collapsed into one as long as they are less then 24 hours apart...

Now, I am pretty sure, it is simply impossible to do what I want with 
count (distinct...) because my 'equality' is not transitive - for 
example, three entries, like
A = 2001 - 01- 01 20:20:00
B = 2001 - 01 - 02 20:19:00
C = 2001 - 01 - 02 20:21:00

Should be counted as *two* (A === B, and B === C, but *not* A === C)...

Also, I could certainly write a simple function, that would get all the 
entries in order, and scan through them, counting according to my rules...
But I was hoping to find some way to do this in plain sql though...

Any ideas?

Thanks!

Dima

---(end of broadcast)---
TIP 6: Have you searched our list archives?
  http://archives.postgresql.org


Re: [SQL] max length of sql select statement (long!)

2003-07-15 Thread greg

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


> ... I don't want to take GO:06 into account (two parents in which 
> I am intested in). That menas, whenever I ask for children of two nodes, 
> I want a DISTINCT SET of children.

To start with, you can avoid the Java and do this in SQL:

SELECT child FROM gograph WHERE parent='GO:002' OR parent='GO:005'
EXCEPT
(SELECT child FROM gograph WHERE parent='GO:002'
INTERSECT 
SELECT child FROM gograph WHERE parent='GO:005');


And yes, I would certainly start by normalizing things a little bit:


CREATE SEQUENCE goid_seq;

CREATE TABLE goID (
  idname TEXT,
  id INTEGER NOT NULL DEFAULT nextval('goid_seq')
);

INSERT INTO goid(idname) SELECT DISTINCT parent FROM gograph;

INSERT INTO goid(idname) 
SELECT DISTINCT child FROM gograph WHERE NOT EXISTS (SELECT 1 FROM goID WHERE idname = 
child);

CREATE TABLE gomap (
  parent INTEGER,
  child INTEGER
);

INSERT INTO gomap SELECT 
(SELECT id FROM goid WHERE idname=parent),
(SELECT id FROM goid WHERE idname=child)
FROM gograph


As far as the binaryInteraction table, a little more information is needed: 
how are each of these tables being populated? Why the distinct? Is it because 
there may be duplicate rows in the table? The reason I as is that it might be 
better to ue triggers to compute some of the information as it comes in, 
depending on which tables are changes and how often.


- --
Greg Sabino Mullane [EMAIL PROTECTED]
PGP Key: 0x14964AC8 200307151035

-BEGIN PGP SIGNATURE-
Comment: http://www.turnstep.com/pgp.html

iD8DBQE/FBGrvJuQZxSWSsgRAlEfAKCL4ttDdTRHxPRW9N00nowPh1/q/QCgqrkv
e7Ncj4al4aJ4ihktEyweJJo=
=Z/rk
-END PGP SIGNATURE-



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


Re: [SQL] Cannot insert dup id in pk

2003-07-15 Thread Henshall, Stuart - TNP Southwest
Title: RE: [SQL] Cannot insert dup id in pk





I suspect the sequence is out of sync with the values actually in you primary key (which I gues is fid.
Try this query
SELECT setval('public.fdata _fid_seq'::text,MAX(fid)+1) FROM fdata;
This should set the value of the sequence to the current maximum+1
hth,
- Stuart
P.S. Sorry about the format change the disclaimer adder forces


> -Original Message-
> From: Scott Cain [mailto:[EMAIL PROTECTED]]
> Sent: 15 July 2003 14:00
> To: [EMAIL PROTECTED]
> Subject: [SQL] Cannot insert dup id in pk
> 
> 
> THIS EMAIL HAS BEEN SWEPT FOR VIRUSES BY THE NORTHCLIFFE 
> GROUP MAILSWEEPER SERVER.
> 
> Hello,
> 
> I sent this question yesterday morning, but it was not 
> allowed because I
> wasn't subscribed to the list.  If it did make it through, I 
> appologize
> for the dup.
> 
> I am having strange behavior when I try to do an insert.  
> Postgres tells
> me that it cannot insert a duplicate key into a primary key 
> index, when
> I am not trying to insert into it.  Can anyone shed light on 
> why this is
> happening, or point out the error of my ways?
> 
> Here are the details:
> wormbase=> \d fdata
>   Table "public.fdata"
> Column |  Type  | 
>   Modifiers   
>   
> ---++-
> -- -
>  fid   | integer    | not null default 
> nextval('public.fdata _fid_seq'::text)
>  fref  | character varying(100) | not null default ''
>  fstart    | integer    | not null default '0'
>  fstop | integer    | not null default '0'
>  fbin  | double precision   | not null default '0.00'
>  ftypeid   | integer    | not null default '0'
>  fscore    | double precision   |
>  fstrand   | character varying(3)   |
>  fphase    | character varying(3)   |
>  gid   | integer    | not null default '0'
>  ftarget_start | integer    |
>  ftarget_stop  | integer    |
> Indexes: pk_fdata primary key btree (fid),
>  fdata_fref_idx btree (fref, fbin, fstart, fstop, 
> ftypeid, gid),
>  fdata_ftypeid_idx btree (ftypeid),
>  fdata_gid_idx btree (gid)
> Check constraints: "chk_fdata_fstrand" ((fstrand = 
> '+'::character varying) OR (f strand = '-'::character varying))
>    "chk_fdata_fphase" (((fphase = 
> '0'::character varying) OR (fp hase = '1'::character 
> varying)) OR (fphase = '2'::character varying))
> 
> Now a chunk from my query log:
> Jul 14 12:48:47 localhost postgres[2998]: [107-1] LOG:  
> query: INSERT INTO fdata 
> (fref,fstart,fstop,fbin,ftypeid,fscore,fstrand,fphase,gid,ftar
> get_start,ftarget_stop)
> Jul 14 12:48:47 localhost postgres[2998]: [107-2] 
> VALUES('XX',7327656,7327658,'1000.007327','41',NULL,'+',NULL,'
> 12358',NULL,NULL)
> Jul 14 12:48:47 localhost postgres[2998]: [108] ERROR:  
> Cannot insert a duplicate key into unique index pk_fdata
> 
> Note that I do not try to insert anything into fid, the primary key on
> this table.  Why does Postgres think I am?
> 
> Thanks much,
> Scott
> 
> -- 
> --
> --
> Scott Cain, Ph. D. 
> [EMAIL PROTECTED]
> GMOD Coordinator (http://www.gmod.org/) 
> 216-392-3087
> Cold Spring Harbor Laboratory
> 
> 
> ---(end of 
> broadcast)---
> TIP 5: Have you checked our extensive FAQ?
> 
>    http://www.postgresql.org/docs/faqs/FAQ.html
> 



DISCLAIMER:The information in this message is confidential and may be legally privileged. It is intended solely for the addressee.  Access to this message by anyone else is unauthorised.  If you are not the intended recipient, any disclosure, copying, or distribution of the message, or any action or omission taken by you in reliance on it, is prohibited and may be unlawful.  Please immediately contact the sender if you have received this message in error. Thank you.





Re: [SQL] Cannot insert dup id in pk

2003-07-15 Thread Dmitry Tkach
You must have your sequence out of date with the content of the table 
(so that the next value in the sequence has already been inserted).
One way to get into a situation like that is loading the table data with 
COPY (the input contains the pks, and the COPY command does not update 
the sequence, you have to do that manually after the copy is done).
Another way is simply inserting a row with an explicitly specified pkey:

insert into fdata (fid,...) values (100, ...);

Now, assuming, that you current sequence value is less then 100, and 
that the statement above succeedes (i.e., there is no fid=100 in the 
table yet), you'll get your sequence out of date. You'll still be able 
to use it, and insert the rows into the table *until* the current value 
reaches 100 - once that happens, an attempt to insert with the default 
fid will cause an error, because the sequence will generate a key, that 
already exists.

To fix this, you need to do something like:

select setval ('fdata_fid_seq', (select fid from fdata order by fid 
limit 1));

This will make sure that the next value your sequence generates is 
greater than any key that already exists in the table.

I hope, it helps...

Dima

insert into fdata

Scott Cain wrote:

Hello,

I sent this question yesterday morning, but it was not allowed because I
wasn't subscribed to the list.  If it did make it through, I appologize
for the dup.
I am having strange behavior when I try to do an insert.  Postgres tells
me that it cannot insert a duplicate key into a primary key index, when
I am not trying to insert into it.  Can anyone shed light on why this is
happening, or point out the error of my ways?
Here are the details:
wormbase=> \d fdata
 Table "public.fdata"
   Column |  Type  |   Modifiers 
---++--- -
fid   | integer| not null default nextval('public.fdata _fid_seq'::text)
fref  | character varying(100) | not null default ''
fstart| integer| not null default '0'
fstop | integer| not null default '0'
fbin  | double precision   | not null default '0.00'
ftypeid   | integer| not null default '0'
fscore| double precision   |
fstrand   | character varying(3)   |
fphase| character varying(3)   |
gid   | integer| not null default '0'
ftarget_start | integer|
ftarget_stop  | integer|
Indexes: pk_fdata primary key btree (fid),
fdata_fref_idx btree (fref, fbin, fstart, fstop, ftypeid, gid),
fdata_ftypeid_idx btree (ftypeid),
fdata_gid_idx btree (gid)
Check constraints: "chk_fdata_fstrand" ((fstrand = '+'::character varying) OR (f strand = '-'::character varying))
  "chk_fdata_fphase" (((fphase = '0'::character varying) OR (fp hase = '1'::character varying)) OR (fphase = '2'::character varying))

Now a chunk from my query log:
Jul 14 12:48:47 localhost postgres[2998]: [107-1] LOG:  query: INSERT INTO fdata 
(fref,fstart,fstop,fbin,ftypeid,fscore,fstrand,fphase,gid,ftarget_start,ftarget_stop)
Jul 14 12:48:47 localhost postgres[2998]: [107-2] 
VALUES('XX',7327656,7327658,'1000.007327','41',NULL,'+',NULL,'12358',NULL,NULL)
Jul 14 12:48:47 localhost postgres[2998]: [108] ERROR:  Cannot insert a duplicate key 
into unique index pk_fdata
Note that I do not try to insert anything into fid, the primary key on
this table.  Why does Postgres think I am?
Thanks much,
Scott
 



---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
   (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])


Re: [SQL] Count dates distinct within an interval

2003-07-15 Thread greg

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1



> Now, I want to count the occurences of each value of stuff in the table, 
> but so that entries within 24 hours from each other count as one...
>...
> A = 2001 - 01- 01 20:20:00
> B = 2001 - 01 - 02 20:19:00
> C = 2001 - 01 - 02 20:21:00
> Should be counted as *two* (A === B, and B === C, but *not* A === C)...

You need to elaborate on your logic some more, and state exactly what you 
would want in the A,B,C case above. Does B get lumped with A or with C? 
It is within 24 hours of both, after all. Does C not get lumped in with 
B simply because B has already been lumped in with A?

Perhaps showing us the sample output of an ideal query would be best, 
along with some sample rows (e.g. use real insert statements)


- --
Greg Sabino Mullane [EMAIL PROTECTED]
PGP Key: 0x14964AC8 200307151045
-BEGIN PGP SIGNATURE-
Comment: http://www.turnstep.com/pgp.html

iD8DBQE/FBS9vJuQZxSWSsgRAnk3AJ0bqyDk6iZWqSZuHfZslFCjxwl7fgCfaZ7r
XdwpPsO4OaTa9YpjmXx1hmA=
=IFRz
-END PGP SIGNATURE-




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


Re: [SQL] Non-Blocking Locks (i.e. Oracle NOWAIT)

2003-07-15 Thread Christoph Haller
>
> though this question has been asked several times before (but never
really
> answered), I have to give it another try.
>
> I have a multi-user application which synchronizes access to certain
datasets
> via the database itself. If a user has a project in that application
open no
> other user should be able to work on it too. When developing the
application I
> considered the database to be a place to handle the synchronization
since
> transactions are (normally) an integral part of a database system.
When a user
> opens a project the application firstly locks a corresponding row. But
since I
> don't want the application to block if that row is already locked I
use the
> Oracle "NOWAIT" feature (SELECT ... FOR UPDATE NOWAIT) which tries to
receive
> the lock on the specified row and if that row is already locked it
returns
> with an error without blocking and I can tell the user that the
project is
> already in use.
>
> Now that the application is to be ported to PG I need a similar
functionality.
> Is there that an animal? If not, what would you recommend?
>
PostgreSQL 7.3.2
T1: begin; select * from foo for update;
T2: set STATEMENT_TIMEOUT = 1000; -- milliseconds
T2: select * from foo for update;
T2: ERROR:  Query was cancelled.

HTH, Christoph



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

   http://archives.postgresql.org


Re: [SQL] summing tables

2003-07-15 Thread Greg Stark

To solve this problem efficiently you probably need the lead/lag analytic
functions. Unfortunately Postgres doesn't have them.

You could do it with something like:

update foo set c = a+b+(select c from foo as x where seq < foo.seq ORDER BY seq desc 
LIMIT 1) 

or the more standard but likely to be way slower:

update foo set c = a+b+(select c from foo as x where seq = (select max(seq) from foo 
as y where seq < foo.seq))


However, i would suggest that if you have an implicit relationship between
records you should make that relationship explicit with a foreign key. If you
had a column that contained the seq of the parent record then this would be
easy. I'm really puzzled how this query as currently specified could be
useful.


-- 
greg


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


Re: [SQL] Count dates distinct within an interval

2003-07-15 Thread Dmitry Tkach


You need to elaborate on your logic some more, and state exactly what you 
would want in the A,B,C case above. Does B get lumped with A or with C? 
It is within 24 hours of both, after all. Does C not get lumped in with 
B simply because B has already been lumped in with A?

Yes. The first (earliest) entry is counted, then all the later ones a 
skipped as long as they are within 24 hours from the last one, that's 
counted.
In this case, A is counted, B is skipped, because it is within 24 hours 
of A, then C is counted, because it is more than 24 hours from A.

Thanks!

Dima



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


Re: [SQL] summing tables

2003-07-15 Thread Jean-Luc Lachance

Erik,

If you intent is to get a running total of a and b ordered by seq, you
should try this (assuming the table name is t):

update t set c = ( select sum(a) + sum(b) from t t1 where t1.seq <=
t.seq);

You should have an index on seq.
If the table is very large, it is going to be painfully slow.
In that case you may want to think about using a function to step thru
each row.

JLL

Erik Thiele wrote:
> 
> hi,
> 
> i have a table consisting of 4 integers.
> 
> seq is for making the table ordered. (ORDER BY SEQ ASC)
> a,b,c maybe null
> 
>  seq | a  | b  | c
> -+++---
>0 |  1 |  2 | 3
>1 |  1 |  2 |
>2 |  5 |  7 |
>3 | -2 | -4 |
> 
> i am needing a sql statement to do
> 
> c=a+b+"the c of the row with seq one less than myself"
> 
> this statement has to run over the whole table, in seq order.
> 
> how can this be acomplished???
> 
> cu&thanks
> erik
> 
> --
> Erik Thiele
> 
> ---(end of broadcast)---
> TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

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


Re: [SQL] summing tables

2003-07-15 Thread Tom Lane
Erik Thiele <[EMAIL PROTECTED]> writes:
> "Viorel Dragomir" <[EMAIL PROTECTED]> wrote:
>> update table_name
>> set c = a + b + (select c from table_name as x where x.seq = seq-1)
>> where c is null;

> hmmm. the query is run row by row, isn't it?
> but it will have different results depending on the order of those rows.

No, it won't, because the SELECTs will not see the changes from the
not-yet-completed UPDATE.  The above command is almost right; it needs
to be

update table_name
set c = a + b + (select c from table_name as x where seq = table_name.seq-1)
where c is null;

because inside the sub-SELECT, unadorned "seq" will refer to the SELECT's
table.

You didn't say exactly what you wanted to do with null inputs, so that
issue may need more thought.

regards, tom lane

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

   http://www.postgresql.org/docs/faqs/FAQ.html


Re: [SQL] Non-Blocking Locks (i.e. Oracle NOWAIT)

2003-07-15 Thread Dmitry Tkach
There is no such thing, as far as I know :-(

Here is the poor man solution  I used to emulate this 'nowait' behaviour:

create table master_lock
(
  projectid text primary key,
  locker int
);
Now, the application first acquires an exclusive lock on the table,
then, while the table is locked it looks at the projectid row and tests 
the 'locker' column. If it is null, the app sets it to its connection id 
(the pid of the backend),
and COMMITS (to release the table lock), then starts another transaction 
and goes about its business, after it is done, it updates the 
master_lock, and sets the locker back to null.
If the locker column is not null, I use pg_stat_activity to test if the 
connection with this pid still exists (in case the app that locked this 
project had crashed before releasing the lock)... if the pid isn't 
there, it considers the project unlock, and does what's described above. 
Otherwise, it releases the lock on the table, and generates an error 
message, reporting that the project is locked.

Also see the earlier reply to your message, about STATEMENT_TIMEOUT as 
an alternative... I am using 7.2, so this wasn't an option for me when I 
came up with this work around
I doubt, I'd use that timeout thing if I was on 7.3 anyway though - one 
problem is, you'd have to parse the actual error message to figure out 
if the cause of the error is really a timeout, or just something bad 
happenning in the database... Another problem is that the timeout number 
is arbitrary - if it is too small, you risk to get a situation when the 
row is not locked, but the query still gets canceled, because the 
database is slow at the moment, if it is too large, you'll have to wait 
for a long time before getting the response (and even then, you can't  
be 100% sure it really happened because of the lock)

I hope, it helps..

Dima

Jan Bernhardt wrote:

Hi there,

though this question has been asked several times before (but never really
answered), I have to give it another try.
I have a multi-user application which synchronizes access to certain datasets
via the database itself. If a user has a project in that application open no
other user should be able to work on it too. When developing the application I
considered the database to be a place to handle the synchronization since
transactions are (normally) an integral part of a database system. When a user
opens a project the application firstly locks a corresponding row. But since I
don't want the application to block if that row is already locked I use the
Oracle "NOWAIT" feature (SELECT ... FOR UPDATE NOWAIT) which tries to receive
the lock on the specified row and if that row is already locked it returns
with an error without blocking and I can tell the user that the project is
already in use.
Now that the application is to be ported to PG I need a similar functionality.
Is there that an animal? If not, what would you recommend?
TIA,

- Jan.

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



---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [SQL] Non-Blocking Locks (i.e. Oracle NOWAIT)

2003-07-15 Thread Tom Lane
Jan Bernhardt <[EMAIL PROTECTED]> writes:
> I have a multi-user application which synchronizes access to certain datasets
> via the database itself. If a user has a project in that application open no
> other user should be able to work on it too. When developing the application I
> considered the database to be a place to handle the synchronization since
> transactions are (normally) an integral part of a database system. When a user
> opens a project the application firstly locks a corresponding row. But since I
> don't want the application to block if that row is already locked I use the
> Oracle "NOWAIT" feature (SELECT ... FOR UPDATE NOWAIT) which tries to receive
> the lock on the specified row and if that row is already locked it returns
> with an error without blocking and I can tell the user that the project is
> already in use.

You might be able to use the contrib/userlock module for this.

regards, tom lane

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [SQL] Cannot insert dup id in pk

2003-07-15 Thread Tom Lane
Scott Cain <[EMAIL PROTECTED]> writes:
> Note that I do not try to insert anything into fid, the primary key on
> this table.  Why does Postgres think I am?

But you *are* trying to insert something into fid, namely the default
value:
default nextval('public.fdata _fid_seq'::text)

My guess is that you have been inconsistent about whether you used the
sequence or explicit assignment to fid, and now you have some rows in
the table that have fid values higher than the current sequence value.

I'd suggest adjusting the sequence, along the lines of

SELECT setval('public.fdata _fid_seq', max(fid)+1) FROM fdata;

regards, tom lane

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


Re: [SQL] summing tables

2003-07-15 Thread Viorel Dragomir
Indeed it was a mistake not to put the table_name. in where clause.
But this doesn't resolve the problem.

Do you know in which order the update will modify the rows?
My lucky guess is that it takes from last inserted rows to the first row. In
this way only one row gets updated correctly.

I add the result from my unfortunate solution, even corrected.

select * from table_name;
 seq | a | b | c
-+---+---+---
   1 | 1 | 2 | 3
   2 | 5 | 9 |
   3 | 1 | 2 |
   4 | 4 | 7 |
   5 | 4 | 2 |
   6 | 0 | 1 |
(6 rows)

update table_name
 set c = a + b + (select c from table_name as x where seq =
table_name.seq-1)
 where c is null;

select * from table_name;
 seq | a | b | c
-+---+---+
   1 | 1 | 2 |  3
   2 | 5 | 9 | 17
   3 | 1 | 2 |
   4 | 4 | 7 |
   5 | 4 | 2 |
   6 | 0 | 1 |


- Original Message -
From: "Tom Lane" <[EMAIL PROTECTED]>
To: "Erik Thiele" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Tuesday, July 15, 2003 6:14 PM
Subject: Re: [SQL] summing tables


> Erik Thiele <[EMAIL PROTECTED]> writes:
> > "Viorel Dragomir" <[EMAIL PROTECTED]> wrote:
> >> update table_name
> >> set c = a + b + (select c from table_name as x where x.seq = seq-1)
> >> where c is null;
>
> > hmmm. the query is run row by row, isn't it?
> > but it will have different results depending on the order of those rows.
>
> No, it won't, because the SELECTs will not see the changes from the
> not-yet-completed UPDATE.  The above command is almost right; it needs
> to be
>
> update table_name
> set c = a + b + (select c from table_name as x where seq =
table_name.seq-1)
> where c is null;
>
> because inside the sub-SELECT, unadorned "seq" will refer to the SELECT's
> table.
>
> You didn't say exactly what you wanted to do with null inputs, so that
> issue may need more thought.
>
> regards, tom lane
>
> ---(end of broadcast)---
> TIP 5: Have you checked our extensive FAQ?
>
>http://www.postgresql.org/docs/faqs/FAQ.html


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


Re: [SQL] summing tables

2003-07-15 Thread Greg Stark

"Viorel Dragomir" <[EMAIL PROTECTED]> writes:

> Anyway, in real life this update modifies only one row with a value wich is
> diff of null. It was really handy if it was specified the option ORDER for
> the update command.

Are you hoping to produce a running total? That's very difficult in standard
SQL. That would be very different from the query you asked for. 

Running totals, ranking, lead/lag, are all things that are very difficult to
do in standard SQL. They don't fit in the unordered set model that SQL follows
so doing them without special non-standard functions is very hard and
inefficient. 

The functions to do them don't fit well within the SQL universe either, which
might be why they don't exist yet in postgres.

-- 
greg


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


Re: [SQL] Count dates distinct within an interval

2003-07-15 Thread greg

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


> Also, I could certainly write a simple function, that would get all the 
> entries in order, and scan through them, counting according to my rules...
> But I was hoping to find some way to do this in plain sql though...

In this example, you are best off using a function.

- --
Greg Sabino Mullane [EMAIL PROTECTED]
PGP Key: 0x14964AC8 200307151137

-BEGIN PGP SIGNATURE-
Comment: http://www.turnstep.com/pgp.html

iD8DBQE/FCAgvJuQZxSWSsgRAg1jAJ9kS9PpIiMkij6TtOg63O59TeezPACgzhMF
ZM/84SEPP4doDR8fsGpnUBU=
=w5Wa
-END PGP SIGNATURE-


---(end of broadcast)---
TIP 3: 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: [SQL] summing tables

2003-07-15 Thread Tom Lane
"Viorel Dragomir" <[EMAIL PROTECTED]> writes:
> Indeed it was a mistake not to put the table_name. in where clause.
> But this doesn't resolve the problem.

> Do you know in which order the update will modify the rows?

No, and *it does not matter*.  You are forgetting that this all runs
under MVCC rules.  The sub-SELECTs will see the pre-existing versions
of the rows, whether or not the UPDATE has yet produced new versions.

regards, tom lane

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

   http://www.postgresql.org/docs/faqs/FAQ.html


Re: [SQL] summing tables

2003-07-15 Thread Viorel Dragomir

- Original Message -
From: "Tom Lane" <[EMAIL PROTECTED]>
To: "Viorel Dragomir" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Tuesday, July 15, 2003 6:42 PM
Subject: Re: [SQL] summing tables


> "Viorel Dragomir" <[EMAIL PROTECTED]> writes:
> > Indeed it was a mistake not to put the table_name. in where clause.
> > But this doesn't resolve the problem.
>
> > Do you know in which order the update will modify the rows?
>
> No, and *it does not matter*.  You are forgetting that this all runs
> under MVCC rules.  The sub-SELECTs will see the pre-existing versions
> of the rows, whether or not the UPDATE has yet produced new versions.

Yes that was correct.
I forgot that the subselect sees only the old rows.

And the ORDER option will not make any difference, only making fool out of
myself. :)
I don't know if the problem is solved with my posted function.

Anyway this is the mail that started all [i get a lot of emails and i'm not
really searching for a solution on this matter]:
"
hi,

i have a table consisting of 4 integers.

seq is for making the table ordered. (ORDER BY SEQ ASC)
a,b,c maybe null


 seq | a  | b  | c
-+++---
   0 |  1 |  2 | 3
   1 |  1 |  2 |
   2 |  5 |  7 |
   3 | -2 | -4 |


i am needing a sql statement to do

c=a+b+"the c of the row with seq one less than myself"

this statement has to run over the whole table, in seq order.


how can this be acomplished???


cu&thanks
erik


--
Erik Thiele
"


---(end of broadcast)---
TIP 3: 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: [SQL] Cannot insert dup id in pk

2003-07-15 Thread Scott Cain
On Tue, 2003-07-15 at 10:43, Dmitry Tkach wrote:
> You must have your sequence out of date with the content of the table 
> (so that the next value in the sequence has already been inserted).
> One way to get into a situation like that is loading the table data with 
> COPY (the input contains the pks, and the COPY command does not update 
> the sequence, you have to do that manually after the copy is done).

Yes, this is exactly what happened.  I had no idea that copy didn't
update the sequence.  I suspect I've got users who are being bitten by
this and don't realize it.  I'll have to change my "bulk loading" script
to update the sequence after the load is done.

Thanks much,
Scott

-- 

Scott Cain, Ph. D. [EMAIL PROTECTED]
GMOD Coordinator (http://www.gmod.org/) 216-392-3087
Cold Spring Harbor Laboratory


---(end of broadcast)---
TIP 3: 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: [SQL] Count dates distinct within an interval

2003-07-15 Thread Stuart
Dmitry Tkach wrote:
Hi, everybody!

I was trying to formulate a sql query, that I now think is impossible :-(
I just thought, I'd run it by you before I give up - perhaps, you guys 
would have some ideas...

Suppose, I have a table like this

create table test
(
  stuff int,
  stamp timestamp
);
Now, I want to count the occurences of each value of stuff in the table, 
but so that entries within 24 hours from each other count as one...
The closest I could think of is:

select stuff, count (distinct date_trunc ('day', stamp)) from test group 
by stuff;

This doesn't do exactly what I need though - for example, if one entry 
is one minute before midnight, and the other one is two minutes later, 
they'd get counted  as 2, and what I am looking for is the way to get 
them collapsed into one as long as they are less then 24 hours apart...

Now, I am pretty sure, it is simply impossible to do what I want with 
count (distinct...) because my 'equality' is not transitive - for 
example, three entries, like
A = 2001 - 01- 01 20:20:00
B = 2001 - 01 - 02 20:19:00
C = 2001 - 01 - 02 20:21:00

Should be counted as *two* (A === B, and B === C, but *not* A === C)...

Also, I could certainly write a simple function, that would get all the 
entries in order, and scan through them, counting according to my rules...
But I was hoping to find some way to do this in plain sql though...

Any ideas?

Thanks!

Dima

You would probably be able to speed the following up using immutable
funtions to aid the query, or just a function to do it. However I think
this does what you asked in a query. I've put a script at the end.
hth,
- Stuart
-- s is the stuff to group by
-- dt is the datetime thing
create table Q (
s int4,
dt timestamptz);
truncate Q;

INSERT INTO Q (s,dt) VALUES (1,'2003/01/01'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/02 04:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/01 08:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/02'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/05 23:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/06 22:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (1,'2003/01/07 05:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (3,'2003/01/01'::timestamptz);
INSERT INTO Q (s,dt) VALUES (4,'2003/01/01'::timestamptz);
INSERT INTO Q (s,dt) VALUES (4,'2003/01/02 05:00'::timestamptz);
INSERT INTO Q (s,dt) VALUES (4,'2003/01/03 04:00'::timestamptz);
SELECT COUNT(*),s FROM Q WHERE dt IN (SELECT min(R.dt) FROM Q AS R WHERE 
Q.s=R.s)
OR dt IN (SELECT min(P.dt) FROM Q AS P WHERE P.s=Q.s AND
P.dt>=date_trunc('day',Q.dt)-
CASE WHEN
(SELECT max(dt)::time FROM Q AS T WHERE Q.s=T.s AND T.dt
(SELECT * FROM Q AS U WHERE T.dt-'1 day'::intervalU.dt 
AND U.s=Q.s))
>Q.dt::time THEN '1 day'::interval
ELSE
'0 day'::interval
END
+(SELECT max(dt)::time FROM Q AS T WHERE Q.s=T.s AND T.dt
(SELECT * FROM Q AS U WHERE T.dt-'1 day'::intervalU.dt 
AND U.s=Q.s)))
GROUP BY s;

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


[SQL] Functional Indexes

2003-07-15 Thread David Olbersen
Hello all,

I have a function (urlhost) which finds the 'host' portion of a URL. In the case of 
http://www.foobar.com/really/long/path/to/a/file it returns "www.foobar.com".

I also have a function (urltld) which returns the TLD of a URL. In the case of 
http://www.foobar.com/really/long/path/to/a/file it returns ".com" (the leading dot is 
OK).

urltld uses urlhost to do it's job (how should be apparent).

Now the question: is there a single index I can create that will be used when my  
WHERE clause contains either urlhost or urltld? I could create two functional indexes, 
but that seems a bit silly to me.

Any thoughts?

--
David Olbersen 
iGuard Engineer
St. Bernard Software
11415 West Bernardo Court 
San Diego, CA 92127 
1-858-676-2277 x2152

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [SQL] Functional Indexes

2003-07-15 Thread Frank Bax
The two functions do not group data the same way, so a common index is not 
possible.
urlhost would put pgsql.org and pgsql.com close together.
urltld would but pgsql.com and xyz.com close together.

Frank

At 01:36 PM 7/15/03, David Olbersen wrote:

Hello all,

I have a function (urlhost) which finds the 'host' portion of a URL. In 
the case of http://www.foobar.com/really/long/path/to/a/file it returns 
"www.foobar.com".

I also have a function (urltld) which returns the TLD of a URL. In the 
case of http://www.foobar.com/really/long/path/to/a/file it returns ".com" 
(the leading dot is OK).

urltld uses urlhost to do it's job (how should be apparent).

Now the question: is there a single index I can create that will be used 
when my  WHERE clause contains either urlhost or urltld? I could create 
two functional indexes, but that seems a bit silly to me.

Any thoughts?

--
David Olbersen
iGuard Engineer
St. Bernard Software
11415 West Bernardo Court
San Diego, CA 92127
1-858-676-2277 x2152
---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


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


Re: [SQL] Functional Indexes

2003-07-15 Thread Tom Lane
"David Olbersen" <[EMAIL PROTECTED]> writes:
> I have a function (urlhost) which finds the 'host' portion of a URL. In the case of 
> http://www.foobar.com/really/long/path/to/a/file it returns "www.foobar.com".
> I also have a function (urltld) which returns the TLD of a URL. In the case of 
> http://www.foobar.com/really/long/path/to/a/file it returns ".com" (the leading dot 
> is OK).
> urltld uses urlhost to do it's job (how should be apparent).

> Now the question: is there a single index I can create that will be
> used when my  WHERE clause contains either urlhost or urltld?

I do not see any way with functions declared like that.  Quite aside
from implementation limitations, the portion of the 'host' string that
urltld is interested in would be the low-order part of the indexed
strings, and you can't usefully use an index to search for low-order
digits of the key.

Could you instead define an index over the reversed host name (eg,
com.foobar.www)?  This would seem to provide about the same
functionality for searches on urlhost, and you could exploit the index
for TLD searching via prefixes.  For example:

regression=# create table t1 (f1 text);
CREATE TABLE
regression=# create index t1i on t1 (lower(f1));
CREATE INDEX
regression=# explain select * from t1 where lower(f1) like 'com.%';
 QUERY PLAN

 Index Scan using t1i on t1  (cost=0.00..17.08 rows=5 width=32)
   Index Cond: ((lower(f1) >= 'com.'::text) AND (lower(f1) < 'com/'::text))
   Filter: (lower(f1) ~~ 'com.%'::text)
(3 rows)


regards, tom lane

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


Re: [SQL] Functional Indexes

2003-07-15 Thread Joe Conway
David Olbersen wrote:
Now the question: is there a single index I can create that will be
used when my  WHERE clause contains either urlhost or urltld? I could
create two functional indexes, but that seems a bit silly to me.
I can't think of how to do only one index in 7.3.x and earlier, but 
FWIW, this works in 7.4devel (which should be in beta next Monday):

create or replace function tld(text) returns text as '
select split_part(split_part(substr($1,8,length($1)),''/'',1),''.'',3)
' language 'sql' STRICT IMMUTABLE;
regression=# select tld('http://www.foobar.com/really/long/path/to/a/file');
 tld
-
 com
(1 row)
create or replace function sld(text) returns text as '
select split_part(split_part(substr($1,8,length($1)),''/'',1),''.'',2)
' language 'sql' STRICT IMMUTABLE;
regression=# select sld('http://www.foobar.com/really/long/path/to/a/file');
  sld

 foobar
(1 row)
create table urls(f1 text);
insert into urls values('http://www.foobar.com/really/long/path/to/a/file');
create index urls_idx1 on urls(tld(f1),sld(f1));
-- just to see index usage on toy table
set enable_seqscan to off;
regression=# explain analyze select * from urls where tld(f1) = 'com';
QUERY PLAN
--
 Index Scan using urls_idx1 on urls  (cost=0.00..4.69 rows=1 width=32) 
(actual time=0.07..0.07 rows=1 loops=1)
   Index Cond: (split_part(split_part(substr(f1, 8, length(f1)), 
'/'::text, 1), '.'::text, 3) = 'com'::text)
 Total runtime: 0.18 msec
(3 rows)

regression=# explain analyze select * from urls where tld(f1) = 'com' 
and sld(f1) = 'foobar';

  QUERY PLAN
-
 Index Scan using urls_idx1 on urls  (cost=0.00..4.70 rows=1 width=32) 
(actual time=0.08..0.09 rows=1 loops=1)
   Index Cond: ((split_part(split_part(substr(f1, 8, length(f1)), 
'/'::text, 1), '.'::text, 3) = 'com'::text) AND 
(split_part(split_part(substr(f1, 8, length(f1)), '/'::text, 1), 
'.'::text, 2) = 'foobar'::text))
 Total runtime: 0.21 msec
(3 rows)

Joe

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


Re: [SQL] Non-Blocking Locks (i.e. Oracle NOWAIT)

2003-07-15 Thread Ang Chin Han
Christoph Haller wrote:

PostgreSQL 7.3.2
T1: begin; select * from foo for update;
T2: set STATEMENT_TIMEOUT = 1000; -- milliseconds
Seems like setting it to 1 (ms) emulates the NOWAIT condition better. 
Can't set it to 0, though.

T2: select * from foo for update;
T2: ERROR:  Query was cancelled.
How picky are we in borrowing syntax and idiocyncracies (?) from other 
DBs? Since we can closely emulate Oracle's behaviour on SELECT ... FOR 
UPDATE NOWAIT, should we just add NOWAIT to the next (non-feature frozen 
version) of postgres?

--
Linux homer 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386 
GNU/Linux
 10:30am  up 202 days,  1:35,  6 users,  load average: 5.40, 5.14, 5.05


pgp0.pgp
Description: PGP signature