summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r--sql/sql_class.h472
1 files changed, 472 insertions, 0 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
new file mode 100644
index 00000000000..2ea18751dea
--- /dev/null
+++ b/sql/sql_class.h
@@ -0,0 +1,472 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* Classes in mysql */
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+
+class Query_log_event;
+class Load_log_event;
+
+
+enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
+enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
+
+// log info errors
+#define LOG_INFO_EOF -1
+#define LOG_INFO_IO -2
+#define LOG_INFO_INVALID -3
+#define LOG_INFO_SEEK -4
+
+typedef struct st_log_info
+{
+ char log_file_name[FN_REFLEN];
+ my_off_t index_file_offset;
+ my_off_t pos;
+} LOG_INFO;
+
+typedef struct st_master_info
+{
+ char log_file_name[FN_REFLEN];
+ ulong pos;
+ FILE* file; // we keep the file open, so we need to remember the file pointer
+
+ // the variables below are needed because we can change masters on the fly
+ char host[HOSTNAME_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
+ char password[HASH_PASSWORD_LENGTH+1];
+ uint port;
+ uint connect_retry;
+ pthread_mutex_t lock;
+ bool inited;
+
+ st_master_info():inited(0) { host[0] = 0; user[0] = 0; password[0] = 0;}
+ inline void inc_pos(ulong val)
+ {
+ pthread_mutex_lock(&lock);
+ pos += val;
+ pthread_mutex_unlock(&lock);
+ }
+ // thread safe read of position - not needed if we are in the slave thread,
+ // but required otherwise
+ inline void read_pos(ulong& var)
+ {
+ pthread_mutex_lock(&lock);
+ var = pos;
+ pthread_mutex_unlock(&lock);
+ }
+} MASTER_INFO;
+
+class MYSQL_LOG {
+ public:
+ private:
+ pthread_mutex_t LOCK_log, LOCK_index;
+ FILE *file, *index_file;
+ time_t last_time,query_start;
+ char *name;
+ enum_log_type log_type;
+ char time_buff[20],db[NAME_LEN+1];
+ char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
+ bool write_error,inited;
+
+public:
+ MYSQL_LOG();
+ ~MYSQL_LOG();
+ pthread_mutex_t* get_log_lock() { return &LOCK_log; }
+ void set_index_file_name(const char* index_file_name = 0);
+ void open(const char *log_name,enum_log_type log_type,
+ const char *new_name=0);
+ void new_file(void);
+ void write(enum enum_server_command command,const char *format,...);
+ void write(const char *query, uint query_length, ulong time_to_do_query=0);
+ void write(Query_log_event* event_info); // binary log write
+ void write(Load_log_event* event_info);
+
+ int generate_new_name(char *new_name,const char *old_name);
+ void make_log_name(char* buf, const char* log_ident);
+ bool is_active(const char* log_file_name);
+ void flush(void);
+ void close(bool exiting = 0); // if we are exiting, we also want to close the
+ // index file
+
+ // iterating through the log index file
+ int find_first_log(LOG_INFO* linfo, const char* log_name);
+ int find_next_log(LOG_INFO* linfo);
+ int get_current_log(LOG_INFO* linfo);
+
+ bool is_open() { return log_type != LOG_CLOSED; }
+ char* get_index_fname() { return index_file_name;}
+ char* get_log_fname() { return log_file_name; }
+};
+
+/* character conversion tables */
+
+class CONVERT
+{
+ const uchar *from_map,*to_map;
+ void convert_array(const uchar *mapping,uchar *buff,uint length);
+public:
+ const char *name;
+ CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
+ :from_map(from_par),to_map(to_par),name(name_par) {}
+ friend CONVERT *get_convert_set(const char *name_ptr);
+ inline void convert(char *a,uint length)
+ {
+ convert_array(from_map, (uchar*) a,length);
+ }
+ bool store(String *, const char *,uint);
+};
+
+typedef struct st_copy_info {
+ ha_rows records;
+ ha_rows deleted;
+ ha_rows copied;
+ ha_rows error;
+ enum enum_duplicates handle_duplicates;
+ int escape_char;
+} COPY_INFO;
+
+
+class key_part_spec :public Sql_alloc {
+public:
+ const char *field_name;
+ uint length;
+ key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {}
+};
+
+
+class Alter_drop :public Sql_alloc {
+public:
+ enum drop_type {KEY, COLUMN };
+ const char *name;
+ enum drop_type type;
+ Alter_drop(enum drop_type par_type,const char *par_name)
+ :name(par_name), type(par_type) {}
+};
+
+
+class Alter_column :public Sql_alloc {
+public:
+ const char *name;
+ Item *def;
+ Alter_column(const char *par_name,Item *literal)
+ :name(par_name), def(literal) {}
+};
+
+
+class Key :public Sql_alloc {
+public:
+ enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT };
+ enum Keytype type;
+ List<key_part_spec> columns;
+ const char *Name;
+
+ Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols)
+ :type(type_par), columns(cols),Name(name_arg) {}
+ ~Key() {}
+ const char *name() { return Name; }
+};
+
+
+typedef struct st_mysql_lock
+{
+ TABLE **table;
+ uint table_count,lock_count;
+ THR_LOCK_DATA **locks;
+} MYSQL_LOCK;
+
+
+class LEX_COLUMN : public Sql_alloc
+{
+public:
+ String column;
+ uint rights;
+ LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
+};
+
+#include "sql_lex.h" /* Must be here */
+
+// needed to be able to have an I_List of char* strings.in mysqld.cc where we cannot use String
+// because it is Sql_alloc'ed
+class i_string: public ilink
+{
+public:
+ char* ptr;
+ i_string():ptr(0) { }
+ i_string(char* s) : ptr(s) {}
+};
+
+/****************************************************************************
+** every connection is handle by a thread with a THD
+****************************************************************************/
+
+class delayed_insert;
+
+class THD :public ilink {
+public:
+ NET net;
+ LEX lex;
+ MEM_ROOT alloc;
+ HASH user_vars;
+ String packet; /* Room for 1 row */
+ struct sockaddr_in remote;
+ struct rand_struct rand;
+ char *query,*thread_stack;
+ char *host,*user,*priv_user,*db,*ip;
+ const char *proc_info;
+ uint client_capabilities,max_packet_length;
+ uint master_access,db_access;
+ TABLE *open_tables,*temporary_tables;
+ MYSQL_LOCK *lock,*locked_tables;
+ ULL *ull;
+ struct st_my_thread_var *mysys_var;
+ enum enum_server_command command;
+ const char *where;
+ char* last_nx_table; // last non-existent table, we need this for replication
+ char* last_nx_db; // database of the last nx table
+ time_t start_time;
+ time_t connect_time,thr_create_time; // track down slow pthread_create
+ thr_lock_type update_lock_default;
+ delayed_insert *di;
+ struct st_transactions {
+ void *bdb_tid;
+ uint bdb_lock_count;
+ } transaction;
+ Item *free_list;
+ CONVERT *convert_set;
+ Field *dupp_field;
+#ifndef __WIN__
+ sigset_t signals,block_signals;
+#endif
+ ulonglong next_insert_id,last_insert_id,current_insert_id;
+ ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
+ max_join_size;
+ ulong query_id,version, inactive_timeout,options,thread_id;
+ long dbug_thread_id;
+ pthread_t real_id;
+ uint current_tablenr,tmp_table,cond_count,col_access,query_length;
+ uint server_status;
+ char scramble[9];
+ bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
+ bool no_errors, allow_sum_func, password, fatal_error;
+ bool query_start_used,last_insert_id_used,insert_id_used,user_time;
+ bool volatile killed,bootstrap;
+ bool system_thread,in_lock_tables,global_read_lock;
+ bool query_error;
+ THD();
+ ~THD();
+ bool store_globals();
+ inline time_t query_start() { query_start_used=1; return start_time; }
+ inline void set_time() { if (!user_time) time(&start_time); }
+ inline void set_time(time_t t) { start_time=t; user_time=1; }
+ inline void insert_id(ulonglong id)
+ { last_insert_id=id; insert_id_used=1; }
+ inline ulonglong insert_id(void)
+ {
+ if (!last_insert_id_used)
+ {
+ last_insert_id_used=1;
+ current_insert_id=last_insert_id;
+ }
+ return last_insert_id;
+ }
+};
+
+
+class sql_exchange :public Sql_alloc
+{
+public:
+ char *file_name;
+ String *field_term,*enclosed,*line_term,*line_start,*escaped;
+ bool opt_enclosed;
+ bool dumpfile;
+ uint skip_lines;
+ sql_exchange(char *name,bool dumpfile_flag);
+ ~sql_exchange() {}
+};
+
+#include "log_event.h"
+
+/*
+** This is used to get result from a select
+*/
+
+class select_result :public Sql_alloc {
+protected:
+ THD *thd;
+public:
+ select_result();
+ virtual ~select_result() {};
+ virtual int prepare(List<Item> &list) { return 0; }
+ virtual bool send_fields(List<Item> &list,uint flag)=0;
+ virtual bool send_data(List<Item> &items)=0;
+ virtual void send_error(uint errcode,const char *err)=0;
+ virtual bool send_eof()=0;
+ virtual void abort() {}
+};
+
+
+class select_send :public select_result {
+public:
+ select_send() {}
+ bool send_fields(List<Item> &list,uint flag);
+ bool send_data(List<Item> &items);
+ void send_error(uint errcode,const char *err);
+ bool send_eof();
+};
+
+
+class select_export :public select_result {
+ sql_exchange *exchange;
+ File file;
+ IO_CACHE cache;
+ ha_rows row_count;
+ uint field_term_length;
+ int field_sep_char,escape_char,line_sep_char;
+ bool fixed_row_size;
+public:
+ select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {}
+ ~select_export();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ void send_error(uint errcode,const char *err);
+ bool send_eof();
+};
+
+class select_dump :public select_result {
+ sql_exchange *exchange;
+ File file;
+ IO_CACHE cache;
+ ha_rows row_count;
+ char path[FN_REFLEN];
+public:
+ select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L)
+ { path[0]=0; }
+ ~select_dump();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ void send_error(uint errcode,const char *err);
+ bool send_eof();
+};
+
+
+class select_insert :public select_result {
+ protected:
+ TABLE *table;
+ List<Item> *fields;
+ uint save_time_stamp;
+ ulonglong last_insert_id;
+ COPY_INFO info;
+
+public:
+ select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
+ :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
+ {
+ bzero((char*) &info,sizeof(info));
+ info.handle_duplicates=duplic;
+ }
+ ~select_insert();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ void send_error(uint errcode,const char *err);
+ bool send_eof();
+};
+
+class select_create: public select_insert {
+ ORDER *group;
+ const char *db;
+ const char *name;
+ List<create_field> *extra_fields;
+ List<Key> *keys;
+ HA_CREATE_INFO *create_info;
+ MYSQL_LOCK *lock;
+ Field **field;
+public:
+ select_create (const char *db_name, const char *table_name,
+ HA_CREATE_INFO *create_info_par,
+ List<create_field> &fields_par,
+ List<Key> &keys_par,
+ List<Item> &select_fields,enum_duplicates duplic)
+ :select_insert (NULL, &select_fields, duplic), db(db_name),
+ name(table_name), extra_fields(&fields_par),keys(&keys_par),
+ create_info(create_info_par),
+ lock(0)
+ {}
+ int prepare(List<Item> &list);
+ bool send_data(List<Item> &values);
+ bool send_eof();
+ void abort();
+};
+
+/* Structs used when sorting */
+
+typedef struct st_sort_field {
+ Field *field; /* Field to sort */
+ Item *item; /* Item if not sorting fields */
+ uint length; /* Length of sort field */
+ my_bool reverse; /* if descending sort */
+ Item_result result_type; /* Type of item */
+} SORT_FIELD;
+
+
+typedef struct st_sort_buffer {
+ uint index; /* 0 or 1 */
+ uint sort_orders;
+ uint change_pos; /* If sort-fields changed */
+ char **buff;
+ SORT_FIELD *sortorder;
+} SORT_BUFFER;
+
+
+/* Structure for db & table in sql_yacc */
+
+class Table_ident :public Sql_alloc {
+ public:
+ LEX_STRING db;
+ LEX_STRING table;
+ inline Table_ident(LEX_STRING db_arg,LEX_STRING table_arg,bool force)
+ :table(table_arg)
+ {
+ if (!force && (current_thd->client_capabilities & CLIENT_NO_SCHEMA))
+ db.str=0;
+ else
+ db= db_arg;
+ }
+ inline Table_ident(LEX_STRING table_arg) :table(table_arg) {db.str=0;}
+ inline void change_db(char *db_name)
+ { db.str= db_name; db.length=strlen(db_name); }
+};
+
+// this is needed for user_vars hash
+class user_var_entry
+{
+ public:
+ LEX_STRING name;
+ char *value;
+ ulong length;
+ Item_result type;
+};
+