~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_func.h

  • Committer: Brian Aker
  • Date: 2008-07-14 22:07:42 UTC
  • Revision ID: brian@tangent.org-20080714220742-y7fjh1mitrfcgfij
Second pass cleanup on removal of my_uint types

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#ifndef DRIZZLED_SERVER_ITEM_FUNC_H
21
 
#define DRIZZLED_SERVER_ITEM_FUNC_H
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
22
16
 
23
17
/* Function items used by mysql */
24
18
 
 
19
#ifdef USE_PRAGMA_INTERFACE
 
20
#pragma interface                       /* gcc class implementation */
 
21
#endif
25
22
 
26
23
#ifdef HAVE_IEEEFP_H
27
24
extern "C"                              /* Bug in BSDI include file */
30
27
}
31
28
#endif
32
29
 
33
 
#include <drizzled/functions/func.h>
34
 
#include <drizzled/functions/additive_op.h>
35
 
#include <drizzled/functions/connection_id.h>
36
 
#include <drizzled/functions/decimal_typecast.h>
37
 
#include <drizzled/functions/divide.h>
38
 
#include <drizzled/functions/int.h>
39
 
#include <drizzled/functions/int_divide.h>
40
 
#include <drizzled/functions/length.h>
41
 
#include <drizzled/functions/min_max.h>
42
 
#include <drizzled/functions/minus.h>
43
 
#include <drizzled/functions/mod.h>
44
 
#include <drizzled/functions/multiply.h>
45
 
#include <drizzled/functions/neg.h>
46
 
#include <drizzled/functions/numhybrid.h>
47
 
#include <drizzled/functions/num_op.h>
48
 
#include <drizzled/functions/num1.h>
49
 
#include <drizzled/functions/abs.h>
50
 
#include <drizzled/functions/plus.h>
51
 
#include <drizzled/functions/real.h>
52
 
#include <drizzled/functions/dec.h>
53
 
#include <drizzled/functions/int_val.h>
54
 
#include <drizzled/functions/acos.h>
55
 
#include <drizzled/functions/asin.h>
56
 
#include <drizzled/functions/atan.h>
57
 
#include <drizzled/functions/ceiling.h>
58
 
#include <drizzled/functions/cos.h>
59
 
#include <drizzled/functions/exp.h>
60
 
#include <drizzled/functions/floor.h>
61
 
#include <drizzled/functions/ln.h>
62
 
#include <drizzled/functions/log.h>
63
 
#include <drizzled/functions/pow.h>
64
 
#include <drizzled/functions/rand.h>
65
 
#include <drizzled/functions/round.h>
66
 
#include <drizzled/functions/sin.h>
67
 
#include <drizzled/functions/sqrt.h>
68
 
#include <drizzled/functions/sign.h>
69
 
#include <drizzled/functions/signed.h>
70
 
#include <drizzled/functions/tan.h>
71
 
#include <drizzled/functions/unsigned.h>
 
30
class Item_func :public Item_result_field
 
31
{
 
32
protected:
 
33
  Item **args, *tmp_arg[2];
 
34
  /*
 
35
    Allowed numbers of columns in result (usually 1, which means scalar value)
 
36
    0 means get this number from first argument
 
37
  */
 
38
  uint allowed_arg_cols;
 
39
public:
 
40
  uint arg_count;
 
41
  table_map used_tables_cache, not_null_tables_cache;
 
42
  bool const_item_cache;
 
43
  enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
 
44
                  GE_FUNC,GT_FUNC,FT_FUNC,
 
45
                  LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
 
46
                  COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
 
47
                  BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
 
48
                  INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
 
49
                  NOT_FUNC, NOT_ALL_FUNC,
 
50
                  NOW_FUNC, TRIG_COND_FUNC,
 
51
                  SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
 
52
                  EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
 
53
                  NEG_FUNC };
 
54
  enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
 
55
                       OPTIMIZE_EQUAL };
 
56
  enum Type type() const { return FUNC_ITEM; }
 
57
  virtual enum Functype functype() const   { return UNKNOWN_FUNC; }
 
58
  Item_func(void):
 
59
    allowed_arg_cols(1), arg_count(0)
 
60
  {
 
61
    with_sum_func= 0;
 
62
  }
 
63
  Item_func(Item *a):
 
64
    allowed_arg_cols(1), arg_count(1)
 
65
  {
 
66
    args= tmp_arg;
 
67
    args[0]= a;
 
68
    with_sum_func= a->with_sum_func;
 
69
  }
 
70
  Item_func(Item *a,Item *b):
 
71
    allowed_arg_cols(1), arg_count(2)
 
72
  {
 
73
    args= tmp_arg;
 
74
    args[0]= a; args[1]= b;
 
75
    with_sum_func= a->with_sum_func || b->with_sum_func;
 
76
  }
 
77
  Item_func(Item *a,Item *b,Item *c):
 
78
    allowed_arg_cols(1)
 
79
  {
 
80
    arg_count= 0;
 
81
    if ((args= (Item**) sql_alloc(sizeof(Item*)*3)))
 
82
    {
 
83
      arg_count= 3;
 
84
      args[0]= a; args[1]= b; args[2]= c;
 
85
      with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
 
86
    }
 
87
  }
 
88
  Item_func(Item *a,Item *b,Item *c,Item *d):
 
89
    allowed_arg_cols(1)
 
90
  {
 
91
    arg_count= 0;
 
92
    if ((args= (Item**) sql_alloc(sizeof(Item*)*4)))
 
93
    {
 
94
      arg_count= 4;
 
95
      args[0]= a; args[1]= b; args[2]= c; args[3]= d;
 
96
      with_sum_func= a->with_sum_func || b->with_sum_func ||
 
97
        c->with_sum_func || d->with_sum_func;
 
98
    }
 
99
  }
 
100
  Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
 
101
    allowed_arg_cols(1)
 
102
  {
 
103
    arg_count= 5;
 
104
    if ((args= (Item**) sql_alloc(sizeof(Item*)*5)))
 
105
    {
 
106
      args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
 
107
      with_sum_func= a->with_sum_func || b->with_sum_func ||
 
108
        c->with_sum_func || d->with_sum_func || e->with_sum_func ;
 
109
    }
 
110
  }
 
111
  Item_func(List<Item> &list);
 
112
  // Constructor used for Item_cond_and/or (see Item comment)
 
113
  Item_func(THD *thd, Item_func *item);
 
114
  bool fix_fields(THD *, Item **ref);
 
115
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
 
116
  table_map used_tables() const;
 
117
  table_map not_null_tables() const;
 
118
  void update_used_tables();
 
119
  bool eq(const Item *item, bool binary_cmp) const;
 
120
  virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
 
121
  virtual bool have_rev_func() const { return 0; }
 
122
  virtual Item *key_item() const { return args[0]; }
 
123
  /*
 
124
    This method is used for debug purposes to print the name of an
 
125
    item to the debug log. The second use of this method is as
 
126
    a helper function of print(), where it is applicable.
 
127
    To suit both goals it should return a meaningful,
 
128
    distinguishable and sintactically correct string.  This method
 
129
    should not be used for runtime type identification, use enum
 
130
    {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
 
131
    instead.
 
132
  */
 
133
  virtual const char *func_name() const= 0;
 
134
  virtual bool const_item() const { return const_item_cache; }
 
135
  inline Item **arguments() const { return args; }
 
136
  void set_arguments(List<Item> &list);
 
137
  inline uint argument_count() const { return arg_count; }
 
138
  inline void remove_arguments() { arg_count=0; }
 
139
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
 
140
  virtual void print(String *str, enum_query_type query_type);
 
141
  void print_op(String *str, enum_query_type query_type);
 
142
  void print_args(String *str, uint from, enum_query_type query_type);
 
143
  virtual void fix_num_length_and_dec();
 
144
  void count_only_length();
 
145
  void count_real_length();
 
146
  void count_decimal_length();
 
147
  inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
 
148
  {
 
149
    return (null_value=args[0]->get_date(ltime, fuzzy_date));
 
150
  }
 
151
  inline bool get_arg0_time(MYSQL_TIME *ltime)
 
152
  {
 
153
    return (null_value=args[0]->get_time(ltime));
 
154
  }
 
155
  bool is_null() { 
 
156
    update_null_value();
 
157
    return null_value; 
 
158
  }
 
159
  void signal_divide_by_null();
 
160
  friend class udf_handler;
 
161
  Field *tmp_table_field() { return result_field; }
 
162
  Field *tmp_table_field(TABLE *t_arg);
 
163
  Item *get_tmp_table_item(THD *thd);
 
164
 
 
165
  my_decimal *val_decimal(my_decimal *);
 
166
 
 
167
  bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
 
168
                          uint flags)
 
169
  {
 
170
    return agg_item_collations(c, func_name(), items, nitems, flags, 1);
 
171
  }
 
172
  bool agg_arg_collations_for_comparison(DTCollation &c,
 
173
                                         Item **items, uint nitems,
 
174
                                         uint flags)
 
175
  {
 
176
    return agg_item_collations_for_comparison(c, func_name(),
 
177
                                              items, nitems, flags);
 
178
  }
 
179
  bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
 
180
                        uint flags, int item_sep)
 
181
  {
 
182
    return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
 
183
  }
 
184
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
185
  Item *transform(Item_transformer transformer, uchar *arg);
 
186
  Item* compile(Item_analyzer analyzer, uchar **arg_p,
 
187
                Item_transformer transformer, uchar *arg_t);
 
188
  void traverse_cond(Cond_traverser traverser,
 
189
                     void * arg, traverse_order order);
 
190
  inline double fix_result(double value)
 
191
  {
 
192
    if (isfinite(value))
 
193
      return value;
 
194
    null_value=1;
 
195
    return 0.0;
 
196
  }
 
197
};
 
198
 
 
199
 
 
200
class Item_real_func :public Item_func
 
201
{
 
202
public:
 
203
  Item_real_func() :Item_func() {}
 
204
  Item_real_func(Item *a) :Item_func(a) {}
 
205
  Item_real_func(Item *a,Item *b) :Item_func(a,b) {}
 
206
  Item_real_func(List<Item> &list) :Item_func(list) {}
 
207
  String *val_str(String*str);
 
208
  my_decimal *val_decimal(my_decimal *decimal_value);
 
209
  int64_t val_int()
 
210
    { assert(fixed == 1); return (int64_t) rint(val_real()); }
 
211
  enum Item_result result_type () const { return REAL_RESULT; }
 
212
  void fix_length_and_dec()
 
213
  { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
 
214
};
 
215
 
 
216
 
 
217
class Item_func_numhybrid: public Item_func
 
218
{
 
219
protected:
 
220
  Item_result hybrid_type;
 
221
public:
 
222
  Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
 
223
  {}
 
224
  Item_func_numhybrid(Item *a,Item *b)
 
225
    :Item_func(a,b), hybrid_type(REAL_RESULT)
 
226
  {}
 
227
  Item_func_numhybrid(List<Item> &list)
 
228
    :Item_func(list), hybrid_type(REAL_RESULT)
 
229
  {}
 
230
 
 
231
  enum Item_result result_type () const { return hybrid_type; }
 
232
  void fix_length_and_dec();
 
233
  void fix_num_length_and_dec();
 
234
  virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
 
235
 
 
236
  double val_real();
 
237
  int64_t val_int();
 
238
  my_decimal *val_decimal(my_decimal *);
 
239
  String *val_str(String*str);
 
240
 
 
241
  /**
 
242
     @brief Performs the operation that this functions implements when the
 
243
     result type is INT.
 
244
 
 
245
     @return The result of the operation.
 
246
  */
 
247
  virtual int64_t int_op()= 0;
 
248
 
 
249
  /**
 
250
     @brief Performs the operation that this functions implements when the
 
251
     result type is REAL.
 
252
 
 
253
     @return The result of the operation.
 
254
  */
 
255
  virtual double real_op()= 0;
 
256
 
 
257
  /**
 
258
     @brief Performs the operation that this functions implements when the
 
259
     result type is DECIMAL.
 
260
 
 
261
     @param A pointer where the DECIMAL value will be allocated.
 
262
     @return 
 
263
       - 0 If the result is NULL
 
264
       - The same pointer it was given, with the area initialized to the
 
265
         result of the operation.
 
266
  */
 
267
  virtual my_decimal *decimal_op(my_decimal *)= 0;
 
268
 
 
269
  /**
 
270
     @brief Performs the operation that this functions implements when the
 
271
     result type is a string type.
 
272
 
 
273
     @return The result of the operation.
 
274
  */
 
275
  virtual String *str_op(String *)= 0;
 
276
  bool is_null() { update_null_value(); return null_value; }
 
277
};
 
278
 
 
279
/* function where type of result detected by first argument */
 
280
class Item_func_num1: public Item_func_numhybrid
 
281
{
 
282
public:
 
283
  Item_func_num1(Item *a) :Item_func_numhybrid(a) {}
 
284
  Item_func_num1(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
 
285
 
 
286
  void fix_num_length_and_dec();
 
287
  void find_num_type();
 
288
  String *str_op(String *str __attribute__((__unused__)))
 
289
  { assert(0); return 0; }
 
290
};
 
291
 
 
292
 
 
293
/* Base class for operations like '+', '-', '*' */
 
294
class Item_num_op :public Item_func_numhybrid
 
295
{
 
296
 public:
 
297
  Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {}
 
298
  virtual void result_precision()= 0;
 
299
 
 
300
  virtual inline void print(String *str, enum_query_type query_type)
 
301
  {
 
302
    print_op(str, query_type);
 
303
  }
 
304
 
 
305
  void find_num_type();
 
306
  String *str_op(String *str __attribute__((__unused__)))
 
307
  { assert(0); return 0; }
 
308
};
 
309
 
 
310
 
 
311
class Item_int_func :public Item_func
 
312
{
 
313
public:
 
314
  Item_int_func() :Item_func() { max_length= 21; }
 
315
  Item_int_func(Item *a) :Item_func(a) { max_length= 21; }
 
316
  Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length= 21; }
 
317
  Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c)
 
318
  { max_length= 21; }
 
319
  Item_int_func(List<Item> &list) :Item_func(list) { max_length= 21; }
 
320
  Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {}
 
321
  double val_real();
 
322
  String *val_str(String*str);
 
323
  enum Item_result result_type () const { return INT_RESULT; }
 
324
  void fix_length_and_dec() {}
 
325
};
 
326
 
 
327
 
 
328
class Item_func_connection_id :public Item_int_func
 
329
{
 
330
  int64_t value;
 
331
 
 
332
public:
 
333
  Item_func_connection_id() {}
 
334
  const char *func_name() const { return "connection_id"; }
 
335
  void fix_length_and_dec();
 
336
  bool fix_fields(THD *thd, Item **ref);
 
337
  int64_t val_int() { assert(fixed == 1); return value; }
 
338
};
 
339
 
 
340
 
 
341
class Item_func_signed :public Item_int_func
 
342
{
 
343
public:
 
344
  Item_func_signed(Item *a) :Item_int_func(a) {}
 
345
  const char *func_name() const { return "cast_as_signed"; }
 
346
  int64_t val_int();
 
347
  int64_t val_int_from_str(int *error);
 
348
  void fix_length_and_dec()
 
349
  { max_length=args[0]->max_length; unsigned_flag=0; }
 
350
  virtual void print(String *str, enum_query_type query_type);
 
351
  uint decimal_precision() const { return args[0]->decimal_precision(); }
 
352
};
 
353
 
 
354
 
 
355
class Item_func_unsigned :public Item_func_signed
 
356
{
 
357
public:
 
358
  Item_func_unsigned(Item *a) :Item_func_signed(a) {}
 
359
  const char *func_name() const { return "cast_as_unsigned"; }
 
360
  void fix_length_and_dec()
 
361
  { max_length=args[0]->max_length; unsigned_flag=1; }
 
362
  int64_t val_int();
 
363
  virtual void print(String *str, enum_query_type query_type);
 
364
};
 
365
 
 
366
 
 
367
class Item_decimal_typecast :public Item_func
 
368
{
 
369
  my_decimal decimal_value;
 
370
public:
 
371
  Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
 
372
  {
 
373
    decimals= dec;
 
374
    max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
 
375
  }
 
376
  String *val_str(String *str);
 
377
  double val_real();
 
378
  int64_t val_int();
 
379
  my_decimal *val_decimal(my_decimal*);
 
380
  enum Item_result result_type () const { return DECIMAL_RESULT; }
 
381
  enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
 
382
  void fix_length_and_dec() {};
 
383
  const char *func_name() const { return "decimal_typecast"; }
 
384
  virtual void print(String *str, enum_query_type query_type);
 
385
};
 
386
 
 
387
 
 
388
class Item_func_additive_op :public Item_num_op
 
389
{
 
390
public:
 
391
  Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {}
 
392
  void result_precision();
 
393
};
 
394
 
 
395
 
 
396
class Item_func_plus :public Item_func_additive_op
 
397
{
 
398
public:
 
399
  Item_func_plus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
 
400
  const char *func_name() const { return "+"; }
 
401
  int64_t int_op();
 
402
  double real_op();
 
403
  my_decimal *decimal_op(my_decimal *);
 
404
};
 
405
 
 
406
class Item_func_minus :public Item_func_additive_op
 
407
{
 
408
public:
 
409
  Item_func_minus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
 
410
  const char *func_name() const { return "-"; }
 
411
  int64_t int_op();
 
412
  double real_op();
 
413
  my_decimal *decimal_op(my_decimal *);
 
414
  void fix_length_and_dec();
 
415
};
 
416
 
 
417
 
 
418
class Item_func_mul :public Item_num_op
 
419
{
 
420
public:
 
421
  Item_func_mul(Item *a,Item *b) :Item_num_op(a,b) {}
 
422
  const char *func_name() const { return "*"; }
 
423
  int64_t int_op();
 
424
  double real_op();
 
425
  my_decimal *decimal_op(my_decimal *);
 
426
  void result_precision();
 
427
};
 
428
 
 
429
 
 
430
class Item_func_div :public Item_num_op
 
431
{
 
432
public:
 
433
  uint prec_increment;
 
434
  Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {}
 
435
  int64_t int_op() { assert(0); return 0; }
 
436
  double real_op();
 
437
  my_decimal *decimal_op(my_decimal *);
 
438
  const char *func_name() const { return "/"; }
 
439
  void fix_length_and_dec();
 
440
  void result_precision();
 
441
};
 
442
 
 
443
 
 
444
class Item_func_int_div :public Item_int_func
 
445
{
 
446
public:
 
447
  Item_func_int_div(Item *a,Item *b) :Item_int_func(a,b)
 
448
  {}
 
449
  int64_t val_int();
 
450
  const char *func_name() const { return "DIV"; }
 
451
  void fix_length_and_dec();
 
452
 
 
453
  virtual inline void print(String *str, enum_query_type query_type)
 
454
  {
 
455
    print_op(str, query_type);
 
456
  }
 
457
 
 
458
};
 
459
 
 
460
 
 
461
class Item_func_mod :public Item_num_op
 
462
{
 
463
public:
 
464
  Item_func_mod(Item *a,Item *b) :Item_num_op(a,b) {}
 
465
  int64_t int_op();
 
466
  double real_op();
 
467
  my_decimal *decimal_op(my_decimal *);
 
468
  const char *func_name() const { return "%"; }
 
469
  void result_precision();
 
470
  void fix_length_and_dec();
 
471
};
 
472
 
 
473
 
 
474
class Item_func_neg :public Item_func_num1
 
475
{
 
476
public:
 
477
  Item_func_neg(Item *a) :Item_func_num1(a) {}
 
478
  double real_op();
 
479
  int64_t int_op();
 
480
  my_decimal *decimal_op(my_decimal *);
 
481
  const char *func_name() const { return "-"; }
 
482
  enum Functype functype() const   { return NEG_FUNC; }
 
483
  void fix_length_and_dec();
 
484
  void fix_num_length_and_dec();
 
485
  uint decimal_precision() const { return args[0]->decimal_precision(); }
 
486
};
 
487
 
 
488
 
 
489
class Item_func_abs :public Item_func_num1
 
490
{
 
491
public:
 
492
  Item_func_abs(Item *a) :Item_func_num1(a) {}
 
493
  double real_op();
 
494
  int64_t int_op();
 
495
  my_decimal *decimal_op(my_decimal *);
 
496
  const char *func_name() const { return "abs"; }
 
497
  void fix_length_and_dec();
 
498
};
 
499
 
 
500
// A class to handle logarithmic and trigonometric functions
 
501
 
 
502
class Item_dec_func :public Item_real_func
 
503
{
 
504
 public:
 
505
  Item_dec_func(Item *a) :Item_real_func(a) {}
 
506
  Item_dec_func(Item *a,Item *b) :Item_real_func(a,b) {}
 
507
  void fix_length_and_dec()
 
508
  {
 
509
    decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
 
510
    maybe_null=1;
 
511
  }
 
512
};
 
513
 
 
514
class Item_func_exp :public Item_dec_func
 
515
{
 
516
public:
 
517
  Item_func_exp(Item *a) :Item_dec_func(a) {}
 
518
  double val_real();
 
519
  const char *func_name() const { return "exp"; }
 
520
};
 
521
 
 
522
 
 
523
class Item_func_ln :public Item_dec_func
 
524
{
 
525
public:
 
526
  Item_func_ln(Item *a) :Item_dec_func(a) {}
 
527
  double val_real();
 
528
  const char *func_name() const { return "ln"; }
 
529
};
 
530
 
 
531
 
 
532
class Item_func_log :public Item_dec_func
 
533
{
 
534
public:
 
535
  Item_func_log(Item *a) :Item_dec_func(a) {}
 
536
  Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
 
537
  double val_real();
 
538
  const char *func_name() const { return "log"; }
 
539
};
 
540
 
 
541
 
 
542
class Item_func_log2 :public Item_dec_func
 
543
{
 
544
public:
 
545
  Item_func_log2(Item *a) :Item_dec_func(a) {}
 
546
  double val_real();
 
547
  const char *func_name() const { return "log2"; }
 
548
};
 
549
 
 
550
 
 
551
class Item_func_log10 :public Item_dec_func
 
552
{
 
553
public:
 
554
  Item_func_log10(Item *a) :Item_dec_func(a) {}
 
555
  double val_real();
 
556
  const char *func_name() const { return "log10"; }
 
557
};
 
558
 
 
559
 
 
560
class Item_func_sqrt :public Item_dec_func
 
561
{
 
562
public:
 
563
  Item_func_sqrt(Item *a) :Item_dec_func(a) {}
 
564
  double val_real();
 
565
  const char *func_name() const { return "sqrt"; }
 
566
};
 
567
 
 
568
 
 
569
class Item_func_pow :public Item_dec_func
 
570
{
 
571
public:
 
572
  Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {}
 
573
  double val_real();
 
574
  const char *func_name() const { return "pow"; }
 
575
};
 
576
 
 
577
 
 
578
class Item_func_acos :public Item_dec_func
 
579
{
 
580
public:
 
581
  Item_func_acos(Item *a) :Item_dec_func(a) {}
 
582
  double val_real();
 
583
  const char *func_name() const { return "acos"; }
 
584
};
 
585
 
 
586
class Item_func_asin :public Item_dec_func
 
587
{
 
588
public:
 
589
  Item_func_asin(Item *a) :Item_dec_func(a) {}
 
590
  double val_real();
 
591
  const char *func_name() const { return "asin"; }
 
592
};
 
593
 
 
594
class Item_func_atan :public Item_dec_func
 
595
{
 
596
public:
 
597
  Item_func_atan(Item *a) :Item_dec_func(a) {}
 
598
  Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
 
599
  double val_real();
 
600
  const char *func_name() const { return "atan"; }
 
601
};
 
602
 
 
603
class Item_func_cos :public Item_dec_func
 
604
{
 
605
public:
 
606
  Item_func_cos(Item *a) :Item_dec_func(a) {}
 
607
  double val_real();
 
608
  const char *func_name() const { return "cos"; }
 
609
};
 
610
 
 
611
class Item_func_sin :public Item_dec_func
 
612
{
 
613
public:
 
614
  Item_func_sin(Item *a) :Item_dec_func(a) {}
 
615
  double val_real();
 
616
  const char *func_name() const { return "sin"; }
 
617
};
 
618
 
 
619
class Item_func_tan :public Item_dec_func
 
620
{
 
621
public:
 
622
  Item_func_tan(Item *a) :Item_dec_func(a) {}
 
623
  double val_real();
 
624
  const char *func_name() const { return "tan"; }
 
625
};
72
626
 
73
627
class Item_func_integer :public Item_int_func
74
628
{
77
631
  void fix_length_and_dec();
78
632
};
79
633
 
 
634
 
 
635
class Item_func_int_val :public Item_func_num1
 
636
{
 
637
public:
 
638
  Item_func_int_val(Item *a) :Item_func_num1(a) {}
 
639
  void fix_num_length_and_dec();
 
640
  void find_num_type();
 
641
};
 
642
 
 
643
 
 
644
class Item_func_ceiling :public Item_func_int_val
 
645
{
 
646
public:
 
647
  Item_func_ceiling(Item *a) :Item_func_int_val(a) {}
 
648
  const char *func_name() const { return "ceiling"; }
 
649
  int64_t int_op();
 
650
  double real_op();
 
651
  my_decimal *decimal_op(my_decimal *);
 
652
};
 
653
 
 
654
 
 
655
class Item_func_floor :public Item_func_int_val
 
656
{
 
657
public:
 
658
  Item_func_floor(Item *a) :Item_func_int_val(a) {}
 
659
  const char *func_name() const { return "floor"; }
 
660
  int64_t int_op();
 
661
  double real_op();
 
662
  my_decimal *decimal_op(my_decimal *);
 
663
};
 
664
 
 
665
/* This handles round and truncate */
 
666
 
 
667
class Item_func_round :public Item_func_num1
 
668
{
 
669
  bool truncate;
 
670
public:
 
671
  Item_func_round(Item *a, Item *b, bool trunc_arg)
 
672
    :Item_func_num1(a,b), truncate(trunc_arg) {}
 
673
  const char *func_name() const { return truncate ? "truncate" : "round"; }
 
674
  double real_op();
 
675
  int64_t int_op();
 
676
  my_decimal *decimal_op(my_decimal *);
 
677
  void fix_length_and_dec();
 
678
};
 
679
 
 
680
 
 
681
class Item_func_rand :public Item_real_func
 
682
{
 
683
  struct rand_struct *rand;
 
684
public:
 
685
  Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
 
686
  Item_func_rand()        :Item_real_func() {}
 
687
  double val_real();
 
688
  const char *func_name() const { return "rand"; }
 
689
  bool const_item() const { return 0; }
 
690
  void update_used_tables();
 
691
  bool fix_fields(THD *thd, Item **ref);
 
692
private:
 
693
  void seed_random (Item * val);  
 
694
};
 
695
 
 
696
 
 
697
class Item_func_sign :public Item_int_func
 
698
{
 
699
public:
 
700
  Item_func_sign(Item *a) :Item_int_func(a) {}
 
701
  const char *func_name() const { return "sign"; }
 
702
  int64_t val_int();
 
703
};
 
704
 
 
705
 
80
706
class Item_func_units :public Item_real_func
81
707
{
82
708
  char *name;
91
717
};
92
718
 
93
719
 
 
720
class Item_func_min_max :public Item_func
 
721
{
 
722
  Item_result cmp_type;
 
723
  String tmp_value;
 
724
  int cmp_sign;
 
725
  /* TRUE <=> arguments should be compared in the DATETIME context. */
 
726
  bool compare_as_dates;
 
727
  /* An item used for issuing warnings while string to DATETIME conversion. */
 
728
  Item *datetime_item;
 
729
  THD *thd;
 
730
protected:
 
731
  enum_field_types cached_field_type;
 
732
public:
 
733
  Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
 
734
    cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(false),
 
735
    datetime_item(0) {}
 
736
  double val_real();
 
737
  int64_t val_int();
 
738
  String *val_str(String *);
 
739
  my_decimal *val_decimal(my_decimal *);
 
740
  void fix_length_and_dec();
 
741
  enum Item_result result_type () const { return cmp_type; }
 
742
  bool result_as_int64_t() { return compare_as_dates; };
 
743
  uint cmp_datetimes(uint64_t *value);
 
744
  enum_field_types field_type() const { return cached_field_type; }
 
745
};
 
746
 
 
747
class Item_func_min :public Item_func_min_max
 
748
{
 
749
public:
 
750
  Item_func_min(List<Item> &list) :Item_func_min_max(list,1) {}
 
751
  const char *func_name() const { return "least"; }
 
752
};
 
753
 
 
754
class Item_func_max :public Item_func_min_max
 
755
{
 
756
public:
 
757
  Item_func_max(List<Item> &list) :Item_func_min_max(list,-1) {}
 
758
  const char *func_name() const { return "greatest"; }
 
759
};
 
760
 
 
761
 
94
762
/* 
95
763
  Objects of this class are used for ROLLUP queries to wrap up 
96
764
  each constant item referred to in GROUP BY list. 
121
789
  }
122
790
};
123
791
 
 
792
 
 
793
class Item_func_length :public Item_int_func
 
794
{
 
795
  String value;
 
796
public:
 
797
  Item_func_length(Item *a) :Item_int_func(a) {}
 
798
  int64_t val_int();
 
799
  const char *func_name() const { return "length"; }
 
800
  void fix_length_and_dec() { max_length=10; }
 
801
};
 
802
 
124
803
class Item_func_bit_length :public Item_func_length
125
804
{
126
805
public:
199
878
class Item_func_find_in_set :public Item_int_func
200
879
{
201
880
  String value,value2;
202
 
  uint32_t enum_value;
 
881
  uint enum_value;
203
882
  uint64_t enum_bit;
204
883
  DTCollation cmp_collation;
205
884
public:
292
971
      max_length= args[0]->max_length;
293
972
  }
294
973
  bool fix_fields(THD *thd, Item **ref);
295
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
296
 
  { return true; }
297
974
};
298
975
 
299
976
 
307
984
  const char *func_name() const { return "benchmark"; }
308
985
  void fix_length_and_dec() { max_length=1; maybe_null=0; }
309
986
  virtual void print(String *str, enum_query_type query_type);
310
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
 
987
};
 
988
 
 
989
 
 
990
#ifdef HAVE_DLOPEN
 
991
 
 
992
class Item_udf_func :public Item_func
 
993
{
 
994
protected:
 
995
  udf_handler udf;
 
996
  bool is_expensive_processor(uchar *arg __attribute__((__unused__)))
311
997
  { return true; }
312
 
};
 
998
 
 
999
public:
 
1000
  Item_udf_func(udf_func *udf_arg)
 
1001
    :Item_func(), udf(udf_arg) {}
 
1002
  Item_udf_func(udf_func *udf_arg, List<Item> &list)
 
1003
    :Item_func(list), udf(udf_arg) {}
 
1004
  const char *func_name() const { return udf.name(); }
 
1005
  enum Functype functype() const   { return UDF_FUNC; }
 
1006
  bool fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
 
1007
  {
 
1008
    assert(fixed == 0);
 
1009
    bool res= udf.fix_fields(thd, this, arg_count, args);
 
1010
    used_tables_cache= udf.used_tables_cache;
 
1011
    const_item_cache= udf.const_item_cache;
 
1012
    fixed= 1;
 
1013
    return res;
 
1014
  }
 
1015
  void update_used_tables() 
 
1016
  {
 
1017
    /*
 
1018
      TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
 
1019
      not.
 
1020
      Currently UDF_INIT has a member (const_item) that is an in/out 
 
1021
      parameter to the init() call.
 
1022
      The code in udf_handler::fix_fields also duplicates the arguments 
 
1023
      handling code in Item_func::fix_fields().
 
1024
      
 
1025
      The lack of information if a UDF is deterministic makes writing
 
1026
      a correct update_used_tables() for UDFs impossible.
 
1027
      One solution to this would be :
 
1028
       - Add a is_deterministic member of UDF_INIT
 
1029
       - (optionally) deprecate the const_item member of UDF_INIT
 
1030
       - Take away the duplicate code from udf_handler::fix_fields() and
 
1031
         make Item_udf_func call Item_func::fix_fields() to process its 
 
1032
         arguments as for any other function.
 
1033
       - Store the deterministic flag returned by <udf>_init into the 
 
1034
       udf_handler. 
 
1035
       - Don't implement Item_udf_func::fix_fields, implement
 
1036
       Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
 
1037
       functions).
 
1038
       - Override Item_func::update_used_tables to call 
 
1039
       Item_func::update_used_tables() and add a RAND_TABLE_BIT to the 
 
1040
       result of Item_func::update_used_tables() if the UDF is 
 
1041
       non-deterministic.
 
1042
       - (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
 
1043
       better describe its usage.
 
1044
       
 
1045
      The above would require a change of the UDF API.
 
1046
      Until that change is done here's how the current code works:
 
1047
      We call Item_func::update_used_tables() only when we know that
 
1048
      the function depends on real non-const tables and is deterministic.
 
1049
      This can be done only because we know that the optimizer will
 
1050
      call update_used_tables() only when there's possibly a new const
 
1051
      table. So update_used_tables() can only make a Item_func more
 
1052
      constant than it is currently.
 
1053
      That's why we don't need to do anything if a function is guaranteed
 
1054
      to return non-constant (it's non-deterministic) or is already a
 
1055
      const.
 
1056
    */  
 
1057
    if ((used_tables_cache & ~PSEUDO_TABLE_BITS) && 
 
1058
        !(used_tables_cache & RAND_TABLE_BIT))
 
1059
    {
 
1060
      Item_func::update_used_tables();
 
1061
      if (!const_item_cache && !used_tables_cache)
 
1062
        used_tables_cache= RAND_TABLE_BIT;
 
1063
    }
 
1064
  }
 
1065
  void cleanup();
 
1066
  Item_result result_type () const { return udf.result_type(); }
 
1067
  table_map not_null_tables() const { return 0; }
 
1068
  virtual void print(String *str, enum_query_type query_type);
 
1069
};
 
1070
 
 
1071
 
 
1072
class Item_func_udf_float :public Item_udf_func
 
1073
{
 
1074
 public:
 
1075
  Item_func_udf_float(udf_func *udf_arg)
 
1076
    :Item_udf_func(udf_arg) {}
 
1077
  Item_func_udf_float(udf_func *udf_arg,
 
1078
                      List<Item> &list)
 
1079
    :Item_udf_func(udf_arg, list) {}
 
1080
  int64_t val_int()
 
1081
  {
 
1082
    assert(fixed == 1);
 
1083
    return (int64_t) rint(Item_func_udf_float::val_real());
 
1084
  }
 
1085
  my_decimal *val_decimal(my_decimal *dec_buf)
 
1086
  {
 
1087
    double res=val_real();
 
1088
    if (null_value)
 
1089
      return NULL;
 
1090
    double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 
1091
    return dec_buf;
 
1092
  }
 
1093
  double val_real();
 
1094
  String *val_str(String *str);
 
1095
  void fix_length_and_dec() { fix_num_length_and_dec(); }
 
1096
};
 
1097
 
 
1098
 
 
1099
class Item_func_udf_int :public Item_udf_func
 
1100
{
 
1101
public:
 
1102
  Item_func_udf_int(udf_func *udf_arg)
 
1103
    :Item_udf_func(udf_arg) {}
 
1104
  Item_func_udf_int(udf_func *udf_arg,
 
1105
                    List<Item> &list)
 
1106
    :Item_udf_func(udf_arg, list) {}
 
1107
  int64_t val_int();
 
1108
  double val_real() { return (double) Item_func_udf_int::val_int(); }
 
1109
  String *val_str(String *str);
 
1110
  enum Item_result result_type () const { return INT_RESULT; }
 
1111
  void fix_length_and_dec() { decimals= 0; max_length= 21; }
 
1112
};
 
1113
 
 
1114
 
 
1115
class Item_func_udf_decimal :public Item_udf_func
 
1116
{
 
1117
public:
 
1118
  Item_func_udf_decimal(udf_func *udf_arg)
 
1119
    :Item_udf_func(udf_arg) {}
 
1120
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
 
1121
    :Item_udf_func(udf_arg, list) {}
 
1122
  int64_t val_int();
 
1123
  double val_real();
 
1124
  my_decimal *val_decimal(my_decimal *);
 
1125
  String *val_str(String *str);
 
1126
  enum Item_result result_type () const { return DECIMAL_RESULT; }
 
1127
  void fix_length_and_dec();
 
1128
};
 
1129
 
 
1130
 
 
1131
class Item_func_udf_str :public Item_udf_func
 
1132
{
 
1133
public:
 
1134
  Item_func_udf_str(udf_func *udf_arg)
 
1135
    :Item_udf_func(udf_arg) {}
 
1136
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
 
1137
    :Item_udf_func(udf_arg, list) {}
 
1138
  String *val_str(String *);
 
1139
  double val_real()
 
1140
  {
 
1141
    int err_not_used;
 
1142
    char *end_not_used;
 
1143
    String *res;
 
1144
    res= val_str(&str_value);
 
1145
    return res ? my_strntod(res->charset(),(char*) res->ptr(), 
 
1146
                            res->length(), &end_not_used, &err_not_used) : 0.0;
 
1147
  }
 
1148
  int64_t val_int()
 
1149
  {
 
1150
    int err_not_used;
 
1151
    String *res;  res=val_str(&str_value);
 
1152
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
 
1153
                             (char**) 0, &err_not_used) : (int64_t) 0;
 
1154
  }
 
1155
  my_decimal *val_decimal(my_decimal *dec_buf)
 
1156
  {
 
1157
    String *res=val_str(&str_value);
 
1158
    if (!res)
 
1159
      return NULL;
 
1160
    string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 
1161
    return dec_buf;
 
1162
  }
 
1163
  enum Item_result result_type () const { return STRING_RESULT; }
 
1164
  void fix_length_and_dec();
 
1165
};
 
1166
 
 
1167
#else /* Dummy functions to get sql_yacc.cc compiled */
 
1168
 
 
1169
class Item_func_udf_float :public Item_real_func
 
1170
{
 
1171
 public:
 
1172
  Item_func_udf_float(udf_func *udf_arg)
 
1173
    :Item_real_func() {}
 
1174
  Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
 
1175
    :Item_real_func(list) {}
 
1176
  double val_real() { assert(fixed == 1); return 0.0; }
 
1177
};
 
1178
 
 
1179
 
 
1180
class Item_func_udf_int :public Item_int_func
 
1181
{
 
1182
public:
 
1183
  Item_func_udf_int(udf_func *udf_arg)
 
1184
    :Item_int_func() {}
 
1185
  Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
 
1186
    :Item_int_func(list) {}
 
1187
  int64_t val_int() { assert(fixed == 1); return 0; }
 
1188
};
 
1189
 
 
1190
 
 
1191
class Item_func_udf_decimal :public Item_int_func
 
1192
{
 
1193
public:
 
1194
  Item_func_udf_decimal(udf_func *udf_arg)
 
1195
    :Item_int_func() {}
 
1196
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
 
1197
    :Item_int_func(list) {}
 
1198
  my_decimal *val_decimal(my_decimal *) { assert(fixed == 1); return 0; }
 
1199
};
 
1200
 
 
1201
 
 
1202
class Item_func_udf_str :public Item_func
 
1203
{
 
1204
public:
 
1205
  Item_func_udf_str(udf_func *udf_arg)
 
1206
    :Item_func() {}
 
1207
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
 
1208
    :Item_func(list) {}
 
1209
  String *val_str(String *)
 
1210
    { assert(fixed == 1); null_value=1; return 0; }
 
1211
  double val_real() { assert(fixed == 1); null_value= 1; return 0.0; }
 
1212
  int64_t val_int() { assert(fixed == 1); null_value=1; return 0; }
 
1213
  enum Item_result result_type () const { return STRING_RESULT; }
 
1214
  void fix_length_and_dec() { maybe_null=1; max_length=0; }
 
1215
};
 
1216
 
 
1217
#endif /* HAVE_DLOPEN */
313
1218
 
314
1219
/* replication functions */
315
1220
 
322
1227
  int64_t val_int();
323
1228
  const char *func_name() const { return "master_pos_wait"; }
324
1229
  void fix_length_and_dec() { max_length=21; maybe_null=1;}
325
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
326
 
  { return true; }
327
1230
};
328
1231
 
329
1232
 
361
1264
  int64_t val_int_result();
362
1265
  String *str_result(String *str);
363
1266
  my_decimal *val_decimal_result(my_decimal *);
364
 
  bool update_hash(void *ptr, uint32_t length, enum Item_result type,
365
 
                   const CHARSET_INFO * const cs, Derivation dv, bool unsigned_arg);
 
1267
  bool update_hash(void *ptr, uint length, enum Item_result type,
 
1268
                   CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
366
1269
  bool send(Protocol *protocol, String *str_arg);
367
1270
  void make_field(Send_field *tmp_field);
368
1271
  bool check(bool use_result_field);
380
1283
    return save_in_field(field, no_conversions, 1);
381
1284
  }
382
1285
  void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
383
 
  bool register_field_in_read_map(unsigned char *arg);
384
 
  bool register_field_in_bitmap(unsigned char *arg);
 
1286
  bool register_field_in_read_map(uchar *arg);
385
1287
};
386
1288
 
387
1289
 
439
1341
  /* fix_fields() binds variable name with its entry structure */
440
1342
  bool fix_fields(THD *thd, Item **ref);
441
1343
  virtual void print(String *str, enum_query_type query_type);
442
 
  void set_null_value(const CHARSET_INFO * const cs);
443
 
  void set_value(const char *str, uint32_t length, const CHARSET_INFO * const cs);
 
1344
  void set_null_value(CHARSET_INFO* cs);
 
1345
  void set_value(const char *str, uint length, CHARSET_INFO* cs);
444
1346
};
445
1347
 
446
1348
 
493
1395
  int64_t val_int();
494
1396
  const char *func_name() const { return "is_free_lock"; }
495
1397
  void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
496
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
497
 
  { return true; }
498
1398
};
499
1399
 
500
1400
class Item_func_is_used_lock :public Item_int_func
505
1405
  int64_t val_int();
506
1406
  const char *func_name() const { return "is_used_lock"; }
507
1407
  void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
508
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
509
 
  { return true; }
510
1408
};
511
1409
 
512
1410
/* For type casts */
526
1424
  int64_t val_int();
527
1425
  const char *func_name() const { return "row_count"; }
528
1426
  void fix_length_and_dec() { decimals= 0; maybe_null=0; }
529
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
530
 
  { return true; }
531
1427
};
532
1428
 
533
1429
 
546
1442
  int64_t val_int();
547
1443
  const char *func_name() const { return "found_rows"; }
548
1444
  void fix_length_and_dec() { decimals= 0; maybe_null=0; }
549
 
  bool check_vcol_func_processor(unsigned char *int_arg __attribute__((unused)))
550
 
  { return true; }
551
1445
};
552
 
 
553
 
#endif /* DRIZZLE_SERVER_ITEM_FUNC_H */