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 | |
11 | namespace DB::MySQLProtocol |
12 | { |
13 | |
14 | void PacketSender::resetSequenceId() |
15 | { |
16 | sequence_id = 0; |
17 | } |
18 | |
19 | String 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 | |
30 | uint64_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 | |
55 | void 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 | |
78 | size_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 | |
98 | size_t getLengthEncodedStringSize(const String & s) |
99 | { |
100 | return getLengthEncodedNumberSize(s.size()) + s.size(); |
101 | } |
102 | |
103 | ColumnDefinition 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 | |