Return-Path: pg_adm@postgres.berkeley.edu
Received: by postgres.Berkeley.EDU (5.61/1.29)
	id AA08765; Mon, 19 Apr 93 10:57:00 -0700
Date: Mon, 19 Apr 93 10:57:00 -0700
Message-Id: <9304191757.AA08765@postgres.Berkeley.EDU>
From: Postgres Account <postgres@hercules.eng.miami.edu>
Subject: oid[] and C-functions problem
To: postgres@postgres.berkeley.edu
Sender: pg_adm@postgres.berkeley.edu

The following is a fragment from the C-code that I wrote
to use an oid[] array to implement a setofoid. I defined
the operator @ to be the membership test and the + operator
to add elements to the set. So one could write:

Q1:
replace TEST (oids = TEST.oids + P.oid)
from P in PATIENT
where P.name = "name" and TEST.t = "one"

The oid[]+oid calls the function add_oid_to_array, defined
in the code below. My problem is the following:

The membershipfunction works fine, the add function seems to work,
but when I retrieve the updated tuple, it shows the 
array attribute to be (null). The function did NOT return (null).
					       ^^^
before Q1 and after Q1:
-----------------------------
| t           | oids        |
-----------------------------
| two         | (null)      |
-----------------------------
| three       | (null)      |
-----------------------------
| four        | {179936,181933}|
-----------------------------
| one         | (null)      |
-----------------------------

What happened???

I'm really completely in the dark here, so if anyone could
help me out, I'd really appreciate it. Thanks

Frank Sauer
sauer@hercules.eng.miami.edu

code:

/******************************************************
 * the following is the type that postgres expects for
 * variable-length arrays
 ******************************************************/
typedef struct {
  long length;
  unsigned char bytes[1]; /* force contiguity */
} VAR_LEN_ATTR;

/******************
 * membership test 
 ******************/
bool oid_in_array (obj, arr)
oid obj;
VAR_LEN_ATTR *arr;
{ oid *p,*end;

  p = (oid *)&(arr->bytes[0]);
  end = (oid *) ((long)arr + arr->length);
  while ((p < end) && (*p < obj)) p++;
  return (*p == obj);
}

/********************
 * add element to set
 ********************/
VAR_LEN_ATTR *add_oid_to_array(arr, obj)
VAR_LEN_ATTR *arr;
oid obj;
{ VAR_LEN_ATTR *n;
  oid *p1, *p2,*end;
  
  /* element already in set */
  if (oid_in_array(arr,obj)) 
  { printf("DEBUG: Case 1 : object already in set\n");
    return arr;
  }

  /* set is empty, obj is first element */
  if (!arr)
  { n = (VAR_LEN_ATTR *)palloc(sizeof(long)+sizeof(oid));
    if (!n) 
    { printf("DEBUG: palloc failed\n");
      return 0;
    }
    n->length = sizeof(long)+sizeof(oid);
    p1   = (oid *)&(n->bytes[0]);
    p1[0] = obj;
    return n;
  }
  /* obj is new, arr is not empty */

  ...
  ...
