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

SQL Server

开发平台:

Unix_Linux

  1. /************************************************************************/
  2. /* check_tp - type checking and correction                              */
  3. /*
  4.  *
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by Konstantin Dyshlevoi
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  *  Contacts:  gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: check_tp.c,v 1.247 1997/04/04 16:05:05 kml Exp $ */
  29. #include "global.h"
  30. #include "cycler.h"
  31. #include "tassert.h"
  32. #define CORRECT_TYPE(t) correct_type (&(t))
  33. #define DEFAULT_STR_LEN 256
  34. #define OPER_HAS_TYPE(n) (Is_Operation (n) && Is_Typed_Operation (n))
  35. static sql_type_t
  36. correct_type (sql_type_t *t)
  37. {
  38.   return (*t = pack_type (t->code, t->len, t->prec));
  39. }
  40. static CODERT
  41. comp_type (sql_type_t type1, sql_type_t type2, sql_type_t * p_type)
  42. {
  43.   if ( is_casted(type1,type2) )
  44.     {
  45.       *p_type = type1;
  46.       return (SQL_SUCCESS);
  47.     }
  48.   if ( is_casted(type2,type1) )
  49.     {
  50.       *p_type = type2;
  51.       return (SQL_SUCCESS);
  52.     }
  53.   return SQL_ERROR;
  54. } /* comp_type */
  55. void
  56. put_type_to_tree (TXTREF arg_node, sql_type_t *need_type)
  57. {
  58.   TXTREF cur_node;
  59.   sql_type_t *type_ptr;
  60.   
  61.   if (OPER_HAS_TYPE (arg_node))
  62.     {
  63.       type_ptr = node_type (arg_node);
  64.       TASSERT (type_ptr->code == SQLType_0, arg_node);
  65.       *type_ptr = *need_type;
  66.     }
  67.   else
  68.     switch (CODE_TRN (arg_node))
  69.       {
  70.       case PARMPTR:
  71.         {
  72.           TXTREF param = OBJ_DESC (arg_node);
  73.           sql_type_t st,tt;
  74.           
  75.           st = PAR_STYPE (param);
  76.           tt = PAR_TTYPE (param);
  77.           comp_type (st, tt, &tt);
  78.           comp_type (*need_type, tt, &tt);
  79.           CORRECT_TYPE (tt);
  80.           PAR_STYPE (param) = PAR_TTYPE (param) = tt;
  81.         }
  82.         break;
  83.       case NULL_VL:
  84.         NULL_TYPE(arg_node) = *need_type;
  85.         break;
  86.       default: ; 
  87.       }
  88.         
  89.   if (HAS_DOWN (arg_node))
  90.     for (cur_node = DOWN_TRN (arg_node); cur_node;
  91.          cur_node = RIGHT_TRN (cur_node))
  92.       put_type_to_tree (cur_node, need_type);
  93. } /* put_type_to_tree */
  94. static void
  95. check_type (TXTREF node, sql_type_t need_type, char *err_string)
  96. /* type of 'node' must be convinient for type need_type */
  97. {
  98.   sql_type_t tp, *type_source = node_type (node);
  99.   if (type_source->code == SQLType_0)
  100.     put_type_to_tree (node, &need_type);
  101.   else
  102.     if (comp_type (*type_source, need_type, &tp) == SQL_ERROR)
  103.       yyerror (err_string);
  104. } /* check_type */
  105. static void
  106. check_arg_types (TXTREF node)
  107. /* compatibility checking for arguments of operation 'node',  *
  108.  * putting of result type to 'node' if it hasn't type yet,    *
  109.  * & making of types for trees - arguments with unknown types *
  110.  * if result type is known now.                               */
  111. {
  112.   i4_t put_type_fl = FALSE;
  113.   sql_type_t res_type, *right_type, *nd_type_ptr = &(OPRN_TYPE (node));
  114.   TXTREF dn_node, right_node, arg_node;
  115.   TASSERT (OPER_HAS_TYPE (node), node);
  116.   TASSERT (HAS_DOWN (node) && DOWN_TRN (node), node);
  117.   /* res_type is used for finding of result type */
  118.   res_type = pack_type(SQLType_0,0,0);
  119.   dn_node = DOWN_TRN (node);
  120.   for (right_node = dn_node; right_node;right_node = RIGHT_TRN (right_node))
  121.     {
  122.       right_type = node_type (right_node);
  123.       if (right_type->code == SQLType_0)
  124.         put_type_fl = TRUE;
  125.       if (comp_type (res_type, *right_type, &res_type) == SQL_ERROR)
  126.         {
  127.           file_pos = LOCATION_TRN(node);
  128.           lperror("Incompatible types of arguments of operation '%s' ",
  129.                   NAME (CODE_TRN(node)));
  130.         }
  131.     }
  132.   /* saving of res_type in argument node */
  133.   if (nd_type_ptr->code == SQLType_0)
  134.     *nd_type_ptr = res_type;
  135.   if (res_type.code == SQLType_0)
  136.     res_type = *nd_type_ptr;
  137.   
  138.   /* making of types for argument trees if it's needed and possible */
  139.   if (nd_type_ptr->code != SQLType_0 && put_type_fl == TRUE)
  140.     for (arg_node = dn_node; arg_node; arg_node = RIGHT_TRN (arg_node))
  141.       if (node_type (arg_node)->code == SQLType_0)
  142.         put_type_to_tree (arg_node, &res_type);
  143. } /* check_arg_types */
  144. TXTREF 
  145. handle_types (TXTREF cur_node, i4_t f)
  146. {
  147.   static sql_type_t type_bool  = {T_BOOL, 0, 0};
  148.   static sql_type_t type_0     = {SQLType_0, 0, 0};
  149.   if (!f)
  150.     return cycler (cur_node, handle_types, CYCLER_LD + CYCLER_RL +
  151.                    CYCLER_DR + CYCLER_LN + CYCLER_RLC);
  152.   if (f == CYCLER_LD && OPER_HAS_TYPE (cur_node) &&
  153.       node_type (cur_node)->code != SQLType_0)
  154.     cycler_skip_subtree = 1;
  155.   else if (f == CYCLER_RL)
  156.     {
  157.       enum token code = CODE_TRN (cur_node);
  158.         
  159.       if (OPER_HAS_TYPE (cur_node))
  160.         {
  161.           if ( Is_Log_Oper_Code (code) ||   /* NOT, OR, AND   */
  162.                Is_Comp_Code     (code) ||   /* >,<,==,>=,<=,!=*/
  163.                Is_Predic_Code   (code))     /* predicates     */
  164.             {
  165.               OPRN_TYPE (cur_node) = type_bool;
  166.               
  167.               if (Is_Log_Oper_Code(code))
  168.                 {
  169.                   sql_type_t *arg_typ;
  170.                   TXTREF arg = DOWN_TRN (cur_node);
  171.                   
  172.                   for (; arg; arg = RIGHT_TRN (arg))
  173.                     {
  174.                       arg_typ = node_type (arg);
  175.                       if (arg_typ->code != T_BOOL)
  176.                         yyerror ("Argument of logic operation isn't of boolean type");
  177.                     }
  178.                 }
  179.               else
  180.                 check_arg_types (cur_node); 
  181.             }
  182.           else if (code != SUBQUERY && code != COUNT)
  183.             {
  184.               OPRN_TYPE (cur_node) = type_0;
  185.               check_arg_types (cur_node);
  186.             }
  187.           CORRECT_TYPE (OPRN_TYPE (cur_node));
  188.         }
  189.       switch (code)
  190.         {
  191.         case COLPTR:
  192.           CORRECT_TYPE (COL_TYPE (OBJ_DESC (cur_node)));
  193.           break;
  194.           
  195.         case CONST:
  196.           if (CNST_TTYPE (cur_node).code == SQLType_0)
  197.             CNST_TTYPE (cur_node) = CORRECT_TYPE (CNST_STYPE (cur_node));
  198.           else
  199.             CNST_STYPE (cur_node) = CORRECT_TYPE (CNST_TTYPE (cur_node));
  200.           break;
  201.         case CREATE:
  202.           if (CODE_TRN (CREATE_OBJ (cur_node)) == VIEW)
  203.             {
  204.               TXTREF view = CREATE_OBJ (cur_node);
  205.               TXTREF col, sel, query = VIEW_QUERY (view);
  206.               
  207.               handle_types (query, 0);
  208.               /*        sel_list(selection(from    (query */
  209.               for(sel = DOWN_TRN(RIGHT_TRN(DOWN_TRN(query))),
  210.                     col = TBL_COLS(view); col && sel;
  211.                   col = COL_NEXT(col), sel = RIGHT_TRN(sel))
  212.                 COL_TYPE(col) = *node_type(sel);
  213.               TASSERT( !col && !sel, view);
  214.             }
  215.           break;
  216.           
  217.         case AVG:
  218.           OPRN_TYPE (cur_node) = pack_type (SQLType_Real, 0, 0);
  219.         case SUM:
  220.           if (node_type (DOWN_TRN (cur_node))->code == SQLType_Char)
  221.             lperror("String can't be an argument of aggregate function %s",
  222.                     NAME (cur_node));
  223.           break;
  224.           
  225.         case LIKE:
  226.           {
  227.             TXTREF like_arg = DOWN_TRN (cur_node);
  228.             i4_t i;
  229.             
  230.             for (i = 0; like_arg; like_arg = RIGHT_TRN (like_arg), i++)
  231.               check_type (like_arg, pack_type (SQLType_Char, (i < 2) ?
  232.                                                DEFAULT_STR_LEN : 1, 0),
  233.                           "Incorrect type of LIKE argument");
  234.           }
  235.           break;
  236.           
  237. case SUBQUERY:
  238.   OPRN_TYPE (cur_node) =
  239.             *node_type (DOWN_TRN (RIGHT_TRN (DOWN_TRN (cur_node))));
  240.   break;
  241.           
  242.   case CALLPR:
  243.           yyerror ("node CALLPR can't exist before code generation");
  244.   break;
  245.           
  246.   case COUNT:
  247.           OPRN_TYPE (cur_node) = pack_type (SQLType_Int, 0, 0);
  248.   break;
  249.           
  250.         default:
  251.           break;
  252.         }
  253.     }
  254.   
  255.   return cur_node;
  256. } /* handle_types */