home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / lib / libpq / portalbuf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  11.1 KB  |  471 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    portalbuf.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    portal buffer support routines for src/libpq/portal.c
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *    pbuf_alloc       - allocate memory for libpq routines
  10.  *    pbuf_free       - free memory for libpq routines
  11.  *    pbuf_addPortal       - Allocate a new portal buffer
  12.  *    pbuf_addGroup       - Add a new tuple group to the portal
  13.  *    pbuf_addTypes       - Allocate n type blocks
  14.  *    pbuf_addTuples       - Allocate a tuple block
  15.  *    pbuf_addTuple       - Allocate a tuple of n fields (attributes)
  16.  *    pbuf_addValues       - Allocate n bytes for a value
  17.  *    pbuf_addEntry       - Allocate a portal entry
  18.  *    pbuf_freeEntry    - Free a portal entry in the portal table
  19.  *    pbuf_freeTypes       - Free up the space used by a portal 
  20.  *    pbuf_freeTuples   - free space used by tuple block
  21.  *    pbuf_freeGroup       - free space used by group, types and tuples
  22.  *    pbuf_freePortal   - free space used by portal and portal's group
  23.  *    pbuf_getIndex       - Return the index of the portal entry
  24.  *    pbuf_setup       - Set up a portal for dumping data
  25.  *    pbuf_close       - Close a portal, remove it from the portal table
  26.  *    pbuf_findGroup       - Return group given the group_index
  27.  *    pbuf_findFnumber  - Return field index of a given field within a group
  28.  *    pbuf_findFname       - Find the field name given the field index
  29.  *    pbuf_checkFnumber - signal an error if field number is out of bounds
  30.  *
  31.  *   NOTES
  32.  *    These functions may be used by both frontend routines which
  33.  *    communicate with a backend or by user-defined functions which
  34.  *    are compiled or dynamically loaded into a backend.
  35.  *
  36.  *    the portals[] array should be organized as a hash table for
  37.  *    quick portal-by-name lookup.
  38.  *
  39.  *    Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
  40.  *    see utils/mmgr/portalmem.c for why. -cim 2/22/91
  41.  *
  42.  *   IDENTIFICATION
  43.  *    $Header: /private/postgres/src/lib/libpq/RCS/portalbuf.c,v 1.7 1992/07/15 05:12:24 mao Exp $
  44.  * ----------------------------------------------------------------
  45.  */
  46.  
  47. #include <sys/types.h>
  48.  
  49. #include "tmp/c.h"
  50.  
  51. RcsId ("$Header: /private/postgres/src/lib/libpq/RCS/portalbuf.c,v 1.7 1992/07/15 05:12:24 mao Exp $");
  52.  
  53. #include "tmp/simplelists.h"
  54. #include "tmp/libpq.h"
  55. #include "utils/exc.h"
  56.  
  57. PortalEntry *portals[MAXPORTALS];
  58.  
  59. /* --------------------------------
  60.  *    pbuf_alloc - allocate memory for portal buffers
  61.  *
  62.  *    remember: palloc() in the backend uses the postgres MemoryContext
  63.  *    library and palloc() in the frontend (fe-pqstubs.c) calls malloc().
  64.  * --------------------------------
  65.  */
  66. caddr_t
  67. pbuf_alloc(size)
  68.     size_t size;
  69. {
  70.     caddr_t     addr;
  71.  
  72.     if (size <= 0)
  73.     libpq_raise(&MemoryError, form((int)"Invalid argument to pg_alloc()."));
  74.  
  75.     addr = (caddr_t) palloc(size);
  76.     if (addr == NULL)
  77.     libpq_raise(&MemoryError, form((int)"Cannot Allocate space."));
  78.  
  79.     return (addr);
  80. }
  81.  
  82. /* --------------------------------
  83.  *    pbuf_free - free memory for portal buffers
  84.  *
  85.  *    remember: pfree() in the backend uses the postgres MemoryContext
  86.  *    library and pfree() in the frontend (fe-pqstubs.c) calls free().
  87.  * --------------------------------
  88.  */
  89. void
  90. pbuf_free(pointer)
  91.     caddr_t pointer;
  92. {
  93.     pfree(pointer);
  94. }
  95.  
  96. /* --------------------------------
  97.  *    pbuf_addPortal - Allocate a new portal buffer
  98.  * --------------------------------
  99.  */
  100. PortalBuffer *
  101. pbuf_addPortal()
  102. {
  103.     PortalBuffer *portal;
  104.     
  105.     portal = (PortalBuffer *)
  106.     pbuf_alloc(sizeof (PortalBuffer));
  107.     
  108.     portal->rule_p = 0;
  109.     portal->no_tuples = 0;
  110.     portal->no_groups = 0;
  111.     portal->groups = NULL;
  112.  
  113.     return (portal);
  114. }
  115.  
  116. /* --------------------------------
  117.  *    pbuf_addGroup - Add a new tuple group to the portal
  118.  * --------------------------------
  119.  */
  120. GroupBuffer *
  121. pbuf_addGroup(portal)
  122.     PortalBuffer *portal;
  123. {
  124.     GroupBuffer *group, *group1;
  125.  
  126.     group = (GroupBuffer *)
  127.     pbuf_alloc(sizeof (GroupBuffer));
  128.     
  129.     /* Initialize the new group buffer. */
  130.     group->no_tuples  = 0;
  131.     group->no_fields = 0;
  132.     group->types = NULL;
  133.     group->tuples = NULL;
  134.     group->next = NULL;
  135.     
  136.     if ((group1 = portal->groups) == NULL)
  137.     portal->groups = group;
  138.     else {
  139.     while (group1->next != NULL) 
  140.         group1 = group1->next;
  141.     group1->next = group;
  142.     }
  143.     
  144.     return (group);
  145. }
  146.  
  147. /* --------------------------------
  148.  *    pbuf_addTypes - Allocate n type blocks
  149.  * --------------------------------
  150.  */
  151. TypeBlock *
  152. pbuf_addTypes(n)
  153.     int n;
  154. {
  155.     TypeBlock *types;
  156.  
  157.     types = (TypeBlock *)
  158.     pbuf_alloc(n * sizeof (TypeBlock));
  159.  
  160.     return (types);
  161. }
  162.  
  163. /* --------------------------------
  164.  *    pbuf_addTuples - Allocate a tuple block
  165.  * --------------------------------
  166.  */
  167. /*  */
  168. TupleBlock *
  169. pbuf_addTuples()
  170. {
  171.     TupleBlock *tuples;
  172.  
  173.     tuples = (TupleBlock *)
  174.     pbuf_alloc(sizeof (TupleBlock));
  175.     
  176.     tuples->next = NULL;
  177.  
  178.     return (tuples);
  179. }
  180.  
  181. /* --------------------------------
  182.  *    pbuf_addTuple - Allocate a tuple of n fields (attributes)
  183.  * --------------------------------
  184.  */
  185. char **
  186. pbuf_addTuple(n)
  187. {
  188.    return (char **)
  189.     pbuf_alloc(n * sizeof (char *));
  190. }
  191.  
  192. /* --------------------------------
  193.  *    pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes)
  194.  * --------------------------------
  195.  */
  196. int *
  197. pbuf_addTupleValueLengths(n)
  198. {
  199.     return (int *)
  200.     pbuf_alloc(n * sizeof (int));
  201. }
  202.  
  203. /* --------------------------------
  204.  *    pbuf_addValues - Allocate n bytes for a value
  205.  * --------------------------------
  206.  */
  207. char *
  208. pbuf_addValues(n)
  209.     int n;
  210. {
  211.     return
  212.     pbuf_alloc(n);
  213. }
  214.  
  215. /* --------------------------------
  216.  *    pbuf_addEntry - Allocate a portal entry
  217.  * --------------------------------
  218.  */
  219. PortalEntry *
  220. pbuf_addEntry()
  221. {
  222.     return (PortalEntry *)
  223.     pbuf_alloc (sizeof (PortalEntry));
  224. }
  225.  
  226. /* --------------------------------
  227.  *    pbuf_freeEntry - Free a portal entry in the portal table
  228.  *    the portal is freed separately.
  229.  * --------------------------------
  230.  */
  231. void
  232. pbuf_freeEntry(i)
  233.     int i;
  234. {
  235.     pbuf_free ((caddr_t)portals[i]);
  236.     portals[i] = NULL;
  237. }
  238.  
  239.  
  240. /* --------------------------------
  241.  *    pbuf_freeTypes - Free up the space used by a portal 
  242.  * --------------------------------
  243.  */
  244.  
  245. void 
  246. pbuf_freeTypes(types)
  247.     TypeBlock *types;
  248. {
  249.     pbuf_free((caddr_t)types);
  250. }
  251.  
  252. /* --------------------------------
  253.  *    pbuf_freeTuples - free space used by tuple block
  254.  * --------------------------------
  255.  */
  256. void
  257. pbuf_freeTuples(tuples, no_tuples, no_fields)
  258.     TupleBlock *tuples;
  259.     int        no_tuples;
  260.     int        no_fields;
  261. {
  262.     int i, j;
  263.     
  264.     if (no_tuples > TupleBlockSize) {
  265.     pbuf_freeTuples (tuples->next, no_tuples - TupleBlockSize, no_fields);
  266.     no_tuples = TupleBlockSize;
  267.     }
  268.     
  269.     /* For each tuple, free all its attribute values. */
  270.     for (i = 0; i < no_tuples; i++) {
  271.     for (j = 0; j < no_fields; j++)
  272.       if (tuples->values[i][j] != NULL)
  273.         pbuf_free((caddr_t)tuples->values[i][j]);
  274.     pbuf_free((caddr_t)tuples->lengths[i]);
  275.     pbuf_free((caddr_t)tuples->values[i]);
  276.     }
  277.     
  278.     pbuf_free((caddr_t)tuples);
  279. }
  280.  
  281. /* --------------------------------
  282.  *    pbuf_freeGroup - free space used by group, types and tuples
  283.  * --------------------------------
  284.  */
  285. void
  286. pbuf_freeGroup(group)
  287.     GroupBuffer *group;
  288. {
  289.     if (group->next != NULL)
  290.     pbuf_freeGroup(group->next);
  291.  
  292.     if (group->types != NULL)
  293.     pbuf_freeTypes(group->types);
  294.  
  295.     if (group->tuples != NULL)
  296.     pbuf_freeTuples(group->tuples, group->no_tuples,group->no_fields);
  297.  
  298.     pbuf_free((caddr_t)group);
  299. }
  300.  
  301. /* --------------------------------
  302.  *    pbuf_freePortal - free space used by portal and portal's group
  303.  * --------------------------------
  304.  */
  305. void
  306. pbuf_freePortal(portal)
  307.     PortalBuffer *portal;
  308. {
  309.     if (portal->groups != NULL)
  310.     pbuf_freeGroup(portal->groups);
  311.     
  312.     pbuf_free((caddr_t)portal);
  313. }
  314.  
  315. /* --------------------------------
  316.  *    pbuf_getIndex - Return the index of the portal entry
  317.  *     note: portals[] maps portal names to portal buffers.
  318.  * --------------------------------
  319.  */
  320. int 
  321. pbuf_getIndex(pname)
  322.     char *pname;
  323. {
  324.     int i;
  325.  
  326.     for (i = 0; i < MAXPORTALS; i++) 
  327.     if (portals[i] != NULL && strcmp(portals[i]->name, pname) == 0)
  328.         return i;
  329.     
  330.     return (-1);
  331. }
  332.  
  333. /* --------------------------------
  334.  *    pbuf_setportalname - assign a user given name to a portal
  335.  * --------------------------------
  336.  */
  337.  
  338. void
  339. pbuf_setportalinfo(entry, pname)
  340.     PortalEntry *entry;
  341.     char *pname;
  342. {
  343.     if (entry)
  344.     strncpy(entry->name, pname, PortalNameLength-1);
  345. }
  346.  
  347. /* --------------------------------
  348.  *    pbuf_setup - Set up a portal for dumping data
  349.  * --------------------------------
  350.  */
  351. PortalEntry *
  352. pbuf_setup(pname)
  353.     char *pname;
  354. {
  355.     int i;
  356.  
  357.     /* If a portal with the same name already exists, close it. */
  358.     /* else look for an empty entry in the portal table. */
  359.     if ((i = pbuf_getIndex(pname)) != -1) 
  360.     pbuf_freePortal(portals[i]->portal);
  361.     else {
  362.     for (i = 0; i < MAXPORTALS; i++)
  363.         if (portals[i] == NULL)
  364.         break;
  365.     /* If the portal table is full, signal an error. */
  366.     if (i >= MAXPORTALS) 
  367.         libpq_raise(&PortalError, form((int)"Portal Table overflows!"));
  368.     
  369.     portals[i] = pbuf_addEntry();
  370.     strncpy(portals[i]->name, pname, PortalNameLength-1);
  371.     }
  372.     portals[i]->portal = pbuf_addPortal();
  373.     portals[i]->portalcxt = NULL;
  374.     portals[i]->result = NULL;
  375.     
  376.     return (PortalEntry *)
  377.     portals[i];
  378. }
  379.  
  380. /* --------------------------------
  381.  *    pbuf_close - Close a portal, remove it from the portal table
  382.  *            and free up the space
  383.  * --------------------------------
  384.  */
  385. void
  386. pbuf_close(pname)
  387.     char *pname;
  388. {
  389.     int i;
  390.  
  391.     if ((i = pbuf_getIndex(pname)) == -1) 
  392.     libpq_raise(&PortalError, form((int)"Portal %s does not exist.", pname));
  393.  
  394.     pbuf_freePortal(portals[i]->portal);
  395.     pbuf_freeEntry(i);
  396. }
  397.  
  398. /* --------------------------------
  399.  *    pbuf_findGroup - Return the group given the group_index
  400.  * --------------------------------
  401.  */
  402. GroupBuffer *
  403. pbuf_findGroup(portal, group_index)
  404.     PortalBuffer *portal;
  405.     int      group_index;
  406. {
  407.     GroupBuffer *group;
  408.  
  409.     group = portal->groups;
  410.     while (group_index > 0 && group != NULL) {
  411.     group = group->next;
  412.     group_index--;
  413.     }
  414.  
  415.     if (group == NULL)
  416.     libpq_raise(&PortalError, 
  417.             form((int)"Group index %d out of bound.", group_index));
  418.  
  419.     return (group);
  420. }
  421.  
  422. /* --------------------------------
  423.  *    pbuf_findFnumber - Return the field index of a given field within a group
  424.  * --------------------------------
  425.  */
  426. pbuf_findFnumber(group, field_name)
  427.     GroupBuffer *group;
  428.     char    *field_name;
  429. {    
  430.     TypeBlock *types;
  431.     int i;
  432.  
  433.     types = group->types;
  434.  
  435.     for (i = 0; i < group->no_fields; i++, types++) 
  436.     if (strcmp(types->name, field_name) == 0)
  437.         return (i);
  438.     
  439.     libpq_raise(&PortalError, 
  440.         form((int)"Field-name %s does not exist.", field_name));
  441. }
  442.  
  443. /* --------------------------------
  444.  *    pbuf_checkFnumber - signal an error if field number is out of bounds
  445.  * --------------------------------
  446.  */
  447. void
  448. pbuf_checkFnumber(group, field_number)
  449.     GroupBuffer *group;
  450.     int         field_number;
  451. {
  452.     if (field_number < 0 || field_number >= group->no_fields)
  453.     libpq_raise(&PortalError, 
  454.             form((int)"Field number %d out of bound.", field_number));
  455. }
  456.  
  457. /* --------------------------------
  458.  *    pbuf_findFname - Find the field name given the field index
  459.  * --------------------------------
  460.  */
  461. char *
  462. pbuf_findFname(group, field_number)
  463.     GroupBuffer *group;
  464.     int        field_number;
  465. {
  466.      pbuf_checkFnumber(group, field_number);
  467.      return
  468.      (group->types + field_number)->name;
  469. }
  470.  
  471.