[SQL] Extracting user db tabel info from system tables???

2001-01-05 Thread Marc Cromme

QUESTIONS ON USEFULL JOINS ON SYSTEM TABLES FOR USE WITH PHP-WEBINTERFACE

I have some problems on making the right joins on system tables to extract
the 
structure of some user defined tables/databases. I use PostgreSQL 7.0.2 on
an 
RedHat 7.0 box.

PROBLEM 1: I tried to make a Foreign key constraint from the primary key of 
table 'pred' to the table 'prey'. The PRIMARY KEY ("yeartime", "pred",
"pred_age") 
of ' pred' should be a Foreign key in 'prey'. Hovever, when I make a dump I
get this: 


CREATE TABLE "pred" (
"yeartime" float8 NOT NULL,
"pred" character varying(10) NOT NULL,
"pred_age" int8 NOT NULL,
"stomachn" float8,
"totcon" float8,
"consum" float8,
PRIMARY KEY ("yeartime", "pred", "pred_age")
);
REVOKE ALL on "pred" from PUBLIC;
GRANT SELECT on "pred" to PUBLIC;
GRANT UPDATE,DELETE,SELECT on "pred" to "mac";


CREATE TABLE "prey" (
"yeartime" float8 NOT NULL,
"pred" character varying(10) NOT NULL,
"pred_age" int8 NOT NULL,
"prey" character varying(10) NOT NULL,
"prey_age" int8 NOT NULL,
"wstom" float8,
"stomcon" float8,
PRIMARY KEY ("yeartime", "pred", "pred_age", "prey", "prey_age")
);
REVOKE ALL on "prey" from PUBLIC;
GRANT SELECT on "prey" to PUBLIC;
GRANT UPDATE,DELETE,SELECT on "prey" to "mac";

QUESTION 1): How to define Foreign keys properly



PROBLEM 2:
I try to make some queries on POSTGRES system tables to determine the table
definitions 
dynamically in a PHP script- the idea is that I do not want to toutch the
PHP code in case 
that the database table structure changes. I can retrieve the structure of
the 'prey' table
primary keys by the following SQL query:  

baltic=> SELECT a.attname, ic.relname, i.indisunique, i.indisprimary 
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a 
WHERE bc.oid = i.indrelid and ic.oid = i.indexrelid and a.attrelid = bc.oid 
and bc.relname = 'prey' and (i.indkey[0] = a.attnum or i.indkey[1] =
a.attnum 
or i.indkey[2] = a.attnum or i.indkey[3] = a.attnum or i.indkey[4] =
a.attnum 
or i.indkey[5] = a.attnum or i.indkey[6] = a.attnum or i.indkey[7] =
a.attnum) 
ORDER BY ic.relname, a.attname;

 attname  |  relname  | indisunique | indisprimary 
--+---+-+--
 pred | prey_pkey | t   | t
 pred_age | prey_pkey | t   | t
 prey | prey_pkey | t   | t
 prey_age | prey_pkey | t   | t
 yeartime | prey_pkey | t   | t
(5 rows)

Question 2: How can I avoid the sequences of OR statements, which are
errorprone (and unelegant) 
in case that there are more than 7 fields in the primary key?



PROBLEM 3:
I can get a nice description of all the 'prey' table fields by issuing the
following SQL query:

baltic=> SELECT c.relname,  u.usename, c.relacl, a.attname, t.typname,
a.attlen, a.attnotnull 
FROM pg_class c, pg_attribute a, pg_type t , pg_user u 
WHERE u.usesysid = c.relowner AND c.relname = 'prey' AND a.attnum > 0 AND
a.attrelid = c.oid 
AND a.atttypid = t.oid 
ORDER BY a.attnum;

 relname | usename | relacl  | attname  | typname | attlen |
attnotnull  
-+-+-+--+-++
 
 prey| mac | {"=r","mac=rw"} | yeartime | float8  |  8 | t
 prey| mac | {"=r","mac=rw"} | pred | varchar | -1 | t
 prey| mac | {"=r","mac=rw"} | pred_age | int8|  8 | t
 prey| mac | {"=r","mac=rw"} | prey | varchar | -1 | t
 prey| mac | {"=r","mac=rw"} | prey_age | int8|  8 | t
 prey| mac | {"=r","mac=rw"} | wstom| float8  |  8 | f
 prey| mac | {"=r","mac=rw"} | stomcon  | float8  |  8 | f
(7 rows)


QUESTION 3: How do I merge the two above queries to get a table like this
(Outer Join  Union???
I know how to emulate outer joints by an Union and Where ... Not In
(select..), but I can't find out
how to join two queries, and not two tables..)

 relname | usename | relacl  | attname  | typname | attlen |
attnotnull |  relname  | indisunique | indisprimary
-+-+-+--+-++
+---+-+-- 
 prey| mac | {"=r","mac=rw"} | yeartime | float8  |  8 | t
| prey_pkey | t   | t
 prey| mac | {"=r","mac=rw"} | pred | varchar | -1 | t
| prey_pkey | t   | t
 prey| mac | {"=r","mac=rw"} | pred_age | int8|  8 | t
| prey_pkey | t   | t
 prey| mac | {"=r","mac=rw"} | prey | varchar | -1 | t
| prey_pkey | t   | t
 prey| mac | {"=r","mac=rw"} | prey_age | int8|  8 | t
| prey_pkey | t   | t
 prey| mac | {"=r","mac=rw"} | wstom| float8  |  8 | f
| NULL` | NULL| NULL  
 prey| mac | {"=r","mac=rw"} | stomcon  | float8  |  8 | f
| NULL` | NULL| NULL  
(7 rows)



[SQL] Non-procedural field merging?

2001-01-05 Thread Richard Huxton

I have two tables, foo and foo2:

richardh=> select * from foo;
 a |  b
---+-
 1 | xxx
 1 | yyy

richardh=> select * from foo2;
 c | d
---+---
 1 |

And I would like to set d to 'xxxyyy' (i.e. merge entries from b). Of course
the following doesn't work because the 'd' seen is the one from before the
query starts.

richardh=> update foo2 set d = d || foo.b from foo where foo.a=foo2.c;
UPDATE 1
richardh=> select * from foo2;
 c |  d
---+-
 1 | yyy

Now - I can always solve the problem procedurally, merging the values in my
application but I was wondering if any of the smarter people on the list
have an SQL way of doing it (something with sub-queries?)

PS - I realise I might get 'xxxyyy' or 'yyyxxx' without forcing an order but
I don't actually care in this case.

TIA

- Richard Huxton




Re: [SQL] Non-procedural field merging?

2001-01-05 Thread Tom Lane

"Richard Huxton" <[EMAIL PROTECTED]> writes:
> I have two tables, foo and foo2:
> richardh=> select * from foo;
>  a |  b
> ---+-
>  1 | xxx
>  1 | yyy

> richardh=> select * from foo2;
>  c | d
> ---+---
>  1 |

> And I would like to set d to 'xxxyyy' (i.e. merge entries from b).

You could do it with a user-defined aggregate function (initial
value '' and transition function ||).  I am not sure that aggregates
work in an intelligent way in UPDATE --- ie, I am not sure it would
work to do

update foo2 set d = catenate(foo.b) from foo where foo.a=foo2.c;

I seem to recall some discussion concluding that that didn't have
very well-defined semantics.  But you could do

SELECT a, catenate(b) INTO TEMP TABLE t1 FROM foo GROUP BY a;

and then update into foo2 from the temp table.

> PS - I realise I might get 'xxxyyy' or 'yyyxxx' without forcing an order but
> I don't actually care in this case.

Check.  You don't have any control over the order in which input rows
will be presented to an aggregate function.

regards, tom lane



Re: [SQL] Extracting user db tabel info from system tables???

2001-01-05 Thread Stephan Szabo


On Fri, 5 Jan 2001, Marc Cromme wrote:

> I have some problems on making the right joins on system tables to extract
> the 
> structure of some user defined tables/databases. I use PostgreSQL 7.0.2 on
> an 
> RedHat 7.0 box.
> 
> PROBLEM 1: I tried to make a Foreign key constraint from the primary key of 
> table 'pred' to the table 'prey'. The PRIMARY KEY ("yeartime", "pred",
> "pred_age") 
> of ' pred' should be a Foreign key in 'prey'. Hovever, when I make a dump I
> get this: 

Later on in the dump, there should be a line of the form:
CREATE CONSTRANT TRIGGER ... 
referencing the tables in question.  It'll probably be near the end.  We 
currently dump the fk constraints as their internal representation
(constraint triggers) rather than as the original constraints.

> PROBLEM 2:
> I try to make some queries on POSTGRES system tables to determine the table
> definitions 
> dynamically in a PHP script- the idea is that I do not want to toutch the
> PHP code in case 
> that the database table structure changes. I can retrieve the structure of
> the 'prey' table
> primary keys by the following SQL query:  
> 
> baltic=> SELECT a.attname, ic.relname, i.indisunique, i.indisprimary 
> FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a 
> WHERE bc.oid = i.indrelid and ic.oid = i.indexrelid and a.attrelid = bc.oid 
> and bc.relname = 'prey' and (i.indkey[0] = a.attnum or i.indkey[1] =
> a.attnum 
> or i.indkey[2] = a.attnum or i.indkey[3] = a.attnum or i.indkey[4] =
> a.attnum 
> or i.indkey[5] = a.attnum or i.indkey[6] = a.attnum or i.indkey[7] =
> a.attnum) 
> ORDER BY ic.relname, a.attname;
> 
>  attname  |  relname  | indisunique | indisprimary 
> --+---+-+--
>  pred | prey_pkey | t   | t
>  pred_age | prey_pkey | t   | t
>  prey | prey_pkey | t   | t
>  prey_age | prey_pkey | t   | t
>  yeartime | prey_pkey | t   | t
> (5 rows)
> 
> Question 2: How can I avoid the sequences of OR statements, which are
> errorprone (and unelegant) 
> in case that there are more than 7 fields in the primary key?

You could probably look at the array stuff in contrib for the 
element in array functions/operators and use that.

> PROBLEM 3:
> I can get a nice description of all the 'prey' table fields by issuing the
> following SQL query:
> 
> baltic=> SELECT c.relname,  u.usename, c.relacl, a.attname, t.typname,
> a.attlen, a.attnotnull 
> FROM pg_class c, pg_attribute a, pg_type t , pg_user u 
> WHERE u.usesysid = c.relowner AND c.relname = 'prey' AND a.attnum > 0 AND
> a.attrelid = c.oid 
> AND a.atttypid = t.oid 
> ORDER BY a.attnum;
> 
>  relname | usename | relacl  | attname  | typname | attlen |
> attnotnull  
> -+-+-+--+-++
>  
>  prey| mac | {"=r","mac=rw"} | yeartime | float8  |  8 | t
>  prey| mac | {"=r","mac=rw"} | pred | varchar | -1 | t
>  prey| mac | {"=r","mac=rw"} | pred_age | int8|  8 | t
>  prey| mac | {"=r","mac=rw"} | prey | varchar | -1 | t
>  prey| mac | {"=r","mac=rw"} | prey_age | int8|  8 | t
>  prey| mac | {"=r","mac=rw"} | wstom| float8  |  8 | f
>  prey| mac | {"=r","mac=rw"} | stomcon  | float8  |  8 | f
> (7 rows)
> 
> 
> QUESTION 3: How do I merge the two above queries to get a table like this
> (Outer Join  Union???
> I know how to emulate outer joints by an Union and Where ... Not In
> (select..), but I can't find out
> how to join two queries, and not two tables..)

Your best bet is probably to make views for the two queries and then do
the outer join using those in which case they effectively look like 
tables.  You could do it without the views, but that'll be kind of 
long and hard to read.

> QUESTION 4: How do I extract also information on foreign keys from the
> system tables, 
> and add two columns to the above table like the following?
> 
> fkey   | ftable
> ---+-
> pred_pkey  | pred
> pred_pkey  | pred
> pred_pkey  | pred
> NULL   | NULL
> NULL   | NULL
> NULL   | NULL
> NULL   | NULL

The foreign key constraint information is stored in pg_trigger.  The
problem is that there's no good way to get the column information from
within sql right now (they're stored as arguments in tgargs).




[SQL] pqReadData()

2001-01-05 Thread Najm Hashmi

Hi all,
 I was trying to simply update single field in one of my tables as given
below:
fliprdb=#  update artist set extrinfo='independent' where artist_id=6;
pqReadData() -- backend closed the channel unexpectedly.
This probably means the backend terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

Anyone have idea where the problem is and how it can be fixed?
Thank you all in advance.
Regards.
 Najm




Re: [SQL] Casting

2001-01-05 Thread Peter Eisentraut

Thomas SMETS writes:

> I'm removing charaters from a String which should be numbers.
> I then want to make calculations on these numbers (calculate the ISBN
> number).

(You might want to look into contrib/isbn_issn for an isbn type.)

> Do I have to cast the char into int's before I can do the calulations.

Depends on the calculation.  I'd just try to see if it works.  When in
doubt add casts.

> Also I looked in the User manual but could not find the modulo function
> where is it ?

5 % 4
mod(5, 4)

-- 
Peter Eisentraut  [EMAIL PROTECTED]   http://yi.org/peter-e/




Re: [SQL] Non-procedural field merging?

2001-01-05 Thread Richard Huxton

From: "Tom Lane" <[EMAIL PROTECTED]>

[snipped my Q about merging text fields from one table into another]

> You could do it with a user-defined aggregate function (initial
> value '' and transition function ||).  I am not sure that aggregates
> work in an intelligent way in UPDATE --- ie, I am not sure it would
> work to do
>
> update foo2 set d = catenate(foo.b) from foo where foo.a=foo2.c;

Actually, (to my surprise) it did work. I used:

richardh=> create aggregate catenate(sfunc1=textcat, basetype=text,
stype1=text, initcond1='');
CREATE
richardh=> select a,catenate(b) from foo group by a;
 a | catenate
---+--
 1 | xxxyyy
(1 row)

Then tried the update - worked with no problem, noting that:

richardh=> update foo2 set d = catenate(foo.b) from foo where foo.a=foo2.c;
UPDATE 1
richardh=> select * from foo2;
 c |   d
---+
 1 | yyyxxx
(1 row)

The order is reversed between the select and the update! Important lesson in
the relationship between SQL and set theory noted (my college lecturers
would be proud of me ;-)

> I seem to recall some discussion concluding that that didn't have
> very well-defined semantics.

I can see how you'd have problems if you were expecting the aggregate to
return the same value on each run (a vacuum presumably could reorder the
values). In my case, this isn't important.

I must admit it didn't occur to me you could create your own aggregates
without resorting to C. Shame it's not a standard SQL feature.

Thanks Tom - don't know how you find the time to give so much help in the
lists.

- Richard Huxton




Re: [SQL] pqReadData()

2001-01-05 Thread Tom Lane

Najm Hashmi <[EMAIL PROTECTED]> writes:
> fliprdb=#  update artist set extrinfo='independent' where artist_id=6;
> pqReadData() -- backend closed the channel unexpectedly.

Hmm.  Looks like you hit a backend crash :-(.  Hard to say more with
only this amount of info.  What PG version are you using?  What is
the table's declaration?  There should be a core file from the backend
crash, in $PGDATA/base/fliprdb/core --- can you get a backtrace from
it with gdb?

regards, tom lane



[SQL] Postgresql database access

2001-01-05 Thread Marcos Aurélio S. da Silva

Dear Pg experts,

I have two databases and i want to refer to one table in a database "X"
when
i'm using database "Y". Something like this:

select * from X.table

This causes a parse error.  What's the correct sintax?

Best regards,

Marcos Aurelio
Brazil



Re: [SQL] Postgresql database access

2001-01-05 Thread Oliver Elphick

"Marcos =?iso-8859-1?Q?Aur=E9lio?= S. da Silva" wrote:
  >Dear Pg experts,
  >
  >I have two databases and i want to refer to one table in a database "X"
  >when
  >i'm using database "Y". Something like this:
  >
  >select * from X.table
  >
  >This causes a parse error.  What's the correct sintax?

It isn't possible to do this; you can only look at one database at a
time.

-- 
Oliver Elphick[EMAIL PROTECTED]
Isle of Wight  http://www.lfix.co.uk/oliver
PGP: 1024R/32B8FAA1: 97 EA 1D 47 72 3F 28 47  6B 7E 39 CC 56 E4 C1 47
GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839  932A 614D 4C34 3E1D 0C1C
 
 "And thou shalt love the LORD thy God with all thine 
  heart, and with all thy soul, and with all thy might."
 Deuteronomy 6:5