Drizzled Public API Documentation

ref.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #pragma once
00021 
00022 #include <drizzled/item/ident.h>
00023 
00024 namespace drizzled {
00025 
00026 class Item_ref :public Item_ident
00027 {
00028 protected:
00029   void set_properties();
00030 public:
00031   enum Ref_Type { REF, DIRECT_REF, OUTER_REF };
00032   Field *result_field;       /* Save result here */
00033   Item **ref;
00034   Item_ref(Name_resolution_context *context_arg,
00035            const char *db_arg, const char *table_name_arg,
00036            const char *field_name_arg)
00037     :Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
00038      result_field(0), ref(0) {}
00039   /*
00040     This constructor is used in two scenarios:
00041     A) *item = NULL
00042       No initialization is performed, fix_fields() call will be necessary.
00043 
00044     B) *item points to an Item this Item_ref will refer to. This is
00045       used for GROUP BY. fix_fields() will not be called in this case,
00046       so we call set_properties to make this item "fixed". set_properties
00047       performs a subset of action Item_ref::fix_fields does, and this subset
00048       is enough for Item_ref's used in GROUP BY.
00049 
00050     TODO we probably fix a superset of problems like in BUG#6658. Check this
00051          with Bar, and if we have a more broader set of problems like this.
00052   */
00053   Item_ref(Name_resolution_context *context_arg, Item **item,
00054            const char *table_name_arg, const char *field_name_arg,
00055            bool alias_name_used_arg= false);
00056 
00057   /* Constructor need to process subselect with temporary tables (see Item) */
00058   Item_ref(Session *session, Item_ref *item)
00059     :Item_ident(session, item), result_field(item->result_field), ref(item->ref) {}
00060   enum Type type() const    { return REF_ITEM; }
00061   bool eq(const Item *item, bool binary_cmp) const
00062   {
00063     const Item *it= item->real_item();
00064     return ref && (*ref)->eq(it, binary_cmp);
00065   }
00066   double val_real();
00067   int64_t val_int();
00068   type::Decimal *val_decimal(type::Decimal *);
00069   bool val_bool();
00070   String *val_str(String* tmp);
00071   bool is_null();
00072   bool get_date(type::Time &ltime,uint32_t fuzzydate);
00073   double val_result();
00074   int64_t val_int_result();
00075   String *str_result(String* tmp);
00076   type::Decimal *val_decimal_result(type::Decimal *);
00077   bool val_bool_result();
00078   void send(plugin::Client *client, String *tmp);
00079   void make_field(SendField *field);
00080   bool fix_fields(Session *, Item **);
00081   void fix_after_pullout(Select_Lex *new_parent, Item **ref);
00082   int save_in_field(Field *field, bool no_conversions);
00083   void save_org_in_field(Field *field);
00084   enum Item_result result_type () const { return (*ref)->result_type(); }
00085   enum_field_types field_type() const   { return (*ref)->field_type(); }
00086   Field *get_tmp_table_field()
00087   { return result_field ? result_field : (*ref)->get_tmp_table_field(); }
00088   Item *get_tmp_table_item(Session *session);
00089   table_map used_tables() const
00090   {
00091     return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
00092   }
00093   void update_used_tables()
00094   {
00095     if (!depended_from)
00096       (*ref)->update_used_tables();
00097   }
00098   table_map not_null_tables() const { return (*ref)->not_null_tables(); }
00099   void set_result_field(Field *field) { result_field= field; }
00100   bool is_result_field() { return 1; }
00101   void save_in_result_field(bool no_conversions)
00102   {
00103     (*ref)->save_in_field(result_field, no_conversions);
00104   }
00105   Item *real_item(void)
00106   {
00107     return ref ? (*ref)->real_item() : this;
00108   }
00109   const Item *real_item(void) const
00110   {
00111     return ref ? (*ref)->real_item() : this;
00112   }
00113   bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
00114   { return (*ref)->walk(processor, walk_subquery, arg); }
00115   virtual void print(String *str);
00116   bool result_as_int64_t()
00117   {
00118     return (*ref)->result_as_int64_t();
00119   }
00120   void cleanup();
00121   virtual Ref_Type ref_type() { return REF; }
00122 
00123   // Row emulation: forwarding of ROW-related calls to ref
00124   uint32_t cols()
00125   {
00126     return ref && result_type() == ROW_RESULT ? (*ref)->cols() : 1;
00127   }
00128   Item* element_index(uint32_t i)
00129   {
00130     return ref && result_type() == ROW_RESULT ? (*ref)->element_index(i) : this;
00131   }
00132   Item** addr(uint32_t i)
00133   {
00134     return ref && result_type() == ROW_RESULT ? (*ref)->addr(i) : 0;
00135   }
00136   bool check_cols(uint32_t c)
00137   {
00138     return ref && result_type() == ROW_RESULT ? (*ref)->check_cols(c)
00139                                               : Item::check_cols(c);
00140   }
00141   bool null_inside()
00142   {
00143     return ref && result_type() == ROW_RESULT ? (*ref)->null_inside() : 0;
00144   }
00145   void bring_value()
00146   {
00147     if (ref && result_type() == ROW_RESULT)
00148       (*ref)->bring_value();
00149   }
00150   bool basic_const_item() const
00151   {
00152     return (*ref)->basic_const_item();
00153   }
00154 };
00155 
00156 } /* namespace drizzled */
00157