home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 168_01 / sel.c < prev    next >
Text File  |  1985-08-21  |  21KB  |  752 lines

  1. /* SDB - select data from the database */
  2.  
  3. #include "sdbio.h"
  4.  
  5. extern int dbv_token;
  6. extern char dbv_tstring[];
  7. extern int dbv_tvalue;
  8.  
  9. /* db_select - select a set of tuples from a set of relations */
  10. struct sel *db_select(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
  11.   char *fmt;
  12. {
  13.     struct sel *slptr;
  14.  
  15.     /* check for a command line */
  16.     if (fmt != NULL)
  17.         db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
  18.  
  19.     /* allocate a sel structure */
  20.     if ((slptr = malloc(sizeof(struct sel))) == NULL)
  21.         return (db_nerror(INSMEM));
  22.  
  23.     /* initialize the structure */
  24.     slptr->sl_rels = NULL;
  25.     slptr->sl_attrs = NULL;
  26.     slptr->sl_where = NULL;
  27.     slptr->sl_bindings = NULL;
  28.  
  29.     /* parse the list of selected attributes */
  30.     if (!get_sattrs(slptr)) {
  31.         db_done(slptr);
  32.         return (NULL);
  33.     }
  34.  
  35.     /* check for "from" clause */
  36.     if (db_token() == FROM) {
  37.         db_ntoken();
  38.         if (!get_srels(slptr)) {
  39.             db_done(slptr);
  40.             return (NULL);
  41.         }
  42.     }
  43.     else {
  44.         if (!srelation(slptr,"sdbcur",NULL)) {
  45.             db_done(slptr);
  46.             return (NULL);
  47.         }
  48.     }
  49.  
  50.     /* check the list of selected attributes */
  51.     if (!check_attrs(slptr)) {
  52.         db_done(slptr);
  53.         return (NULL);
  54.     }
  55.  
  56.     /* check for the existance of a "where" clause */
  57.     if (db_token() == WHERE) {
  58.         db_ntoken();
  59.  
  60.         /* parse the boolean expression */
  61.         if (!db_compile(slptr)) {
  62.             db_done(slptr);
  63.             return (FALSE);
  64.         }
  65.     }
  66.  
  67.     /* return the new selection structure */
  68.     return (slptr);
  69. }
  70.  
  71. /* db_retrieve - retrieve a set of tuples from a set of relations */
  72. struct sel *db_retrieve(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
  73.   char *fmt;
  74. {
  75.     struct sel *slptr;
  76.  
  77.     /* check for a command line */
  78.     if (fmt != NULL)
  79.         db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
  80.  
  81.     /* allocate a sel structure */
  82.     if ((slptr = malloc(sizeof(struct sel))) == NULL)
  83.         return (db_nerror(INSMEM));
  84.  
  85.     /* initialize the structure */
  86.     slptr->sl_rels = NULL;
  87.     slptr->sl_attrs = NULL;
  88.     slptr->sl_where = NULL;
  89.     slptr->sl_bindings = NULL;
  90.  
  91.     /* check for selected relations clause */
  92.     if (db_token() == ID) {
  93.         if (!get_srels(slptr)) {
  94.             db_done(slptr);
  95.             return (NULL);
  96.         }
  97.     }
  98.     else {
  99.         if (!srelation(slptr,"sdbcur",NULL)) {
  100.             db_done(slptr);
  101.             return (NULL);
  102.         }
  103.     }
  104.  
  105.     /* check the list of selected attributes */
  106.     if (!check_attrs(slptr)) {
  107.         db_done(slptr);
  108.         return (NULL);
  109.     }
  110.  
  111.     /* check for the existance of a "where" clause */
  112.     if (db_token() == WHERE) {
  113.         db_ntoken();
  114.  
  115.         /* parse the boolean expression */
  116.         if (!db_compile(slptr)) {
  117.             db_done(slptr);
  118.             return (FALSE);
  119.         }
  120.     }
  121.  
  122.     /* return the new selection structure */
  123.     return (slptr);
  124. }
  125.  
  126. /* db_done(slptr) - finish a selection */
  127. db_done(slptr)
  128.   struct sel *slptr;
  129. {
  130.     struct sattr *saptr,*nxtsa;
  131.     struct srel *srptr,*nxtsr;
  132.     struct binding *bdptr,*nxtbd;
  133.  
  134.     /* free the selected attribute blocks */
  135.     for (saptr = slptr->sl_attrs; saptr != NULL; saptr = nxtsa) {
  136.         nxtsa = saptr->sa_next;
  137.         if (saptr->sa_rname != NULL)
  138.             free(saptr->sa_rname);
  139.         free(saptr->sa_aname);
  140.         if (saptr->sa_name != NULL)
  141.             free(saptr->sa_name);
  142.         free(saptr);
  143.     }
  144.  
  145.     /* close the scans and free the selected relation blocks */
  146.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = nxtsr) {
  147.         nxtsr = srptr->sr_next;
  148.         if (srptr->sr_name != NULL)
  149.             free(srptr->sr_name);
  150.         db_rclose(srptr->sr_scan);
  151.         free(srptr);
  152.     }
  153.  
  154.     /* free the where clause */
  155.     db_fcode(slptr);
  156.  
  157.     /* free the user bindings */
  158.     for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = nxtbd) {
  159.         nxtbd = bdptr->bd_next;
  160.         free(bdptr);
  161.     }
  162.  
  163.     /* free the selection structure */
  164.     free(slptr);
  165. }
  166.  
  167. /* db_fetch(slptr) - fetch the next tuple from a selection */
  168. int db_fetch(slptr)
  169.   struct sel *slptr;
  170. {
  171.     struct srel *srptr;
  172.     struct binding *bdptr;
  173.  
  174.     /* clear the update flags */
  175.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
  176.         srptr->sr_update = FALSE;
  177.  
  178.     /* find a matching tuple */
  179.     while (process(slptr->sl_rels))
  180.         if (db_interpret(slptr)) {
  181.             for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = bdptr->bd_next)
  182.                 db_aget(bdptr->bd_attr,bdptr->bd_vtuple,bdptr->bd_vuser);
  183.             return (TRUE);
  184.         }
  185.  
  186.     /* no matches, failure return */
  187.     return (FALSE);
  188. }
  189.  
  190. /* db_update - update modified tuples */
  191. int db_update(slptr)
  192.   struct sel *slptr;
  193. {
  194.     struct srel *srptr;
  195.  
  196.     /* check each selected relation for updates */
  197.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
  198.         if (srptr->sr_update)
  199.             if (!db_rupdate(srptr->sr_scan))
  200.                 return (FALSE);
  201.  
  202.     /* return successfully */
  203.     return (TRUE);
  204. }
  205.  
  206. /* db_store - store tuples */
  207. int db_store(slptr)
  208.   struct sel *slptr;
  209. {
  210.     struct srel *srptr;
  211.  
  212.     /* check each selected relation for stores */
  213.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
  214.         if (srptr->sr_update)
  215.             if (!db_rstore(srptr->sr_scan))
  216.                 return (FALSE);
  217.  
  218.     /* return successfully */
  219.     return (TRUE);
  220. }
  221.  
  222. /* db_bind - bind a user buffer to the value of an attribute */
  223. int db_bind(slptr,rname,aname,avalue)
  224.   struct sel *slptr; char *rname,*aname,*avalue;
  225. {
  226.     struct binding *newbd;
  227.     struct srel *srptr;
  228.  
  229.     /* allocate and initialize a binding structure */
  230.     if ((newbd = malloc(sizeof(struct binding))) == NULL)
  231.         return (db_ferror(INSMEM));
  232.     newbd->bd_vuser = avalue;
  233.  
  234.     /* find the attribute */
  235.     if (!find_attr(slptr,rname,aname,&newbd->bd_vtuple,&srptr,&newbd->bd_attr))
  236.         return (FALSE);
  237.  
  238.     /* link the new binding into the binding list */
  239.     newbd->bd_next = slptr->sl_bindings;
  240.     slptr->sl_bindings = newbd;
  241.  
  242.     /* return successfully */
  243.     return (TRUE);
  244. }
  245.  
  246. /* db_get - get the value of an attribute */
  247. int db_get(slptr,rname,aname,avalue)
  248.   struct sel *slptr; char *rname,*aname,*avalue;
  249. {
  250.     struct srel *srptr;
  251.     struct attribute *aptr;
  252.     char *vptr;
  253.  
  254.     /* find the attribute */
  255.     if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
  256.         return (FALSE);
  257.  
  258.     /* get the attribute value */
  259.     db_aget(aptr,vptr,avalue);
  260.  
  261.     /* return successfully */
  262.     return (TRUE);
  263. }
  264.  
  265. /* db_put - put the value of an attribute */
  266. int db_put(slptr,rname,aname,avalue)
  267.   struct sel *slptr; char *rname,*aname,*avalue;
  268. {
  269.     struct srel *srptr;
  270.     struct attribute *aptr;
  271.     char *vptr;
  272.  
  273.     /* find the attribute */
  274.     if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
  275.         return (FALSE);
  276.  
  277.     /* put the attribute value */
  278.     db_aput(aptr,vptr,avalue);
  279.  
  280.     /* mark the tuple as updated */
  281.     srptr->sr_update = TRUE;
  282.  
  283.     /* return successfully */
  284.     return (TRUE);
  285. }
  286.  
  287. /* db_sattr - get selected attribute type, pointer, and length */
  288. int db_sattr(slptr,rname,aname,ptype,pptr,plen)
  289.   struct sel *slptr; char *rname,*aname;
  290.   int *ptype; char **pptr; int *plen;
  291. {
  292.     struct srel *srptr;
  293.     struct attribute *aptr;
  294.  
  295.     if (!find_attr(slptr,rname,aname,pptr,&srptr,&aptr))
  296.         return (FALSE);
  297.     *ptype = aptr->at_type;
  298.     *plen = aptr->at_size;
  299.     return (TRUE);
  300. }
  301.  
  302. /* get_sattrs(slptr) - get selected attributes */
  303. static get_sattrs(slptr)
  304.   struct sel *slptr;
  305. {
  306.     struct sattr *newsattr,*lastsattr;
  307.  
  308.     /* check for "*" or blank field meaning all attributes are selected */
  309.     if (db_token() == '*') {
  310.         db_ntoken();
  311.         return (TRUE);
  312.     }
  313.     else if (db_token() != ID)
  314.         return (TRUE);
  315.  
  316.     /* parse a list of attribute names */
  317.     lastsattr = NULL;
  318.     while (TRUE) {
  319.  
  320.         /* get attribute name */
  321.         if (db_ntoken() != ID)
  322.             return (db_ferror(SYNTAX));
  323.  
  324.         /* allocate a selected attribute structure */
  325.         if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
  326.             return (db_ferror(INSMEM));
  327.  
  328.         /* initialize the selected attribute structure */
  329.         newsattr->sa_next = NULL;
  330.  
  331.         /* save the attribute name */
  332.         if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
  333.             free(newsattr);
  334.             return (db_ferror(INSMEM));
  335.         }
  336.         strcpy(newsattr->sa_aname,dbv_tstring);
  337.  
  338.         /* check for "." meaning "<rel-name>.<att-name>" */
  339.         if (db_token() == '.') {
  340.             db_ntoken();
  341.  
  342.             /* the previous ID was really the relation name */
  343.             newsattr->sa_rname = newsattr->sa_aname;
  344.  
  345.             /* check for attribute name */
  346.             if (db_ntoken() != ID) {
  347.                 free(newsattr->sa_aname); free(newsattr);
  348.                 return (db_ferror(SYNTAX));
  349.             }
  350.  
  351.             /* save the attribute name */
  352.             if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
  353.                 free(newsattr->sa_aname); free(newsattr);
  354.                 return (db_ferror(INSMEM));
  355.             }
  356.             strcpy(newsattr->sa_aname,dbv_tstring);
  357.         }
  358.         else
  359.             newsattr->sa_rname = NULL;
  360.  
  361.         /* check for alternate attribute name */
  362.         if (db_token() == ID) {
  363.             db_ntoken();
  364.  
  365.             /* allocate space for the alternate name */
  366.             if ((newsattr->sa_name = malloc(strlen(dbv_tstring)+1)) == NULL) {
  367.                 if (newsattr->sa_rname != NULL)
  368.                     free(newsattr->sa_rname);
  369.                 free(newsattr->sa_aname);
  370.                 free(newsattr);
  371.                 return (db_ferror(INSMEM));
  372.             }
  373.             strcpy(newsattr->sa_name,dbv_tstring);
  374.         }
  375.         else
  376.             newsattr->sa_name = NULL;
  377.  
  378.         /* link the selected attribute structure into the list */
  379.         if (lastsattr == NULL)
  380.             slptr->sl_attrs = newsattr;
  381.         else
  382.             lastsattr->sa_next = newsattr;
  383.         lastsattr = newsattr;
  384.  
  385.         /* check for more attributes */
  386.         if (db_token() != ',')
  387.             break;
  388.         db_ntoken();
  389.     }
  390.  
  391.     /* return successfully */
  392.     return (TRUE);
  393. }
  394.  
  395. /* get_srels(slptr) - get selected relations */
  396. static get_srels(slptr)
  397.   struct sel *slptr;
  398. {
  399.     char rname[KEYWORDMAX+1],*aname;
  400.  
  401.     /* get the list of selected relations */
  402.     while (TRUE) {
  403.  
  404.         /* check for relation name */
  405.         if (db_ntoken() != ID)
  406.             return (db_ferror(SYNTAX));
  407.         strcpy(rname,dbv_tstring);
  408.  
  409.         /* check for alternate relation name */
  410.         if (db_token() == ID) {
  411.             db_ntoken();
  412.             aname = dbv_tstring;
  413.         }
  414.         else
  415.             aname = NULL;
  416.  
  417.         /* add the relation name to the list */
  418.         if (!srelation(slptr,rname,aname))
  419.             return (FALSE);
  420.  
  421.         /* check for more selected relations */
  422.         if (db_token() != ',')
  423.             break;
  424.         db_ntoken();
  425.     }
  426.  
  427.     /* return successfully */
  428.     return (TRUE);
  429. }
  430.  
  431. /* srelation - select a relation */
  432. static srelation(slptr,rname,aname)
  433.   struct sel *slptr; char *rname,*aname;
  434. {
  435.     struct srel *srptr,*newsrel;
  436.  
  437.     /* allocate a new selected relation structure */
  438.     if ((newsrel = malloc(sizeof(struct srel))) == NULL)
  439.         return (db_ferror(INSMEM));
  440.  
  441.     /* initialize the new selected relation structure */
  442.     newsrel->sr_ctuple = FALSE;
  443.     newsrel->sr_update = FALSE;
  444.     newsrel->sr_next = NULL;
  445.  
  446.     /* open the relation */
  447.     if ((newsrel->sr_scan = db_ropen(rname)) == NULL) {
  448.         free(newsrel);
  449.         return (FALSE);
  450.     }
  451.  
  452.     /* check for alternate relation name */
  453.     if (aname != NULL) {
  454.  
  455.         /* allocate space for the alternate name */
  456.         if ((newsrel->sr_name = malloc(strlen(aname)+1)) == NULL) {
  457.             free(newsrel);
  458.             return (db_ferror(INSMEM));
  459.         }
  460.         strcpy(newsrel->sr_name,aname);
  461.     }
  462.     else
  463.         newsrel->sr_name = NULL;
  464.  
  465.     /* find the end of the list of relation names */
  466.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
  467.         if (srptr->sr_next == NULL)
  468.             break;
  469.  
  470.     /* link the new selected relation structure into the list */
  471.     if (srptr == NULL)
  472.         slptr->sl_rels = newsrel;
  473.     else
  474.         srptr->sr_next = newsrel;
  475.  
  476.     /* return successfully */
  477.     return (TRUE);
  478. }
  479.  
  480. /* check_attrs(slptr) - check the list of selected attributes */
  481. static int check_attrs(slptr)
  482.   struct sel *slptr;
  483. {
  484.     struct sattr *saptr;
  485.  
  486.     /* check for all attributes selected */
  487.     if (slptr->sl_attrs == NULL)
  488.         return (all_attrs(slptr));
  489.  
  490.     /* check each selected attribute */
  491.     for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next)
  492.         if (!find_attr(slptr,saptr->sa_rname,saptr->sa_aname,
  493.                         &saptr->sa_aptr,&saptr->sa_srel,&saptr->sa_attr))
  494.             return (FALSE);
  495.  
  496.     /* return successfully */
  497.     return (TRUE);
  498. }
  499.  
  500. /* all_attrs(slptr) - create a list of all attributes */
  501. static int all_attrs(slptr)
  502.   struct sel *slptr;
  503. {
  504.     struct sattr *newsattr,*lastsattr;
  505.     struct srel *srptr;
  506.     struct attribute *aptr;
  507.     int i,astart;
  508.  
  509.     /* loop through each selected relation */
  510.     lastsattr = NULL;
  511.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
  512.  
  513.         /* loop through each attribute within the relation */
  514.         astart = 1;
  515.         for (i = 0; i < NATTRS; i++) {
  516.  
  517.             /* get a pointer to the current attribute */
  518.             aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
  519.  
  520.             /* check for last attribute */
  521.             if (aptr->at_name[0] == 0)
  522.                 break;
  523.  
  524.             /* allocate a new selected attribute structure */
  525.             if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
  526.                 return (db_ferror(INSMEM));
  527.  
  528.             /* initialize the new selected attribute structure */
  529.             newsattr->sa_name = NULL;
  530.             newsattr->sa_srel = srptr;
  531.             newsattr->sa_aptr = srptr->sr_scan->sc_tuple + astart;
  532.             newsattr->sa_attr = aptr;
  533.             newsattr->sa_next = NULL;
  534.  
  535.             /* save the relation name */
  536.             if ((newsattr->sa_rname = malloc(RNSIZE+1)) == NULL) {
  537.                 free(newsattr);
  538.                 return (db_ferror(INSMEM));
  539.             }
  540.             strncpy(newsattr->sa_rname,
  541.                     srptr->sr_scan->sc_relation->rl_name,
  542.                     RNSIZE);
  543.             newsattr->sa_rname[RNSIZE] = 0;
  544.  
  545.             /* save the attribute name */
  546.             if ((newsattr->sa_aname = malloc(ANSIZE+1)) == NULL) {
  547.                 free(newsattr->sa_rname);
  548.                 free(newsattr);
  549.                 return (db_ferror(INSMEM));
  550.             }
  551.             strncpy(newsattr->sa_aname,
  552.                     srptr->sr_scan->sc_relation->rl_header.hd_attrs[i].at_name,
  553.                     ANSIZE);
  554.             newsattr->sa_aname[ANSIZE] = 0;
  555.  
  556.             /* link the selected attribute into the list */
  557.             if (lastsattr == NULL)
  558.                 slptr->sl_attrs = newsattr;
  559.             else
  560.                 lastsattr->sa_next = newsattr;
  561.             lastsattr = newsattr;
  562.  
  563.             /* update the attribute start */
  564.             astart += aptr->at_size;
  565.         }
  566.     }
  567.  
  568.     /* return successfully */
  569.     return (TRUE);
  570. }
  571.  
  572. /* find_attr - find a named attribute */
  573. static int find_attr(slptr,rname,aname,paptr,psrel,pattr)
  574.   struct sel *slptr; char *rname,*aname;
  575.   char **paptr; struct attribute **pattr;
  576. {
  577.     /* check for unqualified or qualified attribute names */
  578.     if (rname == NULL)
  579.         return (uattr(slptr,aname,paptr,psrel,pattr));
  580.     else
  581.         return (qattr(slptr,rname,aname,paptr,psrel,pattr));
  582. }
  583.  
  584. /* uattr - find an unqualified attribute name */
  585. static int uattr(slptr,aname,paptr,psrel,pattr)
  586.   struct sel *slptr; char *aname;
  587.   char **paptr; struct srel **psrel; struct attribute **pattr;
  588. {
  589.     struct srel *srptr;
  590.     struct attribute *aptr;
  591.     int i,astart;
  592.  
  593.     /* loop through each selected relation */
  594.     *pattr = NULL;
  595.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
  596.  
  597.         /* loop through each attribute within the relation */
  598.         astart = 1;
  599.         for (i = 0; i < NATTRS; i++) {
  600.  
  601.             /* get a pointer to the current attribute */
  602.             aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
  603.  
  604.             /* check for last attribute */
  605.             if (aptr->at_name[0] == 0)
  606.                 break;
  607.  
  608.             /* check for attribute name match */
  609.             if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
  610.                 if (*pattr != NULL)
  611.                     return (db_ferror(ATAMBG));
  612.                 *paptr = srptr->sr_scan->sc_tuple + astart;
  613.                 *psrel = srptr;
  614.                 *pattr = aptr;
  615.             }
  616.  
  617.             /* update the attribute start */
  618.             astart += aptr->at_size;
  619.         }
  620.     }
  621.  
  622.     /* check whether attribute was found */
  623.     if (*pattr == NULL)
  624.         return (db_ferror(ATUNDF));
  625.  
  626.     /* return successfully */
  627.     return (TRUE);
  628. }
  629.  
  630. /* qattr - find a qualified attribute name */
  631. static int qattr(slptr,rname,aname,paptr,psrel,pattr)
  632.   struct sel *slptr; char *rname,*aname;
  633.   char **paptr; struct srel **psrel; struct attribute **pattr;
  634. {
  635.     struct srel *srptr;
  636.     struct attribute *aptr;
  637.     char *crname;
  638.     int i,astart;
  639.  
  640.     /* loop through each selected relation */
  641.     for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
  642.  
  643.         /* get relation name */
  644.         if ((crname = srptr->sr_name) == NULL)
  645.             crname = srptr->sr_scan->sc_relation->rl_name;
  646.  
  647.         /* check for relation name match */
  648.         if (db_sncmp(rname,crname,RNSIZE) == 0) {
  649.  
  650.             /* loop through each attribute within the relation */
  651.             astart = 1;
  652.             for (i = 0; i < NATTRS; i++) {
  653.  
  654.                 /* get a pointer to the current attribute */
  655.                 aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
  656.  
  657.                 /* check for last attribute */
  658.                 if (aptr->at_name[0] == 0)
  659.                     break;
  660.  
  661.                 /* check for attribute name match */
  662.                 if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
  663.                     *paptr = srptr->sr_scan->sc_tuple + astart;
  664.                     *psrel = srptr;
  665.                     *pattr = aptr;
  666.                     return (TRUE);
  667.                 }
  668.  
  669.                 /* update the attribute start */
  670.                 astart += aptr->at_size;
  671.             }
  672.  
  673.             /* attribute name not found */
  674.             return (db_ferror(ATUNDF));
  675.         }
  676.     }
  677.  
  678.     /* relation name not found */
  679.     return (db_ferror(RLUNDF));
  680. }
  681.  
  682. /* process(srptr) - process each tuple in a relation cross-product */
  683. static int process(srptr)
  684.   struct srel *srptr;
  685. {
  686.     /* always get a new tuple if this is the last relation in the list */
  687.     if (srptr->sr_next == NULL) {
  688.  
  689.         /* check for beginning of new scan */
  690.         if (!srptr->sr_ctuple)
  691.             db_rbegin(srptr->sr_scan);
  692.  
  693.         /* return the next tuple in the relation */
  694.         return (srptr->sr_ctuple = db_rfetch(srptr->sr_scan));
  695.     }
  696.  
  697.     /* check for beginning of new scan */
  698.     if (!srptr->sr_ctuple) {
  699.         db_rbegin(srptr->sr_scan);
  700.  
  701.         /* get the first tuple */
  702.         if (!db_rfetch(srptr->sr_scan))
  703.             return (FALSE);
  704.     }
  705.  
  706.     /* look for a match with the remaining relations in list */
  707.     while (!process(srptr->sr_next))
  708.  
  709.         /* get the next tuple in the scan */
  710.         if (!db_rfetch(srptr->sr_scan))
  711.             return (srptr->sr_ctuple = FALSE);
  712.  
  713.     /* found a match at this level */
  714.     return (srptr->sr_ctuple = TRUE);
  715. }
  716.  
  717. /* db_aget - get the value of an attribute */
  718. db_aget(aptr,vptr,avalue)
  719.   struct attribute *aptr; char *vptr,*avalue;
  720. {
  721.     int i;
  722.  
  723.     /* get the attribute value */
  724.     for (i = 0; i < aptr->at_size; i++)
  725.         *avalue++ = vptr[i];
  726.     *avalue = EOS;
  727. }
  728.  
  729. /* db_aput - put the value of an attribute */
  730. db_aput(aptr,vptr,avalue)
  731.   struct attribute *aptr; char *vptr,*avalue;
  732. {
  733.     int i;
  734.  
  735.     /* initialize counter */
  736.     i = 0;
  737.  
  738.     /* right justify numbers */
  739.     if (aptr->at_type == TNUM)
  740.         for (; i < aptr->at_size - strlen(avalue); i++)
  741.             vptr[i] = ' ';
  742.  
  743.     /* put the attribute value */
  744.     for (; i < aptr->at_size; i++)
  745.         if (*avalue == 0)
  746.             vptr[i] = 0;
  747.         else
  748.             vptr[i] = *avalue++;
  749. }
  750.  
  751. :
  752.         ___