sql_class.h
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:15k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* Classes in mysql */
  17. #ifdef __GNUC__
  18. #pragma interface /* gcc class implementation */
  19. #endif
  20. class Query_log_event;
  21. class Load_log_event;
  22. enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
  23. enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
  24. // log info errors 
  25. #define LOG_INFO_EOF -1
  26. #define LOG_INFO_IO  -2
  27. #define LOG_INFO_INVALID -3
  28. #define LOG_INFO_SEEK -4
  29. #define LOG_INFO_PURGE_NO_ROTATE -5
  30. #define LOG_INFO_MEM -6
  31. #define LOG_INFO_FATAL -7
  32. #define LOG_INFO_IN_USE -8
  33. typedef struct st_log_info
  34. {
  35.   char log_file_name[FN_REFLEN];
  36.   my_off_t index_file_offset;
  37.   my_off_t pos;
  38.   bool fatal; // if the purge happens to give us a negative offset
  39.   pthread_mutex_t lock;
  40.   st_log_info():fatal(0) { pthread_mutex_init(&lock, NULL);}
  41.   ~st_log_info() { pthread_mutex_destroy(&lock);}
  42. } LOG_INFO;
  43. class MYSQL_LOG {
  44.  private:
  45.   pthread_mutex_t LOCK_log, LOCK_index;
  46.   time_t last_time,query_start;
  47.   IO_CACHE log_file;
  48.   File index_file;
  49.   char *name;
  50.   volatile enum_log_type log_type;
  51.   char time_buff[20],db[NAME_LEN+1];
  52.   char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
  53.   bool write_error,inited;
  54.   bool no_rotate; // for binlog - if log name can never change
  55.   // we should not try to rotate it or write any rotation events
  56.   // the user should use FLUSH MASTER instead of FLUSH LOGS for
  57.   // purging
  58. public:
  59.   MYSQL_LOG();
  60.   ~MYSQL_LOG();
  61.   pthread_mutex_t* get_log_lock() { return &LOCK_log; }
  62.   void set_index_file_name(const char* index_file_name = 0);
  63.   void open(const char *log_name,enum_log_type log_type,
  64.     const char *new_name=0);
  65.   void new_file(void);
  66.   bool write(THD *thd, enum enum_server_command command,const char *format,...);
  67.   bool write(THD *thd, const char *query, uint query_length,
  68.      time_t query_start=0);
  69.   bool write(Query_log_event* event_info); // binary log write
  70.   bool write(Load_log_event* event_info);
  71.   bool write(IO_CACHE *cache);
  72.   int generate_new_name(char *new_name,const char *old_name);
  73.   void make_log_name(char* buf, const char* log_ident);
  74.   bool is_active(const char* log_file_name);
  75.   int purge_logs(THD* thd, const char* to_log);
  76.   void close(bool exiting = 0); // if we are exiting, we also want to close the
  77.   // index file
  78.   // iterating through the log index file
  79.   int find_first_log(LOG_INFO* linfo, const char* log_name);
  80.   int find_next_log(LOG_INFO* linfo);
  81.   int get_current_log(LOG_INFO* linfo);
  82.   inline bool is_open() { return log_type != LOG_CLOSED; }
  83.   char* get_index_fname() { return index_file_name;}
  84.   char* get_log_fname() { return log_file_name; }
  85.   void lock_index() { pthread_mutex_lock(&LOCK_index);}
  86.   void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
  87.   File get_index_file() { return index_file;}
  88. };
  89. /* character conversion tables */
  90. class CONVERT;
  91. CONVERT *get_convert_set(const char *name_ptr);
  92. class CONVERT
  93. {
  94.   const uchar *from_map,*to_map;
  95.   void convert_array(const uchar *mapping,uchar *buff,uint length);
  96. public:
  97.   const char *name;
  98.   CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
  99.     :from_map(from_par),to_map(to_par),name(name_par) {}
  100.   friend CONVERT *get_convert_set(const char *name_ptr);
  101.   inline void convert(char *a,uint length)
  102.   {
  103.     convert_array(from_map, (uchar*) a,length);
  104.   }
  105.   bool store(String *, const char *,uint);
  106. };
  107. typedef struct st_copy_info {
  108.   ha_rows records;
  109.   ha_rows deleted;
  110.   ha_rows copied;
  111.   ha_rows error;
  112.   enum enum_duplicates handle_duplicates;
  113.   int escape_char;
  114. } COPY_INFO;
  115. class key_part_spec :public Sql_alloc {
  116. public:
  117.   const char *field_name;
  118.   uint length;
  119.   key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {}
  120. };
  121. class Alter_drop :public Sql_alloc {
  122. public:
  123.   enum drop_type {KEY, COLUMN };
  124.   const char *name;
  125.   enum drop_type type;
  126.   Alter_drop(enum drop_type par_type,const char *par_name)
  127.     :name(par_name), type(par_type) {}
  128. };
  129. class Alter_column :public Sql_alloc {
  130. public:
  131.   const char *name;
  132.   Item *def;
  133.   Alter_column(const char *par_name,Item *literal)
  134.     :name(par_name), def(literal) {}
  135. };
  136. class Key :public Sql_alloc {
  137. public:
  138.   enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT };
  139.   enum Keytype type;
  140.   List<key_part_spec> columns;
  141.   const char *Name;
  142.   Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols)
  143.     :type(type_par), columns(cols),Name(name_arg) {}
  144.   ~Key() {}
  145.   const char *name() { return Name; }
  146. };
  147. typedef struct st_mysql_lock
  148. {
  149.   TABLE **table;
  150.   uint table_count,lock_count;
  151.   THR_LOCK_DATA **locks;
  152. } MYSQL_LOCK;
  153. class LEX_COLUMN : public Sql_alloc
  154. {
  155. public:
  156.   String column;
  157.   uint rights;
  158.   LEX_COLUMN (const String& x,const  uint& y ): column (x),rights (y) {}
  159. };
  160. #include "sql_lex.h" /* Must be here */
  161. // needed to be able to have an I_List of char* strings.in mysqld.cc where we cannot use String
  162. // because it is Sql_alloc'ed
  163. class i_string: public ilink
  164. {
  165. public:
  166.   char* ptr;
  167.   i_string():ptr(0) { }
  168.   i_string(char* s) : ptr(s) {}
  169. };
  170. //needed for linked list of two strings for replicate-rewrite-db
  171. class i_string_pair: public ilink
  172. {
  173. public:
  174.   char* key;
  175.   char* val;
  176.   i_string_pair():key(0),val(0) { }
  177.   i_string_pair(char* key_arg, char* val_arg) : key(key_arg),val(val_arg) {}
  178. };
  179. /****************************************************************************
  180. ** every connection is handle by a thread with a THD
  181. ****************************************************************************/
  182. class delayed_insert;
  183. class THD :public ilink {
  184. public:
  185.   NET   net;
  186.   LEX   lex;
  187.   MEM_ROOT mem_root;
  188.   HASH     user_vars;
  189.   String  packet; /* Room for 1 row */
  190.   struct  sockaddr_in remote;
  191.   struct  rand_struct rand;
  192.   char   *query,*thread_stack;
  193.   char   *host,*user,*priv_user,*db,*ip;
  194.   const   char *proc_info;
  195.   uint   client_capabilities,max_packet_length;
  196.   uint   master_access,db_access;
  197.   TABLE   *open_tables,*temporary_tables;
  198.   MYSQL_LOCK *lock,*locked_tables;
  199.   ULL   *ull;
  200.   struct st_my_thread_var *mysys_var;
  201.   enum enum_server_command command;
  202.   uint32 server_id;
  203.   const char *where;
  204.   char* last_nx_table; // last non-existent table, we need this for replication
  205.   char* last_nx_db; // database of the last nx table
  206.   time_t  start_time,time_after_lock,user_time;
  207.   time_t  connect_time,thr_create_time; // track down slow pthread_create
  208.   thr_lock_type update_lock_default;
  209.   delayed_insert *di;
  210.   struct st_transactions {
  211.     IO_CACHE trans_log;
  212.     THD_TRANS all; /* Trans since BEGIN WORK */
  213.     THD_TRANS stmt; /* Trans for current statement */
  214.     uint bdb_lock_count;
  215.   } transaction;
  216.   Item      *free_list;
  217.   CONVERT    *convert_set;
  218.   Field      *dupp_field;
  219. #ifndef __WIN__
  220.   sigset_t signals,block_signals;
  221. #endif
  222. #ifdef SIGNAL_WITH_VIO_CLOSE
  223.   Vio* active_vio;
  224.   pthread_mutex_t active_vio_lock;
  225. #endif  
  226.   ulonglong  next_insert_id,last_insert_id,current_insert_id;
  227.   ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
  228.           max_join_size,sent_row_count;
  229.   table_map used_tables;
  230.   ulong query_id,version, inactive_timeout,options,thread_id;
  231.   long  dbug_thread_id;
  232.   pthread_t  real_id;
  233.   uint current_tablenr,tmp_table,cond_count,col_access,query_length;
  234.   uint  server_status,open_options;
  235.   char      scramble[9];
  236.   bool       slave_thread;
  237.   bool      set_query_id,locked,count_cuted_fields,some_tables_deleted;
  238.   bool      no_errors, allow_sum_func, password, fatal_error;
  239.   bool      query_start_used,last_insert_id_used,insert_id_used;
  240.   bool      system_thread,in_lock_tables,global_read_lock;
  241.   bool       query_error, bootstrap;
  242.   bool      volatile killed;
  243.   LOG_INFO*  current_linfo;
  244.   // if we do a purge of binary logs, log index info of the threads
  245.   // that are currently reading it needs to be adjusted. To do that
  246.   // each thread that is using LOG_INFO needs to adjust the pointer to it
  247.   ulong slave_proxy_id; // in slave thread we need to know in behalf of which
  248.   // thread the query is being run to replicate temp tables properly
  249.   THD();
  250.   ~THD();
  251.   bool store_globals();
  252. #ifdef SIGNAL_WITH_VIO_CLOSE
  253.   inline void set_active_vio(Vio* vio)
  254.   {
  255.     pthread_mutex_lock(&active_vio_lock);
  256.     active_vio = vio;
  257.     pthread_mutex_unlock(&active_vio_lock);
  258.   }
  259.   inline void clear_active_vio()
  260.   {
  261.     pthread_mutex_lock(&active_vio_lock);
  262.     active_vio = 0;
  263.     pthread_mutex_unlock(&active_vio_lock);
  264.   }
  265.   inline void close_active_vio()
  266.   {
  267.     pthread_mutex_lock(&active_vio_lock);
  268.     if(active_vio)
  269.       {
  270. vio_close(active_vio);
  271.         active_vio = 0;
  272.       }
  273.     pthread_mutex_unlock(&active_vio_lock);
  274.   }
  275. #endif  
  276.   void prepare_to_die();
  277.   inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
  278.   const char* msg)
  279.   {
  280.     const char* old_msg = proc_info;
  281.     pthread_mutex_lock(&mysys_var->mutex);
  282.     mysys_var->current_mutex = mutex;
  283.     mysys_var->current_cond = cond;
  284.     proc_info = msg;
  285.     pthread_mutex_unlock(&mysys_var->mutex);
  286.     return old_msg;
  287.   }
  288.   inline void exit_cond(const char* old_msg)
  289.   {
  290.     pthread_mutex_lock(&mysys_var->mutex);
  291.     mysys_var->current_mutex = 0;
  292.     mysys_var->current_cond = 0;
  293.     proc_info = old_msg;
  294.     pthread_mutex_unlock(&mysys_var->mutex);
  295.   }
  296.   inline time_t query_start() { query_start_used=1; return start_time; }
  297.   inline void set_time()    { if (user_time) start_time=time_after_lock=user_time; else time_after_lock=time(&start_time); }
  298.   inline void end_time()    { time(&start_time); }
  299.   inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; }
  300.   inline void lock_time()   { time(&time_after_lock); }
  301.   inline void insert_id(ulonglong id)
  302.   { last_insert_id=id; insert_id_used=1; }
  303.   inline ulonglong insert_id(void)
  304.   {
  305.     if (!last_insert_id_used)
  306.     {      
  307.       last_insert_id_used=1;
  308.       current_insert_id=last_insert_id;
  309.     }
  310.     return last_insert_id;
  311.   }
  312.   inline bool active_transaction()
  313.   {
  314. #ifdef USING_TRANSACTIONS    
  315.     return (transaction.all.bdb_tid != 0 ||
  316.     transaction.all.innobase_tid != 0 || 
  317.     transaction.all.gemini_tid != 0);
  318. #else
  319.     return 0;
  320. #endif
  321.     
  322.   }
  323.   inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
  324.   inline gptr calloc(unsigned int size)
  325.   {
  326.     gptr ptr;
  327.     if ((ptr=alloc_root(&mem_root,size)))
  328.       bzero((char*) ptr,size);
  329.     return ptr;
  330.   }
  331.   inline char *strdup(const char *str)
  332.   { return strdup_root(&mem_root,str); }
  333.   inline char *memdup(const char *str, unsigned int size)
  334.   { return memdup_root(&mem_root,str,size); }
  335. };
  336. class sql_exchange :public Sql_alloc
  337. {
  338. public:
  339.   char *file_name;
  340.   String *field_term,*enclosed,*line_term,*line_start,*escaped;
  341.   bool opt_enclosed;
  342.   bool dumpfile;
  343.   uint skip_lines;
  344.   sql_exchange(char *name,bool dumpfile_flag);
  345.   ~sql_exchange() {}
  346. };
  347. #include "log_event.h"
  348. /*
  349. ** This is used to get result from a select
  350. */
  351. class select_result :public Sql_alloc {
  352. protected:
  353.   THD *thd;
  354. public:
  355.   select_result();
  356.   virtual ~select_result() {};
  357.   virtual int prepare(List<Item> &list) { return 0; }
  358.   virtual bool send_fields(List<Item> &list,uint flag)=0;
  359.   virtual bool send_data(List<Item> &items)=0;
  360.   virtual void send_error(uint errcode,const char *err)=0;
  361.   virtual bool send_eof()=0;
  362.   virtual void abort() {}
  363. };
  364. class select_send :public select_result {
  365. public:
  366.   select_send() {}
  367.   bool send_fields(List<Item> &list,uint flag);
  368.   bool send_data(List<Item> &items);
  369.   void send_error(uint errcode,const char *err);
  370.   bool send_eof();
  371. };
  372. class select_export :public select_result {
  373.   sql_exchange *exchange;
  374.   File file;
  375.   IO_CACHE cache;
  376.   ha_rows row_count;
  377.   uint field_term_length;
  378.   int field_sep_char,escape_char,line_sep_char;
  379.   bool fixed_row_size;
  380. public:
  381.   select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {}
  382.   ~select_export();
  383.   int prepare(List<Item> &list);
  384.   bool send_fields(List<Item> &list,
  385.    uint flag) { return 0; }
  386.   bool send_data(List<Item> &items);
  387.   void send_error(uint errcode,const char *err);
  388.   bool send_eof();
  389. };
  390. class select_dump :public select_result {
  391.   sql_exchange *exchange;
  392.   File file;
  393.   IO_CACHE cache;
  394.   ha_rows row_count;
  395.   char path[FN_REFLEN];
  396. public:
  397.   select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L)
  398.   { path[0]=0; }
  399.   ~select_dump();
  400.   int prepare(List<Item> &list);
  401.   bool send_fields(List<Item> &list,
  402.    uint flag) { return 0; }
  403.   bool send_data(List<Item> &items);
  404.   void send_error(uint errcode,const char *err);
  405.   bool send_eof();
  406. };
  407. class select_insert :public select_result {
  408.  protected:
  409.   TABLE *table;
  410.   List<Item> *fields;
  411.   uint save_time_stamp;
  412.   ulonglong last_insert_id;
  413.   COPY_INFO info;
  414. public:
  415.   select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
  416.     :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
  417.     {
  418.       bzero((char*) &info,sizeof(info));
  419.       info.handle_duplicates=duplic;
  420.     }
  421.   ~select_insert();
  422.   int prepare(List<Item> &list);
  423.   bool send_fields(List<Item> &list,
  424.    uint flag) { return 0; }
  425.   bool send_data(List<Item> &items);
  426.   void send_error(uint errcode,const char *err);
  427.   bool send_eof();
  428. };
  429. class select_create: public select_insert {
  430.   ORDER *group;
  431.   const char *db;
  432.   const char *name;
  433.   List<create_field> *extra_fields;
  434.   List<Key> *keys;
  435.   HA_CREATE_INFO *create_info;
  436.   MYSQL_LOCK *lock;
  437.   Field **field;
  438. public:
  439.   select_create (const char *db_name, const char *table_name,
  440.  HA_CREATE_INFO *create_info_par,
  441.  List<create_field> &fields_par,
  442.  List<Key> &keys_par,
  443.  List<Item> &select_fields,enum_duplicates duplic)
  444.     :select_insert (NULL, &select_fields, duplic), db(db_name),
  445.     name(table_name), extra_fields(&fields_par),keys(&keys_par),
  446.     create_info(create_info_par),
  447.     lock(0)
  448.     {}
  449.   int prepare(List<Item> &list);
  450.   bool send_data(List<Item> &values);
  451.   bool send_eof();
  452.   void abort();
  453. };
  454. /* Structs used when sorting */
  455. typedef struct st_sort_field {
  456.   Field *field; /* Field to sort */
  457.   Item *item; /* Item if not sorting fields */
  458.   uint  length; /* Length of sort field */
  459.   my_bool reverse; /* if descending sort */
  460.   Item_result result_type; /* Type of item */
  461. } SORT_FIELD;
  462. typedef struct st_sort_buffer {
  463.   uint index; /* 0 or 1 */
  464.   uint sort_orders;
  465.   uint change_pos; /* If sort-fields changed */
  466.   char **buff;
  467.   SORT_FIELD *sortorder;
  468. } SORT_BUFFER;
  469. /* Structure for db & table in sql_yacc */
  470. class Table_ident :public Sql_alloc {
  471.  public:
  472.   LEX_STRING db;
  473.   LEX_STRING table;
  474.   inline Table_ident(LEX_STRING db_arg,LEX_STRING table_arg,bool force)
  475.     :table(table_arg)
  476.   {
  477.     if (!force && (current_thd->client_capabilities & CLIENT_NO_SCHEMA))
  478.       db.str=0;
  479.     else
  480.       db= db_arg;
  481.   }
  482.   inline Table_ident(LEX_STRING table_arg) :table(table_arg) {db.str=0;}
  483.   inline void change_db(char *db_name)
  484.   { db.str= db_name; db.length=(uint) strlen(db_name); }
  485. };
  486. // this is needed for user_vars hash
  487. class user_var_entry
  488. {
  489.  public:
  490.   LEX_STRING name;
  491.   char *value;
  492.   ulong length, update_query_id;
  493.   Item_result type;
  494. };