1#include "MySQLProtocol.h"
2#include <IO/WriteBuffer.h>
3#include <IO/ReadBufferFromString.h>
4#include <IO/WriteBufferFromString.h>
5#include <common/logger_useful.h>
6
7#include <random>
8#include <sstream>
9
10
11namespace DB::MySQLProtocol
12{
13
14void PacketSender::resetSequenceId()
15{
16 sequence_id = 0;
17}
18
19String PacketSender::packetToText(const String & payload)
20{
21 String result;
22 for (auto c : payload)
23 {
24 result += ' ';
25 result += std::to_string(static_cast<unsigned char>(c));
26 }
27 return result;
28}
29
30uint64_t readLengthEncodedNumber(ReadBuffer & ss)
31{
32 char c{};
33 uint64_t buf = 0;
34 ss.readStrict(c);
35 auto cc = static_cast<uint8_t>(c);
36 if (cc < 0xfc)
37 {
38 return cc;
39 }
40 else if (cc < 0xfd)
41 {
42 ss.readStrict(reinterpret_cast<char *>(&buf), 2);
43 }
44 else if (cc < 0xfe)
45 {
46 ss.readStrict(reinterpret_cast<char *>(&buf), 3);
47 }
48 else
49 {
50 ss.readStrict(reinterpret_cast<char *>(&buf), 8);
51 }
52 return buf;
53}
54
55void writeLengthEncodedNumber(uint64_t x, WriteBuffer & buffer)
56{
57 if (x < 251)
58 {
59 buffer.write(static_cast<char>(x));
60 }
61 else if (x < (1 << 16))
62 {
63 buffer.write(0xfc);
64 buffer.write(reinterpret_cast<char *>(&x), 2);
65 }
66 else if (x < (1 << 24))
67 {
68 buffer.write(0xfd);
69 buffer.write(reinterpret_cast<char *>(&x), 3);
70 }
71 else
72 {
73 buffer.write(0xfe);
74 buffer.write(reinterpret_cast<char *>(&x), 8);
75 }
76}
77
78size_t getLengthEncodedNumberSize(uint64_t x)
79{
80 if (x < 251)
81 {
82 return 1;
83 }
84 else if (x < (1 << 16))
85 {
86 return 3;
87 }
88 else if (x < (1 << 24))
89 {
90 return 4;
91 }
92 else
93 {
94 return 9;
95 }
96}
97
98size_t getLengthEncodedStringSize(const String & s)
99{
100 return getLengthEncodedNumberSize(s.size()) + s.size();
101}
102
103ColumnDefinition getColumnDefinition(const String & column_name, const TypeIndex type_index)
104{
105 ColumnType column_type;
106 int flags = 0;
107 switch (type_index)
108 {
109 case TypeIndex::UInt8:
110 column_type = ColumnType::MYSQL_TYPE_TINY;
111 flags = ColumnDefinitionFlags::BINARY_FLAG | ColumnDefinitionFlags::UNSIGNED_FLAG;
112 break;
113 case TypeIndex::UInt16:
114 column_type = ColumnType::MYSQL_TYPE_SHORT;
115 flags = ColumnDefinitionFlags::BINARY_FLAG | ColumnDefinitionFlags::UNSIGNED_FLAG;
116 break;
117 case TypeIndex::UInt32:
118 column_type = ColumnType::MYSQL_TYPE_LONG;
119 flags = ColumnDefinitionFlags::BINARY_FLAG | ColumnDefinitionFlags::UNSIGNED_FLAG;
120 break;
121 case TypeIndex::UInt64:
122 column_type = ColumnType::MYSQL_TYPE_LONGLONG;
123 flags = ColumnDefinitionFlags::BINARY_FLAG | ColumnDefinitionFlags::UNSIGNED_FLAG;
124 break;
125 case TypeIndex::Int8:
126 column_type = ColumnType::MYSQL_TYPE_TINY;
127 flags = ColumnDefinitionFlags::BINARY_FLAG;
128 break;
129 case TypeIndex::Int16:
130 column_type = ColumnType::MYSQL_TYPE_SHORT;
131 flags = ColumnDefinitionFlags::BINARY_FLAG;
132 break;
133 case TypeIndex::Int32:
134 column_type = ColumnType::MYSQL_TYPE_LONG;
135 flags = ColumnDefinitionFlags::BINARY_FLAG;
136 break;
137 case TypeIndex::Int64:
138 column_type = ColumnType::MYSQL_TYPE_LONGLONG;
139 flags = ColumnDefinitionFlags::BINARY_FLAG;
140 break;
141 case TypeIndex::Float32:
142 column_type = ColumnType::MYSQL_TYPE_FLOAT;
143 flags = ColumnDefinitionFlags::BINARY_FLAG;
144 break;
145 case TypeIndex::Float64:
146 column_type = ColumnType::MYSQL_TYPE_DOUBLE;
147 flags = ColumnDefinitionFlags::BINARY_FLAG;
148 break;
149 case TypeIndex::Date:
150 column_type = ColumnType::MYSQL_TYPE_DATE;
151 flags = ColumnDefinitionFlags::BINARY_FLAG;
152 break;
153 case TypeIndex::DateTime:
154 column_type = ColumnType::MYSQL_TYPE_DATETIME;
155 flags = ColumnDefinitionFlags::BINARY_FLAG;
156 break;
157 case TypeIndex::String:
158 case TypeIndex::FixedString:
159 column_type = ColumnType::MYSQL_TYPE_STRING;
160 break;
161 default:
162 column_type = ColumnType::MYSQL_TYPE_STRING;
163 break;
164 }
165 return ColumnDefinition(column_name, CharacterSet::binary, 0, column_type, flags, 0);
166}
167
168}
169