Subject: new type & rule ?!

From: [email-masked] (Eric de Jonge)
Date: Wed, 15 Jun 1994 13:21:14 +0200 (MET DST)

I've defined :
- new data type IMAGEOBJ
- operator '=' to test if IMAGEOBJ = text

Example:

create imclass(field=IMAGEOBJ)
create teclass(field=text)

contents:

IMCLASS:
---------------
| field       |
---------------
| db_600629   |
---------------
| db_600636   |
---------------
| db_600643   |
---------------

TECLASS:
---------------
| field       |
---------------
| db_600629   |
---------------
| db_600636   |
---------------
| db_600643   |
---------------

AND NOW: define rule cascades is on delete to imclass 
         do delete teclass where current.field = teclass.field

So, on delete of an instance in imclass, the instance which's equal is also
removed.

COMMAND: delete imclass where imclass.field = "db_600643"

RESULT: remove the last instance of imclass and teclass

REALITY: ALL the instances of teclass were REMOVED!!

Conclusion : define a rule for built-in data types with CURRENT works;
          => define a rule for new data types with CURRENT not?!

Is this right?
-- 
_/ Eric de Jonge
_/ Email: [email-masked] 

==============================================================================
   To add/remove yourself to/from the POSTGRES mailing list: send mail with 
   the subject line ADD or DEL to "[email-masked]"

   If this fails, send mail to "[email-masked]" and
   a human will deal with it.  DO NOT post to the "postgres" mailing list.
==============================================================================

---

From: [email-masked] (Paul M. Aoki)
Date: Thu, 16 Jun 94 00:36:33 -0700

>           => define a rule for new data types with CURRENT not?!

hi eric.

more likely the = operator isn't working right.  below, the attribute
of "a" is of new (dynamically-loaded) type "footext" and "a" is the 
"current" of the delete rule.  this is using the 4.2beta on mips/ultrix;
your actual mileage may vary.

Script started on Thu Jun 16 00:28:01 1994
faerie:aoki (1)> destroydb chigau
faerie:aoki (2)> createdb chigau
faerie:aoki (3)> monitor chigau
Welcome to the POSTGRES terminal monitor

Go 
* \i /home2/aoki/blah

Query sent to backend is "define function footext_in ( language = "c", returntype = footext )  arg is (any) as "/home2/aoki/footext.o""
NOTICE:Jun 16 00:28:27:ProcedureDefine: type 'footext' is not yet defined
NOTICE:Jun 16 00:28:27:ProcedureDefine: creating a shell for type 'footext'
DEFINE
Query sent to backend is "define function footext_out ( language = "c", returntype = any ) arg  is (any) as "/home2/aoki/footext.o""
DEFINE
Query sent to backend is "define type footext ( internallength = variable, input = footext_in,  output = footext_out )"
DEFINE
Query sent to backend is "define function textfootexteq ( language = "c", returntype = bool )  arg is (text, footext) as "/home2/aoki/footext.o""
DEFINE
Query sent to backend is "define operator = ( arg1 = text, arg2 = footext, procedure =  textfootexteq)"
DEFINE
Query sent to backend is "create a (x=footext)"
CREATE
Query sent to backend is "create b (x=text)"
CREATE
Query sent to backend is "append a (x="foo")"
APPEND 21929
Query sent to backend is "append a (x="bar")"
APPEND 21930
Query sent to backend is "append b (x="foo")"
APPEND 21931
Query sent to backend is "append b (x="bar")"
APPEND 21932
Query sent to backend is "retrieve (a.all)"
---------------
| x           |
---------------
| foo         |
---------------
| bar         |
---------------

Query sent to backend is "retrieve (b.all)"
---------------
| x           |
---------------
| foo         |
---------------
| bar         |
---------------

Query sent to backend is "define rule cascades is on delete to a do delete b where b.x =  current.x"
DEFINE
Query sent to backend is "delete a where "foo"::text = a.x"
DELETE
Query sent to backend is "retrieve (a.all)"
---------------
| x           |
---------------
| bar         |
---------------

Query sent to backend is "retrieve (b.all)"
---------------
| x           |
---------------
| bar         |
---------------

Go 
* \q
faerie:aoki (4)> cat footext.c 
#include <ctype.h>
#include <strings.h>

#include "tmp/postgres.h"
#include "utils/log.h"
#include "utils/palloc.h"
#include "utils/builtins.h"

/*
 *	textin		- converts "..." to internal representation
 */
struct varlena *
footext_in(inputText)
	char 	*inputText;
{
	register struct varlena	*result;
	register int		len;

	if (inputText == NULL)
		return(NULL);
	len = strlen(inputText) + sizeof(int32);		/* varlena? */
	result = (struct varlena *) palloc(len);
	result->vl_len = len;
	bcopy(inputText, result->vl_dat, len - sizeof(int32));	/* varlena? */
	return(result);
}

/*
 *	textout		- converts internal representation to "..."
 */
char *
footext_out(vlena)
	struct varlena	*vlena;
{
	register int	len;
	char		*result;

	if (vlena == NULL) {
		result = (char *) palloc(2);
		result[0] = '-';
		result[1] = '\0';
		return(result);
	}
	len = vlena->vl_len - sizeof(int32);			/* varlena? */
	result = (char *) palloc(len + 1);
	bcopy(vlena->vl_dat, result, len);
	result[len] = '\0';
	return(result);
}

	     /* ========== PUBLIC ROUTINES ========== */

/*
 *	texteq		- returns 1 iff arguments are equal
 *	textne		- returns 1 iff arguments are not equal
 */
int32
textfootexteq(arg1, arg2)
	struct varlena	*arg1, *arg2;
{
	register int	len;
	register char	*a1p, *a2p;

	if (arg1 == NULL || arg2 == NULL)
		return((int32) NULL);
	if ((len = arg1->vl_len) != arg2->vl_len)
		return((int32) 0);
	a1p = arg1->vl_dat;
	a2p = arg2->vl_dat;
	/*
	 * Varlenas are stored as the total size (data + size variable)
	 * followed by the data.  The size variable is an int32 so the
	 * length of the data is the total length less sizeof(int32)
	 */
	len -= sizeof(int32);
	while (len-- != 0)
		if (*a1p++ != *a2p++)
			return((int32) 0);
	return((int32) 1);
}
faerie:aoki (5)> exit
exit

script done on Thu Jun 16 00:28:45 1994
--
  Paul M. Aoki  |  CS Div., Dept. of EECS, UCB  |  [email-masked]
                |  Berkeley, CA 94720           |  ...!uunet!ucbvax!aoki