~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_func.h

Merge/fix in FAQ.

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
 
41
35
    Allowed numbers of columns in result (usually 1, which means scalar value)
42
36
    0 means get this number from first argument
43
37
  */
44
 
  uint32_t allowed_arg_cols;
 
38
  uint allowed_arg_cols;
45
39
public:
46
 
  uint32_t arg_count;
 
40
  uint arg_count;
47
41
  table_map used_tables_cache, not_null_tables_cache;
48
42
  bool const_item_cache;
49
43
  enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
55
49
                  NOT_FUNC, NOT_ALL_FUNC,
56
50
                  NOW_FUNC, TRIG_COND_FUNC,
57
51
                  SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
58
 
                  EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP,
 
52
                  EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
59
53
                  NEG_FUNC };
60
54
  enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
61
55
                       OPTIMIZE_EQUAL };
136
130
    {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
137
131
    instead.
138
132
  */
139
 
  virtual const char *func_name() const { return NULL; };
 
133
  virtual const char *func_name() const= 0;
140
134
  virtual bool const_item() const { return const_item_cache; }
141
135
  inline Item **arguments() const { return args; }
142
136
  void set_arguments(List<Item> &list);
143
 
  inline uint32_t argument_count() const { return arg_count; }
 
137
  inline uint argument_count() const { return arg_count; }
144
138
  inline void remove_arguments() { arg_count=0; }
145
139
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
146
140
  virtual void print(String *str, enum_query_type query_type);
147
141
  void print_op(String *str, enum_query_type query_type);
148
 
  void print_args(String *str, uint32_t from, enum_query_type query_type);
 
142
  void print_args(String *str, uint from, enum_query_type query_type);
149
143
  virtual void fix_num_length_and_dec();
150
144
  void count_only_length();
151
145
  void count_real_length();
152
146
  void count_decimal_length();
153
 
  inline bool get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
 
147
  inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
154
148
  {
155
149
    return (null_value=args[0]->get_date(ltime, fuzzy_date));
156
150
  }
157
 
  inline bool get_arg0_time(DRIZZLE_TIME *ltime)
 
151
  inline bool get_arg0_time(MYSQL_TIME *ltime)
158
152
  {
159
153
    return (null_value=args[0]->get_time(ltime));
160
154
  }
163
157
    return null_value; 
164
158
  }
165
159
  void signal_divide_by_null();
166
 
 
 
160
  friend class udf_handler;
167
161
  Field *tmp_table_field() { return result_field; }
168
 
  Field *tmp_table_field(Table *t_arg);
 
162
  Field *tmp_table_field(TABLE *t_arg);
169
163
  Item *get_tmp_table_item(THD *thd);
170
164
 
171
165
  my_decimal *val_decimal(my_decimal *);
172
166
 
173
 
  bool agg_arg_collations(DTCollation &c, Item **items, uint32_t nitems,
174
 
                          uint32_t flags)
 
167
  bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
 
168
                          uint flags)
175
169
  {
176
170
    return agg_item_collations(c, func_name(), items, nitems, flags, 1);
177
171
  }
178
172
  bool agg_arg_collations_for_comparison(DTCollation &c,
179
 
                                         Item **items, uint32_t nitems,
180
 
                                         uint32_t flags)
 
173
                                         Item **items, uint nitems,
 
174
                                         uint flags)
181
175
  {
182
176
    return agg_item_collations_for_comparison(c, func_name(),
183
177
                                              items, nitems, flags);
184
178
  }
185
 
  bool agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
186
 
                        uint32_t flags, int item_sep)
 
179
  bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
 
180
                        uint flags, int item_sep)
187
181
  {
188
182
    return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
189
183
  }
190
 
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
191
 
  Item *transform(Item_transformer transformer, unsigned char *arg);
192
 
  Item* compile(Item_analyzer analyzer, unsigned char **arg_p,
193
 
                Item_transformer transformer, unsigned char *arg_t);
 
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);
194
188
  void traverse_cond(Cond_traverser traverser,
195
189
                     void * arg, traverse_order order);
196
190
  inline double fix_result(double value)
291
285
 
292
286
  void fix_num_length_and_dec();
293
287
  void find_num_type();
294
 
  String *str_op(String *str __attribute__((unused)))
 
288
  String *str_op(String *str __attribute__((__unused__)))
295
289
  { assert(0); return 0; }
296
290
};
297
291
 
309
303
  }
310
304
 
311
305
  void find_num_type();
312
 
  String *str_op(String *str __attribute__((unused)))
 
306
  String *str_op(String *str __attribute__((__unused__)))
313
307
  { assert(0); return 0; }
314
308
};
315
309
 
354
348
  void fix_length_and_dec()
355
349
  { max_length=args[0]->max_length; unsigned_flag=0; }
356
350
  virtual void print(String *str, enum_query_type query_type);
357
 
  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
 
351
  uint decimal_precision() const { return args[0]->decimal_precision(); }
358
352
};
359
353
 
360
354
 
384
378
  int64_t val_int();
385
379
  my_decimal *val_decimal(my_decimal*);
386
380
  enum Item_result result_type () const { return DECIMAL_RESULT; }
387
 
  enum_field_types field_type() const { return DRIZZLE_TYPE_NEWDECIMAL; }
 
381
  enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
388
382
  void fix_length_and_dec() {};
389
383
  const char *func_name() const { return "decimal_typecast"; }
390
384
  virtual void print(String *str, enum_query_type query_type);
436
430
class Item_func_div :public Item_num_op
437
431
{
438
432
public:
439
 
  uint32_t prec_increment;
 
433
  uint prec_increment;
440
434
  Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {}
441
435
  int64_t int_op() { assert(0); return 0; }
442
436
  double real_op();
488
482
  enum Functype functype() const   { return NEG_FUNC; }
489
483
  void fix_length_and_dec();
490
484
  void fix_num_length_and_dec();
491
 
  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
 
485
  uint decimal_precision() const { return args[0]->decimal_precision(); }
492
486
};
493
487
 
494
488
 
746
740
  void fix_length_and_dec();
747
741
  enum Item_result result_type () const { return cmp_type; }
748
742
  bool result_as_int64_t() { return compare_as_dates; };
749
 
  uint32_t cmp_datetimes(uint64_t *value);
 
743
  uint cmp_datetimes(uint64_t *value);
750
744
  enum_field_types field_type() const { return cached_field_type; }
751
745
};
752
746
 
884
878
class Item_func_find_in_set :public Item_int_func
885
879
{
886
880
  String value,value2;
887
 
  uint32_t enum_value;
 
881
  uint enum_value;
888
882
  uint64_t enum_bit;
889
883
  DTCollation cmp_collation;
890
884
public:
992
986
  virtual void print(String *str, enum_query_type query_type);
993
987
};
994
988
 
 
989
 
 
990
class Item_udf_func :public Item_func
 
991
{
 
992
protected:
 
993
  udf_handler udf;
 
994
  bool is_expensive_processor(uchar *arg __attribute__((__unused__)))
 
995
  { return true; }
 
996
 
 
997
public:
 
998
  Item_udf_func(udf_func *udf_arg)
 
999
    :Item_func(), udf(udf_arg) {}
 
1000
  Item_udf_func(udf_func *udf_arg, List<Item> &list)
 
1001
    :Item_func(list), udf(udf_arg) {}
 
1002
  const char *func_name() const { return udf.name(); }
 
1003
  enum Functype functype() const   { return UDF_FUNC; }
 
1004
  bool fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
 
1005
  {
 
1006
    assert(fixed == 0);
 
1007
    bool res= udf.fix_fields(thd, this, arg_count, args);
 
1008
    used_tables_cache= udf.used_tables_cache;
 
1009
    const_item_cache= udf.const_item_cache;
 
1010
    fixed= 1;
 
1011
    return res;
 
1012
  }
 
1013
  void update_used_tables() 
 
1014
  {
 
1015
    /*
 
1016
      TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
 
1017
      not.
 
1018
      Currently UDF_INIT has a member (const_item) that is an in/out 
 
1019
      parameter to the init() call.
 
1020
      The code in udf_handler::fix_fields also duplicates the arguments 
 
1021
      handling code in Item_func::fix_fields().
 
1022
      
 
1023
      The lack of information if a UDF is deterministic makes writing
 
1024
      a correct update_used_tables() for UDFs impossible.
 
1025
      One solution to this would be :
 
1026
       - Add a is_deterministic member of UDF_INIT
 
1027
       - (optionally) deprecate the const_item member of UDF_INIT
 
1028
       - Take away the duplicate code from udf_handler::fix_fields() and
 
1029
         make Item_udf_func call Item_func::fix_fields() to process its 
 
1030
         arguments as for any other function.
 
1031
       - Store the deterministic flag returned by <udf>_init into the 
 
1032
       udf_handler. 
 
1033
       - Don't implement Item_udf_func::fix_fields, implement
 
1034
       Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
 
1035
       functions).
 
1036
       - Override Item_func::update_used_tables to call 
 
1037
       Item_func::update_used_tables() and add a RAND_TABLE_BIT to the 
 
1038
       result of Item_func::update_used_tables() if the UDF is 
 
1039
       non-deterministic.
 
1040
       - (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
 
1041
       better describe its usage.
 
1042
       
 
1043
      The above would require a change of the UDF API.
 
1044
      Until that change is done here's how the current code works:
 
1045
      We call Item_func::update_used_tables() only when we know that
 
1046
      the function depends on real non-const tables and is deterministic.
 
1047
      This can be done only because we know that the optimizer will
 
1048
      call update_used_tables() only when there's possibly a new const
 
1049
      table. So update_used_tables() can only make a Item_func more
 
1050
      constant than it is currently.
 
1051
      That's why we don't need to do anything if a function is guaranteed
 
1052
      to return non-constant (it's non-deterministic) or is already a
 
1053
      const.
 
1054
    */  
 
1055
    if ((used_tables_cache & ~PSEUDO_TABLE_BITS) && 
 
1056
        !(used_tables_cache & RAND_TABLE_BIT))
 
1057
    {
 
1058
      Item_func::update_used_tables();
 
1059
      if (!const_item_cache && !used_tables_cache)
 
1060
        used_tables_cache= RAND_TABLE_BIT;
 
1061
    }
 
1062
  }
 
1063
  void cleanup();
 
1064
  Item_result result_type () const { return udf.result_type(); }
 
1065
  table_map not_null_tables() const { return 0; }
 
1066
  virtual void print(String *str, enum_query_type query_type);
 
1067
};
 
1068
 
 
1069
 
 
1070
class Item_func_udf_float :public Item_udf_func
 
1071
{
 
1072
 public:
 
1073
  Item_func_udf_float(udf_func *udf_arg)
 
1074
    :Item_udf_func(udf_arg) {}
 
1075
  Item_func_udf_float(udf_func *udf_arg,
 
1076
                      List<Item> &list)
 
1077
    :Item_udf_func(udf_arg, list) {}
 
1078
  int64_t val_int()
 
1079
  {
 
1080
    assert(fixed == 1);
 
1081
    return (int64_t) rint(Item_func_udf_float::val_real());
 
1082
  }
 
1083
  my_decimal *val_decimal(my_decimal *dec_buf)
 
1084
  {
 
1085
    double res=val_real();
 
1086
    if (null_value)
 
1087
      return NULL;
 
1088
    double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 
1089
    return dec_buf;
 
1090
  }
 
1091
  double val_real();
 
1092
  String *val_str(String *str);
 
1093
  void fix_length_and_dec() { fix_num_length_and_dec(); }
 
1094
};
 
1095
 
 
1096
 
 
1097
class Item_func_udf_int :public Item_udf_func
 
1098
{
 
1099
public:
 
1100
  Item_func_udf_int(udf_func *udf_arg)
 
1101
    :Item_udf_func(udf_arg) {}
 
1102
  Item_func_udf_int(udf_func *udf_arg,
 
1103
                    List<Item> &list)
 
1104
    :Item_udf_func(udf_arg, list) {}
 
1105
  int64_t val_int();
 
1106
  double val_real() { return (double) Item_func_udf_int::val_int(); }
 
1107
  String *val_str(String *str);
 
1108
  enum Item_result result_type () const { return INT_RESULT; }
 
1109
  void fix_length_and_dec() { decimals= 0; max_length= 21; }
 
1110
};
 
1111
 
 
1112
 
 
1113
class Item_func_udf_decimal :public Item_udf_func
 
1114
{
 
1115
public:
 
1116
  Item_func_udf_decimal(udf_func *udf_arg)
 
1117
    :Item_udf_func(udf_arg) {}
 
1118
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
 
1119
    :Item_udf_func(udf_arg, list) {}
 
1120
  int64_t val_int();
 
1121
  double val_real();
 
1122
  my_decimal *val_decimal(my_decimal *);
 
1123
  String *val_str(String *str);
 
1124
  enum Item_result result_type () const { return DECIMAL_RESULT; }
 
1125
  void fix_length_and_dec();
 
1126
};
 
1127
 
 
1128
 
 
1129
class Item_func_udf_str :public Item_udf_func
 
1130
{
 
1131
public:
 
1132
  Item_func_udf_str(udf_func *udf_arg)
 
1133
    :Item_udf_func(udf_arg) {}
 
1134
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
 
1135
    :Item_udf_func(udf_arg, list) {}
 
1136
  String *val_str(String *);
 
1137
  double val_real()
 
1138
  {
 
1139
    int err_not_used;
 
1140
    char *end_not_used;
 
1141
    String *res;
 
1142
    res= val_str(&str_value);
 
1143
    return res ? my_strntod(res->charset(),(char*) res->ptr(), 
 
1144
                            res->length(), &end_not_used, &err_not_used) : 0.0;
 
1145
  }
 
1146
  int64_t val_int()
 
1147
  {
 
1148
    int err_not_used;
 
1149
    String *res;  res=val_str(&str_value);
 
1150
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
 
1151
                             (char**) 0, &err_not_used) : (int64_t) 0;
 
1152
  }
 
1153
  my_decimal *val_decimal(my_decimal *dec_buf)
 
1154
  {
 
1155
    String *res=val_str(&str_value);
 
1156
    if (!res)
 
1157
      return NULL;
 
1158
    string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 
1159
    return dec_buf;
 
1160
  }
 
1161
  enum Item_result result_type () const { return STRING_RESULT; }
 
1162
  void fix_length_and_dec();
 
1163
};
 
1164
 
 
1165
 
995
1166
/* replication functions */
996
1167
 
997
1168
class Item_master_pos_wait :public Item_int_func
1040
1211
  int64_t val_int_result();
1041
1212
  String *str_result(String *str);
1042
1213
  my_decimal *val_decimal_result(my_decimal *);
1043
 
  bool update_hash(void *ptr, uint32_t length, enum Item_result type,
1044
 
                   const CHARSET_INFO * const cs, Derivation dv, bool unsigned_arg);
 
1214
  bool update_hash(void *ptr, uint length, enum Item_result type,
 
1215
                   CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
1045
1216
  bool send(Protocol *protocol, String *str_arg);
1046
1217
  void make_field(Send_field *tmp_field);
1047
1218
  bool check(bool use_result_field);
1059
1230
    return save_in_field(field, no_conversions, 1);
1060
1231
  }
1061
1232
  void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
1062
 
  bool register_field_in_read_map(unsigned char *arg);
 
1233
  bool register_field_in_read_map(uchar *arg);
1063
1234
};
1064
1235
 
1065
1236
 
1117
1288
  /* fix_fields() binds variable name with its entry structure */
1118
1289
  bool fix_fields(THD *thd, Item **ref);
1119
1290
  virtual void print(String *str, enum_query_type query_type);
1120
 
  void set_null_value(const CHARSET_INFO * const cs);
1121
 
  void set_value(const char *str, uint32_t length, const CHARSET_INFO * const cs);
 
1291
  void set_null_value(CHARSET_INFO* cs);
 
1292
  void set_value(const char *str, uint length, CHARSET_INFO* cs);
1122
1293
};
1123
1294
 
1124
1295
 
1219
1390
  const char *func_name() const { return "found_rows"; }
1220
1391
  void fix_length_and_dec() { decimals= 0; maybe_null=0; }
1221
1392
};
1222
 
 
1223
 
#endif /* DRIZZLE_SERVER_ITEM_FUNC_H */