mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			149 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <HTML>
 | |
| <HEAD>
 | |
| 	<TITLE>The POSTGRES95 User Manual - EXTENDING SQL: TYPES</TITLE>
 | |
| </HEAD>
 | |
| 
 | |
| <BODY>
 | |
| 
 | |
| <font size=-1>
 | |
| <A HREF="pg95user.html">[ TOC ]</A> 
 | |
| <A HREF="xfunc.html">[ Previous ]</A> 
 | |
| <A HREF="xoper.html">[ Next ]</A> 
 | |
| </font>
 | |
| <HR>
 | |
| <H1>8.  EXTENDING SQL: TYPES</H1>
 | |
| <HR>
 | |
|      As previously mentioned, there are two kinds  of  types
 | |
|      in  POSTGRES: base types (defined in a programming language) 
 | |
|      and composite types (instances).
 | |
|      Examples in this section up to interfacing indices  can
 | |
|      be  found in <CODE>complex.sql</CODE> and <CODE>complex.c</CODE>.  Composite examples 
 | |
|      are in <CODE>funcs.sql</CODE>.
 | |
| <p>
 | |
| <H2><A NAME="user-defined-types">8.1.  User-Defined Types</A></H2>
 | |
| <p>
 | |
| <H3><A NAME="functions-needed-for-a-user-defined-type">8.1.1.  Functions Needed for a User-Defined Type</A></H3>
 | |
|      A  user-defined  type must always have input and output
 | |
|      functions.  These  functions  determine  how  the  type
 | |
|      appears in strings (for input by the user and output to
 | |
|      the user) and how the type is organized in memory.  The
 | |
|      input  function takes a null-delimited character string
 | |
|      as its input and returns the internal (in memory)  
 | |
|      representation of the type.  The output function takes the
 | |
|      internal representation of the type and returns a null
 | |
|      delimited character string.
 | |
|      Suppose  we  want to define a complex type which represents 
 | |
|      complex numbers. Naturally, we choose  to  represent a 
 | |
|      complex in memory as the following <B>C</B> structure:
 | |
| 
 | |
| <pre>         typedef struct Complex {
 | |
|              double      x;
 | |
|              double      y;
 | |
|          } Complex;
 | |
| </pre>
 | |
|      and  a  string of the form (x,y) as the external string
 | |
|      representation.
 | |
|      These functions are usually not hard  to  write,  especially  
 | |
|      the output function.  However, there are a number of points 
 | |
|      to remember.
 | |
|      
 | |
|      <OL>
 | |
|       <LI>  When defining your external (string) representation,  
 | |
|             remember that you must eventually write a
 | |
|             complete and robust parser for that  representation 
 | |
|             as your input function!
 | |
|             
 | |
| <pre>                Complex *
 | |
|                 complex_in(char *str)
 | |
|                 {
 | |
|                     double x, y;
 | |
|                     Complex *result;
 | |
| 
 | |
|                     if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
 | |
|                         elog(WARN, "complex_in: error in parsing
 | |
|                         return NULL;
 | |
|                     }
 | |
|                     result = (Complex *)palloc(sizeof(Complex));
 | |
|                     result->x = x;
 | |
|                     result->y = y;
 | |
|                     return (result);
 | |
|                 }
 | |
| </pre>
 | |
| 
 | |
|             The output function can simply be:
 | |
| 
 | |
| <pre>                char *
 | |
|                 complex_out(Complex *complex)
 | |
|                 {
 | |
|                     char *result;
 | |
| <p>
 | |
|                     if (complex == NULL)
 | |
|                         return(NULL);
 | |
| <p>
 | |
|                     result = (char *) palloc(60);
 | |
|                     sprintf(result, "(%g,%g)", complex->x, complex->y);
 | |
|                     return(result);
 | |
|                 }
 | |
| </pre>
 | |
|       <LI>  You  should  try  to  make  the input and output
 | |
|             functions inverses of each  other.   If  you  do
 | |
|             not, you will have severe problems when you need
 | |
|             to dump your data into a file and then  read  it
 | |
|             back  in  (say,  into someone else's database on
 | |
|             another computer).  This is a particularly  common  
 | |
|             problem  when  floating-point  numbers  are
 | |
|             involved.
 | |
|      </OL>
 | |
|      To define the <B>complex</B> type, we need to create  the  two
 | |
|      user-defined   functions   complex_in  and  complex_out
 | |
|      before creating the type:
 | |
|      
 | |
| <pre>         CREATE FUNCTION complex_in(opaque)
 | |
|             RETURNS complex
 | |
|             AS '/usr/local/postgres95/tutorial/obj/complex.so'
 | |
|             LANGUAGE 'c';
 | |
| 
 | |
|          CREATE FUNCTION complex_out(opaque)
 | |
|             RETURNS opaque
 | |
|             AS '/usr/local/postgres95/tutorial/obj/complex.so'
 | |
|             LANGUAGE 'c';
 | |
| 
 | |
|          CREATE TYPE complex (
 | |
|             internallength = 16,
 | |
|             input = complex_in,
 | |
|             output = complex_out
 | |
|          );
 | |
| </pre>
 | |
| 
 | |
|      As discussed earlier, POSTGRES fully supports arrays of
 | |
|      base  types.  Additionally, POSTGRES supports arrays of
 | |
|      user-defined types as well.  When you  define  a  type,
 | |
|      POSTGRES  automatically  provides support for arrays of
 | |
|      that type.  For historical reasons, the array type  has
 | |
|      the  same name as the user-defined type with the 
 | |
|      underscore character _ prepended.
 | |
|      Composite types do not need  any  function  defined  on
 | |
|      them,  since  the  system already understands what they
 | |
|      look like inside.
 | |
| <p>
 | |
| <H3><A NAME="large-objects">8.1.2.  Large Objects</A></H3>
 | |
|      The types discussed  to  this  point  are  all  "small"
 | |
|      objects -- that is, they are smaller than 8KB<A HREF="#7"><font size=-1>[7]</font></A> in size.
 | |
|      If you require a larger type for something like a document  
 | |
|      retrieval system or for storing bitmaps, you will
 | |
|      need to use the POSTGRES large object interface.
 | |
| <p>
 | |
| <HR>
 | |
| <A NAME="8"><B>[7]</B></A> 8 * 1024 == 8192 bytes.  In fact, the type must be considerably smaller than 8192 bytes, since the POSTGRES  tuple
 | |
| and  page  overhead  must also fit into this 8KB limitation.
 | |
| The actual value that fits depends on the machine  architecture.
 | |
| <HR>
 | |
| <font size=-1>
 | |
| <A HREF="pg95user.html">[ TOC ]</A> 
 | |
| <A HREF="xfunc.html">[ Previous ]</A> 
 | |
| <A HREF="xoper.html">[ Next ]</A> 
 | |
| </font>
 | |
| </BODY>
 | |
| </HTML>
 | |
| 
 |