[GENERAL] Negating the list of selected rows of a join

1999-03-14 Thread Manuel Lemos

Hello,

I want to list the rows of a table with a text field whose values do not
exist in a similar field of another table.  Basically what I want to get
is negated results of a join.

Lets say the tables table_a and table_b have the field name.

table_a table_b
name  age   name   
- ---   -
Peter 27Paul
Paul  42
Mary  20

If I asked for a join like this:

SELECT table_a.name,table_a.age FROM table_a,table_b WHERE table_a.name=table_b.name

I would get:

name  age
- ---
Paul  42

But I want the opposite. I tried a non-equi join like this:

SELECT table_a.name,table_a.age FROM table_a,table_b WHERE table_a.nametable_b.name

and I got:

name  age
- ---
Peter 27 
Mary  20

It worked except for the case when table_b is empty.  In this case the
nothing was returned.  Is this the expected behaviour or is it a bug in
PostgreSQL?

How can I make a query that works the way I want all the time, even for the
case when table_b is empty?


Regards,
Manuel Lemos

E-mail: [EMAIL PROTECTED]
URL: http://www.e-na.net/the_author.html
PGP key: finger:[EMAIL PROTECTED]
--




Re: [GENERAL] PostgreSQL EndTransactionBlock and not inprogress/abort state

1999-03-14 Thread Clark Evans

Manuel Lemos wrote:
 
 Hello,
 
 I am trying to use transactions with PostgreSQL with the normal sequence
 
 BEGIN
 one or more SELECT/INSERT/UPDATE/DELETE queries
 COMMIT
 END
 
 But I am getting the following message just like if I haven't started a
 transaction when I commit.
 
 EndTransactionBlock and not inprogress/abort state
 

I could be wrong, but the END isn't necessary.

BEGIN
 
COMMIT;

  or

BEGIN
  
ROLLBACK;



Hope this helps,

Clark



Re: [GENERAL] PostgreSQL EndTransactionBlock and not inprogress/abort state

1999-03-14 Thread Clark Evans

Clark Evans wrote:
 
 Manuel Lemos wrote:
 
  Hello,
 
  I am trying to use transactions with PostgreSQL with the normal sequence
 
  BEGIN
  one or more SELECT/INSERT/UPDATE/DELETE queries
  COMMIT
  END
 
  But I am getting the following message just like if I haven't started a
  transaction when I commit.
 
  EndTransactionBlock and not inprogress/abort state
 

Oops! forgot the semicolon.  *whap*

 
  BEGIN;
  
 COMMIT;
 
   or
 
  BEGIN;
   
 ROLLBACK;
 

BTW, are you putting on the "END" beacuse you are in a 
PL/pgsql block?  If so, I'm not sure if transactions
can work inside this language.  Hmm.

Clark



Re: [GENERAL] Negating the list of selected rows of a join

1999-03-14 Thread Ulf Mehlig

Manuel Lemos [EMAIL PROTECTED] wrote:

  I want to list the rows of a table with a text field whose values do not
  exist in a similar field of another table.  Basically what I want to get
  is negated results of a join. [...]
  It worked except for the case when table_b is empty.  In this case the
  nothing was returned.  Is this the expected behaviour or is it a bug in
  PostgreSQL?

If you list two (or more) tables in the 'from' clause of a select
(that is, if you do a 'join'), a result table is built, in which each
row of the first table is combined with each row from (all) the other
table(s). To clarify, do simply

   SELECT table_a.name,table_b.name FROM table_a,table_b;
  
on your table. When one of the tables has no rows, all the rows from
the other(s) are combined with *nothing*; this gives nothing!
('combined' may be the wrong word; it's like a multiplication, and
people speak of a 'Cartesian product' of the tables)

The 'where' clause can restrict the rows of the result table to
something useful, e.g., you can restrict to 'table_a.name =
table_b.name'. A feature that probably will help you is the
construction of a so-called 'sub-select' in the where clause:

   SELECT name FROM table_a 
   WHERE name NOT IN (SELECT name FROM table_b);

Hope it helps!
Ulf

-- 
==
Ulf Mehlig[EMAIL PROTECTED]
  Center for Tropical Marine Ecology/ZMT, Bremen, Germany
--



Re: [GENERAL] Negating the list of selected rows of a join

1999-03-14 Thread Ulf Mehlig

Clark Evans [EMAIL PROTECTED]:

  Manuel Lemos wrote:
   How can I make a query that works the way I want all the time, even for the
   case when table_b is empty?
  
  SELECT table_a.name, table_a.age 
FROM table_a
   WHERE NOT EXISTS ( 
SELECT 'x' 
  FROM table_b
 WHERE table_b.name = table_a.name 
 );
  
  Hope this will do the trick.

Maybe not -- doesn't that mean, that the query won't return a single
row in case there is *any* pair of equal names in both tables?!

Have a nice (sun)day,
Ulf

-- 
==
Ulf Mehlig[EMAIL PROTECTED]
  Center for Tropical Marine Ecology/ZMT, Bremen, Germany
--



Re: [GENERAL] Negating the list of selected rows of a join

1999-03-14 Thread Clark Evans

Manuel Lemos wrote:
 
 I want to list the rows of a table with a text field whose values do not
 exist in a similar field of another table.  Basically what I want to get
 is negated results of a join.


Ulf Mehlig wrote:
SELECT name FROM table_a
WHERE name NOT IN (SELECT name FROM table_b);


Clark Evans wrote:
 SELECT table_a.name, table_a.age
   FROM table_a
  WHERE NOT EXISTS (
   SELECT 'x'
 FROM table_b
WHERE table_b.name = table_a.name
);


I'm not sure about how well PostgreSQL handles 
these two.  I'd try them both with your data set.
If table_b is small (less than a few thousand rows)
then Ulf's approach would work best.  However, 
if table_b is large (more than a thousand)
then I think the other approach may work better
if table_b.name is indexed.

Clark



Re: [GENERAL] Negating the list of selected rows of a join

1999-03-14 Thread Ulf Mehlig

Clark Evans [EMAIL PROTECTED]/Ulf Mehlig
[EMAIL PROTECTED] wrote:

 Hope this will do the trick.
   
   Maybe not -- doesn't that mean, that the query won't return a
   single row in case there is *any* pair of equal names in both
   tables?!
 
  No.  It's a correlated sub-query.  It's actually much more efficient
  with large tables than the other approach (which has to put
  the entire result set of table_b on the heap before it can
  process table_a).  Your approach is, however, much better (by a 
  large factor) if table_a is very large and table_b is very small,
  since you don't have to hit the index for table_b on every 
  row of table_a...

Yes, it *will* do the trick!! Sorry, Clark, I misinterpreted your
sub-query ... have to read more carefully ...

Thanks for your correction!
Ulf

-- 
==
Ulf Mehlig[EMAIL PROTECTED]
  Center for Tropical Marine Ecology/ZMT, Bremen, Germany
--



[GENERAL] Error building pg 6.4 on RH Linux

1999-03-14 Thread Henk Jan Barendregt

LS,

When I try to build PG 6.4 on Red Hat Linux 5.2 gmake cant't
find the file y.tab.h in the backand/bootstrap directory.
I seems that this file should be created during the build
process.

What can i do to get this file.

Henk Jan



Re: [GENERAL] daily check for expired data ?

1999-03-14 Thread Herouth Maoz

At 22:48 +0200 on 11/3/99, Ralf Weidemann wrote:



 how could I do an automatic daily check
 to delete some expired data ? I mean
 can I have a cron functionality in post-
 gresql ?

You don't need to have cron functionality in postgresql when you have cron
functionality in cron. :)

What you have to do is make a simple script, more or less like this:

#!/usr/bin/sh
PGHOST=...
PGPORT=...
PGUSER=...
psql my_database END_SQL
DELETE FROM table_in_question
WHERE datetime_field  ( 'now'::datetime - '1 day'::timespan );
END_SQL

And then run it with cron...

Herouth

--
Herouth Maoz, Internet developer.
Open University of Israel - Telem project
http://telem.openu.ac.il/~herutma





Re: [GENERAL] Foreign Keys: check_primary_function

1999-03-14 Thread Bruce Momjian

Applied.


 Hi All,
 I've changed the check_primary_key() function code to allow for either
 the "automatic insert key rule" or "dependent insert key rule".
 Previously it restricted the addtion of a child entry if the
 corresponding parent entry was not there. Now if the option is
 "automatic" it will add an entry in the parent too ( it will be
 successful if there are no no-null fields in the parent apart from the
 primary key).
 The way to use it now is:
 /*
  * check_primary_key () -- check that key in tuple being
 inserted/updated
  *   references existing tuple in "primary" table.
  * Though it's called without args You have to specify referenced
  * table/keys while creating trigger:  key field names in triggered
 table,
  * referenced table name, referenced key field names,type of action
 [automatic|dependent]:
  * EXECUTE PROCEDURE
  * check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2',
 '[automatic|dependent]').
  */
 I am attaching the new ../contrib/spi/refint.c file which will do this.
 I will be glad to help in case of any problems.
 
 - Anand.
 
 

 /*
  * refint.c --set of functions to define referential integrity
  *constraints using general triggers.
  */
 
 #include "executor/spi.h" /* this is what you need to work with SPI */
 #include "commands/trigger.h" /* -"- and triggers */
 #include ctype.h/* tolower () */
 
 HeapTuple check_primary_key(void);
 HeapTuple check_foreign_key(void);
 
 
 typedef struct
 {
   char   *ident;
   int nplans;
   void  **splan;
 } EPlan;
 
 static EPlan *FPlans = NULL;
 static intnFPlans = 0;
 static EPlan *PPlans = NULL;
 static intnPPlans = 0;
 
 static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
 
 /*
  * check_primary_key () -- check that key in tuple being inserted/updated
  * references existing tuple in "primary" table.
  * Though it's called without args You have to specify referenced
  * table/keys while creating trigger:  key field names in triggered table,
  * referenced table name, referenced key field names,type of action 
[automatic|dependent]:
  * EXECUTE PROCEDURE
  * check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 
'Pkey2','[automatic|dependent]').
  */
 
 HeapTuple /* have to return HeapTuple to 
Executor */
 check_primary_key()
 {
   Trigger*trigger;/* to get trigger name */
   int nargs;  /* # of args specified in 
CREATE TRIGGER */
   char  **args;   /* arguments: column names and table 
name */
   int nkeys;  /* # of key columns (= 
(nargs-1) / 2) */
   Datum  *kvals;  /* key values */
   char   *relname;/* referenced relation name */
   char   *action; /* action on insert or update*/
   Relationrel;/* triggered relation */
   HeapTuple   tuple = NULL;   /* tuple to return */
   TupleDesc   tupdesc;/* tuple description */
   EPlan  *plan;   /* prepared plan */
   Oid*argtypes = NULL;/* key types to prepare execution plan */
   boolisnull; /* to know is some column NULL or not 
*/
   charident[2 * NAMEDATALEN]; /* to identify myself */
   int ret;
   int i;
 
   /*
* Some checks first...
*/
 
   /* Called by trigger manager ? */
   if (!CurrentTriggerData)
   elog(ERROR, "check_primary_key: triggers are not initialized");
 
   /* Should be called for ROW trigger */
   if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData-tg_event))
   elog(ERROR, "check_primary_key: can't process STATEMENT events");
 
   /* If INSERTion then must check Tuple to being inserted */
   if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData-tg_event))
 
   tuple = CurrentTriggerData-tg_trigtuple;
 
   /* Not should be called for DELETE */
   else if (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData-tg_event))
 
   elog(ERROR, "check_primary_key: can't process DELETE events");
 
   /* If UPDATion the must check new Tuple, not old one */
   else
   tuple = CurrentTriggerData-tg_newtuple;
 
   trigger = CurrentTriggerData-tg_trigger;
   nargs = trigger-tgnargs;
   args = trigger-tgargs;
 
   if ((nargs-1) % 2 != 1) /* odd number of arguments! */
   elog(ERROR, "check_primary_key: even number of arguments should be 
specified");
 
   nkeys = (nargs-1) / 2;
   action=args[nargs -1];
   if (strcmp(action,"automatic")  strcmp(action,"dependent"))
 

[GENERAL] The value returned by autoinc ?

1999-03-14 Thread Silvio Emanuel Barbosa de Macedo


Hi! 
When I insert data into a table with a sequence associated to a column
(and the required trigger), how can I know the value the sequence has
just generated ? (think in parallel accesses)

Would this approach be the answer ?
begin work
insert...
select max...
commit 


,
`
Silvio Emanuel Nunes Barbosa de Macedo
mailto:[EMAIL PROTECTED]

INESC - Porto - Grupo CAV
Pc da Republica, 93 R/C   Tel:351 2 209 42 21
4000 PORTO  PORTUGAL  Fax:351 2 208 41 72