mirror of
https://github.com/MariaDB/server.git
synced 2025-10-11 02:09:15 +02:00

Works for the following simple case --disable_query_log --disable_result_log --source ../../t/test_init.inc --enable_result_log --enable_query_log set spider_same_server_link= 1; set spider_disable_select_handler= 0; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c int); create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; insert into t1 values (1), (2), (3); select c from t1; drop table t1, t2; drop server srv; --disable_query_log --disable_result_log --source ../../t/test_deinit.inc --enable_result_log --enable_query_log
140 lines
4.4 KiB
C++
140 lines
4.4 KiB
C++
#define MYSQL_SERVER 1
|
|
#include <my_global.h>
|
|
#include "sql_select.h"
|
|
#include "spd_param.h"
|
|
#include "spd_db_include.h"
|
|
/* TODO: remove this include */
|
|
#include "spd_group_by_handler.h"
|
|
#include "spd_select_handler.h"
|
|
/* needed by ha_spider.h for SPIDER_PARTITION_HANDLER */
|
|
#include "spd_include.h"
|
|
#include "ha_spider.h"
|
|
/* needed for spider_current_trx */
|
|
#include "spd_malloc.h"
|
|
/* for spider_check_trx_and_get_conn */
|
|
#include "spd_trx.h"
|
|
/* for spider_lock_before_query */
|
|
#include "spd_conn.h"
|
|
/* for spider_db_fetch */
|
|
#include "spd_db_conn.h"
|
|
/* for spd_table.h */
|
|
#include "partition_element.h"
|
|
/* for spider_set_result_list_param */
|
|
#include "spd_table.h"
|
|
|
|
extern handlerton *spider_hton_ptr;
|
|
|
|
spider_select_handler::spider_select_handler(THD *thd, SELECT_LEX *select_lex,
|
|
spider_fields *fields)
|
|
: select_handler(thd, spider_hton_ptr, select_lex), fields(fields)
|
|
{}
|
|
|
|
spider_select_handler::~spider_select_handler()
|
|
{
|
|
spider_free(spider_current_trx, fields->get_first_table_holder(), MYF(0));
|
|
delete fields;
|
|
}
|
|
|
|
select_handler *spider_create_select_handler(THD *thd, SELECT_LEX *select_lex,
|
|
SELECT_LEX_UNIT *)
|
|
{
|
|
SPIDER_TABLE_HOLDER *table_holder;
|
|
uint n_tables= 0;
|
|
spider_fields *fields;
|
|
ha_spider *spider;
|
|
if (spider_param_disable_select_handler(thd))
|
|
return NULL;
|
|
for (TABLE_LIST *tl= select_lex->get_table_list(); tl;
|
|
n_tables++, tl= tl->next_local)
|
|
{
|
|
spider = (ha_spider *) tl->table->file;
|
|
spider->idx_for_direct_join = n_tables;
|
|
}
|
|
if (!(table_holder= spider_create_table_holder(n_tables)))
|
|
DBUG_RETURN(NULL);
|
|
for (TABLE_LIST *tl= select_lex->get_table_list(); tl; tl= tl->next_local)
|
|
{
|
|
spider = (ha_spider *) tl->table->file;
|
|
spider_add_table_holder(spider, table_holder);
|
|
}
|
|
spider_check_trx_and_get_conn(thd, spider);
|
|
fields= new spider_fields();
|
|
fields->set_table_holder(table_holder, n_tables);
|
|
/* only add MYSQL for now */
|
|
fields->add_dbton_id(0);
|
|
return new spider_select_handler(thd, select_lex, fields);
|
|
}
|
|
|
|
int spider_select_handler::init_scan()
|
|
{
|
|
/*
|
|
longlong unused;
|
|
*/
|
|
Query query= {select_lex->get_item_list(), 0, select_lex->distinct,
|
|
select_lex->get_table_list(), select_lex->where,
|
|
/* TODO: do we need to reference join here? Can we get GROUP BY /
|
|
ORDER BY from select_lex directly */
|
|
select_lex->join->group_list,
|
|
select_lex->join->order,
|
|
select_lex->having,
|
|
&select_lex->master_unit()->lim};
|
|
ha_spider *spider= fields->get_first_table_holder()->spider;
|
|
int link_idx= 0;
|
|
SPIDER_CONN *conn= spider->conns[link_idx];
|
|
spider_db_handler *dbton_hdl= spider->dbton_handler[conn->dbton_id];
|
|
/*
|
|
spider_prepare_init_scan(query, NULL, fields, spider,
|
|
spider->wide_handler->trx, unused, thd);
|
|
*/
|
|
SPIDER_RESULT_LIST *result_list = &spider->result_list;
|
|
spider_set_result_list_param(spider);
|
|
/* TODO: we need to extract result_list init to a separate
|
|
function, see also spider_prepare_init_scan. */
|
|
result_list->keyread = FALSE;
|
|
/* Use original limit and offset for now */
|
|
if (select_lex->limit_params.explicit_limit)
|
|
{
|
|
result_list->limit_num= select_lex->get_limit();
|
|
result_list->internal_offset= select_lex->get_offset();
|
|
}
|
|
else
|
|
{
|
|
result_list->limit_num= 9223372036854775807LL;
|
|
result_list->internal_offset= 0;
|
|
}
|
|
/* print query */
|
|
spider_make_query(query, fields, spider, table);
|
|
|
|
/* send query */
|
|
dbton_hdl->set_sql_for_exec(
|
|
SPIDER_SQL_TYPE_SELECT_SQL, link_idx, NULL);
|
|
spider_lock_before_query(conn, &spider->need_mons[link_idx]);
|
|
dbton_hdl->execute_sql(
|
|
SPIDER_SQL_TYPE_SELECT_SQL,
|
|
conn,
|
|
spider->result_list.quick_mode,
|
|
&spider->need_mons[link_idx]);
|
|
/*
|
|
So that in spider_db_store_results the check
|
|
if (conn->connection_id != spider->connection_ids[link_idx])
|
|
will go through
|
|
*/
|
|
spider->connection_ids[link_idx] = conn->connection_id;
|
|
spider_unlock_after_query_2(conn, spider, link_idx, table);
|
|
return 0;
|
|
}
|
|
|
|
int spider_select_handler::next_row()
|
|
{
|
|
ha_spider *spider= fields->get_first_table_holder()->spider;
|
|
SPIDER_RESULT_LIST *result_list= &spider->result_list;
|
|
if (result_list->current_row_num >= result_list->current->record_num)
|
|
return HA_ERR_END_OF_FILE;
|
|
else
|
|
return spider_db_fetch(table->record[0], spider, table);
|
|
}
|
|
|
|
int spider_select_handler::end_scan()
|
|
{
|
|
return 0;
|
|
}
|