1 /**
2 Copyright (C) 1995, 1996 by Ke Jin <kejin@visigenic.com>
3 Enhanced for unixODBC (1999) by Peter Harvey <pharvey@codebydesign.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 **/
15
16 #include <config.h>
17 #include <nnconfig.h>
18 #include <yystmt.h>
19 #include <yylex.h>
20 #include <nncol.h>
21 #include <nndate.h>
22 #include <yyerr.h>
23
getleaftype(yystmt_t * yystmt,node_t * nd)24 static int getleaftype(yystmt_t* yystmt, node_t* nd)
25 {
26 yypar_t* par;
27 yyattr_t* attr;
28
29 switch( nd->type )
30 {
31 case en_nt_attr:
32 attr = yystmt->pattr + (nd->value).iattr;
33
34 switch((nd->value).iattr)
35 {
36 case en_lines:
37 case en_article_num:
38 case en_sql_num:
39 case en_sql_count:
40 return en_nt_num;
41
42 case en_date:
43 case en_sql_date:
44 return en_nt_date;
45
46 default:
47 break;
48 }
49 return en_nt_qstr;
50
51 case en_nt_param:
52 par = yystmt->ppar + (nd->value).ipar - 1;
53
54 switch(par->type)
55 {
56 case en_nt_null:
57 case en_nt_num:
58 case en_nt_qstr:
59 case en_nt_date:
60 break;
61
62 default:
63 return -1;
64 }
65 return par->type;
66
67 case en_nt_num:
68 case en_nt_qstr:
69 case en_nt_date:
70 case en_nt_null:
71 return nd->type;
72
73 default:
74 return -1;
75 }
76 }
77
cmp_tchk(yystmt_t * yystmt,node_t * a,node_t * b)78 static int cmp_tchk(yystmt_t* yystmt, node_t* a, node_t* b)
79 {
80 int ta, tb;
81
82 ta = getleaftype( yystmt, a );
83 tb = getleaftype( yystmt, b );
84
85 if( ta == -1 || tb == -1 )
86 return -1;
87
88 if( ta == en_nt_date && tb == en_nt_qstr )
89 return 0;
90
91 if( ta != tb && ta != en_nt_null && tb != en_nt_null )
92 return -1;
93
94 return 0;
95 }
96
evl_like_tchk(yystmt_t * yystmt,node_t * a,node_t * b)97 static int evl_like_tchk(yystmt_t* yystmt, node_t* a, node_t* b)
98 {
99 int ta, tb;
100
101 ta = getleaftype(yystmt, a);
102 tb = getleaftype(yystmt, b);
103
104 if( tb == en_nt_null
105 || tb == en_nt_null )
106 return 0;
107
108 if( ta != en_nt_qstr
109 || tb != en_nt_qstr )
110 return -1;
111
112 return 0;
113 }
114
srchtree_tchk(yystmt_t * yystmt,node_t * node)115 static int srchtree_tchk(yystmt_t* yystmt, node_t* node)
116 /* return -1: err or syserr, 0: ok */
117 {
118 int r, s, flag = 0;
119 node_t* ptr;
120
121 if( ! node )
122 return 0;
123
124 switch( node->type )
125 {
126 case en_nt_cmpop:
127 return cmp_tchk(yystmt, node->left, node->right);
128
129 case en_nt_logop:
130 switch( (node->value).logop )
131 {
132 case en_logop_not:
133 return srchtree_tchk(yystmt, node->right);
134
135 case en_logop_and:
136 case en_logop_or:
137 r = srchtree_tchk(yystmt, node->left);
138 s = srchtree_tchk(yystmt, node->right);
139
140 if( r == -1 || s == -1 )
141 return -1;
142
143 return 0;
144
145 default:
146 abort();
147 break; /* just for turn off the warning */
148 }
149 break; /* just for turn off the warning */
150
151 case en_nt_isnull:
152 return 0;
153
154 case en_nt_between:
155 r = cmp_tchk(yystmt, node->left, node->right->left);
156 s = cmp_tchk(yystmt, node->left, node->right->right);
157
158 if( r == -1 || s == -1 )
159 return -1;
160
161 return 0;
162
163 case en_nt_in:
164 for(ptr=node->right; ptr; ptr=ptr->right)
165 {
166 r = cmp_tchk(yystmt, node->left, ptr);
167
168 if( r == -1 )
169 return -1;
170 }
171 return 0;
172
173 case en_nt_caselike:
174 case en_nt_like:
175 return evl_like_tchk( yystmt, node->left, node->right);
176
177 default:
178 abort();
179 break; /* turn off the warning */
180 }
181
182 return -1; /* just for turn off the warning */
183 }
184
nnsql_srchtree_tchk(void * hstmt)185 int nnsql_srchtree_tchk(void* hstmt)
186 {
187 yystmt_t* yystmt = hstmt;
188 int r;
189
190 r = srchtree_tchk(yystmt, yystmt->srchtree);
191
192 if( r )
193 yystmt->errcode = TYPE_VIOLATION;
194
195 return r;
196 }
197