dyn_funcs.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:24k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  dyn_funcs.c  -  functions of GNU dynamic SQL
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by Konstantin Dyshlevoi.
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contacts: gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: dyn_funcs.c,v 1.246 1997/04/03 13:35:23 kml Exp $ */
  28. #include "setup_os.h"
  29. #ifdef HAVE_STDARG_H
  30. # include <stdarg.h>
  31. #endif
  32. #include "gsqltrn.h"
  33. #include "xmem.h"
  34. #include "dyn_funcs.h"
  35. #include "sql.h"
  36. #include "global.h"
  37. /* states of declared cursor */
  38. #define CUR_CLOSED   0
  39. #define HAS_CUR_ROW  1
  40. #define NO_CUR_ROW   2
  41. /* interpreter commands */
  42. #define COM_START  0
  43. #define COM_FETCH  1
  44. #define COM_CLOSE  2
  45. #define COM_DELETE 3
  46. #define XFREE(v)                {if (v) xfree (v); v = NULL;     }
  47. #define STRCPY(src, dest) {if (src) dest = savestring(src);}
  48. #define CHECK_FREE_DATA(val, cnt)
  49. {
  50.   int i;
  51.   for (i = 0; i < (cnt); i++)
  52.     if ((val)->data_allocated_size)
  53.       XFREE ((val)->data);
  54. }
  55. struct s_cursor {
  56.   char            *name;
  57.   char            *stmt_name;
  58.   char             status;
  59.   struct s_stmt   *stmt_ptr;
  60.   i4_t             segm; /* virtual address of made cursor segment */
  61.   struct s_cursor *next;
  62. };
  63. struct s_descr {
  64.   char           *name;
  65.   SQL_DESCR       body_ptr;
  66.   struct s_descr *next;
  67. };
  68. static struct s_stmt   *fir_stmt   = NULL;
  69. static struct s_cursor *fir_cursor = NULL;
  70. static struct s_descr  *fir_descr  = NULL;
  71. i4_t SQL__prepare_stmt (char *stmt_text, char *stmt_name,
  72.                          compiled_t **prep_res);
  73. i4_t server_seg_del (i4_t seg_cnt, i4_t *seg_vadr, i4_t mem_ptr);
  74. i4_t SQL__get_cursor_segm (char *cursor_name, struct s_stmt *stmt);
  75. struct module interp_mdl;
  76. #define typ_user2sql(user_type) get_sqltype_code(user_type)
  77. #define typ_sql2user(sql_type)  get_dyn_sqltype_code(sql_type)
  78. static char *
  79. cat_strings (i4_t str_cnt, ...)
  80. {
  81.   i4_t i, len = 0;
  82.   va_list args;
  83.   char *str, *cur_pos, *res_str = NULL;
  84.   va_start (args, str_cnt);
  85.   for (i = 0; i < str_cnt; i++)
  86.     {
  87.       str = va_arg (args, char *);
  88.       if (str)
  89.         len += strlen (str);
  90.     }
  91.   va_end (args);
  92.   
  93.   if (len)
  94.     {
  95.       res_str = TYP_ALLOC (len+1, char);
  96.       cur_pos = res_str;
  97.       va_start (args, str_cnt);
  98.       for (i = 0; i < str_cnt; i++)
  99.         {
  100.           str = va_arg (args, char *);
  101.           if (str)
  102.             {
  103.               strcpy (cur_pos, str);
  104.               cur_pos += strlen (str);
  105.             }
  106.         }
  107.       cur_pos[0] = 0;
  108.       va_end (args);
  109.     }
  110.       
  111.   return res_str;
  112. } /* cat_strings */
  113. SQL_DESCR
  114. SQL__allocate_descr (char *descr_name, i4_t maximum)
  115. {
  116.   struct s_descr  *descr;
  117.   SQL_DESCR        body;
  118.   
  119.   if (!descr_name || !(*descr_name))
  120.     return NULL; /* incorrect name of descriptor */
  121.   
  122.   if (SQL__get_descr (descr_name))
  123.     return NULL; /* there is already descriptor with this name */
  124.   descr = TYP_ALLOC (1, struct s_descr);
  125.   STRCPY (descr_name, descr->name);
  126.   descr->body_ptr = body = TYP_ALLOC (1, sql_descr_t);
  127.   descr->next = fir_descr;
  128.   fir_descr = descr;
  129.   body->maximum = maximum;
  130.   if (maximum)
  131.     {
  132.       body->values = TYP_ALLOC (maximum, sql_descr_element_t);
  133.       body->alloc_cnt = maximum;
  134.     }
  135.   
  136.   return body;
  137. } /* allocate_descr */
  138. void
  139. SQL__deallocate_descr (SQL_DESCR *descr_ptr)
  140. {
  141.   struct s_descr *cur_descr, *pred_descr;
  142.   SQL_DESCR descr;
  143.   if (!descr_ptr)
  144.     return;
  145.   descr = *descr_ptr;
  146.   *descr_ptr = NULL;
  147.   for (cur_descr = fir_descr, pred_descr = NULL; cur_descr;
  148.        pred_descr = cur_descr, cur_descr = cur_descr->next)
  149.     if (cur_descr->body_ptr == descr)
  150.       break;
  151.   if (cur_descr)
  152.     {
  153.       CHECK_FREE_DATA (descr->values, descr->alloc_cnt);
  154.       XFREE (descr->values);
  155.       XFREE (cur_descr->name);
  156.       XFREE (cur_descr->body_ptr);
  157.       if (pred_descr)
  158.         pred_descr->next = cur_descr->next;
  159.       else
  160.         fir_descr = cur_descr->next;
  161.       xfree (cur_descr);
  162.     }
  163. } /* deallocate_descr */
  164. SQL_DESCR
  165. SQL__get_descr (char *descr_name)
  166. {
  167.   struct s_descr *cur_descr = NULL;
  168.   SQL_DESCR body_ptr = NULL;
  169.   
  170.   if (descr_name)
  171.     for (cur_descr = fir_descr; cur_descr; cur_descr = cur_descr->next)
  172.       if (!strcmp (descr_name, cur_descr->name))
  173.         break;
  174.   if (cur_descr)
  175.     body_ptr = cur_descr->body_ptr;
  176.   return body_ptr;
  177. } /* get_descr */
  178. static struct s_stmt *
  179. SQL__find_stmt (char *stmt_name)
  180. {
  181.   struct s_stmt *cur_stmt = NULL;
  182.   
  183.   if (stmt_name)
  184.     for (cur_stmt = fir_stmt; cur_stmt; cur_stmt = cur_stmt->next)
  185.       if (!strcmp (stmt_name, cur_stmt->name))
  186.         break;
  187.   return cur_stmt;
  188. } /* find_stmt */
  189. static
  190. struct s_cursor *
  191. SQL__find_cursor (char *cursor_name)
  192. {
  193.   struct s_cursor *cur_cursor = NULL;
  194.   
  195.   if (cursor_name)
  196.     for (cur_cursor = fir_cursor; cur_cursor;
  197.          cur_cursor = cur_cursor->next)
  198.       if (!strcmp (cursor_name, cur_cursor->name))
  199.         break;
  200.   return cur_cursor;
  201. } /* find_cursor */
  202. /* all following functions return error code = SQLCODE */
  203. int
  204. SQL__prepare (char *stmt_name, char *stmt_text)
  205. {
  206.   struct s_stmt *stmt = SQL__find_stmt (stmt_name);
  207.   compiled_t *prep_res;
  208.   i4_t err, do_out, n, i;
  209.   sql_descr_element_t *val_to;
  210.   prep_elem_t *val_from;
  211.   
  212.   if (stmt && (err = SQL__deallocate_prepare (stmt_name)))
  213.     return err;
  214.   
  215.   /* statement creation */
  216.   if (!stmt_name || !(*stmt_name))
  217.     return -DS_NMARG;
  218.   
  219.   stmt = TYP_ALLOC (1, struct s_stmt);
  220.   STRCPY (stmt_name, stmt->name);
  221.   stmt->next = fir_stmt;
  222.   fir_stmt = stmt;
  223.   if ((err = SQL__prepare_stmt (stmt_text, stmt_name, &prep_res)))
  224.     return err;
  225.   /* filling of preparing result to statement descriptor */
  226.   if (!prep_res->objects)
  227.     {
  228.       stmt->sectnum = -3;
  229.       return 0;
  230.     }
  231.   stmt->sectnum = prep_res->objects->object;
  232.   if (prep_res->objects->cursor_name)
  233.     stmt->dep_on_cursor = SQL__find_cursor (prep_res->objects->cursor_name);
  234.   if (!*prep_res->objects->table_name)
  235.     stmt->table_name = NULL;
  236.   else
  237.     STRCPY (prep_res->objects->table_name, stmt->table_name);
  238.   if (!*prep_res->objects->table_owner)
  239.     stmt->table_owner = NULL;
  240.   else
  241.     STRCPY (prep_res->objects->table_owner, stmt->table_owner);
  242.   
  243.   if (prep_res->stored.comp_type == COMP_DYNAMIC_SIMPLE)
  244.     stmt->segm = prep_res->stored.comp_data_t_u.segm;
  245.   else
  246.     stmt->mem_ptr = prep_res->stored.comp_data_t_u.seg_ptr;
  247.   
  248.   n = stmt->in_descr.count = prep_res->objects->descr_in.descr_t_len;
  249.   val_from = prep_res->objects->descr_in.descr_t_val;
  250.   val_to = stmt->in_descr.values = TYP_ALLOC (n, sql_descr_element_t);
  251.   for (do_out = 1; do_out >= 0; do_out--)
  252.     {
  253.       for (i = 0; i < n; i++, val_to++, val_from++)
  254.         {
  255.           val_to->type = val_from->type;
  256.           val_to->length = val_from->length;
  257.           val_to->nullable = val_from->nullable;
  258.           val_to->unnamed = (val_from->name) ? 0 : 1;
  259.           STRCPY (val_from->name, val_to->name);
  260.         }
  261.       if (do_out)
  262.         {
  263.           n = stmt->out_descr.count = prep_res->objects->descr_out.descr_t_len;
  264.           val_from = prep_res->objects->descr_out.descr_t_val;
  265.           val_to = stmt->out_descr.values =
  266.             TYP_ALLOC (n, sql_descr_element_t);
  267.         }
  268.     }
  269.   return 0;
  270. } /* prepare */
  271. int
  272. SQL__deallocate_prepare (char *stmt_name)
  273. {
  274.   struct s_stmt *stmt = NULL, *cur_stmt, *next_stmt, *pred_stmt = NULL;
  275.   i4_t i, err, cursor_cnt = 0, *seg_vadr;
  276.   sql_descr_element_t *in_values, *out_values;
  277.   struct s_cursor *cur_cursor, *pred_cursor, *next_cursor;
  278.   
  279.   if (stmt_name)
  280.     for (stmt = fir_stmt; stmt; pred_stmt = stmt, stmt = stmt->next)
  281.       if (!strcmp (stmt_name, stmt->name))
  282.         break;
  283.   if (!stmt)
  284.     return -DS_STMT;
  285.   /* checking of cursors states */
  286.   if (stmt->mem_ptr) /* statement can have cursors depended on it */
  287.     {
  288.       
  289.       for (cur_cursor = fir_cursor; cur_cursor;
  290.            cur_cursor = cur_cursor->next, cursor_cnt++)
  291.         if (cur_cursor->stmt_ptr == stmt)
  292.           if (cur_cursor->status != CUR_CLOSED)
  293.             break;
  294.       if (cur_cursor)
  295.         return -DS_CURST;
  296.     }
  297.   if (stmt->segm)
  298.     {
  299.       seg_vadr = TYP_ALLOC (cursor_cnt + 1, i4_t);
  300.       seg_vadr[0] = stmt->segm;
  301.       if (cursor_cnt)
  302.         for (i = 0, cur_cursor = fir_cursor, pred_cursor = NULL; cur_cursor;
  303.              pred_cursor = cur_cursor, cur_cursor = next_cursor)
  304.           {
  305.             next_cursor = cur_cursor->next;
  306.             if (cur_cursor->stmt_ptr == stmt)
  307.               /* current cursor was declared for argument statement */
  308.               {
  309.                 seg_vadr[++i] = cur_cursor->segm;
  310.                 /* making DEALLOCATE PREPARE for all prepared statement *
  311.                  * that are being depended on current cursor            */
  312.                 for (cur_stmt = fir_stmt; cur_stmt; cur_stmt = next_stmt)
  313.                   {
  314.                     next_stmt = cur_stmt->next;
  315.                     if (cur_stmt->dep_on_cursor == cur_cursor)
  316.                       if ((err = SQL__deallocate_prepare (cur_stmt->name)) < 0)
  317.                         return err;
  318.                   }
  319.                 /* making 'deallocate' cursor */
  320.                 if (cur_cursor->stmt_name)
  321.                   /* cursor made by DECLARE CURSOR */
  322.                   {
  323.                     cur_cursor->stmt_ptr = NULL;
  324.                     cur_cursor->segm = 0;
  325.                   }
  326.                 else
  327.                   /* cursor made by ALLOCATE CURSOR */
  328.                   {
  329.                     XFREE (cur_cursor->name);
  330.                     if (pred_cursor)
  331.                       pred_cursor->next = next_cursor;
  332.                     else
  333.                       fir_cursor = next_cursor;
  334.                     xfree (cur_cursor);
  335.                   }
  336.               }
  337.           }
  338.       if ((err = server_seg_del (cursor_cnt + 1, seg_vadr, stmt->mem_ptr)) < 0)
  339.         return err;
  340.       xfree (seg_vadr);
  341.   
  342.       in_values  = stmt->in_descr.values;
  343.       out_values = stmt->out_descr.values;
  344.   
  345.       for (i = 0; i < stmt->in_descr.count; i++)
  346.         {
  347.           XFREE ((in_values[i]).name);
  348.           XFREE ((in_values[i]).data);
  349.         }
  350.       for (i = 0; i < stmt->out_descr.count; i++)
  351.         {
  352.           XFREE ((out_values[i]).name);
  353.           XFREE ((out_values[i]).data);
  354.         }
  355.       XFREE (stmt->table_name);
  356.       XFREE (stmt->table_owner);
  357.       XFREE (stmt->in_descr.values);
  358.       XFREE (stmt->out_descr.values);
  359.     }
  360.   XFREE (stmt->name);
  361.   
  362.   if (pred_stmt)
  363.     pred_stmt->next = stmt->next;
  364.   else
  365.     fir_stmt = stmt->next;
  366.   xfree (stmt);
  367.   return 0;
  368. } /* deallocate_prepare */
  369. /* In all following fuctions working with descriptors:              *
  370.  * 'using_input' must be correctly filled accordingly description   *
  371.  * of 'stmt_name' input.                                            *
  372.  * Some fields of 'using_output' can be not filled. In this case    *
  373.  * the function will make correspondent result value description.   *
  374.  * In all cases function makes for output-descriptor memory         *
  375.  * allocation for DATA. So we recommend for users of this functions *
  376.  * don't use the same descriptor for input & output description.    */
  377. int
  378. SQL__describe (char *stmt_name, i4_t is_input, SQL_DESCR descr)
  379. /* for internal representation of descriptors (struct sql_descr_t)
  380.    we have the same copies of pointers to strings (fields
  381.    name & data in descriptor elements). But in realization
  382.    of SQL dynamic operators 'GET & SET DESCRIPTOR' we must
  383.    use user's places for strings or generate new ones              */
  384. /* FOR USER of this function (instead of dynamic SQL operator):
  385.    you can't use pointers to strings from descriptor after next
  386.    statement 'stmt_name' preparing                              */
  387. {
  388.   struct s_stmt *stmt = SQL__find_stmt (stmt_name);
  389.   SQL_DESCR      src;
  390.   i4_t            i;
  391.   if (!stmt)
  392.     return -DS_STMT;
  393.   if (!descr)
  394.     return -DS_DESCR;
  395.   src = (is_input) ? &(stmt->in_descr) : &(stmt->out_descr);
  396.   if (src->count > descr->alloc_cnt)
  397.     if (descr->maximum)
  398.       return -DS_DESCRLEN;
  399.     else
  400.       CHECK_ARR_SIZE (descr->values, descr->alloc_cnt,
  401.                       src->count, sql_descr_element_t);
  402.   descr->count = src->count;
  403.   CHECK_FREE_DATA (descr->values, descr->count);
  404.   TYP_COPY (src->values, descr->values, src->count, sql_descr_element_t);
  405.   for (i = 0; i < descr->count; i++)
  406.     ((descr->values)[i]).type = typ_sql2user (((src->values)[i]).type);
  407.   return 0;
  408. } /* describe */
  409. static int
  410. SQL_d_interpret (i4_t segm, int command, SQL_DESCR using_descr, struct s_stmt *stmt)
  411. /* segm can be = 0 => command must be = -1 (rollback) or -2 (commit) */
  412. {
  413.   static gsql_parms  args        = { 0, 0, 0, 0, NULL};
  414.   static int         args_max    = 0;
  415.   static double     *mk_args     = NULL;
  416.   static int         mk_args_max = 0;
  417.   
  418.   SQL_DESCR          stmt_descr = NULL;
  419.   i4_t need_arg = 0, need_res = 0, need_cnt = 0;
  420.   i4_t need_type, real_type, need_length, err = 0;
  421.   sql_descr_element_t *val, *need_val;
  422.   gsql_parm           *arg;
  423.   int                  i;
  424.   if (!segm)
  425.     {
  426.       switch (command)
  427.         {
  428.         case -2: /* commit   */
  429.           _SQL_commit();
  430.           break;
  431.         case -1: /* rollback */
  432.           _SQL_rollback();
  433.           break;
  434.         default:
  435.           err = -ER_8;
  436.         }
  437.       return err;
  438.     }
  439.   
  440.   interp_mdl.segment = segm;
  441.   if (stmt)
  442.     if (command == COM_START)
  443.       {
  444.         stmt_descr = &(stmt->in_descr);
  445.         need_cnt = stmt_descr->count;
  446.         if (need_cnt)
  447.           need_arg++;
  448.       }
  449.     else
  450.       if (command == COM_FETCH)
  451.         {
  452.           stmt_descr = &(stmt->out_descr);
  453.           need_cnt = stmt_descr->count;
  454.           need_res++;
  455.         }
  456.   if (using_descr && using_descr->maximum &&
  457.       using_descr->count > using_descr->maximum)
  458.     return -DS_CNT;
  459.   CHECK_ARR_SIZE (args.prm, args_max, need_cnt+1, gsql_parm);
  460.   
  461.   if (need_arg)
  462.     {
  463.       CHECK_ARR_SIZE (mk_args, mk_args_max, need_cnt, double);
  464.       if (!using_descr || !(using_descr->count))
  465.         return -DS_NOPAR;
  466.       if (using_descr->count != need_cnt)
  467.         return -DS_BADPAR;
  468.       for (i = 0, val = using_descr->values,
  469.              need_val = stmt_descr->values, arg = &(args.prm[0]);
  470.            i < need_cnt; i++, val++, need_val++, arg++)
  471.         {
  472.           /* using this descriptor as argument cancells all        *
  473.            * allocations made in it when it was an result receiver */
  474.           if (val->data_allocated_size)
  475.             val->data_allocated_size = 0;
  476.           
  477.           need_type = need_val->type;
  478.           if (val->indicator >=0)
  479.             {
  480.               real_type = typ_user2sql (val->type);
  481.               if ((!real_type) || (real_type == T_STR && need_type != T_STR) ||
  482.                   (real_type != T_STR && need_type == T_STR))
  483.                 return -DS_BADPAR;
  484.               
  485.               if (real_type != need_type)
  486.                 /* here real_type can't be T_STR */
  487.                 {
  488.                   arg->valptr = mk_args + i;
  489.                   if (put_dat (val->data, 0, real_type, REGULAR_VALUE,
  490.                                arg->valptr, 0, need_type, NULL) < 0)
  491.                     return -DS_BADPAR;
  492.                 }
  493.               else
  494.                 arg->valptr = val->data;
  495.             }
  496.           arg->type = need_type;
  497.           if (need_type == T_STR)
  498.             arg->length = strlen (arg->valptr);
  499.           else
  500.              arg->length = 0;
  501.           arg->flags = 0; /* in-flag */
  502.           arg->indptr = &(val->indicator);
  503.         }
  504.     }
  505.   
  506.   if (need_res)
  507.     {
  508.       if (!using_descr)
  509.         return -DS_NORES;
  510.       if (!(using_descr->count))
  511.         using_descr->count = need_cnt;
  512.       else
  513.         if (using_descr->count != need_cnt)
  514.           return -DS_BADTAR;
  515.           
  516.       if (need_cnt > using_descr->alloc_cnt)
  517.         if (using_descr->maximum)
  518.           return -DS_DESCRLEN;
  519.         else
  520.           CHECK_ARR_SIZE (using_descr->values, using_descr->alloc_cnt,
  521.                           need_cnt, sql_descr_element_t);
  522.       for (i = 0, val = using_descr->values,
  523.              need_val = stmt_descr->values, arg = &(args.prm[0]);
  524.            i < need_cnt; i++, val++, need_val++, arg++)
  525.         {
  526.           if (!(val->data_allocated_size))
  527.             val->data = NULL;
  528.           
  529.           need_type = need_val->type;
  530.           real_type = typ_user2sql (val->type);
  531.           if (!real_type)
  532.             {
  533.               val->type = typ_sql2user (need_type);
  534.               real_type = need_type;
  535.             }
  536.           else
  537.             if ((real_type == T_STR && need_type != T_STR) ||
  538.                 (real_type != T_STR && need_type == T_STR))
  539.               return -DS_BADTAR;
  540.               
  541.           arg->type = real_type;
  542.           if (need_type != T_STR || !(val->length))
  543.             val->length = need_val->length;
  544.           need_length =  val->length;
  545.           arg->flags = 1; /* out-flag */
  546.           arg->indptr = &(val->indicator);
  547.           if (need_type == T_STR)
  548.             need_length++;
  549.           CHECK_ARR_SIZE (val->data, val->data_allocated_size,
  550.                           need_length, char);
  551.           arg->length = need_length;
  552.           arg->valptr = val->data;
  553.         }
  554.     }
  555.   
  556.   if (using_descr && (!need_cnt))
  557.     return -DS_SYNTER;
  558.   
  559.   args.count = need_cnt;
  560.   args.sectnum = 0;
  561.   args.command = command;
  562.   if (command == COM_FETCH && (!stmt->table_name || !*stmt->table_name))
  563.     args.options  = 50;
  564.   else
  565.     args.options  = 0;
  566.   
  567.   SQL__runtime (&interp_mdl, &args);
  568.   return SQLCODE;
  569. } /* SQL_d_interpret */
  570. int
  571. SQL__execute (char *stmt_name,
  572.                SQL_DESCR using_input, SQL_DESCR using_output)
  573. /* using_input & using_output are arguments here, they can be = NULL */
  574. {
  575.   struct s_stmt *stmt = SQL__find_stmt (stmt_name);
  576.   i4_t segm, err, i;
  577.   
  578.   if (!stmt)
  579.     return -DS_STMT;
  580.   segm = stmt->segm;
  581.   if (stmt->mem_ptr) /* select */
  582.     {
  583.       err = SQL_d_interpret (segm, COM_START, using_input, stmt);
  584.       if (err) return err;
  585.       for (i = 0; i < 2 && !err; i++)
  586.         err = SQL_d_interpret (segm, COM_FETCH, using_output, stmt);
  587.       if (err < 0) return err;
  588.       SQL_d_interpret (segm, COM_CLOSE, NULL, stmt);
  589.       if (err == 100)
  590.         SQLCODE = (i == 1) ? 100 : 0;
  591.       else
  592.         {
  593.           CHECK_FREE_DATA (using_output->values, using_output->count);
  594.           SQLCODE = -DS_EXE;
  595.         }
  596.       err = SQLCODE;
  597.     }
  598.   else
  599.     {
  600.       if (using_output)
  601.         return -DS_SYNTER;
  602.       err = SQL_d_interpret (segm, stmt->sectnum, using_input, stmt);
  603.     }
  604.   return err;
  605. } /* execute */
  606. int
  607. SQL__execute_immediate (char *stmt_text)
  608. {
  609.   compiled_t *prep_res;
  610.   i4_t err;
  611.   
  612.   if ((err = SQL__prepare_stmt (stmt_text,"", &prep_res)))
  613.     return err;
  614.   if (!prep_res->objects)
  615.     return 0;
  616.   if ( (prep_res->stored.comp_type != COMP_DYNAMIC_SIMPLE) || 
  617.       *prep_res->objects->table_name || *prep_res->objects->table_owner ||
  618.       prep_res->objects->descr_in.descr_t_len ||
  619.       prep_res->objects->descr_out.descr_t_len ||
  620.       *prep_res->objects->cursor_name )
  621.     return -DS_SYNTER;
  622.   return SQL_d_interpret (prep_res->stored.comp_data_t_u.segm,
  623.                       prep_res->objects->object, NULL, NULL);
  624. } /* execute_immediate */
  625. int
  626. SQL__declare_cursor (char *stmt_name, char *cursor_name)
  627. /* only associates cursor & statement names: *
  628.  * pointed statement can be not prepared yet */
  629. {
  630.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  631.   if (cursor)
  632.     return -DS_CURDECL;
  633.   if (!stmt_name || !(*stmt_name))
  634.     return -DS_STMT;
  635.   cursor = TYP_ALLOC (1, struct s_cursor);
  636.   STRCPY (cursor_name, cursor->name);
  637.   STRCPY (stmt_name, cursor->stmt_name);
  638.   cursor->status = CUR_CLOSED;
  639.   cursor->next = fir_cursor;
  640.   fir_cursor = cursor;
  641.   return 0;
  642. } /* declare_cursor */
  643. int
  644. SQL__allocate_cursor (char *stmt_name, char *cursor_name)
  645. /* associates cursor name with prepared statement */
  646. {
  647.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  648.   struct s_stmt   *stmt   = SQL__find_stmt   (stmt_name);
  649.   if (cursor)
  650.     return -DS_CURDECL;
  651.   if (!stmt /* incorrect statemnet name */
  652.       || !(stmt->mem_ptr) /* prepared statement is not 'cursor specification' */)
  653.     return -DS_STMT;
  654.   cursor = TYP_ALLOC (1, struct s_cursor);
  655.   STRCPY (cursor_name, cursor->name);
  656.   cursor->stmt_ptr = stmt;
  657.   cursor->status = CUR_CLOSED;
  658.   cursor->next = fir_cursor;
  659.   fir_cursor = cursor;
  660.   cursor->segm = SQL__get_cursor_segm (cursor_name, stmt);
  661.   return (cursor->segm < 0) ? cursor->segm : 0;
  662. } /* allocate_cursor */
  663. int
  664. SQL__open_cursor (char *cursor_name, SQL_DESCR using_input)
  665. /* using_input is argument, it can be = NULL */
  666. {
  667.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  668.   i4_t err;
  669.   
  670.   if (!cursor)
  671.     return -DS_CUR;
  672.   
  673.   if (!(cursor->segm))
  674.     {
  675.       cursor->stmt_ptr = SQL__find_stmt (cursor->stmt_name);
  676.       if ((cursor->segm =
  677.            SQL__get_cursor_segm (cursor_name, cursor->stmt_ptr)) < 0)
  678.         return cursor->segm;
  679.     }
  680.   if ((err = SQL_d_interpret (cursor->segm, COM_START,
  681.                           using_input, cursor->stmt_ptr)) < 0)
  682.     return err;
  683.   cursor->status = NO_CUR_ROW;
  684.   return 0;
  685. } /* open_cursor */
  686. int
  687. SQL__fetch (char *cursor_name, SQL_DESCR using_output)
  688. /* using_output is the result, after correct fininshing
  689.    of function's work using_output != NULL */
  690. {
  691.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  692.   i4_t err;
  693.   
  694.   if (!cursor)
  695.     return -DS_CUR;
  696.   if (cursor->status == CUR_CLOSED)
  697.     return -DS_CURST;
  698.   
  699.   if ((err = SQL_d_interpret (cursor->segm, COM_FETCH,
  700.                           using_output, cursor->stmt_ptr)) < 0)
  701.     return err;
  702.   if (!err)
  703.     cursor->status = HAS_CUR_ROW;
  704.   return 0;
  705. } /* fetch */
  706. int
  707. SQL__close_cursor (char *cursor_name)
  708. {
  709.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  710.   i4_t err;
  711.   
  712.   if (!cursor)
  713.     return -DS_CUR;
  714.   if (cursor->status == CUR_CLOSED)
  715.     return -DS_CURST;
  716.   
  717.   if ((err = SQL_d_interpret (cursor->segm, COM_CLOSE, NULL, NULL)) < 0)
  718.     return err;
  719.   cursor->status = CUR_CLOSED;
  720.   return 0;
  721. } /* close_cursor */
  722. int
  723. SQL__delete (char *cursor_name, char *table_name, char *table_owner)
  724. /* table_name is used here for checking of DELETE statement using */
  725. {
  726.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  727.   struct s_stmt   *stmt;
  728.   
  729.   if (!cursor)
  730.     return -DS_CUR;
  731.   if (cursor->status != HAS_CUR_ROW)
  732.     return -DS_CURST;
  733.   stmt = cursor->stmt_ptr;
  734.   if (!table_name || strcmp (table_name, stmt->table_name) ||
  735.       !table_owner || strcmp (table_owner, stmt->table_owner))
  736.     return -TNERR;
  737.   cursor->status = NO_CUR_ROW;
  738.   return SQL_d_interpret (cursor->segm, COM_DELETE, NULL, NULL);
  739. } /* delete */
  740. int
  741. SQL__update (char *cursor_name, char *table_name,
  742.               char *table_owner, char *set_clause)
  743. /* table_name is used here for checking of UPDATE statement using */
  744. /* set_clause = "SET ..." */
  745. {
  746.   struct s_cursor *cursor = SQL__find_cursor (cursor_name);
  747.   struct s_stmt   *stmt;
  748.   compiled_t      *prep_res;
  749.   char            *stmt_text;
  750.   i4_t              err;
  751.   
  752.   if (!cursor)
  753.     return -DS_CUR;
  754.   if (cursor->status != HAS_CUR_ROW)
  755.     return -DS_CURST;
  756.   stmt = cursor->stmt_ptr;
  757.   if (!table_name || strcmp (table_name, stmt->table_name) ||
  758.       !table_owner || strcmp (table_owner, stmt->table_owner))
  759.     return -TNERR;
  760.   stmt_text = cat_strings (8, "UPDATE ", table_owner, ".",
  761.                            table_name, " ", set_clause,
  762.                            " WHERE CURRENT OF ", cursor_name);
  763.   err = SQL__prepare_stmt (stmt_text, NULL, &prep_res);
  764.   xfree (stmt_text);
  765.   if (err)
  766.     return err;
  767.   
  768.   if (prep_res->stored.comp_type!=COMP_DYNAMIC_SIMPLE ||
  769.       !(*prep_res->objects->cursor_name) ||
  770.       prep_res->objects->descr_in.descr_t_len ||
  771.       prep_res->objects->descr_out.descr_t_len)
  772.     return -DS_SYNTER;
  773.     
  774.   return SQL_d_interpret (prep_res->stored.comp_data_t_u.segm,
  775.                       COM_START, NULL, NULL);
  776. } /* update */