~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/eval/eval0eval.cc

Merge/fix in FAQ.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1997, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file eval/eval0eval.c
21
 
SQL evaluator: evaluates simple data structures, like expressions, in
22
 
a query graph
23
 
 
24
 
Created 12/29/1997 Heikki Tuuri
25
 
*******************************************************/
26
 
 
27
 
#include "eval0eval.h"
28
 
 
29
 
#ifdef UNIV_NONINL
30
 
#include "eval0eval.ic"
31
 
#endif
32
 
 
33
 
#include "data0data.h"
34
 
#include "row0sel.h"
35
 
 
36
 
/** The RND function seed */
37
 
static ulint    eval_rnd        = 128367121;
38
 
 
39
 
/** Dummy adress used when we should allocate a buffer of size 0 in
40
 
eval_node_alloc_val_buf */
41
 
 
42
 
static byte     eval_dummy;
43
 
 
44
 
/*****************************************************************//**
45
 
Allocate a buffer from global dynamic memory for a value of a que_node.
46
 
NOTE that this memory must be explicitly freed when the query graph is
47
 
freed. If the node already has an allocated buffer, that buffer is freed
48
 
here. NOTE that this is the only function where dynamic memory should be
49
 
allocated for a query node val field.
50
 
@return pointer to allocated buffer */
51
 
UNIV_INTERN
52
 
byte*
53
 
eval_node_alloc_val_buf(
54
 
/*====================*/
55
 
        que_node_t*     node,   /*!< in: query graph node; sets the val field
56
 
                                data field to point to the new buffer, and
57
 
                                len field equal to size */
58
 
        ulint           size)   /*!< in: buffer size */
59
 
{
60
 
        dfield_t*       dfield;
61
 
        byte*           data;
62
 
 
63
 
        ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
64
 
              || que_node_get_type(node) == QUE_NODE_FUNC);
65
 
 
66
 
        dfield = que_node_get_val(node);
67
 
 
68
 
        data = static_cast<unsigned char *>(dfield_get_data(dfield));
69
 
 
70
 
        if (data && data != &eval_dummy) {
71
 
                mem_free(data);
72
 
        }
73
 
 
74
 
        if (size == 0) {
75
 
                data = &eval_dummy;
76
 
        } else {
77
 
                data = static_cast<unsigned char *>(mem_alloc(size));
78
 
        }
79
 
 
80
 
        que_node_set_val_buf_size(node, size);
81
 
 
82
 
        dfield_set_data(dfield, data, size);
83
 
 
84
 
        return(data);
85
 
}
86
 
 
87
 
/*****************************************************************//**
88
 
Free the buffer from global dynamic memory for a value of a que_node,
89
 
if it has been allocated in the above function. The freeing for pushed
90
 
column values is done in sel_col_prefetch_buf_free. */
91
 
UNIV_INTERN
92
 
void
93
 
eval_node_free_val_buf(
94
 
/*===================*/
95
 
        que_node_t*     node)   /*!< in: query graph node */
96
 
{
97
 
        dfield_t*       dfield;
98
 
        byte*           data;
99
 
 
100
 
        ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
101
 
              || que_node_get_type(node) == QUE_NODE_FUNC);
102
 
 
103
 
        dfield = que_node_get_val(node);
104
 
 
105
 
        data = static_cast<unsigned char *>(dfield_get_data(dfield));
106
 
 
107
 
        if (que_node_get_val_buf_size(node) > 0) {
108
 
                ut_a(data);
109
 
 
110
 
                mem_free(data);
111
 
        }
112
 
}
113
 
 
114
 
/*****************************************************************//**
115
 
Evaluates a comparison node.
116
 
@return the result of the comparison */
117
 
UNIV_INTERN
118
 
ibool
119
 
eval_cmp(
120
 
/*=====*/
121
 
        func_node_t*    cmp_node)       /*!< in: comparison node */
122
 
{
123
 
        que_node_t*     arg1;
124
 
        que_node_t*     arg2;
125
 
        int             res;
126
 
        ibool           val;
127
 
        int             func;
128
 
 
129
 
        ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
130
 
 
131
 
        arg1 = cmp_node->args;
132
 
        arg2 = que_node_get_next(arg1);
133
 
 
134
 
        res = cmp_dfield_dfield(que_node_get_val(arg1),
135
 
                                que_node_get_val(arg2));
136
 
        val = TRUE;
137
 
 
138
 
        func = cmp_node->func;
139
 
 
140
 
        if (func == '=') {
141
 
                if (res != 0) {
142
 
                        val = FALSE;
143
 
                }
144
 
        } else if (func == '<') {
145
 
                if (res != -1) {
146
 
                        val = FALSE;
147
 
                }
148
 
        } else if (func == PARS_LE_TOKEN) {
149
 
                if (res == 1) {
150
 
                        val = FALSE;
151
 
                }
152
 
        } else if (func == PARS_NE_TOKEN) {
153
 
                if (res == 0) {
154
 
                        val = FALSE;
155
 
                }
156
 
        } else if (func == PARS_GE_TOKEN) {
157
 
                if (res == -1) {
158
 
                        val = FALSE;
159
 
                }
160
 
        } else {
161
 
                ut_ad(func == '>');
162
 
 
163
 
                if (res != 1) {
164
 
                        val = FALSE;
165
 
                }
166
 
        }
167
 
 
168
 
        eval_node_set_ibool_val(cmp_node, val);
169
 
 
170
 
        return(val);
171
 
}
172
 
 
173
 
/*****************************************************************//**
174
 
Evaluates a logical operation node. */
175
 
UNIV_INLINE
176
 
void
177
 
eval_logical(
178
 
/*=========*/
179
 
        func_node_t*    logical_node)   /*!< in: logical operation node */
180
 
{
181
 
        que_node_t*     arg1;
182
 
        que_node_t*     arg2;
183
 
        ibool           val1;
184
 
        ibool           val2 = 0; /* remove warning */
185
 
        ibool           val = 0;  /* remove warning */
186
 
        int             func;
187
 
 
188
 
        ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
189
 
 
190
 
        arg1 = logical_node->args;
191
 
        arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is 'NOT' */
192
 
 
193
 
        val1 = eval_node_get_ibool_val(arg1);
194
 
 
195
 
        if (arg2) {
196
 
                val2 = eval_node_get_ibool_val(arg2);
197
 
        }
198
 
 
199
 
        func = logical_node->func;
200
 
 
201
 
        if (func == PARS_AND_TOKEN) {
202
 
                val = val1 & val2;
203
 
        } else if (func == PARS_OR_TOKEN) {
204
 
                val = val1 | val2;
205
 
        } else if (func == PARS_NOT_TOKEN) {
206
 
                val = TRUE - val1;
207
 
        } else {
208
 
                ut_error;
209
 
        }
210
 
 
211
 
        eval_node_set_ibool_val(logical_node, val);
212
 
}
213
 
 
214
 
/*****************************************************************//**
215
 
Evaluates an arithmetic operation node. */
216
 
UNIV_INLINE
217
 
void
218
 
eval_arith(
219
 
/*=======*/
220
 
        func_node_t*    arith_node)     /*!< in: arithmetic operation node */
221
 
{
222
 
        que_node_t*     arg1;
223
 
        que_node_t*     arg2;
224
 
        lint            val1;
225
 
        lint            val2 = 0; /* remove warning */
226
 
        lint            val;
227
 
        int             func;
228
 
 
229
 
        ut_ad(que_node_get_type(arith_node) == QUE_NODE_FUNC);
230
 
 
231
 
        arg1 = arith_node->args;
232
 
        arg2 = que_node_get_next(arg1); /* arg2 is NULL if func is unary '-' */
233
 
 
234
 
        val1 = eval_node_get_int_val(arg1);
235
 
 
236
 
        if (arg2) {
237
 
                val2 = eval_node_get_int_val(arg2);
238
 
        }
239
 
 
240
 
        func = arith_node->func;
241
 
 
242
 
        if (func == '+') {
243
 
                val = val1 + val2;
244
 
        } else if ((func == '-') && arg2) {
245
 
                val = val1 - val2;
246
 
        } else if (func == '-') {
247
 
                val = -val1;
248
 
        } else if (func == '*') {
249
 
                val = val1 * val2;
250
 
        } else {
251
 
                ut_ad(func == '/');
252
 
                val = val1 / val2;
253
 
        }
254
 
 
255
 
        eval_node_set_int_val(arith_node, val);
256
 
}
257
 
 
258
 
/*****************************************************************//**
259
 
Evaluates an aggregate operation node. */
260
 
UNIV_INLINE
261
 
void
262
 
eval_aggregate(
263
 
/*===========*/
264
 
        func_node_t*    node)   /*!< in: aggregate operation node */
265
 
{
266
 
        que_node_t*     arg;
267
 
        lint            val;
268
 
        lint            arg_val;
269
 
        int             func;
270
 
 
271
 
        ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
272
 
 
273
 
        val = eval_node_get_int_val(node);
274
 
 
275
 
        func = node->func;
276
 
 
277
 
        if (func == PARS_COUNT_TOKEN) {
278
 
 
279
 
                val = val + 1;
280
 
        } else {
281
 
                ut_ad(func == PARS_SUM_TOKEN);
282
 
 
283
 
                arg = node->args;
284
 
                arg_val = eval_node_get_int_val(arg);
285
 
 
286
 
                val = val + arg_val;
287
 
        }
288
 
 
289
 
        eval_node_set_int_val(node, val);
290
 
}
291
 
 
292
 
/*****************************************************************//**
293
 
Evaluates a predefined function node where the function is not relevant
294
 
in benchmarks. */
295
 
static
296
 
void
297
 
eval_predefined_2(
298
 
/*==============*/
299
 
        func_node_t*    func_node)      /*!< in: predefined function node */
300
 
{
301
 
        que_node_t*     arg;
302
 
        que_node_t*     arg1;
303
 
        que_node_t*     arg2 = 0; /* remove warning (??? bug ???) */
304
 
        lint            int_val;
305
 
        byte*           data;
306
 
        ulint           len1;
307
 
        ulint           len2;
308
 
        int             func;
309
 
        ulint           i;
310
 
 
311
 
        ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
312
 
 
313
 
        arg1 = func_node->args;
314
 
 
315
 
        if (arg1) {
316
 
                arg2 = que_node_get_next(arg1);
317
 
        }
318
 
 
319
 
        func = func_node->func;
320
 
 
321
 
        if (func == PARS_PRINTF_TOKEN) {
322
 
 
323
 
                arg = arg1;
324
 
 
325
 
                while (arg) {
326
 
                        dfield_print(que_node_get_val(arg));
327
 
 
328
 
                        arg = que_node_get_next(arg);
329
 
                }
330
 
 
331
 
                putc('\n', stderr);
332
 
 
333
 
        } else if (func == PARS_ASSERT_TOKEN) {
334
 
 
335
 
                if (!eval_node_get_ibool_val(arg1)) {
336
 
                        fputs("SQL assertion fails in a stored procedure!\n",
337
 
                              stderr);
338
 
                }
339
 
 
340
 
                ut_a(eval_node_get_ibool_val(arg1));
341
 
 
342
 
                /* This function, or more precisely, a debug procedure,
343
 
                returns no value */
344
 
 
345
 
        } else if (func == PARS_RND_TOKEN) {
346
 
 
347
 
                len1 = (ulint)eval_node_get_int_val(arg1);
348
 
                len2 = (ulint)eval_node_get_int_val(arg2);
349
 
 
350
 
                ut_ad(len2 >= len1);
351
 
 
352
 
                if (len2 > len1) {
353
 
                        int_val = (lint) (len1
354
 
                                          + (eval_rnd % (len2 - len1 + 1)));
355
 
                } else {
356
 
                        int_val = (lint) len1;
357
 
                }
358
 
 
359
 
                eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
360
 
 
361
 
                eval_node_set_int_val(func_node, int_val);
362
 
 
363
 
        } else if (func == PARS_RND_STR_TOKEN) {
364
 
 
365
 
                len1 = (ulint)eval_node_get_int_val(arg1);
366
 
 
367
 
                data = eval_node_ensure_val_buf(func_node, len1);
368
 
 
369
 
                for (i = 0; i < len1; i++) {
370
 
                        data[i] = (byte)(97 + (eval_rnd % 3));
371
 
 
372
 
                        eval_rnd = ut_rnd_gen_next_ulint(eval_rnd);
373
 
                }
374
 
        } else {
375
 
                ut_error;
376
 
        }
377
 
}
378
 
 
379
 
/*****************************************************************//**
380
 
Evaluates a notfound-function node. */
381
 
UNIV_INLINE
382
 
void
383
 
eval_notfound(
384
 
/*==========*/
385
 
        func_node_t*    func_node)      /*!< in: function node */
386
 
{
387
 
        sym_node_t*     cursor;
388
 
        sel_node_t*     sel_node;
389
 
        ibool           ibool_val;
390
 
 
391
 
        ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
392
 
 
393
 
        cursor = static_cast<sym_node_t *>(func_node->args);
394
 
 
395
 
        ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
396
 
 
397
 
        if (cursor->token_type == SYM_LIT) {
398
 
 
399
 
                ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
400
 
                                "SQL", 3) == 0);
401
 
 
402
 
                sel_node = cursor->sym_table->query_graph->last_sel_node;
403
 
        } else {
404
 
                sel_node = cursor->alias->cursor_def;
405
 
        }
406
 
 
407
 
        if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
408
 
                ibool_val = TRUE;
409
 
        } else {
410
 
                ibool_val = FALSE;
411
 
        }
412
 
 
413
 
        eval_node_set_ibool_val(func_node, ibool_val);
414
 
}
415
 
 
416
 
/*****************************************************************//**
417
 
Evaluates a substr-function node. */
418
 
UNIV_INLINE
419
 
void
420
 
eval_substr(
421
 
/*========*/
422
 
        func_node_t*    func_node)      /*!< in: function node */
423
 
{
424
 
        que_node_t*     arg1;
425
 
        que_node_t*     arg2;
426
 
        que_node_t*     arg3;
427
 
        dfield_t*       dfield;
428
 
        byte*           str1;
429
 
        ulint           len1;
430
 
        ulint           len2;
431
 
 
432
 
        arg1 = func_node->args;
433
 
        arg2 = que_node_get_next(arg1);
434
 
 
435
 
        ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
436
 
 
437
 
        arg3 = que_node_get_next(arg2);
438
 
 
439
 
        str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
440
 
 
441
 
        len1 = (ulint)eval_node_get_int_val(arg2);
442
 
        len2 = (ulint)eval_node_get_int_val(arg3);
443
 
 
444
 
        dfield = que_node_get_val(func_node);
445
 
 
446
 
        dfield_set_data(dfield, str1 + len1, len2);
447
 
}
448
 
 
449
 
/*****************************************************************//**
450
 
Evaluates a replstr-procedure node. */
451
 
static
452
 
void
453
 
eval_replstr(
454
 
/*=========*/
455
 
        func_node_t*    func_node)      /*!< in: function node */
456
 
{
457
 
        que_node_t*     arg1;
458
 
        que_node_t*     arg2;
459
 
        que_node_t*     arg3;
460
 
        que_node_t*     arg4;
461
 
        byte*           str1;
462
 
        byte*           str2;
463
 
        ulint           len1;
464
 
        ulint           len2;
465
 
 
466
 
        arg1 = func_node->args;
467
 
        arg2 = que_node_get_next(arg1);
468
 
 
469
 
        ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
470
 
 
471
 
        arg3 = que_node_get_next(arg2);
472
 
        arg4 = que_node_get_next(arg3);
473
 
 
474
 
        str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
475
 
        str2 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg2)));
476
 
 
477
 
        len1 = (ulint)eval_node_get_int_val(arg3);
478
 
        len2 = (ulint)eval_node_get_int_val(arg4);
479
 
 
480
 
        if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
481
 
            || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
482
 
 
483
 
                ut_error;
484
 
        }
485
 
 
486
 
        ut_memcpy(str1 + len1, str2, len2);
487
 
}
488
 
 
489
 
/*****************************************************************//**
490
 
Evaluates an instr-function node. */
491
 
static
492
 
void
493
 
eval_instr(
494
 
/*=======*/
495
 
        func_node_t*    func_node)      /*!< in: function node */
496
 
{
497
 
        que_node_t*     arg1;
498
 
        que_node_t*     arg2;
499
 
        dfield_t*       dfield1;
500
 
        dfield_t*       dfield2;
501
 
        lint            int_val;
502
 
        byte*           str1;
503
 
        byte*           str2;
504
 
        byte            match_char;
505
 
        ulint           len1;
506
 
        ulint           len2;
507
 
        ulint           i;
508
 
        ulint           j;
509
 
 
510
 
        arg1 = func_node->args;
511
 
        arg2 = que_node_get_next(arg1);
512
 
 
513
 
        dfield1 = que_node_get_val(arg1);
514
 
        dfield2 = que_node_get_val(arg2);
515
 
 
516
 
        str1 = static_cast<unsigned char *>(dfield_get_data(dfield1));
517
 
        str2 = static_cast<unsigned char *>(dfield_get_data(dfield2));
518
 
 
519
 
        len1 = dfield_get_len(dfield1);
520
 
        len2 = dfield_get_len(dfield2);
521
 
 
522
 
        if (len2 == 0) {
523
 
                ut_error;
524
 
        }
525
 
 
526
 
        match_char = str2[0];
527
 
 
528
 
        for (i = 0; i < len1; i++) {
529
 
                /* In this outer loop, the number of matched characters is 0 */
530
 
 
531
 
                if (str1[i] == match_char) {
532
 
 
533
 
                        if (i + len2 > len1) {
534
 
 
535
 
                                break;
536
 
                        }
537
 
 
538
 
                        for (j = 1;; j++) {
539
 
                                /* We have already matched j characters */
540
 
 
541
 
                                if (j == len2) {
542
 
                                        int_val = i + 1;
543
 
 
544
 
                                        goto match_found;
545
 
                                }
546
 
 
547
 
                                if (str1[i + j] != str2[j]) {
548
 
 
549
 
                                        break;
550
 
                                }
551
 
                        }
552
 
                }
553
 
        }
554
 
 
555
 
        int_val = 0;
556
 
 
557
 
match_found:
558
 
        eval_node_set_int_val(func_node, int_val);
559
 
}
560
 
 
561
 
/*****************************************************************//**
562
 
Evaluates a predefined function node. */
563
 
UNIV_INLINE
564
 
void
565
 
eval_binary_to_number(
566
 
/*==================*/
567
 
        func_node_t*    func_node)      /*!< in: function node */
568
 
{
569
 
        que_node_t*     arg1;
570
 
        dfield_t*       dfield;
571
 
        byte*           str1;
572
 
        byte*           str2;
573
 
        ulint           len1;
574
 
        ulint           int_val;
575
 
 
576
 
        arg1 = func_node->args;
577
 
 
578
 
        dfield = que_node_get_val(arg1);
579
 
 
580
 
        str1 = static_cast<unsigned char *>(dfield_get_data(dfield));
581
 
        len1 = dfield_get_len(dfield);
582
 
 
583
 
        if (len1 > 4) {
584
 
                ut_error;
585
 
        }
586
 
 
587
 
        if (len1 == 4) {
588
 
                str2 = str1;
589
 
        } else {
590
 
                int_val = 0;
591
 
                str2 = (byte*)&int_val;
592
 
 
593
 
                ut_memcpy(str2 + (4 - len1), str1, len1);
594
 
        }
595
 
 
596
 
        eval_node_copy_and_alloc_val(func_node, str2, 4);
597
 
}
598
 
 
599
 
/*****************************************************************//**
600
 
Evaluates a predefined function node. */
601
 
static
602
 
void
603
 
eval_concat(
604
 
/*========*/
605
 
        func_node_t*    func_node)      /*!< in: function node */
606
 
{
607
 
        que_node_t*     arg;
608
 
        dfield_t*       dfield;
609
 
        byte*           data;
610
 
        ulint           len;
611
 
        ulint           len1;
612
 
 
613
 
        arg = func_node->args;
614
 
        len = 0;
615
 
 
616
 
        while (arg) {
617
 
                len1 = dfield_get_len(que_node_get_val(arg));
618
 
 
619
 
                len += len1;
620
 
 
621
 
                arg = que_node_get_next(arg);
622
 
        }
623
 
 
624
 
        data = eval_node_ensure_val_buf(func_node, len);
625
 
 
626
 
        arg = func_node->args;
627
 
        len = 0;
628
 
 
629
 
        while (arg) {
630
 
                dfield = que_node_get_val(arg);
631
 
                len1 = dfield_get_len(dfield);
632
 
 
633
 
                ut_memcpy(data + len, dfield_get_data(dfield), len1);
634
 
 
635
 
                len += len1;
636
 
 
637
 
                arg = que_node_get_next(arg);
638
 
        }
639
 
}
640
 
 
641
 
/*****************************************************************//**
642
 
Evaluates a predefined function node. If the first argument is an integer,
643
 
this function looks at the second argument which is the integer length in
644
 
bytes, and converts the integer to a VARCHAR.
645
 
If the first argument is of some other type, this function converts it to
646
 
BINARY. */
647
 
UNIV_INLINE
648
 
void
649
 
eval_to_binary(
650
 
/*===========*/
651
 
        func_node_t*    func_node)      /*!< in: function node */
652
 
{
653
 
        que_node_t*     arg1;
654
 
        que_node_t*     arg2;
655
 
        dfield_t*       dfield;
656
 
        byte*           str1;
657
 
        ulint           len;
658
 
        ulint           len1;
659
 
 
660
 
        arg1 = func_node->args;
661
 
 
662
 
        str1 = static_cast<unsigned char *>(dfield_get_data(que_node_get_val(arg1)));
663
 
 
664
 
        if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
665
 
 
666
 
                len = dfield_get_len(que_node_get_val(arg1));
667
 
 
668
 
                dfield = que_node_get_val(func_node);
669
 
 
670
 
                dfield_set_data(dfield, str1, len);
671
 
 
672
 
                return;
673
 
        }
674
 
 
675
 
        arg2 = que_node_get_next(arg1);
676
 
 
677
 
        len1 = (ulint)eval_node_get_int_val(arg2);
678
 
 
679
 
        if (len1 > 4) {
680
 
 
681
 
                ut_error;
682
 
        }
683
 
 
684
 
        dfield = que_node_get_val(func_node);
685
 
 
686
 
        dfield_set_data(dfield, str1 + (4 - len1), len1);
687
 
}
688
 
 
689
 
/*****************************************************************//**
690
 
Evaluates a predefined function node. */
691
 
UNIV_INLINE
692
 
void
693
 
eval_predefined(
694
 
/*============*/
695
 
        func_node_t*    func_node)      /*!< in: function node */
696
 
{
697
 
        que_node_t*     arg1;
698
 
        lint            int_val;
699
 
        byte*           data;
700
 
        int             func;
701
 
 
702
 
        func = func_node->func;
703
 
 
704
 
        arg1 = func_node->args;
705
 
 
706
 
        if (func == PARS_LENGTH_TOKEN) {
707
 
 
708
 
                int_val = (lint)dfield_get_len(que_node_get_val(arg1));
709
 
 
710
 
        } else if (func == PARS_TO_CHAR_TOKEN) {
711
 
 
712
 
                /* Convert number to character string as a
713
 
                signed decimal integer. */
714
 
 
715
 
                ulint   uint_val;
716
 
                int     int_len;
717
 
 
718
 
                int_val = eval_node_get_int_val(arg1);
719
 
 
720
 
                /* Determine the length of the string. */
721
 
 
722
 
                if (int_val == 0) {
723
 
                        int_len = 1; /* the number 0 occupies 1 byte */
724
 
                } else {
725
 
                        int_len = 0;
726
 
                        if (int_val < 0) {
727
 
                                uint_val = ((ulint) -int_val - 1) + 1;
728
 
                                int_len++; /* reserve space for minus sign */
729
 
                        } else {
730
 
                                uint_val = (ulint) int_val;
731
 
                        }
732
 
                        for (; uint_val > 0; int_len++) {
733
 
                                uint_val /= 10;
734
 
                        }
735
 
                }
736
 
 
737
 
                /* allocate the string */
738
 
                data = eval_node_ensure_val_buf(func_node, int_len + 1);
739
 
 
740
 
                /* add terminating NUL character */
741
 
                data[int_len] = 0;
742
 
 
743
 
                /* convert the number */
744
 
 
745
 
                if (int_val == 0) {
746
 
                        data[0] = '0';
747
 
                } else {
748
 
                        int tmp;
749
 
                        if (int_val < 0) {
750
 
                                data[0] = '-'; /* preceding minus sign */
751
 
                                uint_val = ((ulint) -int_val - 1) + 1;
752
 
                        } else {
753
 
                                uint_val = (ulint) int_val;
754
 
                        }
755
 
                        for (tmp = int_len; uint_val > 0; uint_val /= 10) {
756
 
                                data[--tmp] = (byte)
757
 
                                        ('0' + (byte)(uint_val % 10));
758
 
                        }
759
 
                }
760
 
 
761
 
                dfield_set_len(que_node_get_val(func_node), int_len);
762
 
 
763
 
                return;
764
 
 
765
 
        } else if (func == PARS_TO_NUMBER_TOKEN) {
766
 
 
767
 
                int_val = atoi((char*)
768
 
                               dfield_get_data(que_node_get_val(arg1)));
769
 
 
770
 
        } else if (func == PARS_SYSDATE_TOKEN) {
771
 
                int_val = (lint)ut_time();
772
 
        } else {
773
 
                eval_predefined_2(func_node);
774
 
 
775
 
                return;
776
 
        }
777
 
 
778
 
        eval_node_set_int_val(func_node, int_val);
779
 
}
780
 
 
781
 
/*****************************************************************//**
782
 
Evaluates a function node. */
783
 
UNIV_INTERN
784
 
void
785
 
eval_func(
786
 
/*======*/
787
 
        func_node_t*    func_node)      /*!< in: function node */
788
 
{
789
 
        que_node_t*     arg;
790
 
        ulint           func_class;
791
 
        ulint           func;
792
 
 
793
 
        ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
794
 
 
795
 
        func_class = func_node->func_class;
796
 
        func = func_node->func;
797
 
 
798
 
        arg = func_node->args;
799
 
 
800
 
        /* Evaluate first the argument list */
801
 
        while (arg) {
802
 
                eval_exp(arg);
803
 
 
804
 
                /* The functions are not defined for SQL null argument
805
 
                values, except for eval_cmp and notfound */
806
 
 
807
 
                if (dfield_is_null(que_node_get_val(arg))
808
 
                    && (func_class != PARS_FUNC_CMP)
809
 
                    && (func != PARS_NOTFOUND_TOKEN)
810
 
                    && (func != PARS_PRINTF_TOKEN)) {
811
 
                        ut_error;
812
 
                }
813
 
 
814
 
                arg = que_node_get_next(arg);
815
 
        }
816
 
 
817
 
        if (func_class == PARS_FUNC_CMP) {
818
 
                eval_cmp(func_node);
819
 
        } else if (func_class == PARS_FUNC_ARITH) {
820
 
                eval_arith(func_node);
821
 
        } else if (func_class == PARS_FUNC_AGGREGATE) {
822
 
                eval_aggregate(func_node);
823
 
        } else if (func_class == PARS_FUNC_PREDEFINED) {
824
 
 
825
 
                if (func == PARS_NOTFOUND_TOKEN) {
826
 
                        eval_notfound(func_node);
827
 
                } else if (func == PARS_SUBSTR_TOKEN) {
828
 
                        eval_substr(func_node);
829
 
                } else if (func == PARS_REPLSTR_TOKEN) {
830
 
                        eval_replstr(func_node);
831
 
                } else if (func == PARS_INSTR_TOKEN) {
832
 
                        eval_instr(func_node);
833
 
                } else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
834
 
                        eval_binary_to_number(func_node);
835
 
                } else if (func == PARS_CONCAT_TOKEN) {
836
 
                        eval_concat(func_node);
837
 
                } else if (func == PARS_TO_BINARY_TOKEN) {
838
 
                        eval_to_binary(func_node);
839
 
                } else {
840
 
                        eval_predefined(func_node);
841
 
                }
842
 
        } else {
843
 
                ut_ad(func_class == PARS_FUNC_LOGICAL);
844
 
 
845
 
                eval_logical(func_node);
846
 
        }
847
 
}