Re: [SQL] after delete trigger behavior

2005-06-22 Thread Russell Simpkins
Actually, I had a larger script that did exactly what you propose. However I 
started to think that a profecient where clause would do the trick.


In my mapping table, a and b are primary keys. a_id, b_id, c_sort_order. 
a_id is the parent and b_id is the child for my purposes, so if a_id is 
deleted then all relations are deleted, but if b_id is deleted, then there 
stands a chance for an index order in c_sort_order appearing.


Rather then selecting and looping, I thought I could short circut the 
procedure by saying


update mapping set c_sort_order = c_sort_order - 1 where a_id = OLD.a_id and 
c_sort_order > OLD.c_sort_order.


My thought was that there was no real reason to select and loop as this 
function would perform the resort for this series of a_id mappings. It seems 
to me that your code does the exact same thing, only in a longer form. Also 
there is no need to do anyone less then sort_order since sort_order will be 
0 to n-1 where n is the total number of mappings.


a_id, b_id, c_sort_order
1, 1, 0
1, 2, 1
1, 3, 2
1, 4, 3

if you delete where b_id = 1 then you want to update where b_id = 2, 3 and 4 
since a_id = 1 and c_sort_order is greater then 0.


Again, the issue was that postgres only executes one delete.

After changing the trigger to an after delete, I was able to delete all and 
even delete multiple rows. I now have one small problem that I will have to 
test more on. Using my where statement, if i delete from table where b_id = 
2 or b_id = 3, c_sort_order becomes out of sync. I will do another test and 
see if the select loop fairs any better.


I have a real-world function like so:

CREATE OR REPLACE FUNCTION cms.resort_content_flash() RETURNS TRIGGER AS '
DECLARE
  eachrow RECORD;
  innerrow RECORD;
  sort INT := 0;
BEGIN
  FOR eachrow IN EXECUTE ''SELECT * FROM cms.content_flash WHERE flash_id = 
'' || OLD.flash_id LOOP

   sort := 0;
	   FOR innerrow IN EXECUTE ''SELECT * FROM cms.content_flash WHERE 
content_id = '' || eachrow.content_id || '' ORDER BY sort_order'' LOOP

   IF innerrow.flash_id != OLD.flash_id THEN
		   EXECUTE ''UPDATE cms.content_flash SET sort_order = '' || sort || 
'' WHERE content_id = '' || innerrow.content_id || '' AND flash_id = '' || 
innerrow.flash_id || ;

  sort := sort +1;
   END IF;
   END LOOP;
  END LOOP;
  RETURN OLD;
END;
' language 'plpgsql';

that I will rejigger to the test table and try out.

Thanks for the input.


From: Tom Lane <[EMAIL PROTECTED]>
To: Stephan Szabo <[EMAIL PROTECTED]>
CC: Russell Simpkins <[EMAIL PROTECTED]>, 
pgsql-sql@postgresql.org
Subject: Re: [SQL] after delete trigger behavior Date: Wed, 22 Jun 2005 
15:46:41 -0400


Stephan Szabo <[EMAIL PROTECTED]> writes:
> Is there anything we have right now that will handle this kind of thing
> without requiring either updating all the counts after a deletion in a
> statement trigger or once per row updating all the counts for records 
with

> the same "a" (doing something like make a sequence and using it in a
> subselect matching keys)?

The best thing I can think of is your first idea, ie, renumbering all
the rows in a statement-level AFTER DELETE trigger.  Something like
(untested)

DECLARE
rec record;
n integer := 1;
BEGIN
FOR rec IN
SELECT * FROM table
WHERE <>
ORDER BY sort_order
LOOP
IF rec.sort_order != n THEN
UPDATE table SET sort_order = n
WHERE <>;
END IF;
n := n + 1;
END LOOP;
END;

Ugly as this is, it's at least linear in the number of rows to be
changed; the originally proposed trigger was O(N^2) in the number of
rows affected, and would surely be intolerably slow for multiple deletes
in a reasonably sized table.  Given an index on the grouping columns
plus sort_order, it could even be reasonably fast (don't forget to make
the ORDER BY match the index).

regards, tom lane




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


Re: [SQL] after delete trigger behavior

2005-06-22 Thread Tom Lane
Stephan Szabo <[EMAIL PROTECTED]> writes:
> Is there anything we have right now that will handle this kind of thing
> without requiring either updating all the counts after a deletion in a
> statement trigger or once per row updating all the counts for records with
> the same "a" (doing something like make a sequence and using it in a
> subselect matching keys)?

The best thing I can think of is your first idea, ie, renumbering all
the rows in a statement-level AFTER DELETE trigger.  Something like
(untested)

DECLARE
rec record;
n integer := 1;
BEGIN
FOR rec IN
SELECT * FROM table
WHERE <>
ORDER BY sort_order
LOOP
IF rec.sort_order != n THEN
UPDATE table SET sort_order = n
WHERE <>;
END IF;
n := n + 1;
END LOOP;
END;

Ugly as this is, it's at least linear in the number of rows to be
changed; the originally proposed trigger was O(N^2) in the number of
rows affected, and would surely be intolerably slow for multiple deletes
in a reasonably sized table.  Given an index on the grouping columns
plus sort_order, it could even be reasonably fast (don't forget to make
the ORDER BY match the index).

regards, tom lane

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


[SQL] encoding question

2005-06-22 Thread Joel Fradkin








Hi,

 

I am trying to convert from SQL_ASCII to UNICODE.

 

I have a program that will read from a table in one database
and write to a table in a different database.

I am hoping this all I need do (One data base is SQL_ASCII and 
the other is UNICODE).

I get a byte sequence error writing.

I tried using encoding =UNICODE and did not get the error,
but the data looked different stored in the field, so I am guessing it messed
it up.

I am using NpgsqlConnection.

Any one know the proper way to convert using a .net
app?

 

Joel Fradkin



 



Wazagua, Inc.
2520 Trailmate Dr
Sarasota, Florida 34243
Tel.  941-753-7111 ext 305



 



[EMAIL PROTECTED]
www.wazagua.com
Powered by Wazagua
Providing you with the latest Web-based technology & advanced tools.
© 2004. WAZAGUA, Inc. All rights reserved. WAZAGUA, Inc
 This email message is for the use of the intended recipient(s) and may
contain confidential and privileged information.  Any unauthorized review,
use, disclosure or distribution is prohibited.  If you are not the
intended recipient, please contact the sender by reply email and delete and
destroy all copies of the original message, including attachments.



 




 

 








Re: [SQL] after delete trigger behavior

2005-06-22 Thread Russell Simpkins



I suspect that if you read the spec carefully it would want a "triggered
data change violation" error raised here.  My advice is not to use a
BEFORE trigger for this.


What would you recommend then. I am using Hibernate in my java application 
and if the sort_order column (in this example column.c) gets out of sync, 
then the Hibernate application fails. In hind site, the after delete trigger 
would be the better choice.


The trigger works fine for one row deletes, but I noticed that you can't 
even do multiple row deletes with the trigger. Postgres only executes one 
row delete.




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


Re: [SQL] after delete trigger behavior

2005-06-22 Thread Stephan Szabo
On Wed, 22 Jun 2005, Tom Lane wrote:

> Stephan Szabo <[EMAIL PROTECTED]> writes:
> >> CREATE TRIGGER u_test1 BEFORE DELETE ON portfolio.test1 FOR EACH ROW 
> >> EXECUTE
> >> PROCEDURE resort_test1();
>
> > I think this will work in an after delete trigger, but not in a before
> > delete trigger (and seems to in my tests). I'm not sure what the spec says
> > about the visibility of rows in cases like this.
>
> Well, the actual effect is that the first trigger's UPDATE changes all
> the rows that the DELETE might later delete, thus overriding the delete.
> (A query cannot modify rows already modified by commands started later
> in the same transaction, such as commands issued by triggers fired by
> the query itself.)
>
> Depending on the order that the DELETE hits the rows in, there might be
> more than one row that can get processed before the UPDATEs have touched
> all remaining rows, so this is all pretty messy and not to be relied on.
>
> I suspect that if you read the spec carefully it would want a "triggered
> data change violation" error raised here.  My advice is not to use a
> BEFORE trigger for this.
>
> Even an AFTER trigger will have some pretty significant problems with
> this, I'm afraid, because of the uncertainty about the order in which
> the rows are deleted (and hence the order in which the trigger instances
> fire).  For instance, suppose you delete the rows with c=1 and c=2, and
> they get visited in that order.  The UPDATE for c=1 will update the row
> currently having c=3 to c=2 ... whereupon that row will NOT be seen as
> an update candidate by the UPDATE for c=2.  (You could work around that
> case by using ">= OLD.c" instead of "> OLD.c", but it could still fail
> with more than 2 rows being deleted.)  The proposed trigger only works
> cleanly if the rows are deleted in decreasing order of c, and there's no
> very easy way to guarantee that.

Is there anything we have right now that will handle this kind of thing
without requiring either updating all the counts after a deletion in a
statement trigger or once per row updating all the counts for records with
the same "a" (doing something like make a sequence and using it in a
subselect matching keys)?

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


Re: [SQL] after delete trigger behavior

2005-06-22 Thread Tom Lane
Stephan Szabo <[EMAIL PROTECTED]> writes:
>> CREATE TRIGGER u_test1 BEFORE DELETE ON portfolio.test1 FOR EACH ROW EXECUTE
>> PROCEDURE resort_test1();

> I think this will work in an after delete trigger, but not in a before
> delete trigger (and seems to in my tests). I'm not sure what the spec says
> about the visibility of rows in cases like this.

Well, the actual effect is that the first trigger's UPDATE changes all
the rows that the DELETE might later delete, thus overriding the delete.
(A query cannot modify rows already modified by commands started later
in the same transaction, such as commands issued by triggers fired by
the query itself.)

Depending on the order that the DELETE hits the rows in, there might be
more than one row that can get processed before the UPDATEs have touched
all remaining rows, so this is all pretty messy and not to be relied on.

I suspect that if you read the spec carefully it would want a "triggered
data change violation" error raised here.  My advice is not to use a
BEFORE trigger for this.

Even an AFTER trigger will have some pretty significant problems with
this, I'm afraid, because of the uncertainty about the order in which
the rows are deleted (and hence the order in which the trigger instances
fire).  For instance, suppose you delete the rows with c=1 and c=2, and
they get visited in that order.  The UPDATE for c=1 will update the row
currently having c=3 to c=2 ... whereupon that row will NOT be seen as
an update candidate by the UPDATE for c=2.  (You could work around that
case by using ">= OLD.c" instead of "> OLD.c", but it could still fail
with more than 2 rows being deleted.)  The proposed trigger only works
cleanly if the rows are deleted in decreasing order of c, and there's no
very easy way to guarantee that.

regards, tom lane

---(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] after delete trigger behavior

2005-06-22 Thread Stephan Szabo

On Wed, 22 Jun 2005, Russell Simpkins wrote:

> Hello,
>
> I have created a trigger function to update the sort_order column of a
> mapping table. I have table a that has a many to many relation ship with
> table b that is mapped as a_b where a_id, and b_id are the pk columns and
> there is a sort_order column.  Since a_b is a mapping table there are
> foreign key constraints with a cascade option. So, if i delete an entry from
> b, an entry in a_b is deleted. What I want though is for the sort_order
> column to be updated so that all entries of a_b for a given a entry remain
> in order.
>
> a_id, b_id, sort_order
> 1, 2, 0
> 1, 3, 1
> 1, 4, 2
> 1, 7, 3
>
> if I delete b_id = 4 then the b_id 7 should get a sort order of 2. I created
> an after delete trigger and the trigger works just fine when i delete only
> one row, but if I delete all using "delete from a_b" I am only able to
> delete one row. Here is an example:
> -
> -- a test table
> CREATE TABLE test1 (
> a int,
> b int,
> c int);
> -
> -- a resort function
> CREATE OR REPLACE FUNCTION resort_test1() RETURNS TRIGGER AS '
> DECLARE
>eachrow RECORD;
>innerrow RECORD;
>sort INT := 0;
> BEGIN
>EXECUTE ''UPDATE portfolio.test1 set c = c - 1 where a = '' || OLD.a ||
> '' and c > '' || OLD.c;
>RETURN OLD;
> END;
> ' language 'plpgsql';
> -
> -- the trigger
> CREATE TRIGGER u_test1 BEFORE DELETE ON portfolio.test1 FOR EACH ROW EXECUTE
> PROCEDURE resort_test1();

I think this will work in an after delete trigger, but not in a before
delete trigger (and seems to in my tests). I'm not sure what the spec says
about the visibility of rows in cases like this.

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


[SQL] after delete trigger behavior

2005-06-22 Thread Russell Simpkins

Hello,

I have created a trigger function to update the sort_order column of a 
mapping table. I have table a that has a many to many relation ship with 
table b that is mapped as a_b where a_id, and b_id are the pk columns and 
there is a sort_order column.  Since a_b is a mapping table there are 
foreign key constraints with a cascade option. So, if i delete an entry from 
b, an entry in a_b is deleted. What I want though is for the sort_order 
column to be updated so that all entries of a_b for a given a entry remain 
in order.


a_id, b_id, sort_order
1, 2, 0
1, 3, 1
1, 4, 2
1, 7, 3

if I delete b_id = 4 then the b_id 7 should get a sort order of 2. I created 
an after delete trigger and the trigger works just fine when i delete only 
one row, but if I delete all using "delete from a_b" I am only able to 
delete one row. Here is an example:

-
-- a test table
CREATE TABLE test1 (
a int,
b int,
c int);
-
-- a resort function
CREATE OR REPLACE FUNCTION resort_test1() RETURNS TRIGGER AS '
DECLARE
  eachrow RECORD;
  innerrow RECORD;
  sort INT := 0;
BEGIN
  EXECUTE ''UPDATE portfolio.test1 set c = c - 1 where a = '' || OLD.a || 
'' and c > '' || OLD.c;

  RETURN OLD;
END;
' language 'plpgsql';
-
-- the trigger
CREATE TRIGGER u_test1 BEFORE DELETE ON portfolio.test1 FOR EACH ROW EXECUTE 
PROCEDURE resort_test1();

--
-- dummy data
insert into test1 values(1,1,0);
insert into test1 values(1,2,1);
insert into test1 values(1,3,2);
insert into test1 values(1,4,3);
insert into test1 values(1,5,4);

insert into test1 values(2,1,0);
insert into test1 values(2,2,1);
insert into test1 values(2,3,2);
insert into test1 values(2,4,3);
insert into test1 values(2,5,4);

-- delete that works
delete from test1 where b = 3;
-- review results
select c from test1 where a = 1 order by c;
-- delete all
delete from test1;

 note that it will only delete one row.

Is this by design? Is there something I can do to remedy this behavior? I 
would expect to have all rows delete and not just the first one.


Any help is appreciated.

Russ



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


Re: [SQL] Alias to a type

2005-06-22 Thread KÖPFERL Robert
Keep in mind, though. Using a DOMAIN in some definition 'seals' the domain.
Yo can't change the domain unless you drop all dependent objects

|-Original Message-
|From: Veikko Mäkinen [mailto:[EMAIL PROTECTED]
|Sent: Mittwoch, 22. Juni 2005 15:14
|To: pgsql-sql@postgresql.org
|Subject: Re: [SQL] Alias to a type
|
|
|Richard Huxton wrote:
|> Veikko Mäkinen wrote:
|> 
|>> Hey,
|>>
|>> Is it possible to create a new type as an alias to a 
|pre-defined type? 
|>> I use "USERID varchar(20)" in almost every table I have I'd like to 
|>> make an alias for that type eg.
|> 
|> 
|> CREATE DOMAIN username_string AS varchar(20);
|> 
|> Test it with your client applications though, make sure they 
|cope. Some 
|> don't cope well with user-defined types.
|
|
|Splendid, thank you all :) I'm quite sure loosely typed PHP can cope 
|with my user-defined types ;)
|
|But now I need a better modeling tool because Azzurri Clay 1.1 
|(Eclipse 
|plug-in) doesn't let me define new types... Any suggestions? SQL DDL 
|generation is the only demand I really have.
|
|
|-veikko
|
|
|---(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 4: Don't 'kill -9' the postmaster


Re: [SQL] Alias to a type

2005-06-22 Thread Veikko Mäkinen

Richard Huxton wrote:

Veikko Mäkinen wrote:


Hey,

Is it possible to create a new type as an alias to a pre-defined type? 
I use "USERID varchar(20)" in almost every table I have I'd like to 
make an alias for that type eg.



CREATE DOMAIN username_string AS varchar(20);

Test it with your client applications though, make sure they cope. Some 
don't cope well with user-defined types.



Splendid, thank you all :) I'm quite sure loosely typed PHP can cope 
with my user-defined types ;)


But now I need a better modeling tool because Azzurri Clay 1.1 (Eclipse 
plug-in) doesn't let me define new types... Any suggestions? SQL DDL 
generation is the only demand I really have.



-veikko


---(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] Alias to a type

2005-06-22 Thread Achilleus Mantzios
O Sean Davis έγραψε στις Jun 22, 2005 :

> 
> On Jun 22, 2005, at 7:42 AM, Achilleus Mantzios wrote:
> 
> > O Veikko MΞ΄kinen έγραψΡ στις Jun 22, 2005 :
> >
> >> Hey,
> >>
> >> Is it possible to create a new type as an alias to a pre-defined 
> >> type? I
> >> use "USERID varchar(20)" in almost every table I have I'd like to make
> >> an alias for that type eg.
> >>
> >> 
> >>create type myschema.useridtype as varchar(20);
> >> 
> >>
> >
> > Try something like
> >
> > CREATE DOMAIN my_integer AS INTEGER;
> 
> Just for my own edification, does creating a "simple" domain like this 
> then require a whole set of functions for indexing, etc., like other 
> more complex user-defined types, or will postgres "do the right thing"?

In the above example you may safely consider indexing columns
of type my_integer as indexing INTEGERs.

> 
> Thanks,
> Sean
> 
> 

-- 
-Achilleus


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


Re: [SQL] Alias to a type

2005-06-22 Thread Richard Huxton

Veikko Mäkinen wrote:

Hey,

Is it possible to create a new type as an alias to a pre-defined type? I 
use "USERID varchar(20)" in almost every table I have I'd like to make 
an alias for that type eg.


CREATE DOMAIN username_string AS varchar(20);

Test it with your client applications though, make sure they cope. Some 
don't cope well with user-defined types.

--
  Richard Huxton
  Archonet Ltd


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

  http://archives.postgresql.org


Re: [SQL] Alias to a type

2005-06-22 Thread Bruno Wolff III
On Wed, Jun 22, 2005 at 08:04:39 -0400,
  Sean Davis <[EMAIL PROTECTED]> wrote:
> 
> 
> Just for my own edification, does creating a "simple" domain like this 
> then require a whole set of functions for indexing, etc., like other 
> more complex user-defined types, or will postgres "do the right thing"?

No, the underlying type's class is still used. You don't need to create
new comparison or type conversion functions.

---(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] Alias to a type

2005-06-22 Thread Sean Davis


On Jun 22, 2005, at 7:42 AM, Achilleus Mantzios wrote:


O Veikko Mδkinen έγραψε στις Jun 22, 2005 :


Hey,

Is it possible to create a new type as an alias to a pre-defined 
type? I

use "USERID varchar(20)" in almost every table I have I'd like to make
an alias for that type eg.


   create type myschema.useridtype as varchar(20);




Try something like

CREATE DOMAIN my_integer AS INTEGER;


Just for my own edification, does creating a "simple" domain like this 
then require a whole set of functions for indexing, etc., like other 
more complex user-defined types, or will postgres "do the right thing"?


Thanks,
Sean


---(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] Alias to a type

2005-06-22 Thread Achilleus Mantzios
O Veikko Mδkinen έγραψε στις Jun 22, 2005 :

> Hey,
> 
> Is it possible to create a new type as an alias to a pre-defined type? I 
> use "USERID varchar(20)" in almost every table I have I'd like to make 
> an alias for that type eg.
> 
> 
>create type myschema.useridtype as varchar(20);
> 
> 

Try something like

CREATE DOMAIN my_integer AS INTEGER;

> I might have to alter the type some day and this way I'd have to just 
> re-define the alias. Can this be achieved by creating a new type with 
> CREATE TYPE? What are the input/output functions in the CREATE TYPE 
> definition?
> 
> Thanks.
> 
> 
> -veikko
> 
> 
> ---(end of broadcast)---
> TIP 6: Have you searched our list archives?
> 
>http://archives.postgresql.org
> 

-- 
-Achilleus


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

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


[SQL] Alias to a type

2005-06-22 Thread Veikko Mäkinen

Hey,

Is it possible to create a new type as an alias to a pre-defined type? I 
use "USERID varchar(20)" in almost every table I have I'd like to make 
an alias for that type eg.



  create type myschema.useridtype as varchar(20);


I might have to alter the type some day and this way I'd have to just 
re-define the alias. Can this be achieved by creating a new type with 
CREATE TYPE? What are the input/output functions in the CREATE TYPE 
definition?


Thanks.


-veikko


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

  http://archives.postgresql.org