1 //-< QUERY.CPP >-----------------------------------------------------*--------*
2 // GigaBASE Version 1.0 (c) 1999 GARRET * ? *
3 // (Post Relational Database Management System) * /\| *
4 // * / \ *
5 // Created: 20-Nov-98 K.A. Knizhnik * / [] \ *
6 // Last update: 10-Dec-98 K.A. Knizhnik * GARRET *
7 //-------------------------------------------------------------------*--------*
8 // Constructing and hashing database query statements
9 //-------------------------------------------------------------------*--------*
10
11 #define INSIDE_GIGABASE
12
13 #include "gigabase.h"
14 #include "symtab.h"
15 #include "compiler.h"
16
17 BEGIN_GIGABASE_NAMESPACE
18
19 dbQueryElementAllocator dbQueryElementAllocator::instance;
20
operator new(size_t size)21 void* dbQueryElement::operator new(size_t size) {
22 return dbQueryElementAllocator::instance.allocate(size);
23 }
24
operator delete(void * p)25 void dbQueryElement::operator delete(void* p) {
26 dbFree(p);
27 }
28
dump(char_t * buf)29 char_t* dbQueryElement::dump(char_t* buf)
30 {
31 switch (type) {
32 case qExpression:
33 buf += SPRINTF(SPRINTF_BUFFER(buf), _T(" %s "), (char_t*)ptr);
34 break;
35 case qVarBool:
36 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{bool}"));
37 break;
38 case qVarInt1:
39 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{int1}"));
40 break;
41 case qVarInt2:
42 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{int2}"));
43 break;
44 case qVarInt4:
45 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{int4}"));
46 break;
47 case qVarInt8:
48 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{db_int8}"));
49 break;
50 case qVarReal4:
51 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{real4}"));
52 break;
53 case qVarReal8:
54 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{real8}"));
55 break;
56 case qVarString:
57 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{char*}"));
58 break;
59 case qVarStringPtr:
60 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{char**}"));
61 break;
62 case qVarReference:
63 if (ref != NULL) {
64 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbReference<%s>}"), ref->getName());
65 } else {
66 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbAnyReference}"));
67 }
68 break;
69 case qVarArrayOfRef:
70 if (ref != NULL) {
71 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray< dbReference<%s> >}"), ref->getName());
72 } else {
73 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray<dbAnyReference>}"));
74 }
75 break;
76 case qVarArrayOfRefPtr:
77 if (ref != NULL) {
78 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray< dbReference<%s> >*}"), ref->getName());
79 } else {
80 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray<dbAnyReference>*}"));
81 }
82 break;
83 case qVarRawData:
84 case qVarRawDataPtr:
85 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{raw binary}"));
86 break;
87 case qVarRectangle:
88 case qVarRectanglePtr:
89 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{rectangle}"));
90 break;
91 case qVarUnknown:
92 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("???"));
93 break;
94 #ifdef USE_MFC_STRING
95 case qVarMfcString:
96 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{CString}"));
97 break;
98 #endif
99 #ifdef USE_STD_STRING
100 case qVarStdString:
101 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{string}"));
102 break;
103 #endif
104 default:
105 break;
106 }
107 return buf;
108 }
109
dumpValues(char_t * buf)110 char_t* dbQueryElement::dumpValues(char_t* buf)
111 {
112 switch (type) {
113 case qExpression:
114 buf += SPRINTF(SPRINTF_BUFFER(buf), _T(" %s "), (char*)ptr);
115 break;
116 case qVarBool:
117 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%s"), *(bool*)ptr ? _T("true") : _T("false"));
118 break;
119 case qVarInt1:
120 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%d"), *(int1*)ptr);
121 break;
122 case qVarInt2:
123 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%d"), *(int2*)ptr);
124 break;
125 case qVarInt4:
126 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%d"), *(int4*)ptr);
127 break;
128 case qVarInt8:
129 buf += SPRINTF(SPRINTF_BUFFER(buf), T_INT8_FORMAT, *(db_int8*)ptr);
130 break;
131 case qVarReal4:
132 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%f"), *(real4*)ptr);
133 break;
134 case qVarReal8:
135 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%f"), *(real8*)ptr);
136 break;
137 case qVarString:
138 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("'%s'"), (char*)ptr);
139 break;
140 case qVarStringPtr:
141 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("'%s'"), *(char**)ptr);
142 break;
143 case qVarReference:
144 if (ref != NULL) {
145 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("@%s:%lx"), ref->getName(), (unsigned long)*(oid_t*)ptr);
146 } else {
147 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("@%lx"), (unsigned long)*(oid_t*)ptr);
148 }
149 break;
150 case qVarArrayOfRef:
151 if (ref != NULL) {
152 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray< dbReference<%s> >}"), ref->getName());
153 } else {
154 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray<dbAnyReference>}"));
155 }
156 break;
157 case qVarArrayOfRefPtr:
158 if (ref != NULL) {
159 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray< dbReference<%s> >*}"), ref->getName());
160 } else {
161 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{dbArray<dbAnyReference>*}"));
162 }
163 break;
164 case qVarRawData:
165 case qVarRawDataPtr:
166 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("{raw binary}"));
167 break;
168 case qVarRectangle:
169 {
170 int i, sep = '(';
171 rectangle& r = *(rectangle*)ptr;
172 for (i = 0; i < rectangle::dim*2; i++) {
173 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%c%f"), sep, (double)r.boundary[i]);
174 sep = ',';
175 }
176 *buf++ = ')';
177 *buf = '\0';
178 }
179 break;
180 case qVarRectanglePtr:
181 {
182 int i, sep = '(';
183 rectangle& r = **(rectangle**)ptr;
184 for (i = 0; i < rectangle::dim*2; i++) {
185 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("%c%f"), sep, (double)r.boundary[i]);
186 sep = ',';
187 }
188 *buf++ = ')';
189 *buf = '\0';
190 }
191 break;
192 case qVarUnknown:
193 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("???"));
194 break;
195 #ifdef USE_MFC_STRING
196 case qVarMfcString:
197 buf += SPRINTF(SPRINTF_BUFFER(buf), (sizeof(MFC_STRING::XCHAR)==sizeof(char)) ? _T("'%hs'") : _T("'%ls'"), (MFC_STRING::PCXSTR)*(MFC_STRING*)ptr);
198 break;
199 #endif
200 #ifdef USE_STD_STRING
201 case qVarStdString:
202 buf += SPRINTF(SPRINTF_BUFFER(buf), _T("'%s'"), ((STD_STRING*)ptr)->c_str());
203 break;
204 #endif
205 default:
206 break;
207 }
208 return buf;
209 }
210
211
dbQueryElementAllocator()212 dbQueryElementAllocator::dbQueryElementAllocator()
213 : freeChain(NULL)
214 {
215 }
216
~dbQueryElementAllocator()217 dbQueryElementAllocator::~dbQueryElementAllocator()
218 {
219 dbQueryElement *elem, *next;
220 for (elem = freeChain; elem != NULL; elem = next) {
221 next = elem->next;
222 delete elem;
223 }
224 }
225
operator =(dbComponent const & comp)226 dbQueryExpression& dbQueryExpression::operator = (dbComponent const& comp)
227 {
228 first = NULL;
229 last = &first;
230 add(dbQueryElement::qExpression, comp.structure);
231 if (comp.field != NULL) {
232 add(dbQueryElement::qExpression, _T("."));
233 add(dbQueryElement::qExpression, comp.field);
234 }
235 operand = false;
236 return *this;
237 }
238
operator =(dbQueryExpression const & expr)239 dbQueryExpression& dbQueryExpression::operator=(dbQueryExpression const& expr)
240 {
241 first = new dbQueryElement(dbQueryElement::qExpression, _T("("));
242 first->next = expr.first;
243 last = expr.last;
244 *last = new dbQueryElement(dbQueryElement::qExpression, _T(")"));
245 last = &(*last)->next;
246 operand = false;
247 return *this;
248 }
249
add(dbQueryExpression const & expr)250 dbQuery& dbQuery::add(dbQueryExpression const& expr)
251 {
252 append(dbQueryElement::qExpression, _T("("));
253 *nextElement = expr.first;
254 nextElement = expr.last;
255 append(dbQueryElement::qExpression, _T(")"));
256 operand = false;
257 return *this;
258 }
259
260
261
reset()262 dbQuery& dbQuery::reset()
263 {
264 dbQueryElementAllocator::instance.free(elements, nextElement);
265 elements = NULL;
266 nextElement = &elements;
267 operand = false;
268 mutexLocked = false;
269
270 dbCompiledQuery::destroy();
271 return *this;
272 }
273
destroy()274 void dbCompiledQuery::destroy()
275 {
276 if (tree != NULL) {
277 dbMutex& mutex = dbExprNodeAllocator::instance.getMutex();
278 dbCriticalSection cs(mutex);
279 if (mutex.isInitialized()) {
280 delete tree;
281 for (dbOrderByNode *op = order, *nop; op != NULL; op = nop) {
282 nop = op->next;
283 delete op;
284 }
285 for (dbFollowByNode *fp = follow, *nfp; fp != NULL; fp = nfp) {
286 nfp = fp->next;
287 delete fp;
288 }
289 }
290 tree = NULL;
291 }
292 startFrom = StartFromAny;
293 follow = NULL;
294 order = NULL;
295 table = NULL;
296 limitSpecified = false;
297 }
298
getParameterType()299 int dbUserFunction::getParameterType()
300 {
301 static byte argType[] = {
302 tpInteger,
303 tpReal,
304 tpString,
305 tpInteger,
306 tpReal,
307 tpString,
308 tpInteger,
309 tpReal,
310 tpString,
311 tpInteger,
312 tpReal,
313 tpString,
314 tpList,
315 tpList,
316 tpList,
317 tpList,
318 tpList,
319 tpList,
320 tpList,
321 tpList,
322 tpList,
323 tpList,
324 tpList,
325 tpList
326 };
327 return argType[type];
328 }
329
330
getNumberOfParameters()331 int dbUserFunction::getNumberOfParameters()
332 {
333 static byte nArgs[] = {
334 1,
335 1,
336 1,
337 1,
338 1,
339 1,
340 1,
341 1,
342 1,
343 1,
344 1,
345 1,
346 1,
347 1,
348 1,
349 1,
350 2,
351 2,
352 2,
353 2,
354 3,
355 3,
356 3,
357 3
358 };
359 return nArgs[type];
360 }
361
362 dbUserFunction* dbUserFunction::list;
363
364
bind(char_t * name,void * f,funcType ftype)365 void dbUserFunction::bind(char_t* name, void* f, funcType ftype)
366 {
367 fname = name;
368 dbSymbolTable::add(fname, tkn_ident, GB_CLONE_ANY_IDENTIFIER);
369 next = list;
370 list = this;
371 fptr = f;
372 type = ftype;
373 }
374
~dbUserFunction()375 dbUserFunction::~dbUserFunction()
376 {
377 dbUserFunction *fp, **fpp;
378 for (fpp = &list; (fp = *fpp) != this; fpp = &fp->next);
379 *fpp = next;
380 }
381
382
dbUserFunctionArgument(dbExprNode * expr,dbInheritedAttribute & iattr,dbSynthesizedAttribute & sattr,int i)383 dbUserFunctionArgument::dbUserFunctionArgument(dbExprNode* expr,
384 dbInheritedAttribute& iattr,
385 dbSynthesizedAttribute& sattr,
386 int i)
387 {
388 dbDatabase::execute(expr->func.arg[i], iattr, sattr);
389 switch (expr->func.arg[i]->type) {
390 case tpInteger:
391 u.intValue = sattr.ivalue;
392 type = atInteger;
393 break;
394 case tpReal:
395 u.realValue = sattr.fvalue;
396 type = atReal;
397 break;
398 case tpString:
399 u.strValue = (char_t*)sattr.array.base;
400 type = atString;
401 break;
402 case tpBoolean:
403 u.boolValue = sattr.bvalue;
404 type = atBoolean;
405 break;
406 case tpReference:
407 u.oidValue = sattr.oid;
408 type = atReference;
409 break;
410 case tpRawBinary:
411 u.rawValue = sattr.raw;
412 type = atRawBinary;
413 break;
414 default:
415 assert(false);
416 }
417 }
418
419 END_GIGABASE_NAMESPACE
420
421