~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

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

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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->class;
 
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
}