[SQL] Set binary column dependent on cumulative value of integer column

2006-12-01 Thread Markus Juenemann

Hi

I've got a bit of a tricky (or me!) problem. The example below is
completely ficticious but
describes my real problem in a way which might be easier to understand.

Imagine your table contains

CREATE TABLE passenger_queue (
id serial NOT NULL,
   name character varying(40) NOT NULL,

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


[SQL] Setting boolean column based on cumulative integer value

2006-12-01 Thread Markus Juenemann

Hi (again!)

[stupid email program sent my message before I finished it!!!]

I've got a bit of a tricky (for me!) problem. The example below is
completely ficticious but
describes my real problem in a way which might be easier to understand.

Imagine the table contains a list of passenger wanting to get on a
small(!) plane.
The plane can carry at most 200kg of passengers and will be filled
strictly on a first-come
first-serve basis - well, check-in staff is a bit stupid ;-). So what
needs to be done is to set the 'gets_seat' column to true until the
weight limit is reached.

CREATE TABLE passenger_queue (
id serial NOT NULL,
name character varying(40) NOT NULL,
weight integer NOT NULL,
gets_seat boolean default false
)

insert into passenger_queue values (1,Peter,75,false)
insert into passenger_queue values (2,Mary,50,false)
insert into passenger_queue values (3,John,70,false)
insert into passenger_queue values (4,Steve,80,false)

According to the specifications given above Peter, Mary and John would
have 'gets_seat'
set to true because their cumulative weight is 195kg while Steve misses out.

The big question is: How can I do this in a nice SQL query???

Thanks

Markus

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

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


Re: [SQL] Grants

2006-12-01 Thread Ezequias Rodrigues da Rocha

Schema grants

CREATE SCHEMA base
 AUTHORIZATION root;
GRANT ALL ON SCHEMA base TO root;
GRANT USAGE ON SCHEMA base TO administrators;

Table grants
GRANT ALL ON TABLE base.local TO root;
GRANT SELECT, UPDATE, INSERT ON TABLE base.local TO administrators;

Still the same problem. :(

2006/11/30, imad [EMAIL PROTECTED]:

You did not grant access privileges to schema.
Also GRANT administrators on the base schema as you did for the table.

--Imad
www.EnterpriseDB.com


On 12/1/06, Ezequias Rodrigues da Rocha [EMAIL PROTECTED] wrote:
 Hi list,

 I am having problem with grants and users on PostgreSQL.

 I am using pgAdmin to connect like other user to test my permissions.

 As the owner of the database I have criated two roles:

 administrators (cannot connect)
 ezequias (can connect)

 I give permissions to a table I have:
 GRANT SELECT, UPDATE, INSERT ON TABLE base.table1 TO administrators;


 My user:
 CREATE ROLE ezequias LOGIN
   NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;
 GRANT administradores TO ezequias;

 My group
 CREATE ROLE administradores
   NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;

 When I try to access the table base.table1 with ezequias login the
 pgAdmin reports:
 (see attached image)

 Could someone tell me what I did wrong ?
 Ezequias



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








--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Atenciosamente (Sincerely)
   Ezequias Rodrigues da Rocha
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
A pior das democracias ainda é melhor do que a melhor das ditaduras
The worst of democracies is still better than the better of dictatorships
http://ezequiasrocha.blogspot.com/

---(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] Setting boolean column based on cumulative integer value

2006-12-01 Thread A. Kretschmer
am  Sat, dem 02.12.2006, um  0:50:37 +1100 mailte Markus Juenemann folgendes:
 I've got a bit of a tricky (for me!) problem. The example below is
 completely ficticious but
 describes my real problem in a way which might be easier to understand.
 
 Imagine the table contains a list of passenger wanting to get on a
 small(!) plane.
 The plane can carry at most 200kg of passengers and will be filled
 strictly on a first-come
 first-serve basis - well, check-in staff is a bit stupid ;-). So what
 needs to be done is to set the 'gets_seat' column to true until the
 weight limit is reached.

With your example, i wrote a little function for this:

---%--
create or replace function check_wight( out id int,
out name text,
out weight int,
out gets_seat boolean ) returns setof 
record as $$
declare rec record;
sum int;
begin
sum = 0;
for rec in select * from passenger_queue order by id LOOP
id = rec.id;
name = rec.name;
weight = rec.weight;
sum = sum + weight;
if sum  200 then
gets_seat='t'::bool;
else
gets_seat='f'::bool;
end if;
return next ;
end loop;
end
$$ language plpgsql;
---%--


test=# select * from passenger_queue;
 id | name  | weight | gets_seat
+---++---
  1 | Peter | 75 | f
  2 | Mary  | 50 | f
  3 | John  | 70 | f
  4 | Steve | 80 | f
(4 rows)

test=# select * from check_wight();
 id | name  | weight | gets_seat
+---++---
  1 | Peter | 75 | t
  2 | Mary  | 50 | t
  3 | John  | 70 | t
  4 | Steve | 80 | f
(4 rows)


HTH, Andreas
-- 
Andreas Kretschmer
Kontakt:  Heynitz: 035242/47215,   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


Re: [SQL] Setting boolean column based on cumulative integer value

2006-12-01 Thread Richard Broersma Jr
 CREATE TABLE passenger_queue (
 id serial NOT NULL,
 name character varying(40) NOT NULL,
 weight integer NOT NULL,
 gets_seat boolean default false
 )
 
 insert into passenger_queue values (1,Peter,75,false)
 insert into passenger_queue values (2,Mary,50,false)
 insert into passenger_queue values (3,John,70,false)
 insert into passenger_queue values (4,Steve,80,false)
 
 According to the specifications given above Peter, Mary and John would
 have 'gets_seat'
 set to true because their cumulative weight is 195kg while Steve misses out.
 
 The big question is: How can I do this in a nice SQL query???

Well there are two ways that I can think of:

The first option is probably the best.  But the second is a good mental 
exercise.

1) a trigger that checks to insure that a new record doesn't exceed your max.
2) instead of inserting passenger weight you could insert begin/end weight 
range for each
passenger. i.e.:

CREATE TABLE passenger_queue (
id serial NOT NULL,
name character varying(40) NOT NULL,
plane_start_weight integer NOT NULL,
plane_end_weight integer not null,

constraint
plane_max_wieght
check( plane_end_weight = 200 ),

constraint
sanity_check
check( plane_end_weight  plane_start_weight)
)

insert into passenger_queue values (1,Peter,
   (select max(end_weight) from 
passenger_queue),
   (select max(end_weight) from 
passenger_queue) + 75);
insert into passenger_queue values (2,Mary,
   (select max(end_weight) from 
passenger_queue),
   (select max(end_weight) from 
passenger_queue) + 50);
insert into passenger_queue values (3,John,
   (select max(end_weight) from 
passenger_queue),
   (select max(end_weight) from 
passenger_queue) + 70);
insert into passenger_queue values (4,Steve,
   (select max(end_weight) from 
passenger_queue),
   (select max(end_weight) from 
passenger_queue) + 80);
once you try to insert a record that exceeds your max weight the insert will 
fail.

ofcourse if you have to delete a passenger record because he/she wishes to get 
off early you will
need to have an additional update statement to shift down higher valued records 
insure that the
range does not have any gaps.

Regards,

Richard Broersma Jr.

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

2006-12-01 Thread Adrian Klaver
On Friday 01 December 2006 06:03 am, Ezequias Rodrigues da Rocha wrote:

 2006/11/30, imad [EMAIL PROTECTED]:
  You did not grant access privileges to schema.
  Also GRANT administrators on the base schema as you did for the table.
 
  --Imad
  www.EnterpriseDB.com
 
  On 12/1/06, Ezequias Rodrigues da Rocha [EMAIL PROTECTED] wrote:
   Hi list,
  
   I am having problem with grants and users on PostgreSQL.
  
   I am using pgAdmin to connect like other user to test my permissions.
  
   As the owner of the database I have criated two roles:
  
   administrators (cannot connect)
   ezequias (can connect)
  
   I give permissions to a table I have:
   GRANT SELECT, UPDATE, INSERT ON TABLE base.table1 TO administrators;
  
  
   My user:
   CREATE ROLE ezequias LOGIN
 NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;
   GRANT administradores TO ezequias;
  
   My group
   CREATE ROLE administradores
 NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;
  
   When I try to access the table base.table1 with ezequias login the
   pgAdmin reports:
   (see attached image)
  
   Could someone tell me what I did wrong ?
   Ezequias
  
  
  
   ---(end of
   broadcast)--- TIP 5: don't forget to increase
   your free space map settings
 Schema grants

 CREATE SCHEMA base
   AUTHORIZATION root;
 GRANT ALL ON SCHEMA base TO root;
 GRANT USAGE ON SCHEMA base TO administrators;

 Table grants
 GRANT ALL ON TABLE base.local TO root;
 GRANT SELECT, UPDATE, INSERT ON TABLE base.local TO administrators;

 Still the same problem. :(

Two things I see. 
The first may only be a translation artifact. You have CREATE ROLE 
administradores and then GRANT to administrators on the table.
Second in the CREATE ROLE  ezequias you have NOINHERIT. This means  ezequias  
does not automatically assume the privileges of the ROLES it belongs to. To 
acquire the privileges you have to do a SET ROLE administrators at the 
connection.
-- 
Adrian Klaver   
[EMAIL PROTECTED]

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

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


[SQL] calling elog possibly causing problem in DirectFunctionCall1

2006-12-01 Thread Rajesh Kumar Mallah

Hi ,
In certain C trigger function following code snippet causes ERROR:
---
elog (NOTICE , before calling DirectFunctionCall1);
 data-time_stamp =
   DirectFunctionCall1(timestamptz_in, CStringGetDatum(now));
elog (NOTICE , after calling DirectFunctionCall1);


begin work;INSERT INTO  audittest.test_table (name,foo) values
('test','test'); rollback;
BEGIN
NOTICE:  before calling DirectFunctionCall1
ERROR:  timestamp(-1073748880) precision must be between 0 and 6
ROLLBACK

If the elog before DirectFunctionCall1 is removed the code works fine.

begin work;INSERT INTO  audittest.test_table (name,foo) values
('test','test'); rollback;
BEGIN
NOTICE:  after calling DirectFunctionCall1
INSERT 0 1
ROLLBACK

Can anyone please explain how removing a elog makes a difference?

Regds
Mallah.


Re: [SQL] Autovaccum

2006-12-01 Thread Shane Ambler

Ezequias Rodrigues da Rocha wrote:

Could you tell me if only this both options are ok (attach) ?

If I don't mark the interval of vacuuns what will be the interval of
each vacuum ?


The default settings may be fine for you, it depends a bit on how many 
insert/updates you get in a given time frame.


http://www.postgresql.org/docs/8.1/interactive/runtime-config-autovacuum.html
will give a definition of each parameter that can be set.

http://www.postgresql.org/docs/8.1/interactive/maintenance.html#AUTOVACUUM
will explain in more detail.

Basically every autovacuum_naptime seconds autovacuum looks at estimates 
of how much the database has changed since the last run. If the amount 
of change is greater than the thresholds determined from the other 
settings then a vacuum/analyze will be done.


If you have 100 records added/updated per day then you may only need it 
to run 1 or 2 times a day using smaller thresholds.


If you are adding 10,000 records an hour then you will want it to run 
more often.




2006/11/30, Shane Ambler [EMAIL PROTECTED]:

Alvaro Herrera wrote:
 Ezequias Rodrigues da Rocha wrote:
 Hi list,

 I would like to know if it is necessary to set my database to
 autovaccum if the intent of my DB Manager is do not make any deletion
 in any time.

 If there is no deletions why autovaccum ok ?
 
 You need to vacuum from time to time anyway, even if you don't delete
 anything.  The easiest way to do it is let autovacuum do it for you.


One thing that vacuum/autovacuum does is mark space used by deleted rows
to be reused. Without deletes this won't be necessary in table data
files. But when you update a record an index may also be updated and
have the same effect within the index storage space.

There are other things that vacuum does to keep your database running
optimally. One is to update planner statistics about how many rows are
in each table which effects the query planning and optimizing.

Without deletes a plain vacuum won't achieve a great deal, but a regular
VACUUM ANALYZE (as done by autovacuum) will make a difference to the
performance of your database.

If no data in your db changes then you won't have to bother vacuuming.

--

Shane Ambler
[EMAIL PROTECTED]

Get Sheeky @ http://Sheeky.Biz







--

Shane Ambler
[EMAIL PROTECTED]

Get Sheeky @ http://Sheeky.Biz

---(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] calling elog possibly causing problem in DirectFunctionCall1

2006-12-01 Thread Tom Lane
Rajesh Kumar Mallah [EMAIL PROTECTED] writes:
   data-time_stamp =
 DirectFunctionCall1(timestamptz_in, CStringGetDatum(now));

This code is incorrect, as timestamptz_in takes three arguments.

regards, tom lane

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

   http://archives.postgresql.org


Re: [SQL] calling elog possibly causing problem in DirectFunctionCall1

2006-12-01 Thread Rajesh Kumar Mallah

On 12/1/06, Tom Lane [EMAIL PROTECTED] wrote:


Rajesh Kumar Mallah [EMAIL PROTECTED] writes:
   data-time_stamp =
 DirectFunctionCall1(timestamptz_in, CStringGetDatum(now));

This code is incorrect, as timestamptz_in takes three arguments.



Dear Sir,

thanks for the kind reply.

field time_stamp of data is declared as:
Datum time_stamp;

it is supposed to be populated with current timestamp , (now())
can you please tell me what should be passed as the third argument?

Regds
Mallah.



   regards, tom lane




Re: [SQL] calling elog possibly causing problem in DirectFunctionCall1

2006-12-01 Thread Rajesh Kumar Mallah

On 12/1/06, Tom Lane [EMAIL PROTECTED] wrote:


Rajesh Kumar Mallah [EMAIL PROTECTED] writes:
   data-time_stamp =
 DirectFunctionCall1(timestamptz_in, CStringGetDatum(now));

This code is incorrect, as timestamptz_in takes three arguments.



replaced it with:

data-time_stamp = DirectFunctionCall3(timestamptz_in,
   CStringGetDatum(now),
   ObjectIdGetDatum(InvalidOid),
   Int32GetDatum(-1))

now it works fine. (code lifted from contrib/spi/moddatetime.c(line 73)
hopefully its correct.

   regards, tom lane




[SQL] Problem inserting composite type values

2006-12-01 Thread Chris Dunworth

Hi all --

(huge apologies if this is a duplicate post -- I sent from an 
unsubscribed email account before...)


I have a problem trying to INSERT INTO a table by selecting from a 
function that returns a composite type. (I'm running version 8.1.4, FYI)


Basically, I have two tables. I want to retrieve rows from one table and 
store them into the other. The schema of the two tables is not the same, 
so I use a conversion function (written in plperl) that takes a row from 
the start table and returns a row from the end table. However, I can't 
get the insert working.


Here's a simplified example of my real system (must have plperl 
installed to try it):


---
-- Read rows from here...
CREATE TABLE startTable ( intVal integer, textVal text );

-- ...and store as rows in here
CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2 integer);

-- Some test data for the startTable
INSERT INTO startTable VALUES ( 1, '10:11');
INSERT INTO startTable VALUES ( 2, '20:25');
INSERT INTO startTable VALUES ( 3, '30:38');

-- Note: Takes composite type as argument, and returns composite type.
-- This just converts a row of startTable into a row of endTable, splitting
-- the colon-delimited integers from textVal into separate integers.
CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS 
endTable AS $$

  my ($startTable) = @_;
  my @newVals = split(/:/, $startTable-{textval});
  my $result = { intval=$startTable-{intval}, 
newval1=@newVals[0], newval2=@newVals[1] };

  return $result;
$$ LANGUAGE plperl;
---

Now, if I run the following SELECT, I get the results below it:

SELECT convertStartToEnd(st.*) FROM startTable st;

convertstarttoend
---
(1,10,11)
(2,20,25)
(3,30,38)
(3 rows)

This seems OK. But when I try to INSERT the results of this select into 
the endTable, I get this error:


INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM startTable st;

ERROR:  column intval is of type integer but expression is of type 
endtable

HINT:  You will need to rewrite or cast the expression

It's taking the entire row coming out of the function (e.g. (3,30,38)) 
and tries to fit it all into just the first column, intVal. I'm 
obviously doing something wrong. Is there some way to format the INSERT 
so that I can get full rows inserted, with the individual columns 
separated out properly (e.g. intVal=3, newVal1=30, newVal2=38)?


I'm still pretty new to all this, so it could be something simple.

Thanks for reading.

Kind Regards,
Chris Dunworth




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


Re: [SQL] Problem inserting composite type values

2006-12-01 Thread Stephan Szabo
On Fri, 1 Dec 2006, Chris Dunworth wrote:

 Hi all --

 (huge apologies if this is a duplicate post -- I sent from an
 unsubscribed email account before...)

 I have a problem trying to INSERT INTO a table by selecting from a
 function that returns a composite type. (I'm running version 8.1.4, FYI)

 Basically, I have two tables. I want to retrieve rows from one table and
 store them into the other. The schema of the two tables is not the same,
 so I use a conversion function (written in plperl) that takes a row from
 the start table and returns a row from the end table. However, I can't
 get the insert working.

 Here's a simplified example of my real system (must have plperl
 installed to try it):

 ---
 -- Read rows from here...
 CREATE TABLE startTable ( intVal integer, textVal text );

 -- ...and store as rows in here
 CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2 integer);

 -- Some test data for the startTable
 INSERT INTO startTable VALUES ( 1, '10:11');
 INSERT INTO startTable VALUES ( 2, '20:25');
 INSERT INTO startTable VALUES ( 3, '30:38');

 -- Note: Takes composite type as argument, and returns composite type.
 -- This just converts a row of startTable into a row of endTable, splitting
 -- the colon-delimited integers from textVal into separate integers.
 CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS
 endTable AS $$
my ($startTable) = @_;
my @newVals = split(/:/, $startTable-{textval});
my $result = { intval=$startTable-{intval},
 newval1=@newVals[0], newval2=@newVals[1] };
return $result;
 $$ LANGUAGE plperl;
 ---

 Now, if I run the following SELECT, I get the results below it:

 SELECT convertStartToEnd(st.*) FROM startTable st;

 convertstarttoend
 ---
 (1,10,11)
 (2,20,25)
 (3,30,38)
 (3 rows)

 This seems OK. But when I try to INSERT the results of this select into
 the endTable, I get this error:

 INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM startTable st;


I think you'd need something like
 INSERT INTO endTable SELECT (convertStartToEnd(st.*)).* FROM startTable
 st;
to make it break up the type into its components.


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


Re: [SQL] Setting boolean column based on cumulative integer value

2006-12-01 Thread Aaron Bono

On 12/1/06, Markus Juenemann [EMAIL PROTECTED] wrote:


Hi (again!)

[stupid email program sent my message before I finished it!!!]

I've got a bit of a tricky (for me!) problem. The example below is
completely ficticious but
describes my real problem in a way which might be easier to understand.

Imagine the table contains a list of passenger wanting to get on a
small(!) plane.
The plane can carry at most 200kg of passengers and will be filled
strictly on a first-come
first-serve basis - well, check-in staff is a bit stupid ;-). So what
needs to be done is to set the 'gets_seat' column to true until the
weight limit is reached.

CREATE TABLE passenger_queue (
id serial NOT NULL,
name character varying(40) NOT NULL,
weight integer NOT NULL,
gets_seat boolean default false
)

insert into passenger_queue values (1,Peter,75,false)
insert into passenger_queue values (2,Mary,50,false)
insert into passenger_queue values (3,John,70,false)
insert into passenger_queue values (4,Steve,80,false)

According to the specifications given above Peter, Mary and John would
have 'gets_seat'
set to true because their cumulative weight is 195kg while Steve misses
out.

The big question is: How can I do this in a nice SQL query???



I would ditch the gets_seat column and instead create a view that calculates
the value when you need it.  This helps eliminate redundant data.

CREATE VIEW passenger_queue_vw (
   id,
   name,
   weight,
   gets_seat
) AS
SELECT
   queue.id,
   queue.name,
   queue.weight,
   CASE sum(others.gets_seat) = 200
FROM passenger_queue queue
INNER JOIN passenger_queue others ON (
   others.id = queue.id
   -- There should really be a create date used here
   -- but for example purposes I assume the id column
   -- is an increasing sequence
)
GROUP BY
   queue.id,
   queue.name,
   queue.weight

If you have performance concerns you can create a materialized view.  Of
course if you don't want the record to even be allowed (cause an error on
insert), you should use a constraint as mentioned in one of the other
responses to your question.

-Aaron

--
==
  Aaron Bono
  Aranya Software Technologies, Inc.
  http://www.aranya.com
  http://codeelixir.com
==


Re: [SQL] Problem inserting composite type values

2006-12-01 Thread Aaron Bono

On 12/1/06, Stephan Szabo [EMAIL PROTECTED] wrote:


On Fri, 1 Dec 2006, Chris Dunworth wrote:

 Hi all --

 (huge apologies if this is a duplicate post -- I sent from an
 unsubscribed email account before...)

 I have a problem trying to INSERT INTO a table by selecting from a
 function that returns a composite type. (I'm running version 8.1.4, FYI)

 Basically, I have two tables. I want to retrieve rows from one table and
 store them into the other. The schema of the two tables is not the same,
 so I use a conversion function (written in plperl) that takes a row from
 the start table and returns a row from the end table. However, I can't
 get the insert working.

 Here's a simplified example of my real system (must have plperl
 installed to try it):

 ---
 -- Read rows from here...
 CREATE TABLE startTable ( intVal integer, textVal text );

 -- ...and store as rows in here
 CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2
integer);

 -- Some test data for the startTable
 INSERT INTO startTable VALUES ( 1, '10:11');
 INSERT INTO startTable VALUES ( 2, '20:25');
 INSERT INTO startTable VALUES ( 3, '30:38');

 -- Note: Takes composite type as argument, and returns composite type.
 -- This just converts a row of startTable into a row of endTable,
splitting
 -- the colon-delimited integers from textVal into separate integers.
 CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS
 endTable AS $$
my ($startTable) = @_;
my @newVals = split(/:/, $startTable-{textval});
my $result = { intval=$startTable-{intval},
 newval1=@newVals[0], newval2=@newVals[1] };
return $result;
 $$ LANGUAGE plperl;
 ---

 Now, if I run the following SELECT, I get the results below it:

 SELECT convertStartToEnd(st.*) FROM startTable st;

 convertstarttoend
 ---
 (1,10,11)
 (2,20,25)
 (3,30,38)
 (3 rows)

 This seems OK. But when I try to INSERT the results of this select into
 the endTable, I get this error:

 INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM startTable st;


I think you'd need something like
INSERT INTO endTable SELECT (convertStartToEnd(st.*)).* FROM startTable
st;
to make it break up the type into its components.



INSERT INTO endTable SELECT * FROM (SELECT convertStartToEnd(st.*) FROM
startTable)

that should work too

--
==
  Aaron Bono
  Aranya Software Technologies, Inc.
  http://www.aranya.com
  http://codeelixir.com
==


Re: [SQL] Problem inserting composite type values

2006-12-01 Thread Chris Dunworth


Stephan Szabo wrote:

On Fri, 1 Dec 2006, Chris Dunworth wrote:

  

Hi all --

(huge apologies if this is a duplicate post -- I sent from an
unsubscribed email account before...)

I have a problem trying to INSERT INTO a table by selecting from a
function that returns a composite type. (I'm running version 8.1.4, FYI)

Basically, I have two tables. I want to retrieve rows from one table and
store them into the other. The schema of the two tables is not the same,
so I use a conversion function (written in plperl) that takes a row from
the start table and returns a row from the end table. However, I can't
get the insert working.

Here's a simplified example of my real system (must have plperl
installed to try it):

---
-- Read rows from here...
CREATE TABLE startTable ( intVal integer, textVal text );

-- ...and store as rows in here
CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2 integer);

-- Some test data for the startTable
INSERT INTO startTable VALUES ( 1, '10:11');
INSERT INTO startTable VALUES ( 2, '20:25');
INSERT INTO startTable VALUES ( 3, '30:38');

-- Note: Takes composite type as argument, and returns composite type.
-- This just converts a row of startTable into a row of endTable, splitting
-- the colon-delimited integers from textVal into separate integers.
CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS
endTable AS $$
   my ($startTable) = @_;
   my @newVals = split(/:/, $startTable-{textval});
   my $result = { intval=$startTable-{intval},
newval1=@newVals[0], newval2=@newVals[1] };
   return $result;
$$ LANGUAGE plperl;
---

Now, if I run the following SELECT, I get the results below it:

SELECT convertStartToEnd(st.*) FROM startTable st;

convertstarttoend
---
(1,10,11)
(2,20,25)
(3,30,38)
(3 rows)

This seems OK. But when I try to INSERT the results of this select into
the endTable, I get this error:

INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM startTable st;




I think you'd need something like
 INSERT INTO endTable SELECT (convertStartToEnd(st.*)).* FROM startTable
 st;
to make it break up the type into its components.

  


Yes! That was exactly it. I thought it might have been something simple.

Thanks, Stephan!

-Chris



Re: [SQL] Problem inserting composite type values

2006-12-01 Thread Chris Dunworth

Aaron Bono wrote:
On 12/1/06, *Stephan Szabo* [EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


On Fri, 1 Dec 2006, Chris Dunworth wrote:

 Hi all --

 (huge apologies if this is a duplicate post -- I sent from an
 unsubscribed email account before...)

 I have a problem trying to INSERT INTO a table by selecting from a
 function that returns a composite type. (I'm running version
8.1.4, FYI)

 Basically, I have two tables. I want to retrieve rows from one
table and
 store them into the other. The schema of the two tables is not
the same,
 so I use a conversion function (written in plperl) that takes a
row from
 the start table and returns a row from the end table. However, I
can't
 get the insert working.

 Here's a simplified example of my real system (must have plperl
 installed to try it):

 ---
 -- Read rows from here...
 CREATE TABLE startTable ( intVal integer, textVal text );

 -- ...and store as rows in here
 CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2
integer);

 -- Some test data for the startTable
 INSERT INTO startTable VALUES ( 1, '10:11');
 INSERT INTO startTable VALUES ( 2, '20:25');
 INSERT INTO startTable VALUES ( 3, '30:38');

 -- Note: Takes composite type as argument, and returns composite
type.
 -- This just converts a row of startTable into a row of
endTable, splitting
 -- the colon-delimited integers from textVal into separate integers.
 CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS
 endTable AS $$
my ($startTable) = @_;
my @newVals = split(/:/, $startTable-{textval});
my $result = { intval=$startTable-{intval},
 newval1=@newVals[0], newval2=@newVals[1] };
return $result;
 $$ LANGUAGE plperl;
 ---

 Now, if I run the following SELECT, I get the results below it:

 SELECT convertStartToEnd(st.*) FROM startTable st;

 convertstarttoend
 ---
 (1,10,11)
 (2,20,25)
 (3,30,38)
 (3 rows)

 This seems OK. But when I try to INSERT the results of this
select into
 the endTable, I get this error:

 INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM
startTable st;


I think you'd need something like
INSERT INTO endTable SELECT (convertStartToEnd(st.*)).* FROM
startTable
st;
to make it break up the type into its components.


INSERT INTO endTable SELECT * FROM (SELECT convertStartToEnd(st.*) 
FROM startTable)


that should work too


Hi Aaron --

I had actually tried your approach earlier, or something very similar:

INSERT INTO endTable SELECT et.* FROM (SELECT convertStartToEnd(st.*) 
FROM startTable st) AS et;


Which is basically the same as you suggest, plus an alias (et) for the 
subquery that postgresql was asking for. But it gave the same type 
mismatch result as I posted about.


Turns out Stephan's suggestion did the trick.

Cheers,
Chris



Re: [SQL] Problem inserting composite type values

2006-12-01 Thread Aaron Bono

On 12/1/06, Chris Dunworth [EMAIL PROTECTED] wrote:


 Aaron Bono wrote:

On 12/1/06, Stephan Szabo [EMAIL PROTECTED] wrote:

 On Fri, 1 Dec 2006, Chris Dunworth wrote:

  Hi all --
 
  (huge apologies if this is a duplicate post -- I sent from an
  unsubscribed email account before...)
 
  I have a problem trying to INSERT INTO a table by selecting from a
  function that returns a composite type. (I'm running version 8.1.4,
 FYI)
 
  Basically, I have two tables. I want to retrieve rows from one table
 and
  store them into the other. The schema of the two tables is not the
 same,
  so I use a conversion function (written in plperl) that takes a row
 from
  the start table and returns a row from the end table. However, I can't
  get the insert working.
 
  Here's a simplified example of my real system (must have plperl
  installed to try it):
 
  ---
  -- Read rows from here...
  CREATE TABLE startTable ( intVal integer, textVal text );
 
  -- ...and store as rows in here
  CREATE TABLE endTable ( intVal integer, newVal1 integer, newVal2
 integer);
 
  -- Some test data for the startTable
  INSERT INTO startTable VALUES ( 1, '10:11');
  INSERT INTO startTable VALUES ( 2, '20:25');
  INSERT INTO startTable VALUES ( 3, '30:38');
 
  -- Note: Takes composite type as argument, and returns composite type.
  -- This just converts a row of startTable into a row of endTable,
 splitting
  -- the colon-delimited integers from textVal into separate integers.
  CREATE OR REPLACE FUNCTION convertStartToEnd(startTable) RETURNS
  endTable AS $$
 my ($startTable) = @_;
 my @newVals = split(/:/, $startTable-{textval});
 my $result = { intval=$startTable-{intval},
  newval1=@newVals[0], newval2=@newVals[1] };
 return $result;
  $$ LANGUAGE plperl;
  ---
 
  Now, if I run the following SELECT, I get the results below it:
 
  SELECT convertStartToEnd(st.*) FROM startTable st;
 
  convertstarttoend
  ---
  (1,10,11)
  (2,20,25)
  (3,30,38)
  (3 rows)
 
  This seems OK. But when I try to INSERT the results of this select
 into
  the endTable, I get this error:
 
  INSERT INTO endTable SELECT convertStartToEnd(st.*) FROM startTable
 st;


 I think you'd need something like
 INSERT INTO endTable SELECT (convertStartToEnd(st.*)).* FROM startTable
 st;
 to make it break up the type into its components.


INSERT INTO endTable SELECT * FROM (SELECT convertStartToEnd(st.*) FROM
startTable)

that should work too

 Hi Aaron --

I had actually tried your approach earlier, or something very similar:

INSERT INTO endTable SELECT et.* FROM (SELECT convertStartToEnd(st.*) FROM
startTable st) AS et;

Which is basically the same as you suggest, plus an alias (et) for the
subquery that postgresql was asking for. But it gave the same type mismatch
result as I posted about.

Turns out Stephan's suggestion did the trick.



Good to know.  I will keep that in mind if I come across that again in the
future.

-Aaron

--
==
  Aaron Bono
  Aranya Software Technologies, Inc.
  http://www.aranya.com
  http://codeelixir.com
==


[SQL] Tracking Down Error in Stored Procedure

2006-12-01 Thread Aaron Bono

I have a nightly batch that runs a stored procedure/function.  This
procedure has a habit of erroring on the first of each month and gives the
following:

ERROR:  cannot EXECUTE a null querystring
CONTEXT:  PL/pgSQL function update_web_site_hits_fn line 200 at execute
statement

My question is this:  What is line 200?  Is it the 200th line after the
CREATE part of the stored procedure?  Or is it the 200th line after the
BEGIN?  Or maybe something else?  I have a possible culprit at both places
and don't know which one is the offender.

Also, if the EXECUTE is over many lines, is line 200 the first line of the
EXECUTE statement or the ending line of the EXECUTE (where the ; is)?

I am using PostgreSQL 8.1.3 on CENTOS Linux.

Thanks,
Aaron

--
==
  Aaron Bono
  Aranya Software Technologies, Inc.
  http://www.aranya.com
  http://codeelixir.com
==


Re: [SQL] Tracking Down Error in Stored Procedure

2006-12-01 Thread Tom Lane
Aaron Bono [EMAIL PROTECTED] writes:
 CONTEXT:  PL/pgSQL function update_web_site_hits_fn line 200 at execute
 statement

 My question is this:  What is line 200?  Is it the 200th line after the
 CREATE part of the stored procedure?  Or is it the 200th line after the
 BEGIN?  Or maybe something else?

It's the 200th line in the function body string.  IIRC there is a
special case to not count a leading newline in the body string,
so that the counting goes like

CREATE FUNCTION foo ...
  RETURNS ...
  AS $$
DECLARE -- this is line 1

or without exploiting the special case

CREATE FUNCTION foo ...
  RETURNS ...
  AS $$DECLARE  -- this is line 1

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


Re: [SQL] Tracking Down Error in Stored Procedure

2006-12-01 Thread Aaron Bono

On 12/2/06, Tom Lane [EMAIL PROTECTED] wrote:


Aaron Bono [EMAIL PROTECTED] writes:
 CONTEXT:  PL/pgSQL function update_web_site_hits_fn line 200 at
execute
 statement

 My question is this:  What is line 200?  Is it the 200th line after the
 CREATE part of the stored procedure?  Or is it the 200th line after the
 BEGIN?  Or maybe something else?

It's the 200th line in the function body string.  IIRC there is a
special case to not count a leading newline in the body string,
so that the counting goes like

CREATE FUNCTION foo ...
  RETURNS ...
  AS $$
DECLARE -- this is line 1

or without exploiting the special case

CREATE FUNCTION foo ...
  RETURNS ...
  AS $$DECLARE  -- this is line 1

regards, tom lane



I got it fixed.  Thanks for the help!

--
==
  Aaron Bono
  Aranya Software Technologies, Inc.
  http://www.aranya.com
  http://codeelixir.com
==


Re: [HACKERS] [SQL] Case Preservation disregarding case

2006-12-01 Thread Ken Johanson

Chuck McDevitt wrote:

At Teradata, we certainly interpreted the spec to allow case-preserving,
but case-insensitive, identifiers.
Users really liked it that way


My 2 thoughts:

1: It seems like this behavior of case sensitive-or-not-identifiers 
could/should be a config option -- either globally for the server, 
database, or at the connection/session level. Other databases *do* 
support this type of granular config of misc SQL behavior -- its 
essential for shared hosting environments. Without it some users just 
*cant* make the switch. Quoting all an app's identifiers -- or renaming 
camel-case to underscored -- show stopper.


2: Even though the spec state different (that identifiers should be 
treated as case sensitive or else folded), precedence seems to have 
changed that:


	a) The databases that enforce this rule are fewer, I believe. IMO SQL 
is now considered even higher than a 4GL language because it use is so 
widespread - laymen need to use it.


	b) the fact that different identifiers of mixed case could even coexist 
in a table-columns or 'AS' or 'JOIN' -- really represents a more of an 
err'd design -- and a case-insen option would detect this (unlike the 
current behavior). It would throw an immediate (fail fast) runtime 
exception. So I think it's *safer*. (If tbl.rowId and tbl.rowid both 
exist in a table or AS identifiers, something bad _will_ happen when 
someone takes over a project)


If there were a new default behavior (or just config option added), my 
vote would, without a doubt, be for case-insens (yet case preserving) 
mode... even when using quoting identifiers. This case sen. behavior 
doesn't seem to offer any advantage/safety.


ken



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