134 lines
4.1 KiB
C++
134 lines
4.1 KiB
C++
|
|
#include "../global_defines.h"
|
|
#ifndef MYSQL8
|
|
#define MYSQL_SERVER
|
|
#endif
|
|
#include "sql/protocol.h"
|
|
#include "sql/sql_class.h"
|
|
|
|
#include "protocol.h"
|
|
#include "log.h"
|
|
|
|
namespace rpc_executor {
|
|
|
|
int Protocol::write_metadata(InternalDataSet &dataset) {
|
|
int ret = 0;
|
|
ExecTable *exec_table = dataset.table();
|
|
TABLE *table = exec_table->table();
|
|
if (xprotocol_.start_result_metadata(table->s->fields,
|
|
::Protocol::SEND_NUM_ROWS | ::Protocol::SEND_EOF,
|
|
&my_charset_utf8mb4_general_ci)) {
|
|
ret = 1;
|
|
log_exec_error("write metadata failed");
|
|
} else {
|
|
#ifdef MYSQL8
|
|
auto &table_name_lex = table->s->table_name;
|
|
auto &schema_name_lex = table->s->db;
|
|
#else
|
|
MYSQL_LEX_STRING &table_name_lex = table->s->table_name;
|
|
MYSQL_LEX_STRING &schema_name_lex = table->s->db;
|
|
#endif
|
|
std::string table_name(table_name_lex.str, table_name_lex.length);
|
|
std::string schema_name(schema_name_lex.str, schema_name_lex.length);
|
|
|
|
Send_field f;
|
|
if (dataset.is_aggr()) {
|
|
auto aggr_info = dataset.get_aggr_info();
|
|
const char *field_name = aggr_info.first.data();
|
|
auto aggr_expr = aggr_info.second;
|
|
auto *protocol_charset = aggr_expr->charset_for_protocol();
|
|
aggr_expr->make_field(&f);
|
|
f.col_name = f.org_col_name = field_name;
|
|
if (xprotocol_.send_field_metadata(&f, protocol_charset)) {
|
|
ret = 1;
|
|
log_exec_error("send_field_metadata from aggr_expr failed");
|
|
}
|
|
} else if (dataset.has_project()) {
|
|
for (auto &expr : dataset.get_project_exprs()) {
|
|
expr.second->make_field(&f);
|
|
f.col_name = f.org_col_name = expr.first.data();
|
|
auto *protocol_charset = expr.second->charset_for_protocol();
|
|
if (xprotocol_.send_field_metadata(&f, protocol_charset)) {
|
|
ret = 1;
|
|
log_exec_error("send_field_metadata from expr failed 2");
|
|
}
|
|
}
|
|
} else {
|
|
Field **project_fields = nullptr;
|
|
uint32_t field_count = 0;
|
|
dataset.get_all_fields(project_fields, field_count);
|
|
for (uint32_t i = 0; i < field_count; ++i) {
|
|
Field *this_field = project_fields[i];
|
|
|
|
this_field->make_field(&f);
|
|
f.db_name = schema_name.data();
|
|
f.table_name = table_name.data();
|
|
f.org_table_name = f.db_name;
|
|
|
|
if (xprotocol_.send_field_metadata(&f, this_field->charset())) {
|
|
ret = 1;
|
|
log_exec_error("send_field_metadata from field failed");
|
|
}
|
|
}
|
|
}
|
|
if (xprotocol_.end_result_metadata()) {
|
|
log_exec_error("end_result_metadata failed");
|
|
ret = 1;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int Protocol::write_row(InternalDataSet &dataset) {
|
|
int ret = 0;
|
|
xprotocol_.start_row();
|
|
|
|
THD *thd = current_thd;
|
|
|
|
if (dataset.is_aggr()) {
|
|
String buffer;
|
|
auto aggr_expr = dataset.get_aggr_info().second;
|
|
aggr_expr->send(&xprotocol_, &buffer);
|
|
if (thd->get_stmt_da()->is_error()) {
|
|
ret = (int)thd->get_stmt_da()->mysql_errno();
|
|
log_exec_error("Agg Item send failed, reason: %s",
|
|
thd->get_stmt_da()->message_text());
|
|
}
|
|
} else if (dataset.has_project()) {
|
|
String buffer;
|
|
for (auto &expr : dataset.get_project_exprs()) {
|
|
expr.second->send(&xprotocol_, &buffer);
|
|
if (thd->get_stmt_da()->is_error()) {
|
|
ret = (int)thd->get_stmt_da()->mysql_errno();
|
|
log_exec_error("Item send failed, reason: %s",
|
|
thd->get_stmt_da()->message_text());
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
Field **project_fields = nullptr;
|
|
uint32_t field_count = 0;
|
|
dataset.get_all_fields(project_fields, field_count);
|
|
for (uint32_t i = 0; i < field_count; ++i) {
|
|
Field *this_field = project_fields[i];
|
|
// xprotocol_.store(this_field->ptr, this_field->pack_length(), this_field->charset());
|
|
#ifdef MYSQL8
|
|
xprotocol_.store_field(this_field);
|
|
#else
|
|
xprotocol_.store(this_field);
|
|
#endif
|
|
}
|
|
}
|
|
// TODO: check again if we need to end_row when failed
|
|
xprotocol_.end_row();
|
|
return ret;
|
|
}
|
|
|
|
int Protocol::send_and_flush() {
|
|
int ret = 0;
|
|
xprotocol_.send_eof(2, 0);
|
|
return ret;
|
|
}
|
|
|
|
}
|