~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Brian Aker
  • Date: 2009-02-08 03:02:04 UTC
  • Revision ID: brian@tangent.org-20090208030204-3gz6xwcq5niux5nm
Class rewrite of Session (aka get all of the junk out)

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
} COPY_INFO;
82
82
 
83
83
 
84
 
 
85
 
 
86
 
 
87
 
typedef struct st_mysql_lock
 
84
typedef struct drizzled_lock_st
88
85
{
89
86
  Table **table;
90
87
  uint32_t table_count,lock_count;
92
89
} DRIZZLE_LOCK;
93
90
 
94
91
 
95
 
class LEX_COLUMN : public Sql_alloc
96
 
{
97
 
public:
98
 
  String column;
99
 
  uint32_t rights;
100
 
  LEX_COLUMN (const String& x,const  uint& y ): column (x),rights (y) {}
101
 
};
 
92
#include <drizzled/lex_column.h>
102
93
 
103
94
class select_result;
104
95
class Time_zone;
410
401
bool xid_cache_insert(XID_STATE *xid_state);
411
402
void xid_cache_delete(XID_STATE *xid_state);
412
403
 
413
 
/**
414
 
  @class Security_context
415
 
  @brief A set of Session members describing the current authenticated user.
416
 
*/
417
 
 
418
 
class Security_context {
419
 
public:
420
 
  Security_context() {}
421
 
  /*
422
 
    host - host of the client
423
 
    user - user of the client, set to NULL until the user has been read from
424
 
    the connection
425
 
    priv_user - The user privilege we are using. May be "" for anonymous user.
426
 
    ip - client IP
427
 
  */
428
 
  std::string user;
429
 
  std::string ip;
430
 
 
431
 
  void skip_grants();
432
 
  inline const char *priv_host_name()
433
 
  {
434
 
    return (ip.c_str() ? ip.c_str() : (char *)"%");
435
 
  }
436
 
};
437
 
 
 
404
#include <drizzled/security_context.h>
438
405
 
439
406
/**
440
407
  A registry for item tree transformations performed during
447
414
typedef I_List<Item_change_record> Item_change_list;
448
415
 
449
416
 
450
 
/**
451
 
  Class that holds information about tables which were opened and locked
452
 
  by the thread. It is also used to save/restore this information in
453
 
  push_open_tables_state()/pop_open_tables_state().
454
 
*/
455
 
 
456
 
class Open_tables_state
457
 
{
458
 
public:
459
 
  /**
460
 
    List of regular tables in use by this thread. Contains temporary and
461
 
    base tables that were opened with @see open_tables().
462
 
  */
463
 
  Table *open_tables;
464
 
  /**
465
 
    List of temporary tables used by this thread. Contains user-level
466
 
    temporary tables, created with CREATE TEMPORARY TABLE, and
467
 
    internal temporary tables, created, e.g., to resolve a SELECT,
468
 
    or for an intermediate table used in ALTER.
469
 
    XXX Why are internal temporary tables added to this list?
470
 
  */
471
 
  Table *temporary_tables;
472
 
  /**
473
 
    List of tables that were opened with HANDLER OPEN and are
474
 
    still in use by this thread.
475
 
  */
476
 
  Table *handler_tables;
477
 
  Table *derived_tables;
478
 
  /*
479
 
    During a MySQL session, one can lock tables in two modes: automatic
480
 
    or manual. In automatic mode all necessary tables are locked just before
481
 
    statement execution, and all acquired locks are stored in 'lock'
482
 
    member. Unlocking takes place automatically as well, when the
483
 
    statement ends.
484
 
    Manual mode comes into play when a user issues a 'LOCK TABLES'
485
 
    statement. In this mode the user can only use the locked tables.
486
 
    Trying to use any other tables will give an error. The locked tables are
487
 
    stored in 'locked_tables' member.  Manual locking is described in
488
 
    the 'LOCK_TABLES' chapter of the MySQL manual.
489
 
    See also lock_tables() for details.
490
 
  */
491
 
  DRIZZLE_LOCK *lock;
492
 
  /*
493
 
    Tables that were locked with explicit or implicit LOCK TABLES.
494
 
    (Implicit LOCK TABLES happens when we are prelocking tables for
495
 
     execution of statement which uses stored routines. See description
496
 
     Session::prelocked_mode for more info.)
497
 
  */
498
 
  DRIZZLE_LOCK *locked_tables;
499
 
 
500
 
  /*
501
 
    CREATE-SELECT keeps an extra lock for the table being
502
 
    created. This field is used to keep the extra lock available for
503
 
    lower level routines, which would otherwise miss that lock.
504
 
   */
505
 
  DRIZZLE_LOCK *extra_lock;
506
 
 
507
 
  ulong version;
508
 
  uint32_t current_tablenr;
509
 
 
510
 
  enum enum_flags {
511
 
    BACKUPS_AVAIL = (1U << 0)     /* There are backups available */
512
 
  };
513
 
 
514
 
  /*
515
 
    Flags with information about the open tables state.
516
 
  */
517
 
  uint32_t state_flags;
518
 
 
519
 
  /*
520
 
    This constructor serves for creation of Open_tables_state instances
521
 
    which are used as backup storage.
522
 
  */
523
 
  Open_tables_state() : state_flags(0U) { }
524
 
 
525
 
  Open_tables_state(ulong version_arg);
526
 
 
527
 
  void set_open_tables_state(Open_tables_state *state)
528
 
  {
529
 
    *this= *state;
530
 
  }
531
 
 
532
 
  void reset_open_tables_state()
533
 
  {
534
 
    open_tables= temporary_tables= handler_tables= derived_tables= 0;
535
 
    extra_lock= lock= locked_tables= 0;
536
 
    state_flags= 0U;
537
 
  }
538
 
};
539
 
 
 
417
#include <drizzled/open_tables_state.h>
540
418
 
541
419
/* Flags for the Session::system_thread variable */
542
420
enum enum_thread_type
545
423
};
546
424
 
547
425
 
548
 
/**
549
 
  This class represents the interface for internal error handlers.
550
 
  Internal error handlers are exception handlers used by the server
551
 
  implementation.
552
 
*/
553
 
class Internal_error_handler
554
 
{
555
 
protected:
556
 
  Internal_error_handler() {}
557
 
  virtual ~Internal_error_handler() {}
558
 
 
559
 
public:
560
 
  /**
561
 
    Handle an error condition.
562
 
    This method can be implemented by a subclass to achieve any of the
563
 
    following:
564
 
    - mask an error internally, prevent exposing it to the user,
565
 
    - mask an error and throw another one instead.
566
 
    When this method returns true, the error condition is considered
567
 
    'handled', and will not be propagated to upper layers.
568
 
    It is the responsability of the code installing an internal handler
569
 
    to then check for trapped conditions, and implement logic to recover
570
 
    from the anticipated conditions trapped during runtime.
571
 
 
572
 
    This mechanism is similar to C++ try/throw/catch:
573
 
    - 'try' correspond to <code>Session::push_internal_handler()</code>,
574
 
    - 'throw' correspond to <code>my_error()</code>,
575
 
    which invokes <code>my_message_sql()</code>,
576
 
    - 'catch' correspond to checking how/if an internal handler was invoked,
577
 
    before removing it from the exception stack with
578
 
    <code>Session::pop_internal_handler()</code>.
579
 
 
580
 
    @param sql_errno the error number
581
 
    @param level the error level
582
 
    @param session the calling thread
583
 
    @return true if the error is handled
584
 
  */
585
 
  virtual bool handle_error(uint32_t sql_errno,
586
 
                            const char *message,
587
 
                            DRIZZLE_ERROR::enum_warning_level level,
588
 
                            Session *session) = 0;
589
 
};
590
 
 
591
 
 
592
 
/**
593
 
  Stores status of the currently executed statement.
594
 
  Cleared at the beginning of the statement, and then
595
 
  can hold either OK, ERROR, or EOF status.
596
 
  Can not be assigned twice per statement.
597
 
*/
598
 
 
599
 
class Diagnostics_area
600
 
{
601
 
public:
602
 
  enum enum_diagnostics_status
603
 
  {
604
 
    /** The area is cleared at start of a statement. */
605
 
    DA_EMPTY= 0,
606
 
    /** Set whenever one calls my_ok(). */
607
 
    DA_OK,
608
 
    /** Set whenever one calls my_eof(). */
609
 
    DA_EOF,
610
 
    /** Set whenever one calls my_error() or my_message(). */
611
 
    DA_ERROR,
612
 
    /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
613
 
    DA_DISABLED
614
 
  };
615
 
  /** True if status information is sent to the client. */
616
 
  bool is_sent;
617
 
  /** Set to make set_error_status after set_{ok,eof}_status possible. */
618
 
  bool can_overwrite_status;
619
 
 
620
 
  void set_ok_status(Session *session, ha_rows affected_rows_arg,
621
 
                     uint64_t last_insert_id_arg,
622
 
                     const char *message);
623
 
  void set_eof_status(Session *session);
624
 
  void set_error_status(Session *session, uint32_t sql_errno_arg, const char *message_arg);
625
 
 
626
 
  void disable_status();
627
 
 
628
 
  void reset_diagnostics_area();
629
 
 
630
 
  bool is_set() const { return m_status != DA_EMPTY; }
631
 
  bool is_error() const { return m_status == DA_ERROR; }
632
 
  bool is_eof() const { return m_status == DA_EOF; }
633
 
  bool is_ok() const { return m_status == DA_OK; }
634
 
  bool is_disabled() const { return m_status == DA_DISABLED; }
635
 
  enum_diagnostics_status status() const { return m_status; }
636
 
 
637
 
  const char *message() const
638
 
  { assert(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
639
 
 
640
 
  uint32_t sql_errno() const
641
 
  { assert(m_status == DA_ERROR); return m_sql_errno; }
642
 
 
643
 
  uint32_t server_status() const
644
 
  {
645
 
    assert(m_status == DA_OK || m_status == DA_EOF);
646
 
    return m_server_status;
647
 
  }
648
 
 
649
 
  ha_rows affected_rows() const
650
 
  { assert(m_status == DA_OK); return m_affected_rows; }
651
 
 
652
 
  uint64_t last_insert_id() const
653
 
  { assert(m_status == DA_OK); return m_last_insert_id; }
654
 
 
655
 
  uint32_t total_warn_count() const
656
 
  {
657
 
    assert(m_status == DA_OK || m_status == DA_EOF);
658
 
    return m_total_warn_count;
659
 
  }
660
 
 
661
 
  Diagnostics_area() { reset_diagnostics_area(); }
662
 
 
663
 
private:
664
 
  /** Message buffer. Can be used by OK or ERROR status. */
665
 
  char m_message[DRIZZLE_ERRMSG_SIZE];
666
 
  /**
667
 
    SQL error number. One of ER_ codes from share/errmsg.txt.
668
 
    Set by set_error_status.
669
 
  */
670
 
  uint32_t m_sql_errno;
671
 
 
672
 
  /**
673
 
    Copied from session->server_status when the diagnostics area is assigned.
674
 
    We need this member as some places in the code use the following pattern:
675
 
    session->server_status|= ...
676
 
    my_eof(session);
677
 
    session->server_status&= ~...
678
 
    Assigned by OK, EOF or ERROR.
679
 
  */
680
 
  uint32_t m_server_status;
681
 
  /**
682
 
    The number of rows affected by the last statement. This is
683
 
    semantically close to session->row_count_func, but has a different
684
 
    life cycle. session->row_count_func stores the value returned by
685
 
    function ROW_COUNT() and is cleared only by statements that
686
 
    update its value, such as INSERT, UPDATE, DELETE and few others.
687
 
    This member is cleared at the beginning of the next statement.
688
 
 
689
 
    We could possibly merge the two, but life cycle of session->row_count_func
690
 
    can not be changed.
691
 
  */
692
 
  ha_rows    m_affected_rows;
693
 
  /**
694
 
    Similarly to the previous member, this is a replacement of
695
 
    session->first_successful_insert_id_in_prev_stmt, which is used
696
 
    to implement LAST_INSERT_ID().
697
 
  */
698
 
  uint64_t   m_last_insert_id;
699
 
  /** The total number of warnings. */
700
 
  uint       m_total_warn_count;
701
 
  enum_diagnostics_status m_status;
702
 
  /**
703
 
    @todo: the following Session members belong here:
704
 
    - warn_list, warn_count,
705
 
  */
706
 
};
707
 
 
 
426
 
 
427
#include <drizzled/internal_error_handler.h> 
 
428
#include <drizzled/diagnostics_area.h> 
708
429
 
709
430
/**
710
431
  Storage engine specific thread local data.
1478
1199
 
1479
1200
#include <storage/myisam/myisam.h>
1480
1201
 
1481
 
/*
1482
 
  Param to create temporary tables when doing SELECT:s
1483
 
  NOTE
1484
 
    This structure is copied using memcpy as a part of JOIN.
1485
 
*/
1486
 
 
1487
 
class TMP_TABLE_PARAM :public Sql_alloc
1488
 
{
1489
 
private:
1490
 
  /* Prevent use of these (not safe because of lists and copy_field) */
1491
 
  TMP_TABLE_PARAM(const TMP_TABLE_PARAM &);
1492
 
  void operator=(TMP_TABLE_PARAM &);
1493
 
 
1494
 
public:
1495
 
  List<Item> copy_funcs;
1496
 
  List<Item> save_copy_funcs;
1497
 
  Copy_field *copy_field, *copy_field_end;
1498
 
  Copy_field *save_copy_field, *save_copy_field_end;
1499
 
  unsigned char     *group_buff;
1500
 
  Item      **items_to_copy;                    /* Fields in tmp table */
1501
 
  MI_COLUMNDEF *recinfo,*start_recinfo;
1502
 
  KEY *keyinfo;
1503
 
  ha_rows end_write_records;
1504
 
  uint  field_count,sum_func_count,func_count;
1505
 
  uint32_t  hidden_field_count;
1506
 
  uint  group_parts,group_length,group_null_parts;
1507
 
  uint  quick_group;
1508
 
  bool  using_indirect_summary_function;
1509
 
  /* If >0 convert all blob fields to varchar(convert_blob_length) */
1510
 
  uint32_t  convert_blob_length;
1511
 
  const CHARSET_INFO *table_charset;
1512
 
  bool schema_table;
1513
 
  /*
1514
 
    True if GROUP BY and its aggregate functions are already computed
1515
 
    by a table access method (e.g. by loose index scan). In this case
1516
 
    query execution should not perform aggregation and should treat
1517
 
    aggregate functions as normal functions.
1518
 
  */
1519
 
  bool precomputed_group_by;
1520
 
  bool force_copy_fields;
1521
 
  /*
1522
 
    If true, create_tmp_field called from create_tmp_table will convert
1523
 
    all BIT fields to 64-bit longs. This is a workaround the limitation
1524
 
    that MEMORY tables cannot index BIT columns.
1525
 
  */
1526
 
  bool bit_fields_as_long;
1527
 
 
1528
 
  TMP_TABLE_PARAM()
1529
 
    :copy_field(0), group_parts(0),
1530
 
     group_length(0), group_null_parts(0), convert_blob_length(0),
1531
 
     schema_table(0), precomputed_group_by(0), force_copy_fields(0),
1532
 
     bit_fields_as_long(0)
1533
 
  {}
1534
 
  ~TMP_TABLE_PARAM()
1535
 
  {
1536
 
    cleanup();
1537
 
  }
1538
 
  void init(void);
1539
 
  void cleanup(void);
1540
 
};
1541
 
 
1542
 
class select_union :public select_result_interceptor
1543
 
{
1544
 
  TMP_TABLE_PARAM tmp_table_param;
1545
 
public:
1546
 
  Table *table;
1547
 
 
1548
 
  select_union() :table(0) {}
1549
 
  int prepare(List<Item> &list, Select_Lex_Unit *u);
1550
 
  bool send_data(List<Item> &items);
1551
 
  bool send_eof();
1552
 
  bool flush();
1553
 
  void cleanup();
1554
 
  bool create_result_table(Session *session, List<Item> *column_types,
1555
 
                           bool is_distinct, uint64_t options,
1556
 
                           const char *alias, bool bit_fields_as_long);
1557
 
};
1558
 
 
1559
 
/* Base subselect interface class */
1560
 
class select_subselect :public select_result_interceptor
1561
 
{
1562
 
protected:
1563
 
  Item_subselect *item;
1564
 
public:
1565
 
  select_subselect(Item_subselect *item);
1566
 
  bool send_data(List<Item> &items)=0;
1567
 
  bool send_eof() { return 0; };
1568
 
};
1569
 
 
1570
 
/* Single value subselect interface class */
1571
 
class select_singlerow_subselect :public select_subselect
1572
 
{
1573
 
public:
1574
 
  select_singlerow_subselect(Item_subselect *item_arg)
1575
 
    :select_subselect(item_arg)
1576
 
  {}
1577
 
  bool send_data(List<Item> &items);
1578
 
};
1579
 
 
1580
 
/* used in independent ALL/ANY optimisation */
1581
 
class select_max_min_finder_subselect :public select_subselect
1582
 
{
1583
 
  Item_cache *cache;
1584
 
  bool (select_max_min_finder_subselect::*op)();
1585
 
  bool fmax;
1586
 
public:
1587
 
  select_max_min_finder_subselect(Item_subselect *item_arg, bool mx)
1588
 
    :select_subselect(item_arg), cache(0), fmax(mx)
1589
 
  {}
1590
 
  void cleanup();
1591
 
  bool send_data(List<Item> &items);
1592
 
  bool cmp_real();
1593
 
  bool cmp_int();
1594
 
  bool cmp_decimal();
1595
 
  bool cmp_str();
1596
 
};
1597
 
 
1598
 
/* EXISTS subselect interface class */
1599
 
class select_exists_subselect :public select_subselect
1600
 
{
1601
 
public:
1602
 
  select_exists_subselect(Item_subselect *item_arg)
1603
 
    :select_subselect(item_arg){}
1604
 
  bool send_data(List<Item> &items);
1605
 
};
 
1202
#include <drizzled/tmp_table_param.h>
 
1203
 
 
1204
#include <drizzled/select_union.h>
 
1205
 
 
1206
#include <drizzled/select_subselect.h>
 
1207
 
 
1208
#include <drizzled/select_singlerow_subselect.h>
 
1209
#include <drizzled/select_max_min_finder_subselect.h>
 
1210
#include <drizzled/select_exists_subselect.h>
1606
1211
 
1607
1212
/* Structs used when sorting */
1608
1213
 
1625
1230
  SORT_FIELD *sortorder;
1626
1231
} SORT_BUFFER;
1627
1232
 
1628
 
/* Structure for db & table in sql_yacc */
1629
 
 
1630
 
class Table_ident :public Sql_alloc
1631
 
{
1632
 
public:
1633
 
  LEX_STRING db;
1634
 
  LEX_STRING table;
1635
 
  Select_Lex_Unit *sel;
1636
 
  inline Table_ident(Session *session, LEX_STRING db_arg, LEX_STRING table_arg,
1637
 
                     bool force)
1638
 
    :table(table_arg), sel((Select_Lex_Unit *)0)
1639
 
  {
1640
 
    if (!force && (session->client_capabilities & CLIENT_NO_SCHEMA))
1641
 
      db.str=0;
1642
 
    else
1643
 
      db= db_arg;
1644
 
  }
1645
 
  inline Table_ident(LEX_STRING table_arg)
1646
 
    :table(table_arg), sel((Select_Lex_Unit *)0)
1647
 
  {
1648
 
    db.str=0;
1649
 
  }
1650
 
  /*
1651
 
    This constructor is used only for the case when we create a derived
1652
 
    table. A derived table has no name and doesn't belong to any database.
1653
 
    Later, if there was an alias specified for the table, it will be set
1654
 
    by add_table_to_list.
1655
 
  */
1656
 
  inline Table_ident(Select_Lex_Unit *s) : sel(s)
1657
 
  {
1658
 
    /* We must have a table name here as this is used with add_table_to_list */
1659
 
    db.str= empty_c_string;                    /* a subject to casedn_str */
1660
 
    db.length= 0;
1661
 
    table.str= internal_table_name;
1662
 
    table.length=1;
1663
 
  }
1664
 
  bool is_derived_table() const { return test(sel); }
1665
 
  inline void change_db(char *db_name)
1666
 
  {
1667
 
    db.str= db_name; db.length= (uint) strlen(db_name);
1668
 
  }
1669
 
};
1670
 
 
1671
 
// this is needed for user_vars hash
1672
 
class user_var_entry
1673
 
{
1674
 
 public:
1675
 
  user_var_entry() {}                         /* Remove gcc warning */
1676
 
  LEX_STRING name;
1677
 
  char *value;
1678
 
  ulong length;
1679
 
  query_id_t update_query_id, used_query_id;
1680
 
  Item_result type;
1681
 
  bool unsigned_flag;
1682
 
 
1683
 
  double val_real(bool *null_value);
1684
 
  int64_t val_int(bool *null_value) const;
1685
 
  String *val_str(bool *null_value, String *str, uint32_t decimals);
1686
 
  my_decimal *val_decimal(bool *null_value, my_decimal *result);
1687
 
  DTCollation collation;
1688
 
};
1689
 
 
1690
 
/*
1691
 
   Unique -- class for unique (removing of duplicates).
1692
 
   Puts all values to the TREE. If the tree becomes too big,
1693
 
   it's dumped to the file. User can request sorted values, or
1694
 
   just iterate through them. In the last case tree merging is performed in
1695
 
   memory simultaneously with iteration, so it should be ~2-3x faster.
1696
 
 */
1697
 
 
1698
 
class Unique :public Sql_alloc
1699
 
{
1700
 
  DYNAMIC_ARRAY file_ptrs;
1701
 
  ulong max_elements;
1702
 
  size_t max_in_memory_size;
1703
 
  IO_CACHE file;
1704
 
  TREE tree;
1705
 
  unsigned char *record_pointers;
1706
 
  bool flush();
1707
 
  uint32_t size;
1708
 
 
1709
 
public:
1710
 
  ulong elements;
1711
 
  Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
1712
 
         uint32_t size_arg, size_t max_in_memory_size_arg);
1713
 
  ~Unique();
1714
 
  ulong elements_in_tree() { return tree.elements_in_tree; }
1715
 
  inline bool unique_add(void *ptr)
1716
 
  {
1717
 
    if (tree.elements_in_tree > max_elements && flush())
1718
 
      return(1);
1719
 
    return(!tree_insert(&tree, ptr, 0, tree.custom_arg));
1720
 
  }
1721
 
 
1722
 
  bool get(Table *table);
1723
 
  static double get_use_cost(uint32_t *buffer, uint32_t nkeys, uint32_t key_size,
1724
 
                             size_t max_in_memory_size);
1725
 
  inline static int get_cost_calc_buff_size(ulong nkeys, uint32_t key_size,
1726
 
                                            size_t max_in_memory_size)
1727
 
  {
1728
 
    register size_t max_elems_in_tree=
1729
 
      (1 + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size));
1730
 
    return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree));
1731
 
  }
1732
 
 
1733
 
  void reset();
1734
 
  bool walk(tree_walk_action action, void *walk_action_arg);
1735
 
 
1736
 
  friend int unique_write_to_file(unsigned char* key, element_count count, Unique *unique);
1737
 
  friend int unique_write_to_ptrs(unsigned char* key, element_count count, Unique *unique);
1738
 
};
1739
 
 
1740
 
 
1741
 
class multi_delete :public select_result_interceptor
1742
 
{
1743
 
  TableList *delete_tables, *table_being_deleted;
1744
 
  Unique **tempfiles;
1745
 
  ha_rows deleted, found;
1746
 
  uint32_t num_of_tables;
1747
 
  int error;
1748
 
  bool do_delete;
1749
 
  /* True if at least one table we delete from is transactional */
1750
 
  bool transactional_tables;
1751
 
  /* True if at least one table we delete from is not transactional */
1752
 
  bool normal_tables;
1753
 
  bool delete_while_scanning;
1754
 
  /*
1755
 
     error handling (rollback and binlogging) can happen in send_eof()
1756
 
     so that afterward send_error() needs to find out that.
1757
 
  */
1758
 
  bool error_handled;
1759
 
 
1760
 
public:
1761
 
  multi_delete(TableList *dt, uint32_t num_of_tables);
1762
 
  ~multi_delete();
1763
 
  int prepare(List<Item> &list, Select_Lex_Unit *u);
1764
 
  bool send_data(List<Item> &items);
1765
 
  bool initialize_tables (JOIN *join);
1766
 
  void send_error(uint32_t errcode,const char *err);
1767
 
  int  do_deletes();
1768
 
  bool send_eof();
1769
 
  virtual void abort();
1770
 
};
1771
 
 
1772
 
 
1773
 
class multi_update :public select_result_interceptor
1774
 
{
1775
 
  TableList *all_tables; /* query/update command tables */
1776
 
  TableList *leaves;     /* list of leves of join table tree */
1777
 
  TableList *update_tables, *table_being_updated;
1778
 
  Table **tmp_tables, *main_table, *table_to_update;
1779
 
  TMP_TABLE_PARAM *tmp_table_param;
1780
 
  ha_rows updated, found;
1781
 
  List <Item> *fields, *values;
1782
 
  List <Item> **fields_for_table, **values_for_table;
1783
 
  uint32_t table_count;
1784
 
  /*
1785
 
   List of tables referenced in the CHECK OPTION condition of
1786
 
   the updated view excluding the updated table.
1787
 
  */
1788
 
  List <Table> unupdated_check_opt_tables;
1789
 
  Copy_field *copy_field;
1790
 
  enum enum_duplicates handle_duplicates;
1791
 
  bool do_update, trans_safe;
1792
 
  /* True if the update operation has made a change in a transactional table */
1793
 
  bool transactional_tables;
1794
 
  bool ignore;
1795
 
  /*
1796
 
     error handling (rollback and binlogging) can happen in send_eof()
1797
 
     so that afterward send_error() needs to find out that.
1798
 
  */
1799
 
  bool error_handled;
1800
 
 
1801
 
public:
1802
 
  multi_update(TableList *ut, TableList *leaves_list,
1803
 
               List<Item> *fields, List<Item> *values,
1804
 
               enum_duplicates handle_duplicates, bool ignore);
1805
 
  ~multi_update();
1806
 
  int prepare(List<Item> &list, Select_Lex_Unit *u);
1807
 
  bool send_data(List<Item> &items);
1808
 
  bool initialize_tables (JOIN *join);
1809
 
  void send_error(uint32_t errcode,const char *err);
1810
 
  int  do_updates();
1811
 
  bool send_eof();
1812
 
  virtual void abort();
1813
 
};
1814
 
 
1815
 
class my_var : public Sql_alloc  {
1816
 
public:
1817
 
  LEX_STRING s;
1818
 
  bool local;
1819
 
  uint32_t offset;
1820
 
  enum_field_types type;
1821
 
  my_var (LEX_STRING& j, bool i, uint32_t o, enum_field_types t)
1822
 
    :s(j), local(i), offset(o), type(t)
1823
 
  {}
1824
 
  ~my_var() {}
1825
 
};
1826
 
 
1827
 
class select_dumpvar :public select_result_interceptor {
1828
 
  ha_rows row_count;
1829
 
public:
1830
 
  List<my_var> var_list;
1831
 
  select_dumpvar()  { var_list.empty(); row_count= 0;}
1832
 
  ~select_dumpvar() {}
1833
 
  int prepare(List<Item> &list, Select_Lex_Unit *u);
1834
 
  bool send_data(List<Item> &items);
1835
 
  bool send_eof();
1836
 
  void cleanup();
1837
 
};
 
1233
 
 
1234
#include <drizzled/table_ident.h>
 
1235
#include <drizzled/user_var_entry.h>
 
1236
#include <drizzled/unique.h>
 
1237
#include <drizzled/multi_delete.h>
 
1238
#include <drizzled/multi_update.h>
 
1239
#include <drizzled/my_var.h>
 
1240
#include <drizzled/select_dumpvar.h>
1838
1241
 
1839
1242
/* Bits in sql_command_flags */
1840
1243