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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  type_lib.c  -  types library of GNU SQL server
  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: type_lib.c,v 1.247 1997/04/06 17:36:02 kml Exp $ */
  28. #include <assert.h>
  29. #include "global.h"
  30. #include "type_lib.h"
  31. #include "inprtyp.h"
  32. #include "sql.h"
  33. #include "totdecl.h"
  34. #include "fieldtp.h"
  35. extern DataUnit *ins_col_values;
  36. DataUnit *data_st = NULL;
  37. i4_t   dt_ind, dt_max;
  38. i4_t res_hole_cnt = 0;
  39. parm_t *res_hole = NULL;
  40. /* In all leafs field Ptr points to element of type DataUnit      *
  41.  * where the type of the value is filled by codegen.              */
  42. /* Type of result of subtree must be put into all according nodes *
  43.  * ( if it's the logic value =>  T_BOOL).                         *
  44.  * in nodes for subquery :.Rh- reference to programm for          *
  45.  * handling this subquery.                                        */
  46. #define CHECK_FLAG(du)                  
  47.   if ((du).dat.nl_fl == NOT_CONVERTED)                 
  48.   {                 
  49.     STR_PTR (&((du).dat)) = V_PTR (STR_VPTR (&((du).dat)), char); 
  50.     (du).dat.nl_fl = REGULAR_VALUE;                 
  51.   }
  52. short
  53. sizeof_sqltype (sql_type_t type)
  54. /* values' lenght of this type */
  55. {
  56.   i2_t res;
  57.   switch (type.code)
  58.     {
  59.     case T_SRT:
  60.       res = SZ_SHT;
  61.       break;
  62.     case T_INT:
  63.       res = SZ_INT;
  64.       break;
  65.     case T_LNG:
  66.       res = SZ_LNG;
  67.       break;
  68.     case T_FLT:
  69.       res = SZ_FLT;
  70.       break;
  71.     case T_DBL:
  72.       res = SZ_DBL;
  73.       break;
  74.     case T_STR:
  75.       res = type.len;
  76.       break;
  77.     default:
  78.       res = 0;
  79.       lperror ("Unexpected expression type '%s'", type2str(type));
  80.     }
  81.   return res;
  82. }
  83. VADR
  84. load_tree (TRNode *node, VADR cur_seg, VADR str_seg)
  85.      /* recursive function for copying the tree      *
  86.       * for CHECK constraint from temporary segment  *
  87.       * to current working segment of virtual memory */
  88. {
  89.   VADR V_res_node, V_ptr = VNULL, V_Dn, V_Rh;
  90.   TRNode *res_node;
  91.   TRNode *Rh_old, *Dn_old;
  92.   DataUnit *du = NULL;
  93.   TpSet *dat = NULL;
  94.   char *str_dat = NULL;
  95.   
  96.   if (!node)
  97.     return VNULL;
  98.   
  99.   switch_to_segment (str_seg);
  100.   Dn_old = V_PTR (node->Dn.off, TRNode);
  101.   Rh_old = V_PTR (node->Rh.off, TRNode);
  102.   if (node->code == COLUMN)
  103.     V_ptr = node->Ptr.off;
  104.   else
  105.     if (node->Ptr.off)
  106.       {
  107. du = V_PTR (node->Ptr.off, DataUnit);
  108. dat = &(du->dat);
  109. if (du->type.code == T_STR)
  110.   str_dat = V_PTR (STR_VPTR (dat), char);
  111.       }
  112.   
  113.   switch_to_segment (cur_seg);
  114.   V_Dn = load_tree (Dn_old, cur_seg, str_seg);
  115.   V_Rh = load_tree (Rh_old, cur_seg, str_seg);
  116.   if (du)
  117.     {
  118.       V_ptr = VMALLOC (1, DataUnit);
  119.       *V_PTR (V_ptr, DataUnit) = *du;
  120.       if (str_dat)
  121. {
  122.   i4_t len = strlen (str_dat);
  123.   char *str_ptr;
  124.   VADR V_str_ptr;
  125.   
  126.   P_VMALLOC (str_ptr, len + 1, char);
  127.   bcopy (str_dat, str_ptr, len + 1);
  128.   STR_VPTR (&(V_PTR (V_ptr, DataUnit)->dat)) = V_str_ptr;
  129. }
  130.     }
  131.   
  132.   P_VMALLOC (res_node, 1, TRNode);
  133.   *res_node = *node;
  134.   res_node->Dn.off = V_Dn;
  135.   res_node->Rh.off = V_Rh;
  136.   res_node->Ptr.off = V_ptr;
  137.     
  138.   return V_res_node;
  139. } /* load_tree */
  140. int
  141. res_row_save (char *nl_arr, i4_t nr, DataUnit **colval)
  142. {
  143.   char *pointbuf, *ptr, nl_fl;
  144.   i4_t i, err;
  145.   DataUnit *to;
  146.   i2_t len;
  147.   
  148.   pointbuf = nl_arr + nr;
  149.   for (i = 0; i < nr; i++)
  150.     {
  151.       to = colval[i];
  152.       len = 0;
  153.       ptr = NULL;
  154.       nl_fl = (nl_arr[i]) ? REGULAR_VALUE : NULL_VALUE;
  155.       
  156.       if (nl_fl == REGULAR_VALUE)
  157. {
  158.   len = t2bunpack (pointbuf);
  159.   if (len < 0)
  160.     return -ER_BUF;
  161.   pointbuf += sizeof(u2_t);
  162.   ptr = pointbuf;
  163.   pointbuf += len;
  164. }
  165.       
  166.       err = mem_to_DU (nl_fl, to->type.code, len, ptr, to);
  167.       if (err < 0)
  168. return err;
  169.     }
  170.   return 0;
  171. } /* res_row_save */
  172. int
  173. DU_to_buf (DataUnit *dt_from, char **pointbuf, sql_type_t *to_type)
  174.      /* returns 0 if O'K and < 0 if error */
  175.      /* if to_type == NULL => type from dt_from won't be changed */
  176. {
  177.   TpSet Place;
  178.   i4_t len, err;
  179.   
  180.   if (dt_from->type.code == T_STR)
  181.     {
  182.       t2bto2char (len = dt_from->type.len, *pointbuf);
  183.       *pointbuf += SZ_SHT;
  184.       memcpy (*pointbuf, STR_PTR (&(dt_from->dat)), len);
  185.       *pointbuf += len;
  186.     }
  187.   else
  188.     {
  189.       len = sizeof_sqltype (*to_type);
  190.       t2bto2char (len, *pointbuf);
  191.       *pointbuf += SZ_SHT;
  192.       err = put_dat (&(dt_from->dat), 0, dt_from->type.code,
  193.      REGULAR_VALUE, &Place, 0,
  194.      (to_type) ? to_type->code : dt_from->type.code, NULL);
  195.       if (err < 0)
  196. return err;
  197.       memcpy (*pointbuf, (char *) (&Place), len);
  198.       *pointbuf += len;
  199.     }
  200.   return 0;
  201. } /* DU_to_buf */
  202. int
  203. DU_to_rpc (DataUnit *dt_from, parm_t *to, i4_t typ)
  204. {
  205.   char null_fl;
  206.   i4_t err = 0;
  207.   
  208.   assert (dt_from && to);
  209.   null_fl= dt_from->dat.nl_fl;
  210.   
  211.   to->value.type = typ;
  212.   to->indicator = (null_fl == NULL_VALUE) ? -1 : 0;
  213.   if (null_fl == REGULAR_VALUE)
  214.     if (typ == T_STR)
  215.       {
  216. to->value.data_u.Str.Str_val = STR_PTR (&(dt_from->dat));
  217. to->value.data_u.Str.Str_len = dt_from->type.len;
  218.       }
  219.     else
  220.       err = put_dat (&VL(&(dt_from->dat)), 0, dt_from->type.code, 
  221.      REGULAR_VALUE, &(to->value.data_u), 0, typ, NULL);
  222.   return err;
  223. } /* DU_to_rpc */
  224. void
  225. conv_DU_to_str (DataUnit *from, DataUnit *to)
  226. {
  227.   sql_type_t *typ_to, *typ_from;
  228.   TpSet *dat_to, *dat_from;
  229.   
  230.   *to = *from;
  231.   dat_from = &(from->dat);
  232.   typ_from = &(from->type);
  233.   dat_to   = &(to->dat);
  234.   typ_to   = &(to->type);
  235.   if (NL_FL (dat_from) == REGULAR_VALUE && typ_from->code != T_STR)
  236.     {
  237.       typ_to->code = T_STR;
  238.       typ_to->len = sizeof_sqltype (*typ_from);
  239.       STR_PTR (dat_to) = (char *) (&VL (dat_from));
  240.     }
  241.   MAX_LEN (dat_to) = 0;
  242. } /* conv_DU_to_str */
  243. int
  244. mem_to_DU (char nl_fl, byte typ_from_code,
  245.    i2_t from_len, void *from, DataUnit *to)
  246. /* This function returns value:                         *
  247.  * 0   - if it's all right,                             *
  248.  * < 0 - if error,                                      *
  249.  * > 0 - if argument is string and this value = lenght  *
  250.  *       of this string. It is greater than res_size    *
  251.  *       (so string was shortened).                     *
  252.  * NOTE : if from_len < 0 & argument is string =>       *
  253.  *        its lenght is evaluated as strlen (from)      */
  254. {
  255.   i4_t err = 0, len;
  256.   sql_type_t *typ_to;
  257.   TpSet *dat_to;
  258.   
  259.   typ_to = &(to->type);
  260.   dat_to = &(to->dat);
  261.   
  262.   NL_FL (dat_to) = nl_fl;
  263.   if (nl_fl == REGULAR_VALUE)
  264.     {
  265.       if (typ_from_code == T_STR)
  266. {
  267.   if (from_len < 0)
  268.     from_len = strlen ((char *)from);
  269.   CHECK_ARR_SIZE (STR_PTR (dat_to), MAX_LEN (dat_to), from_len+1, char);
  270.   len = typ_to->len = from_len;
  271.   STR_PTR (dat_to)[from_len] = 0; /* null-terminating of the string for *
  272.    * functions from catfun.c            */
  273. }
  274.       else
  275. {
  276.   len = sizeof_sqltype (*typ_to);
  277.   if (MAX_LEN (dat_to))
  278.     {
  279.       xfree (STR_PTR (dat_to));
  280.       MAX_LEN (dat_to) = 0;
  281.     }
  282. }
  283.       if (typ_from_code == typ_to->code)
  284. bcopy ((char *) from, DU_PTR_VL (*to), len);
  285.       else if (typ_from_code == T_STR)
  286.         err = -ER_1;
  287.       else
  288.         {
  289.           TpSet tmp;
  290.           sql_type_t type_tmp = pack_type(typ_from_code, 0, 0);
  291.           
  292.           bcopy ((char *) from, (char *)(&tmp), sizeof_sqltype (type_tmp));
  293.           err = put_dat (&tmp, from_len, typ_from_code, REGULAR_VALUE,
  294.                          DU_PTR_VL (*to), typ_to->len, typ_to->code, NULL);
  295.         }
  296.     }
  297.   return err;
  298. } /* rpc_to_mem */
  299.   
  300. int
  301. rpc_to_DU (parm_t *from, DataUnit *to)
  302. /* This function returns value:                         *
  303.  * 0   - if it's all right,                             *
  304.  * < 0 - if error,                                      *
  305.  * > 0 - if argument is string and this value = lenght  *
  306.  *       of this string. It is greater than res_size    *
  307.  *       (so string was shortened).                     */
  308. {
  309.   byte typ_from_code;
  310.   
  311.   typ_from_code = from->value.type;
  312.   return mem_to_DU ((from->indicator < 0) ? NULL_VALUE : REGULAR_VALUE,
  313.     typ_from_code,
  314.     (typ_from_code == T_STR) ?
  315.     from->value.data_u.Str.Str_len : 0,
  316.     (typ_from_code == T_STR) ?
  317.     from->value.data_u.Str.Str_val :
  318.            (void *)(&(from->value.data_u)), to);
  319. } /* rpc_to_DU */
  320. int
  321. PutDataNext (TRNode * cur)
  322. {
  323.   DtPush;
  324.   switch (cur->code)
  325.     {
  326.     case USERNAME :
  327.       NlFlCur = REGULAR_VALUE;
  328.       StrCur = current_user_login_name;
  329.       CodCur = T_STR;
  330.       LenCur = strlen(current_user_login_name);
  331.       break;
  332.       
  333.     case EXISTS   :
  334.       NlFlCur = REGULAR_VALUE;
  335.       LngCur = TRUE; /* result of SubQuery is already calculated */
  336.       CodCur = T_BOOL;
  337.       LenCur = 0;
  338.       
  339.       /* saving of SubQuery result : */
  340.       LngPred = TRUE;
  341.       break;
  342.       
  343.     case COLUMN :
  344.       /* column pointer in tree from CHECK constraint */
  345.       assert(ins_col_values!=NULL);
  346.       DtCurEl = ins_col_values[(i4_t)(cur->Ptr.off)];
  347.       break;
  348.       
  349.     default     :
  350.       DtCurEl = *TP_ADR (cur, Ptr, DataUnit);
  351.       CHECK_FLAG (DtCurEl);
  352.       if (NlFlCur == UNKNOWN_VALUE)
  353. return -ER_1;
  354.       break;
  355.     } /* switch */
  356.   return 0;
  357. } /* PutDataNext */
  358. #define OPERATION(simb) switch (m1) {                          
  359.         case T_SRT : SrtPred = SRT_VL (pt1) simb SRT_VL (pt2); 
  360.                      break;                                    
  361.         case T_INT : IntPred = INT_VL (pt1) simb INT_VL (pt2); 
  362.                      break;                                    
  363.         case T_LNG : LngPred = LNG_VL (pt1) simb LNG_VL (pt2); 
  364.                      break;                                    
  365.         case T_FLT : FltPred = FLT_VL (pt1) simb FLT_VL (pt2); 
  366.                      break;                                    
  367.         case T_DBL : DblPred = DBL_VL (pt1) simb DBL_VL (pt2); 
  368.                      break;                                    
  369.         default    : return(-ER_1);       /* ERROR */          
  370.       } /* switch */                                           
  371.       break
  372.       
  373. #define RET(err) { DtPop;        
  374.                    return err; }
  375. int
  376. oper (byte code, i4_t arity)
  377. /* Operation "code" making. Two highest stack elements are * 
  378.  * arguments. It both are being deleted and result of this *
  379.  * operation is being put into head of stack               */
  380. {
  381.   byte m1, m2;
  382.   TpSet *pt1, *pt2, dop;
  383.   i2_t size;
  384.   i4_t err, m, cod1 = 0, cod2 = 0;
  385.   char cod_res;
  386.   
  387.   /* next table is used for calculation of the result       *
  388.    * of AND & OR operations : 0 - NULL, 1 - FALSE, 2 - TRUE */
  389.   
  390.   char OR_AND_tbl[2][3][3] = { /* NULL   FALSE   TRUE */
  391.     /* AND : */
  392.            /* NULL  */ { { 0,      1,      0 },
  393.                    /* FALSE */   { 1,      1,      1 },
  394.    /* TRUE  */   { 0,      1,      2 } },
  395.   
  396.     /* OR  : */                         
  397.                    /* NULL  */ { { 0,      0,      2 },
  398.                    /* FALSE */   { 0,      1,      2 },
  399.            /* TRUE  */   { 2,      2,      2 } }
  400.   };
  401.   
  402. #define U_MINUS(type, val) case type: val = - val; break;
  403.   if (arity == 1) /* unary operation */
  404.     {
  405.       if (Is_SQPredicate_Code (code))
  406. {
  407.   i4_t res = FALSE;
  408.       
  409.     if (code == SUBQUERY) /* in comparison predicate */
  410.     if (NlFlPred == UNKNOWN_VALUE)
  411.       DtPredEl = DtCurEl; 
  412.     else /* second row in SubQuery result */
  413.       return -ER_SQ;
  414.   
  415.   else /* ALL | SOME */
  416.     {
  417.       if (NlFlCur == NULL_VALUE)
  418. NlFlPred = NULL_VALUE;
  419.       else
  420. if (((code == ALL)  && !LngCur) ||
  421.     ((code == SOME) && LngCur))
  422.   {
  423.     NlFlPred = REGULAR_VALUE;
  424.     LngPred = LngCur;
  425.     res = TRUE; /* exit from SubQuery handling */
  426.   }
  427.     }
  428.   NlFlCur = REGULAR_VALUE;
  429.   LngCur = res;
  430.   CodCur = T_BOOL;
  431.   LenCur = 0;
  432. }
  433.       else
  434. switch (code)
  435.   {
  436.   case UMINUS :
  437.     switch (CodCur)
  438.       {
  439. U_MINUS (T_SRT, SrtCur);
  440. U_MINUS (T_INT, IntCur);
  441. U_MINUS (T_LNG, LngCur);
  442. U_MINUS (T_FLT, FltCur);
  443. U_MINUS (T_DBL, DblCur);
  444.       default:
  445. return (-ER_1);
  446.       }
  447.     break;
  448.     
  449.   case NOT :
  450.     if (NlFlCur == REGULAR_VALUE)
  451.       LngCur = ! LngCur ;
  452.     break;
  453.   
  454.   case ISNULL :
  455.     LngCur = (NlFlCur == NULL_VALUE);
  456.     CodCur = T_BOOL;
  457.     NlFlCur = REGULAR_VALUE;
  458.     break;
  459.   
  460.   case ISNOTNULL :
  461.     LngCur = (NlFlCur == REGULAR_VALUE);
  462.     CodCur = T_BOOL;
  463.     NlFlCur = REGULAR_VALUE;
  464.     break;
  465.   
  466.   case NOOP :
  467.     break;
  468.     
  469.   default:
  470.     return (-ER_3); /* ERROR */
  471.   }
  472.       return 0;
  473.     }
  474.   
  475. #undef U_MINUS
  476.   
  477.   /* other operations are binary */
  478.   
  479.   if ((code == OR) || (code == AND))
  480.     {
  481.       if (NlFlPred == REGULAR_VALUE)
  482. cod1 = LngPred + 1; 
  483.       if (NlFlCur == REGULAR_VALUE)
  484. cod2 = LngCur + 1; 
  485.       cod_res = OR_AND_tbl[code == OR][cod1][cod2];
  486.       
  487.       if (cod_res)
  488. {
  489.   NlFlPred = REGULAR_VALUE;
  490.   LngPred = cod_res - 1;
  491.   CodPred = T_BOOL;
  492. }
  493.       
  494.       else
  495. NlFlPred = NULL_VALUE;
  496.       
  497.       RET (0);
  498.     }
  499.   if ((NlFlPred != REGULAR_VALUE) ||
  500.       (NlFlCur != REGULAR_VALUE))
  501.     {
  502.       NlFlPred = NULL_VALUE;
  503.       RET (0);
  504.     }
  505.   
  506.   NlFlPred = REGULAR_VALUE;
  507.   if (CodPred == T_STR)
  508.     { /* string */
  509.       /* There are only binary comparison operations for strings. *
  510.        * Strings aren't in any other operations.                  */
  511.       size = (LenPred > LenCur) ? LenPred : LenCur;
  512.       m = strncmp (StrPred, StrCur, size);
  513.       LngPred = 0;
  514.       switch (code)
  515. {
  516. case EQU:
  517.   if (m == 0)
  518.     LngPred = 1;
  519.   break;
  520. case NE:
  521.   if (m != 0)
  522.     LngPred = 1;
  523.   break;
  524. case GT:
  525.   if (m > 0)
  526.     LngPred = 1;
  527.   break;
  528. case LT:
  529.   if (m < 0)
  530.     LngPred = 1;
  531.   break;
  532. case GE:
  533.   if (m >= 0)
  534.     LngPred = 1;
  535.   break;
  536. case LE:
  537.   if (m <= 0)
  538.     LngPred = 1;
  539.   break;
  540. default:
  541.   RET (-ER_3);
  542. } /* switch */
  543.       CodPred = T_BOOL;
  544.     }
  545.   else
  546.     { /* operation between numbers */
  547.       m1 = CodPred;
  548.       pt1 = &DatPred;
  549.       m2 = CodCur;
  550.       pt2 = &DatCur;
  551.       if (m1 > m2)
  552. {
  553.   pt2 = &dop;
  554.   err = put_dat (&DatCur, 0, m2, REGULAR_VALUE, pt2, 0, m1, NULL);
  555.   if (err)
  556.     RET (err);
  557. }
  558.       if (m1 < m2)
  559. {
  560.   pt1 = &dop;
  561.   err = put_dat (&DatPred, 0, m1, REGULAR_VALUE, pt1, 0, m2, NULL);
  562.   if (err)
  563.     RET (err);
  564.           m1 = m2;
  565. }
  566.       CodPred = m1;
  567.       /* type of the result is in ResCode now */
  568.       switch (code)
  569. {
  570. case ADD:  OPERATION (+);
  571. case SUB:  OPERATION (-);
  572. case DIV:  OPERATION (/);
  573. case MULT: OPERATION (*);
  574. case NE:   OPERATION (!=);
  575. case EQU:  OPERATION (==);
  576. case GT:   OPERATION (>);
  577. case LT:   OPERATION (<);
  578. case GE:   OPERATION (>=);
  579. case LE:   OPERATION (<=);
  580. default:
  581.   RET (-ER_3);
  582.   /* . . . */
  583. } /* switch */
  584.     } /* if else */
  585.   RET (0);
  586. } /* "oper" */
  587. float
  588. sel_const (i4_t op, DataUnit *cnst, DataUnit *min, DataUnit *max)
  589.      /* makes estimation of selectivity for simple predicate  *
  590.       * of type : col_name 'op' cnst;                        *
  591.       * min & max - statistic about column col_name           *
  592.       * function assumes that cnst, min, max are all REGULAR */
  593. {
  594.   float sel = 0.0;
  595.   int error;
  596. #define pow_256(pow) (0x1000000 >> (8*pow))
  597.   
  598.   if (op == EQU)
  599.     return sel;
  600.   
  601.   CHECK_FLAG (*cnst); 
  602.   assert (cnst->dat.nl_fl == REGULAR_VALUE);
  603.   MK_BIN_OPER (GT, *cnst, *min);
  604.   if (COMP_RESULT)
  605.     /* cnst > min */
  606.     {
  607.       MK_BIN_OPER (LT, *cnst, *max);
  608.       if (COMP_RESULT)
  609. /* cnst < max */
  610. {
  611.   if (cnst->type.code == T_STR)
  612.     {
  613.       u4_t min_long = 0, max_long = 0, cnst_long = 0;
  614.       i4_t min_str_lng, i, j;
  615.       i4_t len_min = min->type.len;
  616.       i4_t len_max = max->type.len;
  617.       i4_t len_cnst = cnst->type.len;
  618.       char *str_min = STR_PTR (&(min->dat));
  619.       char *str_max = STR_PTR (&(max->dat));
  620.       char *str_cnst = STR_PTR (&(cnst->dat));
  621.     
  622.       min_str_lng = (len_min < len_max) ? len_min : len_max;
  623.       min_str_lng = (min_str_lng < len_cnst) ? min_str_lng : len_cnst;
  624.       for (i = 0; i < min_str_lng; i++)
  625. if (str_min[i] != str_cnst[i] || str_max[i] != str_cnst[i])
  626.   break;
  627.     
  628.       for (j = 0; j < SZ_LNG && i+j < len_min; j++)
  629. min_long += ((u4_t) (str_min[i+j])) * pow_256(j);
  630.       for (j = 0; j < SZ_LNG && i+j < len_max; j++)
  631. max_long += ((u4_t) (str_max[i+j])) * pow_256(j);
  632.       for (j = 0; j < SZ_LNG && i+j < len_cnst; j++)
  633. cnst_long += ((u4_t) (str_cnst[i+j])) * pow_256(j);
  634.       assert (min_long != max_long);
  635.     
  636.       sel = ((float)cnst_long - (float)min_long) /
  637. ((float)max_long - (float)min_long);
  638.     }
  639.   else
  640.     {
  641.       DataUnit  cnst_sub_min, max_sub_min;
  642.     
  643.       MK_BIN_OPER (SUB, *max, *min);
  644.       max_sub_min = OPER_RESULT;
  645.       MK_BIN_OPER (SUB, *cnst, *min);
  646.       cnst_sub_min = OPER_RESULT;
  647.     
  648.       /* changing both subtraction results to float */
  649.       error = put_dat (&(cnst_sub_min.dat), 0, cnst_sub_min.type.code,
  650.        REGULAR_VALUE, &(cnst_sub_min.dat), 0, T_FLT, NULL);
  651.       if (error < 0)
  652. return error;
  653.       cnst_sub_min.type.code = T_FLT;
  654.       error = put_dat (&(max_sub_min.dat), 0, max_sub_min.type.code,
  655.        REGULAR_VALUE, &(max_sub_min.dat), 0, T_FLT, NULL);
  656.       if (error < 0)
  657. return error;
  658.       max_sub_min.type.code = T_FLT;
  659.     
  660.       MK_BIN_OPER (DIV, cnst_sub_min, max_sub_min);
  661.       sel = FLT_VL (&(OPER_RESULT.dat));
  662.     }
  663.   if (op == GT || op == GE)
  664.     sel = 1.0 - sel;
  665. }
  666.       else /* cnst >= max */
  667. if (op == LT || op == LE)
  668.   sel = 1.0;
  669.     }
  670.   else/* cnst <= min */
  671.     if (op == GT || op == GE)
  672.       sel = 1.0;
  673.   
  674.   return sel;
  675. } /* sel_const */
  676. /* translate data type in compiler to data type in BD */
  677. void
  678. type_to_bd (sql_type_t *tp_from, sql_type_t *tp_to)
  679. {
  680.   tp_to->len = sizeof_sqltype (*tp_from);
  681.   
  682.   switch (tp_from->code)
  683.     {
  684.     case T_STR:
  685.       tp_to->code = TCH;
  686.       break;
  687.     case T_SRT:
  688.       tp_to->code = T2B;
  689.       break;
  690.     case T_INT:
  691.       tp_to->code = T4B;
  692.       break;
  693.     case T_LNG:
  694.       tp_to->code = T4B;
  695.       break;
  696.     case T_FLT:
  697.     case T_DBL:
  698.       tp_to->code = TFLOAT;
  699.       break;
  700.     }
  701. }
  702. #define PR_CONST(typ_field,trn_func)                        
  703.   typ_field (dat_to) = trn_func (STRING (CNST_NAME (ptr))); 
  704.   break
  705. void
  706. prepare_CONST (TXTREF ptr, VADR V_PTN)
  707. /* this function prepares constant value for plan generator; it   *
  708.  * means that in the place befor constant value function locates  *
  709.  * flag(char) defining whether it's undefined or undeclared or    *
  710.  * regular value; returns pointer to value itself                 */
  711. {
  712.   VADR V_str;
  713.   char *str;
  714.   DataUnit *hole;
  715.   VADR V_hole;
  716.   TpSet *dat_to;
  717.   TRNode *PTN;
  718.   
  719.   P_VMALLOC (hole, 1, DataUnit);
  720.   dat_to = &(hole->dat);
  721.   PTN = V_PTR (V_PTN, TRNode);
  722.   hole->type = PTN->Ty = CNST_STYPE (ptr);
  723.   
  724.   PTN->code = CONST;
  725.   PTN->Ptr.off = V_hole;
  726.   
  727.   if (CODE_TRN (ptr) == NULL_VL)
  728.     {
  729.       NL_FL (dat_to) = NULL_VALUE;
  730.       return;
  731.     }
  732.   
  733.   assert (CODE_TRN (ptr) == CONST);
  734.   NL_FL (dat_to) = REGULAR_VALUE;
  735.   
  736.   switch (CNST_STYPE (ptr).code)
  737.     {
  738.     case SQLType_Short:
  739.       PR_CONST (SRT_VL, atol);
  740.     case SQLType_Int:
  741.       PR_CONST (INT_VL, atol);
  742.     case SQLType_Long:
  743.       PR_CONST (LNG_VL, atol);
  744.     case SQLType_Float:
  745.     case SQLType_Real:
  746.       PR_CONST (FLT_VL, atof);
  747.     case SQLType_Double:
  748.       PR_CONST (DBL_VL, atof);
  749.     case SQLType_Char:
  750.       {
  751. i4_t len = strlen (STRING (CNST_NAME (ptr)));
  752. hole->type.len = PTN->Ty.len = len;
  753. P_VMALLOC (str, len+1, char);
  754. bcopy (STRING (CNST_NAME (ptr)), str, len);
  755.         str[len]=0;
  756. STR_VPTR (dat_to) = V_str;
  757. NL_FL (dat_to) = NOT_CONVERTED;
  758.       }
  759.       break;
  760.     default:
  761.       yyfatal (" Unknown type in constant preparation n");
  762.     }
  763. }
  764. #undef PR_CONST
  765. void
  766. prepare_USERNAME (TRNode *PTN)
  767. {
  768.   PTN->code = USERNAME;
  769.   PTN->Ty.code = T_STR;
  770.   PTN->Ty.len = US_NAME_LNG;
  771. }
  772. VADR
  773. prepare_HOLE (sql_type_t typ)
  774. /* preparation of hole in module for data of this type */
  775. {
  776.   DataUnit *hole;
  777.   VADR V_hole;
  778.   
  779.   P_VMALLOC (hole, 1, DataUnit);
  780.   hole->type = typ;
  781.   return V_hole;
  782. } /* prepare_HOLE */