~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/eval/eval0eval.c

  • Committer: Brian Aker
  • Date: 2009-12-29 01:38:38 UTC
  • mfrom: (1251.1.1 drizzle)
  • Revision ID: brian@gaz-20091229013838-03kb2z5xbqw03ddt
Merge of Diego fix.

Show diffs side-by-side

added added

removed removed

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