home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / access / common / tupdesc.c < prev   
Encoding:
C/C++ Source or Header  |  1992-08-27  |  10.4 KB  |  389 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    tupdesc.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    POSTGRES tuple descriptor support code
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *    TupleDescIsValid       - just PointerIsValid()
  10.  *    CreateTemplateTupleDesc       - just palloc() + bzero().
  11.  *    TupleDescInitEntry       - inits a single attr in a tupdesc
  12.  *    TupleDescMakeSelfReference - initializes self reference attribute
  13.  *    BuildDesc           - builds tup desc from lisp list
  14.  *    BuildDescForRelation       - same as BuildDesc but handles self refs
  15.  *
  16.  *   NOTES
  17.  *    some of the executor utility code such as "ExecTypeFromTL" should be
  18.  *    moved here.
  19.  *
  20.  *   IDENTIFICATION
  21.  *    $Header: /private/postgres/src/access/common/RCS/tupdesc.c,v 1.10 1992/07/06 22:21:26 mao Exp $
  22.  * ----------------------------------------------------------------
  23.  */
  24.  
  25. #include <ctype.h>
  26.  
  27. #include "tmp/postgres.h"
  28.  
  29. RcsId("$Header: /private/postgres/src/access/common/RCS/tupdesc.c,v 1.10 1992/07/06 22:21:26 mao Exp $");
  30.  
  31. #include "nodes/pg_lisp.h"
  32.  
  33. #include "access/att.h"
  34. #include "access/attnum.h"
  35. #include "access/htup.h"
  36. #include "access/tupdesc.h"
  37.  
  38. #include "utils/log.h"        /* XXX generate exceptions instead */
  39. #include "utils/palloc.h"
  40.  
  41. #include "catalog/syscache.h"
  42. #include "catalog/pg_type.h"
  43.  
  44. #include "nodes/primnodes.h"
  45.  
  46. extern ObjectId TypeShellMake();
  47.  
  48. /*
  49.  *    TupleDescIsValid is now a macro in tupdesc.h -cim 4/27/91
  50.  */
  51.  
  52. /* ----------------------------------------------------------------
  53.  *    CreateTemplateTupleDesc
  54.  *
  55.  *    This function allocates and zeros a tuple descriptor structure.
  56.  * ----------------------------------------------------------------
  57.  */
  58. TupleDesc
  59. CreateTemplateTupleDesc(natts)
  60.     AttributeNumber    natts;
  61. {
  62.     uint32    size;
  63.     TupleDesc    desc;
  64.     
  65.     /* ----------------
  66.      *    sanity checks
  67.      * ----------------
  68.      */
  69.     AssertArg(natts >= 1);
  70.     
  71.     /* ----------------
  72.      *  allocate enough memory for the tuple descriptor and
  73.      *  zero it as TupleDescInitEntry assumes that the descriptor
  74.      *  is filled with NULL pointers.
  75.      * ----------------
  76.      */
  77.     size = natts * sizeof (TupleDescD);
  78.     desc = (TupleDesc) palloc(size);
  79.     bzero((Pointer)desc, size);
  80.  
  81.     return (desc);
  82. }
  83.  
  84. /* ----------------------------------------------------------------
  85.  *    TupleDescInitEntry
  86.  *
  87.  *    This function initializes a single attribute structure in
  88.  *    a preallocated tuple descriptor.
  89.  * ----------------------------------------------------------------
  90.  */
  91. bool
  92. TupleDescInitEntry(desc, attributeNumber, attributeName, typeName, attdim)
  93.     TupleDesc        desc;
  94.     AttributeNumber    attributeNumber;
  95.     Name        attributeName;
  96.     Name        typeName;
  97.     int            attdim;
  98. {
  99.     HeapTuple        tuple;
  100.     TypeTupleForm    typeForm;
  101.     Attribute        att;
  102.     
  103.     /* ----------------
  104.      *    sanity checks
  105.      * ----------------
  106.      */
  107.     AssertArg(TupleDescIsValid(desc));
  108.     AssertArg(attributeNumber >= 1);
  109.     AssertArg(NameIsValid(attributeName));
  110.     AssertArg(NameIsValid(typeName));
  111.  
  112.     AssertArg(!AttributeIsValid(desc->data[attributeNumber - 1]));
  113.  
  114.     /* ----------------
  115.      *    allocate storage for this attribute
  116.      * ----------------
  117.      */
  118.     att = (Attribute) palloc(sizeof *desc->data[0]);
  119.     desc->data[attributeNumber - 1] = att;
  120.  
  121.     /* ----------------
  122.      *    initialize some of the attribute fields
  123.      * ----------------
  124.      */
  125.     att->attrelid  = 0;                /* dummy value */
  126.     
  127.     strncpy(&(att->attname), attributeName, 16);
  128.     
  129.     att->attdefrel =     0;            /* dummy value */
  130.     att->attnvals  =     0;            /* dummy value */
  131.     att->atttyparg =     0;            /* dummy value */
  132.     att->attbound =     0;            /* dummy value */
  133.     att->attcanindex =     0;            /* dummy value */
  134.     att->attproc =     0;            /* dummy value */
  135.     att->attcacheoff =     -1;
  136.     
  137.     att->attnum = attributeNumber;
  138.     att->attnelems = attdim;
  139.  
  140.     /* ----------------
  141.      *    search the system cache for the type tuple of the attribute
  142.      *  we are creating so that we can get the typeid and some other
  143.      *  stuff.
  144.      *
  145.      *  Note: in the special case of 
  146.      *
  147.      *        create EMP (name = char16, manager = EMP)
  148.      *
  149.      *  RelationNameCreateHeapRelation() calls BuildDesc() which
  150.      *  calls this routine and since EMP does not exist yet, the
  151.      *  system cache lookup below fails.  That's fine, but rather
  152.      *  then doing a elog(WARN) we just leave that information
  153.      *  uninitialized, return false, then fix things up later.
  154.      *  -cim 6/14/90
  155.      * ----------------
  156.      */
  157.     tuple = SearchSysCacheTuple(TYPNAME, typeName);
  158.     if (! HeapTupleIsValid(tuple)) {
  159.     /* ----------------
  160.      *   here type info does not exist yet so we just fill
  161.      *   the attribute with dummy information and return false.
  162.      * ----------------
  163.      */
  164.     att->atttypid = InvalidObjectId;
  165.     att->attlen   = (int16)    0;
  166.     att->attbyval = (Boolean) 0;
  167.     return false;
  168.     }
  169.     
  170.     /* ----------------
  171.      *    type info exists so we initialize our attribute
  172.      *  information from the type tuple we found..
  173.      * ----------------
  174.      */
  175.     typeForm = (TypeTupleForm) GETSTRUCT(tuple);
  176.     
  177.     att->atttypid = tuple->t_oid;
  178.     att->attlen   = typeForm->typlen;
  179.     att->attbyval = typeForm->typbyval;
  180.  
  181.     return true;
  182. }
  183.  
  184.  
  185. /* ----------------------------------------------------------------
  186.  *    TupleDescMakeSelfReference
  187.  *
  188.  *    This function initializes a "self-referencial" attribute.
  189.  *    It calls TypeShellMake() which inserts a "shell" type
  190.  *    tuple into pg_type.  
  191.  * ----------------------------------------------------------------
  192.  */
  193.  
  194. void
  195. TupleDescMakeSelfReference(desc, attnum, relname)
  196.     TupleDesc        desc;
  197.     AttributeNumber    attnum;
  198.     Name         relname;
  199. {
  200.     Attribute att = desc->data[attnum - 1];
  201.  
  202.     att->atttypid = TypeShellMake(relname);
  203.     att->attlen   = -1;            /* for now, relation-types are */
  204.     att->attbyval = (Boolean) 0;     /* actually "text" internally. */
  205.     att->attnelems = 0;
  206. }
  207.  
  208. /* ----------------------------------------------------------------
  209.  *    BuildDesc
  210.  *
  211.  *    This is a general purpose function which takes a list of
  212.  *    the form:
  213.  *
  214.  *        (("att1" "type1") ("att2" "type2") ... )
  215.  *
  216.  *    and returns a tuple descriptor.
  217.  * ----------------------------------------------------------------
  218.  */
  219. TupleDesc
  220. BuildDesc(schema)
  221.     List schema;
  222. {
  223.     AttributeNumber    natts;
  224.     AttributeNumber    attnum;
  225.     List        p;
  226.     List        entry;
  227.     TupleDesc        desc;
  228.     Name         attname;
  229.     Name         typename;
  230.     Array        arry;
  231.     int            attdim;
  232.     
  233.     /* ----------------
  234.      *    allocate a new tuple descriptor
  235.      * ----------------
  236.      */
  237.     natts =     length(schema);
  238.     desc =     CreateTemplateTupleDesc(natts);
  239.  
  240.     attnum = 0;
  241.     
  242.     foreach(p, schema) {
  243.     /* ----------------
  244.      *    for each entry in the list, get the name and type
  245.      *      information from the list and have TupleDescInitEntry
  246.      *    fill in the attribute information we need.
  247.      * ----------------
  248.      */    
  249.     attnum++;
  250.     
  251.     entry =     CAR(p);
  252.     attname =     (Name) CString(CAR(entry));
  253.     typename =     (Name) CString(CADR(entry));
  254.     arry =        (Array) CDR(CDR(entry));
  255.  
  256.     /*
  257.      *  Support for arrays is extremely limited in the current
  258.      *  release.  We'd like to be able to have lower bounds
  259.      *  other than 1, for example, but we don't, at present.
  260.      *  The only interesting number in the Array node to us
  261.      *  in the current implementation is the upper bound, which
  262.      *  we treat as the array dimension.
  263.      */
  264.  
  265.     if (arry != (Array) NULL) {
  266.         char buf[20];
  267.  
  268.         attdim = get_arrayhigh(arry);
  269.  
  270.         /* array of XXX is _XXX (inherited from release 3) */
  271.         sprintf(buf, "_%s", typename);
  272.         strcpy(typename, buf);
  273.     }
  274.  
  275.     if (!TupleDescInitEntry(desc, attnum, attname, typename, attdim)) {
  276.         /* ----------------
  277.          *    if TupleDescInitEntry() fails, it means there is
  278.          *  no type in the system catalogs, so we signal an
  279.          *  elog(WARN) which aborts the transaction.
  280.          * ----------------
  281.          */
  282.         elog(WARN, "BuildDesc: no such type %s", typename);
  283.     }
  284.     }
  285.  
  286.     return desc;
  287. }
  288.     
  289. /* ----------------------------------------------------------------
  290.  *    BuildDescForRelation
  291.  *
  292.  *    This is a general purpose function identical to BuildDesc
  293.  *    but is used by the DefineRelation() code to catch the
  294.  *    special case where you
  295.  *
  296.  *        create FOO ( ..., x = FOO )
  297.  *
  298.  *    here, the initial type lookup for "x = FOO" will fail
  299.  *    because FOO isn't in the catalogs yet.  But since we
  300.  *    are creating FOO, instead of doing an elog() we add
  301.  *    a shell type tuple to pg_type and fix things later
  302.  *    in amcreate().
  303.  * ----------------------------------------------------------------
  304.  */
  305. TupleDesc
  306. BuildDescForRelation(schema, relname)
  307.     List schema;
  308.     Name relname;
  309. {
  310.     AttributeNumber    natts;
  311.     AttributeNumber    attnum;
  312.     List        p;
  313.     List        entry;
  314.     Array        arry;
  315.     TupleDesc        desc;
  316.     Name         attname;
  317.     Name         typename;
  318.     char        typename2[16];
  319.     char        *pp, *pp2;
  320.     int            attdim;
  321.  
  322.     /* ----------------
  323.      *    allocate a new tuple descriptor
  324.      * ----------------
  325.      */
  326.     natts =     length(schema);
  327.     desc =     CreateTemplateTupleDesc(natts);
  328.  
  329.     attnum = 0;
  330.  
  331.     foreach(p, schema) {
  332.     /* ----------------
  333.      *    for each entry in the list, get the name and type
  334.      *      information from the list and have TupleDescInitEntry
  335.      *    fill in the attribute information we need.
  336.      * ----------------
  337.      */    
  338.     attnum++;
  339.     
  340.     entry =     CAR(p);
  341.     attname =     (Name) CString(CAR(entry));
  342.  
  343.     if (IsA(CADR(entry),LispList)) {
  344.         typename = (Name) CString(CAR(CADR(entry)));
  345.         arry = (Array) CDR(CADR(entry));
  346.     } else {
  347.         typename = (Name) CString(CADR(entry));
  348.         arry = (Array) NULL;
  349.     }
  350.  
  351.     /*
  352.      *  Support for arrays is extremely limited in the current
  353.      *  release.  We'd like to be able to have lower bounds
  354.      *  other than 1, for example, but we don't, at present.
  355.      *  The only interesting number in the Array node to us
  356.      *  in the current implementation is the upper bound, which
  357.      *  we treat as the array dimension.
  358.      */
  359.  
  360.     if (arry != (Array) NULL) {
  361.         char buf[20];
  362.  
  363.         attdim = get_arrayhigh(arry);
  364.  
  365.         /* array of XXX is _XXX (inherited from release 3) */
  366.         sprintf(buf, "_%s", typename);
  367.         strcpy(typename, buf);
  368.     }
  369.     else
  370.         attdim = 0;
  371.  
  372.     if (! TupleDescInitEntry(desc, attnum, attname, typename, attdim)) {
  373.         /* ----------------
  374.          *    if TupleDescInitEntry() fails, it means there is
  375.          *  no type in the system catalogs.  So now we check if
  376.          *  the type name equals the relation name.  If so we
  377.          *  have a self reference, otherwise it's an error.
  378.          * ----------------
  379.          */
  380.         if (!strcmp(typename, relname)) {
  381.         TupleDescMakeSelfReference(desc, attnum, relname);
  382.         } else
  383.         elog(WARN, "DefineRelation: no such type %s", typename);
  384.     }
  385.     }
  386.     return desc;
  387. }
  388.  
  389.