Return-Path: owner-postman
Received: from LOCALHOST (LOCALHOST [127.0.0.1]) by nobozo.CS.Berkeley.EDU (8.6.4/8.6.3) with SMTP id QAA23255 for postgres-redist; Tue, 7 Jun 1994 16:05:31 -0700
Resent-From: POSTGRES mailing list <postman@postgres.Berkeley.EDU>
Resent-Message-Id: <199406072305.QAA23255@nobozo.CS.Berkeley.EDU>
X-Authentication-Warning: nobozo.CS.Berkeley.EDU: Host LOCALHOST didn't use HELO protocol
Sender: owner-postman@postgres.Berkeley.EDU
X-Return-Path: owner-postman
Received: from arcadia.CS.Berkeley.EDU (arcadia.CS.Berkeley.EDU [128.32.149.40]) by nobozo.CS.Berkeley.EDU (8.6.4/8.6.3) with ESMTP id QAA23245 for <postgres@postgres.Berkeley.EDU>; Tue, 7 Jun 1994 16:05:30 -0700
Received: from localhost (jolly@localhost) by arcadia.CS.Berkeley.EDU (8.6.4/8.6.3) id QAA06239; Tue, 7 Jun 1994 16:05:28 -0700
Message-Id: <199406072305.QAA06239@arcadia.CS.Berkeley.EDU>
To: aataneja@cs.mtu.edu (Bruce Taneja.)
cc: postgres@postgres.Berkeley.EDU
Subject: Re: variable size data types.. 
In-reply-to: Your message of "Tue, 07 Jun 1994 02:03:54 EDT."
             <9406070603.AA06822@cs.mtu.edu> 
Date: Tue, 07 Jun 1994 16:05:28 -0700
From: Jolly Chen <jolly@postgres.Berkeley.EDU>
Resent-To: postgres-redist@postgres.Berkeley.EDU
Resent-Date: Tue, 07 Jun 94 16:05:31 -0700
Resent-XMts: smtp



> 
> Howdy Paul & folks,
> 
> Dunno if this is a more of a C question than a postgres question
> but since it concerns postgres's variable user defined (array) 
> data types, here goes:
> 
> example:
> 
> 	typedef struct {
> 
> 		int size; 	/* size of this mem glob */
> 		int n_points;	/* number of points struct nested */
> 		POINT points[1];/* the first one*/
> 		int n_circles;	/* the number of circles */
> 		CIRCLE circles[1]; /* the 1st one*/
> 
> 		} CIRCLES_N_POINTS;
> 
>
> and, if I am (sadly) right, then what is the solution to having two complex 
> variable sized arrays in your defined variable size complex data type?
> 
> Perhaps the C gurus or postgres gurus would like to educate the dumb
> old me ..
>  

One way to accomplish this is to swizzle the pointers explicitly
yourself.  So, you can do something like:

typedef struct {
 		int size; 	/* size of this mem glob */
 		int n_points;	/* number of points struct nested */
		POINT* points;
 		int n_circles;	/* the number of circles */
		CIRCLE* circles;
		char blob;  /* space holder for variable sized storage */
 		} CIRCLES_N_POINTS;
 
When you palloc space for the structure, you need to account for
the space needed by the variable-length arrays of points and circles.
(You also should be careful of architecture-specific alignment padding
that may be needed)

Then, in your adt code, you need to "swizzle" your pointers whenever you
get the data structure back from the database. Based on the other fields
in your structure, you can calculate how far to offset into the blob
field for your pointers.    For example, you may do 

	CIRCLES_N_POINTS* c;
	
	c->points = c->blob;
	c->circles = c->blob + n_points * sizeof(POINT);

or something like that. 

After you've manually swizzled the pointers, you can use the pointer
fields normally.  Since your storage was palloc'd in one chunk, as long
as you have your size stated corrected, postgres will store your entire
contiguous hunk of bytes as your adt.  Just be sure to swizzle your
pointers everytime you get the adt out of the database, because the
unswizzled fields are meaningless when you first read them out of the
database. 

- Jolly Chen

==============================================================================
   To add/remove yourself to/from the POSTGRES mailing list: send mail with 
   the subject line ADD or DEL to "postgres-request@postgres.Berkeley.EDU"

   If this fails, send mail to "post_questions@postgres.Berkeley.EDU" and
   a human will deal with it.  DO NOT post to the "postgres" mailing list.
==============================================================================
