Re: [SQL] Cast on character columns in views

2007-09-04 Thread Luiz K. Matsumura



Luiz K. Matsumura wrote:


Richard Broersma Jr wrote:

--- "Luiz K. Matsumura" <[EMAIL PROTECTED]> wrote:
 

CREATE VIEW view1( id, col1, type1, type2) AS
SELECT table1.id,
   table1.col1,
   CAST( table2.type1 AS CHARACTER( 3 )),
   NULL
FROM   table1
JOIN   table2 ON table2.fk_table1 = table1.id
UNION ALL
SELECT table1.id,
   table1.col1,
   CAST( NULL AS CHARACTER( 3 )),
   table3.type2
FROM   table1
JOIN   table3 ON table3.fk_table1 = table1.id;



Would the above changes work?

Regards,
Richard Broersma Jr.


  

Hi Richard,
Your changes works ! But now I know what mistake I did:

The error is occurring because I'm doing a CREATE OR REPLACE VIEW 
command.

The command with null:character(3) works too.
The error is because I create a view then try to change the definition 
with the CREATE OR REPLACE VIEW command
When I drop the view first , and then create again the view (in a 
separated transaction), now the command works! (this is a bug?)

I'm using a postgres 8.2.4 on Linux.

Thanks a lot!


Ugh, I'm totally crazy with this views
I'm using pgadmin with postgres, when I  clink on "view the data of 
selected object" button all works fine.

But when I open a query tool window and do:

SELECT * FROM view1;

Now, again type1 column returns as bpchar.
But if I do:

SELECT type1 FROM view1;

Now, type1 column returns as character(3)

If I do

select id, col1, type1,type2  from view1;

Again type1 returns as bpchar. But if I do

select id, col1,type2, type1 from view1;

Now type1 return as character(3).



--
Luiz K. Matsumura
Plan IT Tecnologia Informática Ltda.


---(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] Partial index on boolean - Sometimes fails to index scan

2007-09-04 Thread Bryce Nesbitt




This is a reformulation of an earlier question.  I've got a confusing
case of a partial index not working.  The column in question is a
not-null boolean, which is false only for the most recent entries into
the table.

# explain analyze select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_
from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=2
)and(vehicleeve0_.RECONCILED=false);
QUERY PLAN
--
 Aggregate  (cost=49184.62..49184.64 rows=1 width=4) (actual
time=2017.793..2017.794 rows=1 loops=1)
   ->  Seq Scan on eg_vehicle_event vehicleeve0_ 
(cost=0.00..49162.93 rows=8679 width=4) (actual time=1202.175..2006.169
rows=10342 loops=1)
 Filter: ((cso_id = 2) AND (NOT reconciled))
Total runtime: 2018.052 ms

stage=# create index eg_ve_reconciled_partial on eg_vehicle_event
(reconciled) where reconciled=false;

stage=# select pg_total_relation_size('eg_ve_reconciled_partial');
204800

# explain analyze select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_
from EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=2
)and(vehicleeve0_.RECONCILED=false);
QUERY PLAN 
---
 Aggregate  (cost=81.75..81.76 rows=1 width=4) (actual
time=56.218..56.219 rows=1 loops=1)
   ->  Index Scan using eg_ve_reconciled_partial on eg_vehicle_event
vehicleeve0_  (cost=0.00..60.05 rows=8679 width=4) (actual
time=0.118..44.647 rows=10342 loops=1)
 Index Cond: (reconciled = false)
 Filter: (cso_id = 2)
 Total runtime: 56.312 ms


Which is all good.  But the Hibernate version
of query still takes several seconds, and still appears in my pg_log
slow query log:

LOG:  duration: 2248.662 ms  statement: EXECUTE C_51443  [PREPARE: 
select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from
EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1
)and(vehicleeve0_.RECONCILED=$2 )]

A full index on 'reconciled' speeds up the query.  But why should the
partial index not also do it?  Any idea why apparently identical
queries give different partial index scan results?  PostgreSQL 8.1.9.

-- 

Visit http://www.obviously.com/





Re: [SQL] Difference between "foo is false" and "foo=false"? Partial index on boolean.

2007-09-04 Thread Richard Huxton

Bryce Nesbitt wrote:

Tom Lane wrote:

Bryce Nesbitt <[EMAIL PROTECTED]> writes:

They give different results for NULL --- specifically, NULL for the
former and FALSE for the latter.  Don't blame me, it's in the spec...

Thanks, and Got It.  This particular column is:
reconciled   | boolean | not null
On PostgreSQL 8.1.9.


So given all that, why would the Hibernate query fail to use the partial 
index?   I eventually created three indexes, and only the hideously large full 
index increases performance:



Only the full index prevents a "false" scan from taking 4 seconds:

LOG:  duration: 4260.575 ms  statement: EXECUTE C_50292  [PREPARE:  select 
count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from EG_VEHICLE_EVENT vehicleeve0_ 
where (vehicleeve0_.CSO_ID=$1 ) and (vehicleeve0_.*RECONCILED=$2* )]


It's a prepared query-plan, which means it can't plan to use the index 
because the next EXECUTE might have reconciled=true.


--
  Richard Huxton
  Archonet Ltd

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


[SQL] EXECUTE 'EXECUTE ...' or how to use dynamic prepared statements ?

2007-09-04 Thread Marc Mamin

Hello,
 
I have a large upddate to perform on tables which are dynamically
generated (dynamic names).
 
In this simplified example, the operation should replace in each family
the "mygroup" of each item of rang=0 with the "mygroup" value of the
element of rang=1 :
(the * indicate the modified values) 
 
idfamily  rang mygroup
 
1  10  1
2  11  2
3  12  3
4  13  4
 
5  20  6
6  21  6
7  22  7
8  23  7
 
9  30  10
10 31  20
11 32  21
 
After the update: 
 
1 10   2 *
2 11   2
3 12   3
4 13   4
 
5 20   6
6 21   6
7 22   7
8 23   7
 
9 30   20 *
1031   20
1132   21
 

In the following function, I would like to use a prepared statement for
the update command but I get stuck with the tho different meanings of
EXECUTE ...
 
Is there a way to achieve this ?
 
Thanks,
 
Marc
 
 
 

CREATE OR REPLACE FUNCTION test_function(tablename varchar)
  RETURNS integer AS
$BODY$
 
DECLARE
rec record;
top_group int;
top_family character(16);
top_id int;
 
BEGIN
 
   /*
   the prepared statement must be generated dynamically in order to
include the table name.
   */
   EXECUTE 'PREPARE update_stmt (int, int) AS
   update '||tablename||' set mygroup= $1 where id = $2';
 

   
   /*
   using "select distinct on" allows to retrieve and sort the required
information for the update.
   this is faster than a self join on the table
   */
   for rec in execute 
  'select DISTINCT  on (family,rang) 
  family, rang, mygroup, id
  from '||tablename||'
  where  rang < 2
  order by family, rang'
   
   loop
 
 IF rec.rang = 0 THEN
 
   top_group  := rec.mygroup;
   top_family := rec.family;
   top_id := rec.id;
 
 ELSIF rec.family = top_family AND rec.mygroup <> top_group THEN
 
 
   /*
   Update without using a prepared statement
   EXECUTE 'update '||tablename||' set mygroup=
'||rec.mygroup||' where id = '||top_id;
   */
   
   -- This works, but the command has to be computed for each
iteration
   EXECUTE 'EXECUTE
update_stmt('||rec.mygroup||','||top_id||')';
 
   /*
   Following syntax would be fine
   PERFORM EXECUTE update_stmt(rec.mygroup,top_id);
   */
 
 END IF;
 

   end loop;
 
   DEALLOCATE update_stmt;
 
   RETURN 0; 
 

END;
 
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
 

/* 
test data:
=== */
 
--drop table test_table;
create table test_table(id int,family int,rang int,mygroup int);
 
insert into test_table values (1,1,0,1); 
insert into test_table values (2,1,1,2); 
insert into test_table values (3,1,2,3); 
insert into test_table values (4,1,3,4);
 
insert into test_table values (5,2,0,6); 
insert into test_table values (6,2,1,6); 
insert into test_table values (7,2,2,7); 
insert into test_table values (8,2,3,7);
 
insert into test_table values (9, 3,0,10); 
insert into test_table values (10,3,1,20); 
insert into test_table values (11,3,2,21);
 
select test_function('test_table');
 
select * from test_table order by id;


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


Re: [SQL] EXECUTE 'EXECUTE ...' or how to use dynamic prepared statements ?

2007-09-04 Thread Dirk Jagdmann
Hello Marc,

at first I tried to solve your update of the tables. The example you
gave should be done with an update statement like the following:

update test_table
   set mygroup=(select t.mygroup
  from test_table as t
 where t.family = test_table.family
   and t.rang = test_table.rang+1)
 where rang=0;

If you have to write a function which receives the tablename as an
argument it would look like:

CREATE OR REPLACE FUNCTION test_function(tablename text)
RETURNS integer AS $BODY$
 BEGIN
  EXECUTE 'update ' || tablename || '
   set mygroup=(select t.mygroup
  from ' || tablename || ' as t
 where t.family = test_table.family
   and t.rang = test_table.rang+1)
 where rang=0;'
  RETURN 0;
 END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

Generally you should avoid using explicit for/loop constructs in your
stored procedures if the action can be solved by a single SQL
statement, because the optimizer can make a better execution plan.

-- 
---> Dirk Jagdmann
> http://cubic.org/~doj
-> http://llg.cubic.org

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


[SQL] Use of delete...returning in function problem

2007-09-04 Thread Bart Degryse
I'm trying to use a delete statement with returning clause in a function:
  CREATE OR REPLACE FUNCTION "public"."test_delete"() RETURNS void AS
  $body$
  DECLARE
rec billing_errors_new;
  BEGIN
FOR rec IN (
  delete from billing_errors_new where errortypeid IN (1,2) returning *)
LOOP
  RAISE NOTICE 'billingid: % - errortypeid: %', rec.billingid, 
rec.errortypeid;
END LOOP;
  EXCEPTION
WHEN OTHERS THEN
  RAISE NOTICE '%: %', SQLSTATE, SQLERRM;
  END;
  $body$
  LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
 
I get following error though:
  ERROR:  syntax error at or near "delete" at character 4  
  QUERY:   ( delete from billing_errors_new where errortypeid IN (1,2) 
returning *)
  CONTEXT:  SQL statement in PL/PgSQL function "test_delete" near line 5
 
According to the manual (I think) it should be possible:
  The query used in this type of FOR statement can be any SQL command that 
returns rows to the caller: 
  SELECT is the most common case, but you can also use INSERT, UPDATE, or 
DELETE with a RETURNING clause.
  (see 
http://www.postgresql.org/docs/8.2/static/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING)
 
So probably I'm doing something wrong. Can anyone tell me what?
Thanks,
Bart
 
In case it matters:
  CREATE TABLE "public"."billing_errors_new" (
"billingid" INTEGER NOT NULL, 
"errortypeid" INTEGER NOT NULL, 
CONSTRAINT "billing_errors_new_billingid_fkey" FOREIGN KEY ("billingid")
  REFERENCES "public"."billing"("id")
  ON DELETE CASCADE
  ON UPDATE CASCADE
  DEFERRABLE
  INITIALLY DEFERRED, 
CONSTRAINT "billing_errors_new_errortypeid_fkey" FOREIGN KEY ("errortypeid")
  REFERENCES "public"."billing_error_types"("id")
  ON DELETE NO ACTION
  ON UPDATE CASCADE
  NOT DEFERRABLE
  ) WITH (fillfactor = 100, OIDS = FALSE);
 
  CREATE UNIQUE INDEX "billing_errors_new_unq" ON "public"."billing_errors_new"
USING btree ("billingid", "errortypeid")
  WITH (fillfactor =100);
 
  billingid errortypeid
  118075 1
  118076 1
  118077 1
  118078 1
  213774 4
  336717 4
  349906 4
 


[SQL] 8.0.1 to 8.0.13 upgrade added 15% lack of time of query execution

2007-09-04 Thread Aleksandr Vinokurov



Hello all,

I beg your pardon if I do not know some thing, but I was disappointed 
after taken an upgrade from 8.0.1 to 8.0.13, now the query, that I had 
optimized so far to run for 92 sec on 8.0.1, takes 106 seconds on 8.0.13.


The plan seems to stay unmodified, except statistics used for its 
construction, but one nested loop's actual time was largely increased:


[For 8.0.13]
Nested Loop Left Join  (cost=113409.50..137207.88 rows=12214 width=146) 
(actual time=37839.806..104026.224 rows=26139 loops=1)


[For 8.0.1]
Nested Loop Left Join  (cost=116564.46..119674.74 rows=1597 width=146) 
(actual time=32120.292..90484.361 rows=26139 loops=1)



What I have done upgrading:
1. As rel.notes says I don't need dump/restore to perform my upgrade, 
even initdb is not needed for me, as I don't want to add security 
enhancements for now.
2. Compiled 8.0.13 from sources and have installed to a separate 
location (/usr/local/pgsql instead of old /usr/bin, /usr/lib,..)

3. chown-ed all stuff to postgres in /usr/local/pgsql
4. run postmaster with the old data directory specified.
5. reindexed database.

Both plans with queries echoed are attached to this email.


Will appreciate any help in navigating me to the right way.

With best regards,
Aleksandr.
Timing is on.
explain analyze
select log_rec_id,
   log_date,
   log_uid,
   log_name,
   array_accum(trim(trailing ' ' from gh_name)) as groups
from (
   
select distinct on (log_rec_id, start_rec_id, fin_rec_id, gm_rec_id)
   log_rec_id,
   log_date,
   log_uid,
   log_name,
   start_rec_id,
   start_date,
   start_action,
   start_uid,
   start_name,
   fin_rec_id,
   fin_date,
   fin_action,
   fin_uid,
   fin_name,
   gm_rec_id,
   gm_date,
   gm_gid,
   gm_uid,
   gh.rec_id as gh_rec_id,
   gh.date as gh_date,
   gh.action as gh_action,
   gh.gid as gh_gid,
   gh.name as gh_name
from (
select *
from group_history
where action <> 1
) as gh
right join (
   
select log_rec_id,
   log_date,
   log_uid,
   log_name,
   start_rec_id,
   start_date,
   start_action,
   start_uid,
   start_name,
   fin_rec_id,
   fin_date,
   fin_action,
   fin_uid,
   fin_name,
   max(gm_rec_id) as gm_rec_id,
   max(gm_date) as gm_date,
   gm_gid,
   gm_uid
from (
   
select
   luid.*,
   gmh.rec_id as gm_rec_id,
   gmh.date as gm_date,
   gmh.gid as gm_gid,
   gmh.uid as gm_uid,
   gmh.action as gm_action
from group_member_history as gmh
right join (
   
select distinct on (cuh.log_rec_id, cuh.start_rec_id)
   cuh.*, duh.*
from (
select rec_id as fin_rec_id,
   date as fin_date,
   action as fin_action,
   uid as fin_uid,
   name as fin_name
from "user_history" 
where 1 = 1
and action <> 0

) as duh
right join (
select distinct on (log.rec_id)
   log.rec_id as log_rec_id,
   log.date as log_date,
   log.uid as log_uid,
   log.name as log_name,
   uh.rec_id as start_rec_id,
   uh.date as start_date,
   uh.action as start_action,
   uh.uid as start_uid,
   uh.name as start_name
from (
select *
from "user_history"
where 1 = 1
and action <> 1

order by date
) as uh
right join log_example_3 as log
on log.name = uh.name
and uh.date <= log.date
order by log.rec_id, start_date desc
) as cuh
on cuh.start_uid = duh.fin_uid
and duh.fin_date > cuh.start_date and duh.fin_date <= 
cuh.log_date
order by cuh.log_rec_id, cuh.start_rec_id, duh.fin_rec_id
   
) as luid
on gmh.uid = luid.start_uid

Re: [SQL] Use of delete...returning in function problem

2007-09-04 Thread Richard Huxton

Bart Degryse wrote:

I'm trying to use a delete statement with returning clause in a function:



FOR rec IN (
  delete from billing_errors_new where errortypeid IN (1,2) returning *)
LOOP



I get following error though:
  ERROR:  syntax error at or near "delete" at character 4  
  QUERY:   ( delete from billing_errors_new where errortypeid IN (1,2) returning *)

  CONTEXT:  SQL statement in PL/PgSQL function "test_delete" near line 5
 
According to the manual (I think) it should be possible:


I think it's just the brackets () - plpgsql's parser isn't terribly 
sophisticated.


This works for me, but with brackets doesn't.

BEGIN;

CREATE TEMPORARY TABLE test1 (a integer, b text);
INSERT INTO test1 SELECT generate_series(1,100) AS a, 'text for b';

CREATE FUNCTION testdel() RETURNS integer AS $$
DECLARE
n integer;
r RECORD;
BEGIN
n := 0;
FOR r IN DELETE FROM test1 WHERE a % 10 = 1 RETURNING * LOOP
n := n + 1;
END LOOP;
RETURN n;
END;
$$ LANGUAGE plpgsql;

SELECT testdel();

ROLLBACK;

--
  Richard Huxton
  Archonet Ltd

---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

   http://www.postgresql.org/about/donate


Re: [SQL] Cast on character columns in views

2007-09-04 Thread Richard Broersma Jr
--- "Luiz K. Matsumura" <[EMAIL PROTECTED]> wrote:
> When I drop the view first , and then create again the view (in a 
> separated transaction), now the command works! (this is a bug?)

Well according to the manual, it is working as it is intended to work:
http://www.postgresql.org/docs/8.2/interactive/sql-createview.html

I've created large SQL scripts that employ:

DROP VIEW IF EXITS viewname;

CREATE VIEW ...

Regards,
Richard Broersma Jr.

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


Re: [SQL] Cast on character columns in views

2007-09-04 Thread Richard Broersma Jr
--- "Luiz K. Matsumura" <[EMAIL PROTECTED]> wrote:

> Ugh, I'm totally crazy with this views
> I'm using pgadmin with postgres, when I  clink on "view the data of 
> selected object" button all works fine.
> But when I open a query tool window and do:
> 
> SELECT * FROM view1;
> Now, again type1 column returns as bpchar.
> But if I do:

This might be a good question to ask on the PGAdmin mailing list or even try 
using the latest
version of PGAdmin.  Perhaps this is something that PGAdmin is doing rather 
than postgresql.

If you open psql -U your_db_user -d your_database_name.

and type:

\d schema_name.view_name

was does it show as the definition of the column.

Regards,
Richard Broersma Jr.

---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

http://www.postgresql.org/about/donate


Re: [SQL] Use of delete...returning in function problem

2007-09-04 Thread Bart Degryse
Amazing what a bracket can do :)
Thanks for the help.

>>> Richard Huxton <[EMAIL PROTECTED]> 2007-09-04 12:45 >>>
Bart Degryse wrote:
> I'm trying to use a delete statement with returning clause in a function:

> FOR rec IN (
>   delete from billing_errors_new where errortypeid IN (1,2) returning *)
> LOOP

> I get following error though:
>   ERROR:  syntax error at or near "delete" at character 4  
>   QUERY:   ( delete from billing_errors_new where errortypeid IN (1,2) 
> returning *)
>   CONTEXT:  SQL statement in PL/PgSQL function "test_delete" near line 5
>  
> According to the manual (I think) it should be possible:

I think it's just the brackets () - plpgsql's parser isn't terribly 
sophisticated.

This works for me, but with brackets doesn't.

BEGIN;

CREATE TEMPORARY TABLE test1 (a integer, b text);
INSERT INTO test1 SELECT generate_series(1,100) AS a, 'text for b';

CREATE FUNCTION testdel() RETURNS integer AS $$
DECLARE
 n integer;
 r RECORD;
BEGIN
 n := 0;
 FOR r IN DELETE FROM test1 WHERE a % 10 = 1 RETURNING * LOOP
 n := n + 1;
 END LOOP;
 RETURN n;
END;
$$ LANGUAGE plpgsql;

SELECT testdel();

ROLLBACK;

-- 
   Richard Huxton
   Archonet Ltd

---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

http://www.postgresql.org/about/donate


Re: [SQL] How to influence the planner

2007-09-04 Thread Scott Marlowe
On 8/31/07, Richard Ray <[EMAIL PROTECTED]> wrote:

> Changing to enable_seqscan = on does solve this problem, thanks
> Is there some method of crafting a query that will assert my wishes to the 
> planner
> When is enable_seqscan = off appropriate

enable_xxx = off are troubleshooting tools.  They override the query planner.

For instance, I had a query that was running slow, and using set
enable_nestloop=off allowed the query to run fast.  However, using
explain analyze I could see that the estimated number of rows was off.
 Analyze didn't fix it, so I increased the stats target for the column
I was working with, reanalyzed, and voila, the query ran fine with
nestloop=on.

So, enable_xxx=off is normally only appropriate when troubleshooting
an issue, not as a fix all.  That's doubly true for
enable_seqscan=off.

If you do have a query that nothing else seems to work on it, you can
set one of the enable_xxx settings off for that connection only and
not worry about messing up all the other sessions connecting to your
db.

---(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: [SQL] Partial index on boolean - Sometimes fails to index scan

2007-09-04 Thread Bryce Nesbitt




Richard Huxton provided the answer: It's a prepared query-plan,
which means it can't plan to use the index because the next EXECUTE
might have reconciled=true.


Bryce Nesbitt wrote:

  
...Which is all good.  But the Hibernate version
of query still takes several seconds, and still appears in my pg_log
slow query log:
  
  LOG:  duration: 2248.662 ms  statement: EXECUTE C_51443 
[PREPARE: 
select count(vehicleeve0_.VEHICLE_EVENT_ID) as x0_0_ from
EG_VEHICLE_EVENT vehicleeve0_ where (vehicleeve0_.CSO_ID=$1
)and(vehicleeve0_.RECONCILED=$2 )]




Re: [SQL] Cast on character columns in views

2007-09-04 Thread Tom Lane
Richard Broersma Jr <[EMAIL PROTECTED]> writes:
> --- "Luiz K. Matsumura" <[EMAIL PROTECTED]> wrote:
>> But when I open a query tool window and do:
>> SELECT * FROM view1;
>> Now, again type1 column returns as bpchar.

> This might be a good question to ask on the PGAdmin mailing list or even try 
> using the latest
> version of PGAdmin.  Perhaps this is something that PGAdmin is doing rather 
> than postgresql.

The seeming ordering dependency certainly sounds like it might be a
client-side bug --- something failing to keep straight which typmod goes
with which column, maybe?

There are some backend-side issues with simply not being able to tell
the difference between null::bpchar and null::char(3) ... but for
any given view definition, it's pretty hard to see how the order of
selecting the columns would matter.  A client-side bug seems a bit
more likely.

regards, tom lane

---(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] Trigger to change different row in same table

2007-09-04 Thread PostgreSQL Admin
I want to write a trigger that updates a different row on the same
table. It's pretty basic: before the any row  in his table updated I
want to set a only row that has the value true to false.  I keep getting
this error:

SQL statement "update theirry.articles set master_featured = false where
master_featured = true"
PL/pgSQL function "master_featured_maintenance" line 4 at SQL statement

My basic trigger:

CREATE OR REPLACE FUNCTION theirry.master_featured_maintenance()
RETURNS TRIGGER AS
$master_featured_maintenance$
DECLARE
master_feature boolean;
BEGIN
update theirry.articles
set master_featured = false
where master_featured = true;
END;
$master_featured_maintenance$
LANGUAGE plpgsql;

CREATE TRIGGER master_featured_maintenance
BEFORE INSERT OR UPDATE ON theirry.articles
FOR EACH ROW EXECUTE PROCEDURE  theirry.master_featured_maintenance();


Thanks in advance,
J

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


Re: [SQL] Trigger to change different row in same table

2007-09-04 Thread PostgreSQL Admin
chester c young wrote:
> how are you preventing recursion?
>
>   

That could be the problem, suggestions?

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

   http://archives.postgresql.org


Re: [SQL] Use of delete...returning in function problem

2007-09-04 Thread Tom Lane
Richard Huxton <[EMAIL PROTECTED]> writes:
> I think it's just the brackets () - plpgsql's parser isn't terribly 
> sophisticated.

It's not plpgsql's fault --- you'll get the same result if you put
parentheses around a DELETE command at the SQL command line.

regression=# (delete from fool);
ERROR:  syntax error at or near "delete"
LINE 1: (delete from fool);
 ^

The OP may be used to putting parens into his FOR loops because it
works with SELECT:

regression=# (select * from zz1);
 f1 | f2 | f3 
++
(0 rows)

The difference is that SELECT can be put into larger groupings (eg
UNIONs) so it has to be parenthesiz-able.  If we ever considered
supporting DELETE RETURNING as a component of larger queries, this
syntax difference would likely go away.

regards, tom lane

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


Re: [SQL] How to influence the planner

2007-09-04 Thread Richard Ray

Thanks guys
Lesson learned

On Tue, 4 Sep 2007, Scott Marlowe wrote:


On 8/31/07, Richard Ray <[EMAIL PROTECTED]> wrote:


Changing to enable_seqscan = on does solve this problem, thanks
Is there some method of crafting a query that will assert my wishes to the 
planner
When is enable_seqscan = off appropriate


enable_xxx = off are troubleshooting tools.  They override the query planner.

For instance, I had a query that was running slow, and using set
enable_nestloop=off allowed the query to run fast.  However, using
explain analyze I could see that the estimated number of rows was off.
Analyze didn't fix it, so I increased the stats target for the column
I was working with, reanalyzed, and voila, the query ran fine with
nestloop=on.

So, enable_xxx=off is normally only appropriate when troubleshooting
an issue, not as a fix all.  That's doubly true for
enable_seqscan=off.

If you do have a query that nothing else seems to work on it, you can
set one of the enable_xxx settings off for that connection only and
not worry about messing up all the other sessions connecting to your
db.



---(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] work hour calculations

2007-09-04 Thread novice
Hello All,

SELECT notification_time, finished_time, sum(finished_time -
notification_time) as actual
FROM log
GROUP BY notification_time, finished_time;

gives me:

   notification_time| finished_time  | actual
++-
 2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 2 days 15:20:00
 2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 1 day 18:50:00


How can write a query to calculate the duration using custom work
hours which is Monday 7am /  Friday 5pm?

The result I'm expecting for the above to be

   notification_time| finished_time  | actual
++-
 2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 00:20:00
 2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00

Thanks.

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


Re: [SQL] work hour calculations

2007-09-04 Thread novice
correction:

> The result I'm expecting for the above to be
>
>notification_time| finished_time  | actual
> ++-
   2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00
>

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

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


Re: [SQL] work hour calculations

2007-09-04 Thread A. Kretschmer
am  Wed, dem 05.09.2007, um 13:45:46 +1000 mailte novice folgendes:
> Hello All,
> 
> SELECT notification_time, finished_time, sum(finished_time -
> notification_time) as actual
> FROM log
> GROUP BY notification_time, finished_time;
> 
> gives me:
> 
>notification_time| finished_time  | actual
> ++-
>  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 2 days 15:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 1 day 18:50:00
> 
> 
> How can write a query to calculate the duration using custom work
> hours which is Monday 7am /  Friday 5pm?
> 
> The result I'm expecting for the above to be
> 
>notification_time| finished_time  | actual
> ++-
>  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 00:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00

You can write a function. Calculate for every day between
notification_time and finished_time this timestamps for every day. I
mean, for instance your first row:


2007-07-06 15:50:00+10   2007-07-07 00:00:00+10
2007-07-07 00:00:00+10   2007-07-08 00:00:00+10
2007-07-08 00:00:00+10   2007-07-09 00:00:00+10
2007-07-09 00:00:00+10   2007-07-09 07:20:00+10

Now check, if the first timestamp are a working day (select
extract('dow' from '2007-07-06 15:50:00+10'::timestamptz)). If so, than
calculate the working-time and adds all.

A little function for you:

<--- cut
create or replace function intersect_time (IN start timestamptz, IN stop 
timestamptz, IN w_start timestamptz, IN w_end timestamptz, OUT duration 
interval) as $$
declare
_s1 alias for $1;
_e1 alias for $2;
_s2 alias for $3;
_e2 alias for $4;
_start  timestamptz;
_endtimestamptz;

begin

if _s1 < _s2 then
_start := _s2;
else
_start := _s1;
end if;

if _e1 < _e2 then
_end := _e1;
else
_end := _e2;
end if;

if _start < _end then
duration := _end - _start;
else
duration := '0'::interval;
end if;

return;

end;
$$language plpgsql;

--- cut

A simple test:

Only the first and the last are working days, so we call the function
for this rows:


test=*# select intersect_time('2007-07-06 15:50:00+10'::timestamptz,'2007-07-07 
00:00:00+10'::timestamptz, '2007-07-06 07:00:00+10'::timestamptz, '2007-07-06 
17:00:00+10'::timestamptz);
 intersect_time

 01:10:00
(1 row)

test=*# select intersect_time('2007-07-09 00:00:00+10'::timestamptz,'2007-07-09 
07:10:00+10'::timestamptz, '2007-07-09 07:00:00+10'::timestamptz, '2007-07-09 
17:00:00+10'::timestamptz);
 intersect_time

 00:10:00
(1 row)


test=*# select '01:10:00'::interval + '00:10:00'::interval;
 ?column?
--
 01:20:00
(1 row)



Hope that helps, Andreas
-- 
Andreas Kretschmer
Kontakt:  Heynitz: 035242/47150,   D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID:   0x3FFF606C, privat 0x7F4584DA   http://wwwkeys.de.pgp.net

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