Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] support prepare statement #27840

Merged
merged 8 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix mysql result for jdbc request
Signed-off-by: jukejian <jukejian@bytedance.com>
  • Loading branch information
Jay-ju committed Sep 13, 2023
commit 4faaa7cc6e342fddbd9308c493337a25f9800abe
4 changes: 3 additions & 1 deletion be/src/util/mysql_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ typedef unsigned char uchar;
*(T + 1) = (uchar)(((uint32_t)(A) >> 8)); \
*(T + 2) = (uchar)(((A) >> 16)); \
} while (0)
#define int4store(T, A) *((uint32_t*)(T)) = (uint32_t)(A)
#define int8store(T, A) *((int64_t*)(T)) = (uint64_t)(A)

#define float4store(T, A) *((float*)(T)) = (float)(A)
#define float8store(T, A) *((double*)(T)) = (double)(A)
#define MAX_TINYINT_WIDTH 3 /* Max width for a TINY w.o. sign */
#define MAX_SMALLINT_WIDTH 5 /* Max width for a SHORT w.o. sign */
#define MAX_INT_WIDTH 10 /* Max width for a LONG w.o. sign */
Expand Down
67 changes: 67 additions & 0 deletions be/src/util/mysql_row_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "common/logging.h"
#include "gutil/strings/fastmem.h"
#include "util/mysql_global.h"
#include "runtime/large_int_value.h"

namespace starrocks {

Expand Down Expand Up @@ -78,6 +79,16 @@ static uint8_t* pack_vlen(uint8_t* packet, uint64_t length) {
}

void MysqlRowBuffer::push_null() {
if (_is_binary_format) {
uint offset = (_field_pos + 2) / 8 + 1;
uint bit = (1 << ((_field_pos + 2) & 7));
/* Room for this as it's allocated start_binary_row*/
char* to = _data.data() + offset;
*to = (char)((uchar)*to | (uchar)bit);
_field_pos++;
return;
}

if (_array_level == 0) {
_data.push_back(0xfb);
} else {
Expand All @@ -86,9 +97,49 @@ void MysqlRowBuffer::push_null() {
}
}

template<typename T>
void MysqlRowBuffer::push_number_binary_format(T data) {
_field_pos++;
if constexpr (std::is_same_v<T, float>) {
char buff[4];
float4store(buff, data);
_data.append(buff, 4);
} else if constexpr (std::is_same_v<T, double>) {
char buff[8];
float8store(buff, data);
_data.append(buff, 8);
} else if constexpr (std::is_same_v<std::make_signed_t<T>, int8_t>) {
char buff[1];
int1store(buff, data);
_data.append(buff, 1);
} else if constexpr (std::is_same_v<std::make_signed_t<T>, int16_t>) {
char buff[2];
int2store(buff, data);
_data.append(buff, 2);
} else if constexpr (std::is_same_v<std::make_signed_t<T>, int32_t>) {
char buff[4];
int4store(buff, data);
_data.append(buff, 4);
} else if constexpr (std::is_same_v<std::make_signed_t<T>, int64_t>) {
char buff[8];
int8store(buff, data);
_data.append(buff, 8);
} else if constexpr (std::is_same_v<std::make_signed_t<T>, __int128>) {
std::string value = LargeIntValue::to_string(data);
_push_string_normal(value.data(), value.size());
} else {
CHECK(false) << "unhandled data type";
}
}

template <typename T>
void MysqlRowBuffer::push_number(T data) {
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, __int128>);

if (_is_binary_format) {
return push_number_binary_format(data);
}

int length = 0;
char* end = nullptr;
char* pos = nullptr;
Expand Down Expand Up @@ -133,6 +184,10 @@ void MysqlRowBuffer::push_number(T data) {
}

void MysqlRowBuffer::push_string(const char* str, size_t length, char escape_char) {
if (_is_binary_format) {
++_field_pos;
}

if (_array_level == 0) {
_push_string_normal(str, length);
} else {
Expand All @@ -155,6 +210,10 @@ void MysqlRowBuffer::push_string(const char* str, size_t length, char escape_cha
}

void MysqlRowBuffer::push_decimal(const Slice& s) {
if (_is_binary_format) {
++_field_pos;
}

if (_array_level == 0) {
_push_string_normal(s.data, s.size);
} else {
Expand Down Expand Up @@ -252,6 +311,14 @@ template void MysqlRowBuffer::push_number<__int128>(__int128);
template void MysqlRowBuffer::push_number<float>(float);
template void MysqlRowBuffer::push_number<double>(double);

void MysqlRowBuffer::start_binary_row(uint32_t num_cols) {
DCHECK(_is_binary_format) << "start_binary_row() only for is_binary_format=true";
int bit_fields = (num_cols + 9) / 8;
char* pos = _resize_extra(bit_fields + 1);
memset(pos, 0, 1 + bit_fields);
_field_pos = 0;
}

} // namespace starrocks

/* vim: set ts=4 sw=4 sts=4 tw=100 */
11 changes: 11 additions & 0 deletions be/src/util/mysql_row_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ namespace starrocks {
class MysqlRowBuffer final {
public:
MysqlRowBuffer() = default;
MysqlRowBuffer(bool is_binary_format) : _is_binary_format(is_binary_format) { };
~MysqlRowBuffer() = default;

void reset() { _data.clear(); }

void start_binary_row(uint32_t num_cols);

void push_null();
void push_tinyint(int8_t data) { push_number(data); }
void push_smallint(int16_t data) { push_number(data); }
Expand All @@ -63,6 +66,10 @@ class MysqlRowBuffer final {
template <typename T>
void push_number(T data);
void push_number(uint24_t data) { push_number((uint32_t)data); }

template <typename T>
void push_number_binary_format(T data);

void push_decimal(const Slice& s);

void begin_push_array() { _enter_scope('['); }
Expand Down Expand Up @@ -101,6 +108,10 @@ class MysqlRowBuffer final {
raw::RawString _data;
uint32_t _array_level = 0;
uint32_t _array_offset = 0;

bool _is_binary_format = false;
// used for calculate null position if is_binary_format = true
uint32_t _field_pos = 0;
};

} // namespace starrocks