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.h340
1 files changed, 263 insertions, 77 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3f25f7cff9d..abaa7d4d9cb 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ 2009-2011 Monty Program 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
@@ -166,7 +167,7 @@ typedef struct st_user_var_events
#define RP_LOCK_LOG_IS_ALREADY_LOCKED 1
#define RP_FORCE_ROTATE 2
-
+#define RP_BINLOG_CHECKSUM_ALG_CHANGE 4
/*
The COPY_INFO structure is used by INSERT/REPLACE code.
The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
@@ -433,6 +434,9 @@ typedef struct system_variables
ulonglong optimizer_switch;
ulonglong sql_mode; ///< which non-standard SQL behaviour should be enabled
ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING
+ ulonglong join_buff_space_limit;
+ ulonglong log_slow_filter;
+ ulonglong log_slow_verbosity;
ha_rows select_limit;
ha_rows max_join_size;
ulong auto_increment_increment, auto_increment_offset;
@@ -456,13 +460,6 @@ typedef struct system_variables
ulong net_write_timeout;
ulong optimizer_prune_level;
ulong optimizer_search_depth;
- /*
- Controls use of Engine-MRR:
- 0 - auto, based on cost
- 1 - force MRR when the storage engine is capable of doing it
- 2 - disable MRR.
- */
- ulong optimizer_use_mrr;
ulong preload_buff_size;
ulong profiling_history_size;
ulong read_buff_size;
@@ -484,9 +481,9 @@ typedef struct system_variables
ulong group_concat_max_len;
/* Flags for slow log filtering */
ulong log_slow_rate_limit;
- ulong log_slow_filter;
- ulong log_slow_verbosity;
ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)
+ ulong progress_report_time;
+ my_bool binlog_annotate_rows_events;
my_bool binlog_direct_non_trans_update;
my_bool sql_log_bin;
ulong completion_type;
@@ -501,11 +498,11 @@ typedef struct system_variables
my_thread_id pseudo_thread_id;
my_bool low_priority_updates;
- my_bool new_mode;
my_bool query_cache_wlock_invalidate;
my_bool engine_condition_pushdown;
my_bool keep_files_on_create;
+ my_bool old_mode;
my_bool old_alter_table;
my_bool old_passwords;
my_bool big_tables;
@@ -569,6 +566,9 @@ typedef struct system_status_var
ulong ha_rollback_count;
ulong ha_update_count;
ulong ha_write_count;
+ /* The following are for internal temporary tables */
+ ulong ha_tmp_update_count;
+ ulong ha_tmp_write_count;
ulong ha_prepare_count;
ulong ha_discover_count;
ulong ha_savepoint_count;
@@ -593,8 +593,6 @@ typedef struct system_status_var
ulong select_range_count;
ulong select_range_check_count;
ulong select_scan_count;
- ulong rows_read;
- ulong rows_sent;
ulong long_query_count;
ulong filesort_merge_passes;
ulong filesort_range_count;
@@ -624,6 +622,9 @@ typedef struct system_status_var
*/
ulonglong bytes_received;
ulonglong bytes_sent;
+ ulonglong rows_read;
+ ulonglong rows_sent;
+ ulonglong rows_tmp_read;
ulonglong binlog_bytes_written;
double last_query_cost;
double cpu_time, busy_time;
@@ -702,6 +703,8 @@ public:
{ return (int)state < (int)STMT_PREPARED; }
inline bool is_stmt_prepare_or_first_stmt_execute() const
{ return (int)state <= (int)STMT_PREPARED; }
+ inline bool is_stmt_execute() const
+ { return state == STMT_PREPARED || state == STMT_EXECUTED; }
inline bool is_conventional() const
{ return state == STMT_CONVENTIONAL_EXECUTION; }
@@ -796,6 +799,12 @@ public:
ENGINE INNODB STATUS.
*/
CSET_STRING query_string;
+ /*
+ If opt_query_cache_strip_comments is set, this contains query without
+ comments. If not set, it contains pointer to query_string.
+ */
+ String base_query;
+
inline char *query() const { return query_string.str(); }
inline uint32 query_length() const { return query_string.length(); }
@@ -829,7 +838,8 @@ public:
char *db;
size_t db_length;
-public:
+ /* This is set to 1 of last call to send_result_to_client() was ok */
+ my_bool query_cache_is_applicable;
/* This constructor is called for backup statements */
Statement() {}
@@ -1620,11 +1630,32 @@ public:
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
uint16 peer_port;
- time_t start_time, user_time;
+ my_time_t start_time; // start_time and its sec_part
+ ulong start_time_sec_part; // are almost always used separately
+ my_hrtime_t user_time;
// track down slow pthread_create
ulonglong prior_thr_create_utime, thr_create_utime;
ulonglong start_utime, utime_after_lock;
+ // Process indicator
+ struct {
+ /*
+ true, if the currently running command can send progress report
+ packets to a client. Set by mysql_execute_command() for safe commands
+ See CF_REPORT_PROGRESS
+ */
+ bool report_to_client;
+ /*
+ true, if we will send progress report packets to a client
+ (client has requested them, see CLIENT_PROGRESS; report_to_client
+ is true; not in sub-statement)
+ */
+ bool report;
+ uint stage, max_stage;
+ ulonglong counter, max_counter;
+ ulonglong next_report_time;
+ } progress;
+
thr_lock_type update_lock_default;
Delayed_insert *di;
@@ -1644,6 +1675,17 @@ public:
*/
TABLE_LIST *emb_on_expr_nest;
} thd_marker;
+
+ bool prepare_derived_at_open;
+
+ /*
+ To signal that the tmp table to be created is created for materialized
+ derived table or a view.
+ */
+ bool create_tmp_table_for_derived;
+
+ bool save_prep_leaf_list;
+
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
@@ -1652,7 +1694,8 @@ public:
*/
void binlog_start_trans_and_stmt();
void binlog_set_stmt_begin();
- int binlog_write_table_map(TABLE *table, bool is_transactional);
+ int binlog_write_table_map(TABLE *table, bool is_transactional,
+ my_bool *with_annotate= 0);
int binlog_write_row(TABLE* table, bool is_transactional,
MY_BITMAP const* cols, size_t colcnt,
const uchar *buf);
@@ -1790,7 +1833,7 @@ public:
/*
This is to track items changed during execution of a prepared
statement/stored procedure. It's created by
- register_item_tree_change() in memory root of THD, and freed in
+ nocheck_register_item_tree_change() in memory root of THD, and freed in
rollback_item_tree_changes(). For conventional execution it's always
empty.
*/
@@ -2051,7 +2094,7 @@ public:
ulong query_plan_fsort_passes;
pthread_t real_id; /* For debugging */
my_thread_id thread_id;
- uint tmp_table;
+ uint tmp_table, global_disable_checkpoint;
uint server_status,open_options;
enum enum_thread_type system_thread;
uint select_number; //number of select (used for EXPLAIN)
@@ -2137,6 +2180,7 @@ public:
*/
bool is_fatal_sub_stmt_error;
bool query_start_used, rand_used, time_zone_used;
+ bool query_start_sec_part_used;
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
bool substitute_null_with_insert_id;
bool in_lock_tables;
@@ -2200,6 +2244,7 @@ public:
long long_value;
ulong ulong_value;
ulonglong ulonglong_value;
+ double double_value;
} sys_var_tmp;
struct {
@@ -2348,33 +2393,45 @@ public:
mysql_mutex_unlock(&mysys_var->mutex);
return;
}
- inline time_t query_start() { query_start_used=1; return start_time; }
- inline void set_time()
+ inline my_time_t query_start() { query_start_used=1; return start_time; }
+ inline ulong query_start_sec_part()
+ { query_start_sec_part_used=1; return start_time_sec_part; }
+ inline void set_current_time()
{
- if (user_time)
+ my_hrtime_t hrtime= my_hrtime();
+ start_time= hrtime_to_my_time(hrtime);
+ start_time_sec_part= hrtime_sec_part(hrtime);
+ }
+ inline void set_start_time()
+ {
+ if (user_time.val)
{
- start_time= user_time;
- start_utime= utime_after_lock= my_micro_time();
+ start_time= hrtime_to_my_time(user_time);
+ start_time_sec_part= hrtime_sec_part(user_time);
}
else
- start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
+ set_current_time();
}
- inline void set_current_time() { start_time= my_time(MY_WME); }
- inline void set_time(time_t t)
+ inline void set_time()
{
- start_time= user_time= t;
- start_utime= utime_after_lock= my_micro_time();
+ set_start_time();
+ start_utime= utime_after_lock= microsecond_interval_timer();
}
- /*TODO: this will be obsolete when we have support for 64 bit my_time_t */
- inline bool is_valid_time()
- {
- return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time));
+ inline void set_time(my_hrtime_t t)
+ {
+ user_time= t;
+ set_time();
+ }
+ inline void set_time(my_time_t t, ulong sec_part)
+ {
+ my_hrtime_t hrtime= { hrtime_from_time(t) + sec_part };
+ set_time(hrtime);
}
- void set_time_after_lock() { utime_after_lock= my_micro_time(); }
- ulonglong current_utime() { return my_micro_time(); }
+ void set_time_after_lock() { utime_after_lock= microsecond_interval_timer(); }
+ ulonglong current_utime() { return microsecond_interval_timer(); }
+
/**
Update server status after execution of a top level statement.
-
Currently only checks if a query was slow, and assigns
the status accordingly.
Evaluate the current time, and if it exceeds the long-query-time
@@ -2562,8 +2619,30 @@ public:
nocheck_register_item_tree_change(place, *place, mem_root);
*place= new_value;
}
+ /**
+ Make change in item tree after checking whether it needs registering
+
+
+ @param place place where we should assign new value
+ @param new_value place of the new value
+
+ @details
+ see check_and_register_item_tree_change details
+ */
+ void check_and_register_item_tree(Item **place, Item **new_value)
+ {
+ if (!stmt_arena->is_conventional())
+ check_and_register_item_tree_change(place, new_value, mem_root);
+ /*
+ We have to use memcpy instead of *place= *new_value merge to
+ avoid problems with strict aliasing.
+ */
+ memcpy((char*) place, new_value, sizeof(*new_value));
+ }
void nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot);
+ void check_and_register_item_tree_change(Item **place, Item **new_value,
+ MEM_ROOT *runtime_memroot);
void rollback_item_tree_changes();
/*
@@ -2912,6 +2991,14 @@ public:
return backup;
}
+ void clear_wakeup_ready() { wakeup_ready= false; }
+ /*
+ Sleep waiting for others to wake us up with signal_wakeup_ready().
+ Must call clear_wakeup_ready() before waiting.
+ */
+ void wait_for_wakeup_ready();
+ /* Wake this thread up from wait_for_wakeup_ready(). */
+ void signal_wakeup_ready();
private:
/** The current internal error handler for this thread, or NULL. */
@@ -2941,7 +3028,7 @@ private:
statements or default definer is set in CREATE/ALTER SP, SF, Event,
TRIGGER or VIEW statements.
- Current user will be binlogged into Query_log_event if current_user_used
+ Current user will be binlogged into Query_log_event if m_binlog_invoker
is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
*/
bool m_binlog_invoker;
@@ -2954,6 +3041,16 @@ private:
*/
LEX_STRING invoker_user;
LEX_STRING invoker_host;
+ /*
+ Flag, mutex and condition for a thread to wait for a signal from another
+ thread.
+
+ Currently used to wait for group commit to complete, can also be used for
+ other purposes.
+ */
+ bool wakeup_ready;
+ mysql_mutex_t LOCK_wakeup_ready;
+ mysql_cond_t COND_wakeup_ready;
};
@@ -2985,6 +3082,27 @@ my_eof(THD *thd)
/*
+ These functions are for making it later easy to add strict
+ checking for all date handling.
+*/
+
+const my_bool strict_date_checking= 0;
+
+inline ulong sql_mode_for_dates(THD *thd)
+{
+ if (strict_date_checking)
+ return (thd->variables.sql_mode &
+ (MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
+ MODE_INVALID_DATES));
+ return (thd->variables.sql_mode & MODE_INVALID_DATES);
+}
+
+inline ulong sql_mode_for_dates()
+{
+ return sql_mode_for_dates(current_thd);
+}
+
+/*
Used to hold information about file and file structure in exchange
via non-DB file (...INTO OUTFILE..., ...LOAD DATA...)
XXX: We never call destructor for objects of this class.
@@ -3032,7 +3150,11 @@ public:
virtual uint field_count(List<Item> &fields) const
{ return fields.elements; }
virtual bool send_result_set_metadata(List<Item> &list, uint flags)=0;
- virtual bool send_data(List<Item> &items)=0;
+ /*
+ send_data returns 0 on ok, 1 on error and -1 if data was ignored, for
+ example for a duplicate row entry written to a temp table.
+ */
+ virtual int send_data(List<Item> &items)=0;
virtual bool initialize_tables (JOIN *join=0) { return 0; }
virtual void send_error(uint errcode,const char *err);
virtual bool send_eof()=0;
@@ -3068,7 +3190,12 @@ public:
class select_result_interceptor: public select_result
{
public:
- select_result_interceptor() {} /* Remove gcc warning */
+ select_result_interceptor()
+ {
+ DBUG_ENTER("select_result_interceptor::select_result_interceptor");
+ DBUG_PRINT("enter", ("this 0x%lx", (ulong) this));
+ DBUG_VOID_RETURN;
+ } /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
bool send_result_set_metadata(List<Item> &fields, uint flag) { return FALSE; }
};
@@ -3084,7 +3211,7 @@ class select_send :public select_result {
public:
select_send() :is_result_set_started(FALSE) {}
bool send_result_set_metadata(List<Item> &list, uint flags);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
virtual bool check_simple_select() const { return FALSE; }
void abort_result_set();
@@ -3147,7 +3274,7 @@ public:
select_export(sql_exchange *ex) :select_to_file(ex) {}
~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -3155,7 +3282,7 @@ class select_dump :public select_to_file {
public:
select_dump(sql_exchange *ex) :select_to_file(ex) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -3174,7 +3301,7 @@ class select_insert :public select_result_interceptor {
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
virtual int prepare2(void);
- bool send_data(List<Item> &items);
+ virtual int send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; }
void send_error(uint errcode,const char *err);
@@ -3293,6 +3420,8 @@ public:
uint convert_blob_length;
CHARSET_INFO *table_charset;
bool schema_table;
+ /* TRUE if the temp table is created for subquery materialization. */
+ bool materialized_subquery;
/*
True if GROUP BY and its aggregate functions are already computed
by a table access method (e.g. by loose index scan). In this case
@@ -3316,8 +3445,8 @@ public:
TMP_TABLE_PARAM()
:copy_field(0), group_parts(0),
group_length(0), group_null_parts(0), convert_blob_length(0),
- schema_table(0), precomputed_group_by(0), force_copy_fields(0),
- bit_fields_as_long(0), skip_create_table(0)
+ schema_table(0), materialized_subquery(0), precomputed_group_by(0),
+ force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0)
{}
~TMP_TABLE_PARAM()
{
@@ -3336,20 +3465,25 @@ public:
class select_union :public select_result_interceptor
{
-protected:
+public:
TMP_TABLE_PARAM tmp_table_param;
+ int write_err; /* Error code from the last send_data->ha_write_row call. */
public:
TABLE *table;
+ ha_rows records;
- select_union() :table(0) { tmp_table_param.init(); }
+ select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
bool flush();
void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
- const char *alias, bool bit_fields_as_long);
+ const char *alias,
+ bool bit_fields_as_long,
+ bool create_table);
+ TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
};
/* Base subselect interface class */
@@ -3359,7 +3493,7 @@ protected:
Item_subselect *item;
public:
select_subselect(Item_subselect *item);
- bool send_data(List<Item> &items)=0;
+ int send_data(List<Item> &items)=0;
bool send_eof() { return 0; };
};
@@ -3370,7 +3504,7 @@ public:
select_singlerow_subselect(Item_subselect *item_arg)
:select_subselect(item_arg)
{}
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -3401,7 +3535,7 @@ protected:
The number of columns in the biggest sub-row that consists of only
NULL values.
*/
- ha_rows max_nulls_in_row;
+ uint max_nulls_in_row;
/*
Count of rows writtent to the temp table. This is redundant as it is
already stored in handler::stats.records, however that one is relatively
@@ -3413,12 +3547,14 @@ protected:
void reset();
public:
- select_materialize_with_stats() {}
- virtual bool create_result_table(THD *thd, List<Item> *column_types,
- bool is_distinct, ulonglong options,
- const char *alias, bool bit_fields_as_long);
+ select_materialize_with_stats() { tmp_table_param.init(); }
+ bool create_result_table(THD *thd, List<Item> *column_types,
+ bool is_distinct, ulonglong options,
+ const char *alias,
+ bool bit_fields_as_long,
+ bool create_table);
bool init_result_table(ulonglong select_options);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
void cleanup();
ha_rows get_null_count_of_col(uint idx)
{
@@ -3435,7 +3571,7 @@ public:
DBUG_ASSERT(idx < table->s->fields);
return col_stat[idx].min_null_row;
}
- ha_rows get_max_nulls_in_row() { return max_nulls_in_row; }
+ uint get_max_nulls_in_row() { return max_nulls_in_row; }
};
@@ -3450,7 +3586,7 @@ public:
:select_subselect(item_arg), cache(0), fmax(mx)
{}
void cleanup();
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool cmp_real();
bool cmp_int();
bool cmp_decimal();
@@ -3463,7 +3599,7 @@ class select_exists_subselect :public select_subselect
public:
select_exists_subselect(Item_subselect *item_arg)
:select_subselect(item_arg){}
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -3610,6 +3746,7 @@ class user_var_entry
DTCollation collation;
};
+
/*
Unique -- class for unique (removing of duplicates).
Puts all values to the TREE. If the tree becomes too big,
@@ -3626,28 +3763,44 @@ class Unique :public Sql_alloc
IO_CACHE file;
TREE tree;
uchar *record_pointers;
+ ulong filtered_out_elems;
bool flush();
uint size;
+ uint full_size;
+ uint min_dupl_count; /* always 0 for unions, > 0 for intersections */
public:
ulong elements;
Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
- uint size_arg, ulonglong max_in_memory_size_arg);
+ uint size_arg, ulonglong max_in_memory_size_arg,
+ uint min_dupl_count_arg= 0);
~Unique();
ulong elements_in_tree() { return tree.elements_in_tree; }
inline bool unique_add(void *ptr)
{
DBUG_ENTER("unique_add");
DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements));
- if (tree.elements_in_tree > max_elements && flush())
+ if (!(tree.flag & TREE_ONLY_DUPS) &&
+ tree.elements_in_tree >= max_elements && flush())
DBUG_RETURN(1);
DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg));
}
+ bool is_in_memory() { return (my_b_tell(&file) == 0); }
+ void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; }
+
bool get(TABLE *table);
- static double get_use_cost(uint *buffer, uint nkeys, uint key_size,
- ulonglong max_in_memory_size);
- inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size,
+
+ /* Cost of searching for an element in the tree */
+ inline static double get_search_cost(ulonglong tree_elems, uint compare_factor)
+ {
+ return log((double) tree_elems) / (compare_factor * M_LN2);
+ }
+
+ static double get_use_cost(uint *buffer, size_t nkeys, uint key_size,
+ ulonglong max_in_memory_size, uint compare_factor,
+ bool intersect_fl, bool *in_memory);
+ inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size,
ulonglong max_in_memory_size)
{
register ulonglong max_elems_in_tree=
@@ -3663,6 +3816,11 @@ public:
friend int unique_write_to_file(uchar* key, element_count count, Unique *unique);
friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique);
+
+ friend int unique_write_to_file_with_count(uchar* key, element_count count,
+ Unique *unique);
+ friend int unique_intersect_write_to_ptrs(uchar* key, element_count count,
+ Unique *unique);
};
@@ -3689,7 +3847,7 @@ public:
multi_delete(TABLE_LIST *dt, uint num_of_tables);
~multi_delete();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
int do_deletes();
@@ -3706,7 +3864,7 @@ public:
class multi_update :public select_result_interceptor
{
TABLE_LIST *all_tables; /* query/update command tables */
- TABLE_LIST *leaves; /* list of leves of join table tree */
+ List<TABLE_LIST> *leaves; /* list of leves of join table tree */
TABLE_LIST *update_tables, *table_being_updated;
TABLE **tmp_tables, *main_table, *table_to_update;
TMP_TABLE_PARAM *tmp_table_param;
@@ -3732,12 +3890,12 @@ class multi_update :public select_result_interceptor
bool error_handled;
public:
- multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
+ multi_update(TABLE_LIST *ut, List<TABLE_LIST> *leaves_list,
List<Item> *fields, List<Item> *values,
enum_duplicates handle_duplicates, bool ignore);
~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
int do_updates();
@@ -3779,7 +3937,7 @@ public:
select_dumpvar() { var_list.empty(); row_count= 0;}
~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
virtual bool check_simple_select() const;
void cleanup();
@@ -3788,10 +3946,11 @@ public:
/* Bits in sql_command_flags */
#define CF_CHANGES_DATA (1U << 0)
-/* The 2nd bit is unused -- it used to be CF_HAS_ROW_COUNT. */
+#define CF_REPORT_PROGRESS (1U << 1)
#define CF_STATUS_COMMAND (1U << 2)
#define CF_SHOW_TABLE_COMMAND (1U << 3)
#define CF_WRITE_LOGS_COMMAND (1U << 4)
+
/**
Must be set for SQL statements that may contain
Item expressions and/or use joins and tables.
@@ -3932,17 +4091,25 @@ inline int handler::ha_index_read_map(uchar * buf, const uchar * key,
return error;
}
+
+/*
+ @note: Other index lookup/navigation functions require prior
+ handler->index_init() call. This function is different, it requires
+ that the scan is not initialized, and accepts "uint index" as an argument.
+*/
+
inline int handler::ha_index_read_idx_map(uchar * buf, uint index,
const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
+ DBUG_ASSERT(inited==NONE);
MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
increment_statistics(&SSV::ha_read_key_count);
int error= index_read_idx_map(buf, index, key, keypart_map, find_flag);
if (!error)
{
- rows_read++;
+ update_rows_read();
index_rows_read[index]++;
}
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -4020,7 +4187,8 @@ inline int handler::ha_ft_read(uchar *buf)
{
int error= ft_read(buf);
if (!error)
- rows_read++;
+ update_rows_read();
+
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -4031,7 +4199,7 @@ inline int handler::ha_rnd_next(uchar *buf)
increment_statistics(&SSV::ha_read_rnd_next_count);
int error= rnd_next(buf);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_READ_ROW_DONE(error);
return error;
@@ -4043,7 +4211,7 @@ inline int handler::ha_rnd_pos(uchar *buf, uchar *pos)
increment_statistics(&SSV::ha_read_rnd_count);
int error= rnd_pos(buf, pos);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
MYSQL_READ_ROW_DONE(error);
return error;
@@ -4053,7 +4221,7 @@ inline int handler::ha_rnd_pos_by_record(uchar *buf)
{
int error= rnd_pos_by_record(buf);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -4062,11 +4230,29 @@ inline int handler::ha_read_first_row(uchar *buf, uint primary_key)
{
int error= read_first_row(buf, primary_key);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
+inline int handler::ha_write_tmp_row(uchar *buf)
+{
+ MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
+ increment_statistics(&SSV::ha_tmp_write_count);
+ int error= write_row(buf);
+ MYSQL_INSERT_ROW_DONE(error);
+ return error;
+}
+
+inline int handler::ha_update_tmp_row(const uchar *old_data, uchar *new_data)
+{
+ MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
+ increment_statistics(&SSV::ha_tmp_update_count);
+ int error= update_row(old_data, new_data);
+ MYSQL_UPDATE_ROW_DONE(error);
+ return error;
+}
+
#endif /* MYSQL_SERVER */
#endif /* SQL_CLASS_INCLUDED */