home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / database / ingres / 1130 < prev    next >
Encoding:
Text File  |  1992-08-12  |  4.8 KB  |  150 lines

  1. Newsgroups: comp.databases.ingres
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!darwin.sura.net!uvaarpa!cv3.cv.nrao.edu!mail-to-news-gateway
  3. From: CS_PAUL@GSBVAX.UCHICAGO.EDU (Paul Ford 312/702-0335)
  4. Subject: RE: Linked List Problem
  5. Message-ID: <920812110140.20a00063@GSBVAX.UCHICAGO.EDU>
  6. Sender: root@nrao.edu (Operator)
  7. Organization: National Radio Astronomy Observatory
  8. Date: Wed, 12 Aug 1992 16:01:40 GMT
  9. Lines: 139
  10.  
  11. Jeff Rule (11 Aug 92) writes:
  12.  
  13. >I have a problem with the embedded SQL portion of INGRES. I want to fetch data
  14. >into a linked list. The declaration is normally something like:
  15. >
  16. >struct tag
  17. >{
  18. >     char   var1[20];
  19. >     struct tag *next;
  20. >};
  21. >
  22. >But, when the precompiler gets through with this, it turns the *next into
  23. >*...FIELD ERROR. I've temporarily defined the next pointer to be void. I don't
  24. >get any errors, but don't know what the results will be. Any suggestions?
  25. >
  26. >Jeff Rule/Apple Computer rule@apple.com
  27.  
  28. Are you really using the name 'next'?  This is a reserved SQL keyword (see
  29. appendix A of the _INGRES/SQL Reference Manual_).  That may be part of the
  30. problem.
  31.  
  32. I just tried some sample code with INGRES 6.4/01 (vax.vms/02) under VMS 5.4-3
  33. and it compiled and ran without error.  My declarations were as follows:
  34.  
  35.     exec sql BEGIN DECLARE SECTION ;
  36.  
  37.     struct aa
  38.     {
  39.         struct aa * nextitem ;
  40.         char name[40] ;
  41.     } ;
  42.  
  43.     typedef struct aa aa_t ;
  44.  
  45.     aa_t   list[100] ;
  46.     aa_t * list_head ;
  47.     aa_t * listp ;
  48.  
  49.     exec sql END DECLARE SECTION ;
  50.  
  51. If you still have problems (perhaps due to an earlier version of INGRES)
  52. you can try a refinement of your "void *" trick.   Make two declarations, a
  53. real one for the C compiler  and a fake one for the embedded preprocessor.
  54.  
  55.     /* Real declaration, seen only be the C compiler. */
  56.     struct aa
  57.     {
  58.         struct aa * nextitem ;
  59.         char name[40] ;
  60.     } ;
  61.  
  62.  
  63. #if 1==0  /* Fake declaration, seen only by the esqlc preprocessor. */
  64.  
  65.     exec sql BEGIN DECLARE SECTION ;
  66.     struct aa
  67.     {
  68.         void * nextitem ;
  69.         char name[40] ;
  70.     } ;
  71.     exec sql END DECLARE SECTION ;
  72.  
  73. #endif
  74.  
  75. This works because the embedded preprocessor ignores #if/#endif C
  76. preprocessor statements and sees the fake struct declaration.
  77.  
  78. One might wonder if there is a portability problem associated with the fact
  79. that sizeof(void *) can't be assumed to be the same as  sizeof(struct aa*).
  80. I believe there isn't based on my understanding of how the embedded
  81. preprocessor generates C code.
  82.  
  83. Esqlc does need to know the sizes of atomic types (long, short, float,
  84. double, char arrays, etc.) that it actually stuffs data into or reads data
  85. from during queries and form operations.  But it doesn't try to compute
  86. structure member offsets, it just places the literal text of the member
  87. reference in the function calls it generates.  It does need to know the
  88. size of the member, but it leaves the offset and address computation to the
  89. C compiler.  As long as the real and fake declarations agree where their
  90. use overlaps (e.g.,  name is char[40] in both), everything should work
  91. fine.
  92.  
  93. In fact, in the fake declaration, you can go one step further and remove
  94. the nextitem member altogether.  This fake declaration for esqlc
  95. works as well as the one above:
  96.  
  97.     #if 1==0  /* Fake declaration, seen only by the esqlc preprocessor. */
  98.  
  99.         exec sql BEGIN DECLARE SECTION ;
  100.         struct aa
  101.         {
  102.             /* struct aa * nextitem ; */
  103.             char name[40] ;
  104.         } ;
  105.         exec sql END DECLARE SECTION ;
  106.  
  107.     #endif
  108.  
  109.  
  110. All of this is pretty ugly, and doesn't seem necessary under 6.4 in this
  111. particular case.  However there is a situation where we use this fake
  112. declaration trick all the time -- to declare function arguments passed
  113. using ANSI C function prototypes. The advantages of ANSI C function
  114. prototypes far outweigh the inconvenience of ESQLC's inability to recognize
  115. them, and hence make this trick very worthwhile.  Here's how we do it.
  116.  
  117.     /* Pre-ANSI C traditional function definition. ESQLC declarations fit
  118.        right in. */
  119.  
  120.     char * sample_function(id, name)
  121.     exec sql BEGIN DECLARE SECTION ;
  122.       long id  ;
  123.       char * name ;
  124.     exec sql END DECLARE SECTION ;
  125.     {
  126.         ...
  127.     }
  128.  
  129.     /* ANSI C function definition using prototypes. ESQLC declarations
  130.        require the fake declaration trick. */
  131.  
  132.     char * sample_function( long id, const char * name )
  133.     #if 1==0 /* for esqlc */
  134.     exec sql BEGIN DECLARE SECTION ;
  135.       long id  ;
  136.       char * name ;
  137.     exec sql END DECLARE SECTION ;
  138.     #endif
  139.     {
  140.         ...
  141.     }
  142.  
  143. Paul Ford
  144. --------------------------------------------------------------------------
  145. GSB Computing Services                  312.702.0335
  146. University of Chicago                   cs_paul@gsbvax.uchicago.edu
  147. 1101 E. 58th Street
  148. Chicago IL 60637
  149. --------------------------------------------------------------------------
  150.