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 
00027 class Item_ref :public Item_ident
00028 {
00029 protected:
00030   void set_properties();
00031 public:
00032   enum Ref_Type { REF, DIRECT_REF, OUTER_REF };
00033   Field *result_field;       /* Save result here */
00034   Item **ref;
00035   Item_ref(Name_resolution_context *context_arg,
00036            const char *db_arg, const char *table_name_arg,
00037            const char *field_name_arg)
00038     :Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
00039      result_field(0), ref(0) {}
00040   /*
00041     This constructor is used in two scenarios:
00042     A) *item = NULL
00043       No initialization is performed, fix_fields() call will be necessary.
00044 
00045     B) *item points to an Item this Item_ref will refer to. This is
00046       used for GROUP BY. fix_fields() will not be called in this case,
00047       so we call set_properties to make this item "fixed". set_properties
00048       performs a subset of action Item_ref::fix_fields does, and this subset
00049       is enough for Item_ref's used in GROUP BY.
00050 
00051     TODO we probably fix a superset of problems like in BUG#6658. Check this
00052          with Bar, and if we have a more broader set of problems like this.
00053   */
00054   Item_ref(Name_resolution_context *context_arg, Item **item,
00055            const char *table_name_arg, const char *field_name_arg,
00056            bool alias_name_used_arg= false);
00057 
00058   /* Constructor need to process subselect with temporary tables (see Item) */
00059   Item_ref(Session *session, Item_ref *item)
00060     :Item_ident(session, item), result_field(item->result_field), ref(item->ref) {}
00061   enum Type type() const    { return REF_ITEM; }
00062   bool eq(const Item *item, bool binary_cmp) const
00063   {
00064     const Item *it= item->real_item();
00065     return ref && (*ref)->eq(it, binary_cmp);
00066   }
00067   double val_real();
00068   int64_t val_int();
00069   type::Decimal *val_decimal(type::Decimal *);
00070   bool val_bool();
00071   String *val_str(String* tmp);
00072   bool is_null();
00073   bool get_date(type::Time &ltime,uint32_t fuzzydate);
00074   double val_result();
00075   int64_t val_int_result();
00076   String *str_result(String* tmp);
00077   type::Decimal *val_decimal_result(type::Decimal *);
00078   bool val_bool_result();
00079   bool send(plugin::Client *client, String *tmp);
00080   void make_field(SendField *field);
00081   bool fix_fields(Session *, Item **);
00082   void fix_after_pullout(Select_Lex *new_parent, Item **ref);
00083   int save_in_field(Field *field, bool no_conversions);
00084   void save_org_in_field(Field *field);
00085   enum Item_result result_type () const { return (*ref)->result_type(); }
00086   enum_field_types field_type() const   { return (*ref)->field_type(); }
00087   Field *get_tmp_table_field()
00088   { return result_field ? result_field : (*ref)->get_tmp_table_field(); }
00089   Item *get_tmp_table_item(Session *session);
00090   table_map used_tables() const
00091   {
00092     return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
00093   }
00094   void update_used_tables()
00095   {
00096     if (!depended_from)
00097       (*ref)->update_used_tables();
00098   }
00099   table_map not_null_tables() const { return (*ref)->not_null_tables(); }
00100   void set_result_field(Field *field) { result_field= field; }
00101   bool is_result_field() { return 1; }
00102   void save_in_result_field(bool no_conversions)
00103   {
00104     (*ref)->save_in_field(result_field, no_conversions);
00105   }
00106   Item *real_item(void)
00107   {
00108     return ref ? (*ref)->real_item() : this;
00109   }
00110   const Item *real_item(void) const
00111   {
00112     return ref ? (*ref)->real_item() : this;
00113   }
00114   bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
00115   { return (*ref)->walk(processor, walk_subquery, arg); }
00116   virtual void print(String *str);
00117   bool result_as_int64_t()
00118   {
00119     return (*ref)->result_as_int64_t();
00120   }
00121   void cleanup();
00122   virtual Ref_Type ref_type() { return REF; }
00123 
00124   // Row emulation: forwarding of ROW-related calls to ref
00125   uint32_t cols()
00126   {
00127     return ref && result_type() == ROW_RESULT ? (*ref)->cols() : 1;
00128   }
00129   Item* element_index(uint32_t i)
00130   {
00131     return ref && result_type() == ROW_RESULT ? (*ref)->element_index(i) : this;
00132   }
00133   Item** addr(uint32_t i)
00134   {
00135     return ref && result_type() == ROW_RESULT ? (*ref)->addr(i) : 0;
00136   }
00137   bool check_cols(uint32_t c)
00138   {
00139     return ref && result_type() == ROW_RESULT ? (*ref)->check_cols(c)
00140                                               : Item::check_cols(c);
00141   }
00142   bool null_inside()
00143   {
00144     return ref && result_type() == ROW_RESULT ? (*ref)->null_inside() : 0;
00145   }
00146   void bring_value()
00147   {
00148     if (ref && result_type() == ROW_RESULT)
00149       (*ref)->bring_value();
00150   }
00151   bool basic_const_item() const
00152   {
00153     return (*ref)->basic_const_item();
00154   }
00155 };
00156 
00157 } /* namespace drizzled */
00158