polardbxengine/plugin/polarx_rpc/executor/protocol.cc

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;
}
}