~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 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 = 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 = 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 = 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
        que_node_t*     arg1;
 
388
        que_node_t*     arg2;
 
389
        sym_node_t*     cursor;
 
390
        sel_node_t*     sel_node;
 
391
        ibool           ibool_val;
 
392
 
 
393
        arg1 = func_node->args;
 
394
        arg2 = que_node_get_next(arg1);
 
395
 
 
396
        ut_ad(func_node->func == PARS_NOTFOUND_TOKEN);
 
397
 
 
398
        cursor = arg1;
 
399
 
 
400
        ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
 
401
 
 
402
        if (cursor->token_type == SYM_LIT) {
 
403
 
 
404
                ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
 
405
                                "SQL", 3) == 0);
 
406
 
 
407
                sel_node = cursor->sym_table->query_graph->last_sel_node;
 
408
        } else {
 
409
                sel_node = cursor->alias->cursor_def;
 
410
        }
 
411
 
 
412
        if (sel_node->state == SEL_NODE_NO_MORE_ROWS) {
 
413
                ibool_val = TRUE;
 
414
        } else {
 
415
                ibool_val = FALSE;
 
416
        }
 
417
 
 
418
        eval_node_set_ibool_val(func_node, ibool_val);
 
419
}
 
420
 
 
421
/*****************************************************************//**
 
422
Evaluates a substr-function node. */
 
423
UNIV_INLINE
 
424
void
 
425
eval_substr(
 
426
/*========*/
 
427
        func_node_t*    func_node)      /*!< in: function node */
 
428
{
 
429
        que_node_t*     arg1;
 
430
        que_node_t*     arg2;
 
431
        que_node_t*     arg3;
 
432
        dfield_t*       dfield;
 
433
        byte*           str1;
 
434
        ulint           len1;
 
435
        ulint           len2;
 
436
 
 
437
        arg1 = func_node->args;
 
438
        arg2 = que_node_get_next(arg1);
 
439
 
 
440
        ut_ad(func_node->func == PARS_SUBSTR_TOKEN);
 
441
 
 
442
        arg3 = que_node_get_next(arg2);
 
443
 
 
444
        str1 = dfield_get_data(que_node_get_val(arg1));
 
445
 
 
446
        len1 = (ulint)eval_node_get_int_val(arg2);
 
447
        len2 = (ulint)eval_node_get_int_val(arg3);
 
448
 
 
449
        dfield = que_node_get_val(func_node);
 
450
 
 
451
        dfield_set_data(dfield, str1 + len1, len2);
 
452
}
 
453
 
 
454
/*****************************************************************//**
 
455
Evaluates a replstr-procedure node. */
 
456
static
 
457
void
 
458
eval_replstr(
 
459
/*=========*/
 
460
        func_node_t*    func_node)      /*!< in: function node */
 
461
{
 
462
        que_node_t*     arg1;
 
463
        que_node_t*     arg2;
 
464
        que_node_t*     arg3;
 
465
        que_node_t*     arg4;
 
466
        byte*           str1;
 
467
        byte*           str2;
 
468
        ulint           len1;
 
469
        ulint           len2;
 
470
 
 
471
        arg1 = func_node->args;
 
472
        arg2 = que_node_get_next(arg1);
 
473
 
 
474
        ut_ad(que_node_get_type(arg1) == QUE_NODE_SYMBOL);
 
475
 
 
476
        arg3 = que_node_get_next(arg2);
 
477
        arg4 = que_node_get_next(arg3);
 
478
 
 
479
        str1 = dfield_get_data(que_node_get_val(arg1));
 
480
        str2 = dfield_get_data(que_node_get_val(arg2));
 
481
 
 
482
        len1 = (ulint)eval_node_get_int_val(arg3);
 
483
        len2 = (ulint)eval_node_get_int_val(arg4);
 
484
 
 
485
        if ((dfield_get_len(que_node_get_val(arg1)) < len1 + len2)
 
486
            || (dfield_get_len(que_node_get_val(arg2)) < len2)) {
 
487
 
 
488
                ut_error;
 
489
        }
 
490
 
 
491
        ut_memcpy(str1 + len1, str2, len2);
 
492
}
 
493
 
 
494
/*****************************************************************//**
 
495
Evaluates an instr-function node. */
 
496
static
 
497
void
 
498
eval_instr(
 
499
/*=======*/
 
500
        func_node_t*    func_node)      /*!< in: function node */
 
501
{
 
502
        que_node_t*     arg1;
 
503
        que_node_t*     arg2;
 
504
        dfield_t*       dfield1;
 
505
        dfield_t*       dfield2;
 
506
        lint            int_val;
 
507
        byte*           str1;
 
508
        byte*           str2;
 
509
        byte            match_char;
 
510
        ulint           len1;
 
511
        ulint           len2;
 
512
        ulint           i;
 
513
        ulint           j;
 
514
 
 
515
        arg1 = func_node->args;
 
516
        arg2 = que_node_get_next(arg1);
 
517
 
 
518
        dfield1 = que_node_get_val(arg1);
 
519
        dfield2 = que_node_get_val(arg2);
 
520
 
 
521
        str1 = dfield_get_data(dfield1);
 
522
        str2 = dfield_get_data(dfield2);
 
523
 
 
524
        len1 = dfield_get_len(dfield1);
 
525
        len2 = dfield_get_len(dfield2);
 
526
 
 
527
        if (len2 == 0) {
 
528
                ut_error;
 
529
        }
 
530
 
 
531
        match_char = str2[0];
 
532
 
 
533
        for (i = 0; i < len1; i++) {
 
534
                /* In this outer loop, the number of matched characters is 0 */
 
535
 
 
536
                if (str1[i] == match_char) {
 
537
 
 
538
                        if (i + len2 > len1) {
 
539
 
 
540
                                break;
 
541
                        }
 
542
 
 
543
                        for (j = 1;; j++) {
 
544
                                /* We have already matched j characters */
 
545
 
 
546
                                if (j == len2) {
 
547
                                        int_val = i + 1;
 
548
 
 
549
                                        goto match_found;
 
550
                                }
 
551
 
 
552
                                if (str1[i + j] != str2[j]) {
 
553
 
 
554
                                        break;
 
555
                                }
 
556
                        }
 
557
                }
 
558
        }
 
559
 
 
560
        int_val = 0;
 
561
 
 
562
match_found:
 
563
        eval_node_set_int_val(func_node, int_val);
 
564
}
 
565
 
 
566
/*****************************************************************//**
 
567
Evaluates a predefined function node. */
 
568
UNIV_INLINE
 
569
void
 
570
eval_binary_to_number(
 
571
/*==================*/
 
572
        func_node_t*    func_node)      /*!< in: function node */
 
573
{
 
574
        que_node_t*     arg1;
 
575
        dfield_t*       dfield;
 
576
        byte*           str1;
 
577
        byte*           str2;
 
578
        ulint           len1;
 
579
        ulint           int_val;
 
580
 
 
581
        arg1 = func_node->args;
 
582
 
 
583
        dfield = que_node_get_val(arg1);
 
584
 
 
585
        str1 = dfield_get_data(dfield);
 
586
        len1 = dfield_get_len(dfield);
 
587
 
 
588
        if (len1 > 4) {
 
589
                ut_error;
 
590
        }
 
591
 
 
592
        if (len1 == 4) {
 
593
                str2 = str1;
 
594
        } else {
 
595
                int_val = 0;
 
596
                str2 = (byte*)&int_val;
 
597
 
 
598
                ut_memcpy(str2 + (4 - len1), str1, len1);
 
599
        }
 
600
 
 
601
        eval_node_copy_and_alloc_val(func_node, str2, 4);
 
602
}
 
603
 
 
604
/*****************************************************************//**
 
605
Evaluates a predefined function node. */
 
606
static
 
607
void
 
608
eval_concat(
 
609
/*========*/
 
610
        func_node_t*    func_node)      /*!< in: function node */
 
611
{
 
612
        que_node_t*     arg;
 
613
        dfield_t*       dfield;
 
614
        byte*           data;
 
615
        ulint           len;
 
616
        ulint           len1;
 
617
 
 
618
        arg = func_node->args;
 
619
        len = 0;
 
620
 
 
621
        while (arg) {
 
622
                len1 = dfield_get_len(que_node_get_val(arg));
 
623
 
 
624
                len += len1;
 
625
 
 
626
                arg = que_node_get_next(arg);
 
627
        }
 
628
 
 
629
        data = eval_node_ensure_val_buf(func_node, len);
 
630
 
 
631
        arg = func_node->args;
 
632
        len = 0;
 
633
 
 
634
        while (arg) {
 
635
                dfield = que_node_get_val(arg);
 
636
                len1 = dfield_get_len(dfield);
 
637
 
 
638
                ut_memcpy(data + len, dfield_get_data(dfield), len1);
 
639
 
 
640
                len += len1;
 
641
 
 
642
                arg = que_node_get_next(arg);
 
643
        }
 
644
}
 
645
 
 
646
/*****************************************************************//**
 
647
Evaluates a predefined function node. If the first argument is an integer,
 
648
this function looks at the second argument which is the integer length in
 
649
bytes, and converts the integer to a VARCHAR.
 
650
If the first argument is of some other type, this function converts it to
 
651
BINARY. */
 
652
UNIV_INLINE
 
653
void
 
654
eval_to_binary(
 
655
/*===========*/
 
656
        func_node_t*    func_node)      /*!< in: function node */
 
657
{
 
658
        que_node_t*     arg1;
 
659
        que_node_t*     arg2;
 
660
        dfield_t*       dfield;
 
661
        byte*           str1;
 
662
        ulint           len;
 
663
        ulint           len1;
 
664
 
 
665
        arg1 = func_node->args;
 
666
 
 
667
        str1 = dfield_get_data(que_node_get_val(arg1));
 
668
 
 
669
        if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
 
670
 
 
671
                len = dfield_get_len(que_node_get_val(arg1));
 
672
 
 
673
                dfield = que_node_get_val(func_node);
 
674
 
 
675
                dfield_set_data(dfield, str1, len);
 
676
 
 
677
                return;
 
678
        }
 
679
 
 
680
        arg2 = que_node_get_next(arg1);
 
681
 
 
682
        len1 = (ulint)eval_node_get_int_val(arg2);
 
683
 
 
684
        if (len1 > 4) {
 
685
 
 
686
                ut_error;
 
687
        }
 
688
 
 
689
        dfield = que_node_get_val(func_node);
 
690
 
 
691
        dfield_set_data(dfield, str1 + (4 - len1), len1);
 
692
}
 
693
 
 
694
/*****************************************************************//**
 
695
Evaluates a predefined function node. */
 
696
UNIV_INLINE
 
697
void
 
698
eval_predefined(
 
699
/*============*/
 
700
        func_node_t*    func_node)      /*!< in: function node */
 
701
{
 
702
        que_node_t*     arg1;
 
703
        lint            int_val;
 
704
        byte*           data;
 
705
        int             func;
 
706
 
 
707
        func = func_node->func;
 
708
 
 
709
        arg1 = func_node->args;
 
710
 
 
711
        if (func == PARS_LENGTH_TOKEN) {
 
712
 
 
713
                int_val = (lint)dfield_get_len(que_node_get_val(arg1));
 
714
 
 
715
        } else if (func == PARS_TO_CHAR_TOKEN) {
 
716
 
 
717
                /* Convert number to character string as a
 
718
                signed decimal integer. */
 
719
 
 
720
                ulint   uint_val;
 
721
                int     int_len;
 
722
 
 
723
                int_val = eval_node_get_int_val(arg1);
 
724
 
 
725
                /* Determine the length of the string. */
 
726
 
 
727
                if (int_val == 0) {
 
728
                        int_len = 1; /* the number 0 occupies 1 byte */
 
729
                } else {
 
730
                        int_len = 0;
 
731
                        if (int_val < 0) {
 
732
                                uint_val = ((ulint) -int_val - 1) + 1;
 
733
                                int_len++; /* reserve space for minus sign */
 
734
                        } else {
 
735
                                uint_val = (ulint) int_val;
 
736
                        }
 
737
                        for (; uint_val > 0; int_len++) {
 
738
                                uint_val /= 10;
 
739
                        }
 
740
                }
 
741
 
 
742
                /* allocate the string */
 
743
                data = eval_node_ensure_val_buf(func_node, int_len + 1);
 
744
 
 
745
                /* add terminating NUL character */
 
746
                data[int_len] = 0;
 
747
 
 
748
                /* convert the number */
 
749
 
 
750
                if (int_val == 0) {
 
751
                        data[0] = '0';
 
752
                } else {
 
753
                        int tmp;
 
754
                        if (int_val < 0) {
 
755
                                data[0] = '-'; /* preceding minus sign */
 
756
                                uint_val = ((ulint) -int_val - 1) + 1;
 
757
                        } else {
 
758
                                uint_val = (ulint) int_val;
 
759
                        }
 
760
                        for (tmp = int_len; uint_val > 0; uint_val /= 10) {
 
761
                                data[--tmp] = (byte)
 
762
                                        ('0' + (byte)(uint_val % 10));
 
763
                        }
 
764
                }
 
765
 
 
766
                dfield_set_len(que_node_get_val(func_node), int_len);
 
767
 
 
768
                return;
 
769
 
 
770
        } else if (func == PARS_TO_NUMBER_TOKEN) {
 
771
 
 
772
                int_val = atoi((char*)
 
773
                               dfield_get_data(que_node_get_val(arg1)));
 
774
 
 
775
        } else if (func == PARS_SYSDATE_TOKEN) {
 
776
                int_val = (lint)ut_time();
 
777
        } else {
 
778
                eval_predefined_2(func_node);
 
779
 
 
780
                return;
 
781
        }
 
782
 
 
783
        eval_node_set_int_val(func_node, int_val);
 
784
}
 
785
 
 
786
/*****************************************************************//**
 
787
Evaluates a function node. */
 
788
UNIV_INTERN
 
789
void
 
790
eval_func(
 
791
/*======*/
 
792
        func_node_t*    func_node)      /*!< in: function node */
 
793
{
 
794
        que_node_t*     arg;
 
795
        ulint           class;
 
796
        ulint           func;
 
797
 
 
798
        ut_ad(que_node_get_type(func_node) == QUE_NODE_FUNC);
 
799
 
 
800
        class = func_node->class;
 
801
        func = func_node->func;
 
802
 
 
803
        arg = func_node->args;
 
804
 
 
805
        /* Evaluate first the argument list */
 
806
        while (arg) {
 
807
                eval_exp(arg);
 
808
 
 
809
                /* The functions are not defined for SQL null argument
 
810
                values, except for eval_cmp and notfound */
 
811
 
 
812
                if (dfield_is_null(que_node_get_val(arg))
 
813
                    && (class != PARS_FUNC_CMP)
 
814
                    && (func != PARS_NOTFOUND_TOKEN)
 
815
                    && (func != PARS_PRINTF_TOKEN)) {
 
816
                        ut_error;
 
817
                }
 
818
 
 
819
                arg = que_node_get_next(arg);
 
820
        }
 
821
 
 
822
        if (class == PARS_FUNC_CMP) {
 
823
                eval_cmp(func_node);
 
824
        } else if (class == PARS_FUNC_ARITH) {
 
825
                eval_arith(func_node);
 
826
        } else if (class == PARS_FUNC_AGGREGATE) {
 
827
                eval_aggregate(func_node);
 
828
        } else if (class == PARS_FUNC_PREDEFINED) {
 
829
 
 
830
                if (func == PARS_NOTFOUND_TOKEN) {
 
831
                        eval_notfound(func_node);
 
832
                } else if (func == PARS_SUBSTR_TOKEN) {
 
833
                        eval_substr(func_node);
 
834
                } else if (func == PARS_REPLSTR_TOKEN) {
 
835
                        eval_replstr(func_node);
 
836
                } else if (func == PARS_INSTR_TOKEN) {
 
837
                        eval_instr(func_node);
 
838
                } else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
 
839
                        eval_binary_to_number(func_node);
 
840
                } else if (func == PARS_CONCAT_TOKEN) {
 
841
                        eval_concat(func_node);
 
842
                } else if (func == PARS_TO_BINARY_TOKEN) {
 
843
                        eval_to_binary(func_node);
 
844
                } else {
 
845
                        eval_predefined(func_node);
 
846
                }
 
847
        } else {
 
848
                ut_ad(class == PARS_FUNC_LOGICAL);
 
849
 
 
850
                eval_logical(func_node);
 
851
        }
 
852
}