Commit 17ee32fb authored by Roman Nozdrin's avatar Roman Nozdrin Committed by Sergei Petrunia

CLX-19 DH now executes a query only if SH fails.

parent 5f33f012
...@@ -14,8 +14,6 @@ DROP TABLE cx1; ...@@ -14,8 +14,6 @@ DROP TABLE cx1;
SHOW CREATE TABLE cx1; SHOW CREATE TABLE cx1;
ERROR 42S02: Table 'clx.cx1' doesn't exist ERROR 42S02: Table 'clx.cx1' doesn't exist
DROP TABLE IF EXISTS intandtext; DROP TABLE IF EXISTS intandtext;
Warnings:
Note 1051 Unknown table 'clx.intandtext'
CREATE TABLE intandtext(i bigint, t text)ENGINE=clustrixdb; CREATE TABLE intandtext(i bigint, t text)ENGINE=clustrixdb;
INSERT INTO intandtext VALUES(10, 'someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq'); INSERT INTO intandtext VALUES(10, 'someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq');
SELECT i,t FROM intandtext; SELECT i,t FROM intandtext;
...@@ -24,6 +22,7 @@ i t ...@@ -24,6 +22,7 @@ i t
EXPLAIN SELECT i,t FROM intandtext; EXPLAIN SELECT i,t FROM intandtext;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL 1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL
SET @@optimizer_switch='derived_merge=OFF';
SET clustrixdb_select_handler=OFF; SET clustrixdb_select_handler=OFF;
SELECT i,t FROM (SELECT i,t FROM intandtext) t; SELECT i,t FROM (SELECT i,t FROM intandtext) t;
i t i t
...@@ -32,17 +31,17 @@ EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t; ...@@ -32,17 +31,17 @@ EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000
2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
SET clustrixdb_select_handler=OFF; SET clustrixdb_derived_handler=OFF;
SELECT i,t FROM intandtext; SELECT i,t FROM intandtext;
i t i t
10 someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 10 someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
SELECT i,t FROM (SELECT i,t FROM intandtext) t; SELECT i,t FROM (SELECT i,t FROM intandtext) t;
i t i t
10 someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq 10 someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t; EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000
2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL 2 DERIVED intandtext ALL NULL NULL NULL NULL 10000
DROP TABLE intandtext; DROP TABLE intandtext;
USE test; USE test;
DROP DATABASE clx; DROP DATABASE clx;
...@@ -20,14 +20,14 @@ CREATE TABLE intandtext(i bigint, t text)ENGINE=clustrixdb; ...@@ -20,14 +20,14 @@ CREATE TABLE intandtext(i bigint, t text)ENGINE=clustrixdb;
INSERT INTO intandtext VALUES(10, 'someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq'); INSERT INTO intandtext VALUES(10, 'someqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq');
SELECT i,t FROM intandtext; SELECT i,t FROM intandtext;
EXPLAIN SELECT i,t FROM intandtext; EXPLAIN SELECT i,t FROM intandtext;
SET clustrixdb_select_handler=OFF;
SET @@optimizer_switch='derived_merge=OFF';
SET clustrixdb_select_handler=OFF;
SELECT i,t FROM (SELECT i,t FROM intandtext) t; SELECT i,t FROM (SELECT i,t FROM intandtext) t;
EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t; EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t;
SET clustrixdb_select_handler=OFF;
SET clustrixdb_derived_handler=OFF;
SELECT i,t FROM intandtext; SELECT i,t FROM intandtext;
SELECT i,t FROM (SELECT i,t FROM intandtext) t; SELECT i,t FROM (SELECT i,t FROM intandtext) t;
EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t; EXPLAIN SELECT i,t FROM (SELECT i,t FROM intandtext) t;
......
...@@ -13,24 +13,29 @@ extern handlerton *clustrixdb_hton; ...@@ -13,24 +13,29 @@ extern handlerton *clustrixdb_hton;
* Fills up three arrays with: field binlog data types, field * Fills up three arrays with: field binlog data types, field
* metadata and nullability bitmask as in Table_map_log_event * metadata and nullability bitmask as in Table_map_log_event
* ctor. Internally creates a temporary table as does * ctor. Internally creates a temporary table as does
* Pushdown_select. * Pushdown_select. DH uses the actual temp table w/o
* b/c create_DH is called later compared to create_SH.
* More details in server/sql/log_event_server.cc * More details in server/sql/log_event_server.cc
* PARAMETERS: * PARAMETERS:
* thd - THD* * thd - THD*
* table__ - TABLE* temp table for the results
* sl - SELECT_LEX* * sl - SELECT_LEX*
* fieldtype - uchar* * fieldtype - uchar*
* field_metadata - uchar* * field_metadata - uchar*
* null_bits - uchar* * null_bits - uchar*
* num_null_bytes - null bit size * num_null_bytes - null bit size
* fields_count - a number of fields
* RETURN: * RETURN:
* metadata_size int or -1 in case of error * metadata_size int or -1 in case of error
************************************************************/ ************************************************************/
int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype, int get_field_types(THD *thd, TABLE *table__, SELECT_LEX *sl, uchar *fieldtype,
uchar *field_metadata, uchar *null_bits, const int num_null_bytes) uchar *field_metadata, uchar *null_bits, const int num_null_bytes, const uint fields_count)
{ {
int field_metadata_size = 0; int field_metadata_size = 0;
int metadata_index = 0; int metadata_index = 0;
TABLE *tmp_table= table__;
if (!tmp_table) {
// Construct a tmp table with fields to find out result DTs. // Construct a tmp table with fields to find out result DTs.
// This should be reconsidered if it worths the effort. // This should be reconsidered if it worths the effort.
List<Item> types; List<Item> types;
...@@ -39,7 +44,7 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype, ...@@ -39,7 +44,7 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype,
tmp_table_param.init(); tmp_table_param.init();
tmp_table_param.field_count= types.elements; tmp_table_param.field_count= types.elements;
TABLE *tmp_table = create_tmp_table(thd, &tmp_table_param, types, tmp_table = create_tmp_table(thd, &tmp_table_param, types,
(ORDER *) 0, false, 0, (ORDER *) 0, false, 0,
TMP_TABLE_ALL_COLUMNS, 1, TMP_TABLE_ALL_COLUMNS, 1,
&empty_clex_str, true, false); &empty_clex_str, true, false);
...@@ -47,21 +52,19 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype, ...@@ -47,21 +52,19 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype,
field_metadata_size = -1; field_metadata_size = -1;
goto err; goto err;
} }
}
for (unsigned int i = 0 ; i < tmp_table_param.field_count; ++i) { for (unsigned int i = 0 ; i < fields_count; ++i) {
fieldtype[i]= tmp_table->field[i]->binlog_type(); fieldtype[i]= tmp_table->field[i]->binlog_type();
} }
bzero(field_metadata, (tmp_table_param.field_count * 2)); bzero(field_metadata, (fields_count * 2));
for (unsigned int i= 0 ; i < tmp_table_param.field_count ; i++) for (unsigned int i= 0 ; i < fields_count ; i++)
{ {
Binlog_type_info bti= tmp_table->field[i]->binlog_type_info(); Binlog_type_info bti= tmp_table->field[i]->binlog_type_info();
uchar *ptr = reinterpret_cast<uchar*>(&bti.m_metadata); uchar *ptr = reinterpret_cast<uchar*>(&bti.m_metadata);
// Binlog_type_info::m_metadata is u16 memcpy(&field_metadata[metadata_index], ptr, bti.m_metadata_size);
if (bti.m_metadata_size == 1) metadata_index+= bti.m_metadata_size;
field_metadata[metadata_index++]= *ptr++;
if (bti.m_metadata_size == 2)
field_metadata[metadata_index++]= *ptr++;
} }
if (metadata_index < 251) if (metadata_index < 251)
...@@ -70,12 +73,13 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype, ...@@ -70,12 +73,13 @@ int get_field_types(THD *thd, SELECT_LEX *sl, uchar *fieldtype,
field_metadata_size += metadata_index + 3; field_metadata_size += metadata_index + 3;
bzero(null_bits, num_null_bytes); bzero(null_bits, num_null_bytes);
for (unsigned int i= 0 ; i < tmp_table_param.field_count ; ++i) { for (unsigned int i= 0 ; i < fields_count ; ++i) {
if (tmp_table->field[i]->maybe_null()) { if (tmp_table->field[i]->maybe_null()) {
null_bits[(i / 8)]+= 1 << (i % 8); null_bits[(i / 8)]+= 1 << (i % 8);
} }
} }
if (!table__)
free_tmp_table(thd, tmp_table); free_tmp_table(thd, tmp_table);
err: err:
return field_metadata_size; return field_metadata_size;
...@@ -126,7 +130,7 @@ create_clustrixdb_select_handler(THD* thd, SELECT_LEX* select_lex) ...@@ -126,7 +130,7 @@ create_clustrixdb_select_handler(THD* thd, SELECT_LEX* select_lex)
} }
if((field_metadata_size = if((field_metadata_size =
get_field_types(thd, select_lex, fieldtype, field_metadata, null_bits, num_null_bytes)) < 0) { get_field_types(thd, NULL, select_lex, fieldtype, field_metadata, null_bits, num_null_bytes, items_number)) < 0) {
goto err; goto err;
} }
...@@ -284,52 +288,12 @@ create_clustrixdb_derived_handler(THD* thd, TABLE_LIST *derived) ...@@ -284,52 +288,12 @@ create_clustrixdb_derived_handler(THD* thd, TABLE_LIST *derived)
} }
SELECT_LEX_UNIT *unit= derived->derived; SELECT_LEX_UNIT *unit= derived->derived;
// *DRRTUY Check for potential UNIONS in derived
SELECT_LEX *select_lex = unit->first_select(); SELECT_LEX *select_lex = unit->first_select();
String query; String query;
// Print the query into a string provided
select_lex->print(thd, &query, QT_ORDINARY);
int error_code = 0;
int field_metadata_size = 0;
ulonglong scan_refid = 0; ulonglong scan_refid = 0;
clustrix_connection *trx = NULL;
// We presume this number is equal to types.elements in get_field_types
uint items_number = select_lex->get_item_list()->elements;
uint num_null_bytes = (items_number + 7) / 8;
uchar *fieldtype = NULL;
uchar *null_bits = NULL;
uchar *field_metadata = NULL;
uchar *meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME), &fieldtype, items_number,
&null_bits, num_null_bytes, &field_metadata, (items_number * 2), NULL);
if (!meta_memory) {
// The only way to say something here is to raise warning
// b/c we will fallback to other access methods: derived handler or rowstore.
goto err;
}
if((field_metadata_size =
get_field_types(thd, select_lex, fieldtype, field_metadata, null_bits, num_null_bytes)) < 0) {
goto err;
}
trx = get_trx(thd, &error_code);
if (!trx)
goto err;
if ((error_code = trx->scan_query(query, fieldtype, items_number,
null_bits, num_null_bytes, field_metadata, field_metadata_size, &scan_refid))) {
goto err;
}
dh = new ha_clustrixdb_derived_handler(thd, select_lex, scan_refid); dh = new ha_clustrixdb_derived_handler(thd, select_lex, scan_refid);
err:
// deallocate buffers
if (meta_memory)
my_free(meta_memory);
return dh; return dh;
} }
...@@ -362,6 +326,9 @@ ha_clustrixdb_derived_handler::ha_clustrixdb_derived_handler( ...@@ -362,6 +326,9 @@ ha_clustrixdb_derived_handler::ha_clustrixdb_derived_handler(
ha_clustrixdb_derived_handler::~ha_clustrixdb_derived_handler() ha_clustrixdb_derived_handler::~ha_clustrixdb_derived_handler()
{ {
int error_code; int error_code;
clustrix_connection *trx = get_trx(thd, &error_code); clustrix_connection *trx = get_trx(thd, &error_code);
if (!trx) { if (!trx) {
// TBD Log this. // TBD Log this.
...@@ -389,6 +356,42 @@ int ha_clustrixdb_derived_handler::init_scan() ...@@ -389,6 +356,42 @@ int ha_clustrixdb_derived_handler::init_scan()
{ {
// Save this into the base handler class attribute // Save this into the base handler class attribute
table__ = table; table__ = table;
String query;
// Print the query into a string provided
select->print(thd__, &query, QT_ORDINARY);
int error_code = 0;
int field_metadata_size = 0;
clustrix_connection *trx = NULL;
// We presume this number is equal to types.elements in get_field_types
uint items_number= select->get_item_list()->elements;
uint num_null_bytes = (items_number + 7) / 8;
uchar *fieldtype = NULL;
uchar *null_bits = NULL;
uchar *field_metadata = NULL;
uchar *meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME), &fieldtype, items_number,
&null_bits, num_null_bytes, &field_metadata, (items_number * 2), NULL);
if (!meta_memory) {
// The only way to say something here is to raise warning
// b/c we will fallback to other access methods: derived handler or rowstore.
goto err;
}
if((field_metadata_size=
get_field_types(thd__, table__, select, fieldtype, field_metadata, null_bits, num_null_bytes, items_number)) < 0) {
goto err;
}
trx = get_trx(thd__, &error_code);
if (!trx)
goto err;
if ((error_code = trx->scan_query(query, fieldtype, items_number,
null_bits, num_null_bytes, field_metadata, field_metadata_size, &scan_refid))) {
goto err;
}
// need this bitmap future in next_row() // need this bitmap future in next_row()
if (my_bitmap_init(&scan_fields, NULL, table->read_set->n_bits, false)) if (my_bitmap_init(&scan_fields, NULL, table->read_set->n_bits, false))
return ER_OUTOFMEMORY; return ER_OUTOFMEMORY;
...@@ -396,7 +399,12 @@ int ha_clustrixdb_derived_handler::init_scan() ...@@ -396,7 +399,12 @@ int ha_clustrixdb_derived_handler::init_scan()
add_current_table_to_rpl_table_list(); add_current_table_to_rpl_table_list();
return 0; err:
// deallocate buffers
if (meta_memory)
my_free(meta_memory);
return error_code;
} }
/*@brief Fetch next row for derived_handler */ /*@brief Fetch next row for derived_handler */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment