agora inbox for postgres@postgres.berkeley.edu  
help / color / mirror / Atom feed
From: Jolly Chen <jolly@postgres.Berkeley.EDU>
To: Bruce Taneja. <aataneja@cs.mtu.edu>
Cc: postgres@postgres.Berkeley.EDU
Subject: Re: variable size data types..
Date: Tue, 07 Jun 1994 16:05:28 -0700
Message-ID: <199406072305.QAA06239@arcadia.CS.Berkeley.EDU> (raw)
In-Reply-To: <9406070603.AA06822@cs.mtu.edu>



> 
> 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.
==============================================================================



reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: postgres@postgres.berkeley.edu
  Cc: jolly@postgres.Berkeley.EDU, aataneja@cs.mtu.edu
  Subject: Re: variable size data types..
  In-Reply-To: <199406072305.QAA06239@arcadia.CS.Berkeley.EDU>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox