1 | #pragma once |
2 | |
3 | #include <Core/Types.h> |
4 | |
5 | |
6 | namespace DB |
7 | { |
8 | |
9 | |
10 | /// Client-server protocol. |
11 | /// |
12 | /// Client opens a connection and sends Hello packet. |
13 | /// If client version is incompatible, the server can terminate the connection. |
14 | /// Server responds with Hello packet. |
15 | /// If server version is incompatible, the client can terminate the connection. |
16 | /// |
17 | /// The main loop follows: |
18 | /// |
19 | /// 1. The client sends Query packet. |
20 | /// |
21 | /// Starting from version 50263 immediately after sending the Query packet the client starts |
22 | /// transfer of external (temporary) table (external storages) - one or several Data packets. |
23 | /// End of transmission is marked by an empty block. |
24 | /// At present, non-empty tables can be sent only along with SELECT query. |
25 | /// |
26 | /// If the query is an INSERT (and thus requires data transfer from client), then the server transmits |
27 | /// Data packet containing empty block that describes the table structure. |
28 | /// Then the client sends one or several Data packets - data for insertion. |
29 | /// End of data is marked by the transmission of empty block. |
30 | /// Then the server sends EndOfStream packet. |
31 | /// |
32 | /// If the query is a SELECT or a query of other type, then the server transmits packets of |
33 | /// one of the following types: |
34 | /// - Data - data corresponding to one block of query results. |
35 | /// - Progress - query execution progress. |
36 | /// - Exception - error description. |
37 | /// - EndOfStream - the end of data transmission. |
38 | /// |
39 | /// The client should read packets until EndOfStream or Exception. |
40 | /// |
41 | /// The client can also send Cancel packet - a request to cancel the query. |
42 | /// In this case the server can stop executing the query and return incomplete data, |
43 | /// but the client must still read until EndOfStream packet. |
44 | /// |
45 | /// Also if there is profiling info and the client revision is recent enough, the server can |
46 | /// send one of the following packets before EndOfStream: |
47 | /// - Totals - a block with total values |
48 | /// - ProfileInfo - serialized BlockStreamProfileInfo structure. |
49 | /// |
50 | /// If a query returns data, the server sends an empty header block containing |
51 | /// the description of resulting columns before executing the query. |
52 | /// Using this block the client can initialise the output formatter and display the prefix of resulting table |
53 | /// beforehand. |
54 | |
55 | namespace Protocol |
56 | { |
57 | /// Packet types that server transmits. |
58 | namespace Server |
59 | { |
60 | enum Enum |
61 | { |
62 | Hello = 0, /// Name, version, revision. |
63 | Data = 1, /// A block of data (compressed or not). |
64 | Exception = 2, /// The exception during query execution. |
65 | Progress = 3, /// Query execution progress: rows read, bytes read. |
66 | Pong = 4, /// Ping response |
67 | EndOfStream = 5, /// All packets were transmitted |
68 | ProfileInfo = 6, /// Packet with profiling info. |
69 | Totals = 7, /// A block with totals (compressed or not). |
70 | Extremes = 8, /// A block with minimums and maximums (compressed or not). |
71 | TablesStatusResponse = 9, /// A response to TablesStatus request. |
72 | Log = 10, /// System logs of the query execution |
73 | TableColumns = 11, /// Columns' description for default values calculation |
74 | }; |
75 | |
76 | /// NOTE: If the type of packet argument would be Enum, the comparison packet >= 0 && packet < 10 |
77 | /// would always be true because of compiler optimisation. That would lead to out-of-bounds error |
78 | /// if the packet is invalid. |
79 | /// See https://www.securecoding.cert.org/confluence/display/cplusplus/INT36-CPP.+Do+not+use+out-of-range+enumeration+values |
80 | inline const char * toString(UInt64 packet) |
81 | { |
82 | static const char * data[] = { "Hello" , "Data" , "Exception" , "Progress" , "Pong" , "EndOfStream" , "ProfileInfo" , "Totals" , |
83 | "Extremes" , "TablesStatusResponse" , "Log" , "TableColumns" }; |
84 | return packet < 12 |
85 | ? data[packet] |
86 | : "Unknown packet" ; |
87 | } |
88 | |
89 | inline size_t stringsInMessage(UInt64 msg_type) |
90 | { |
91 | switch (msg_type) |
92 | { |
93 | case TableColumns: |
94 | return 2; |
95 | default: |
96 | break; |
97 | } |
98 | return 0; |
99 | } |
100 | } |
101 | |
102 | /// Packet types that client transmits. |
103 | namespace Client |
104 | { |
105 | enum Enum |
106 | { |
107 | Hello = 0, /// Name, version, revision, default DB |
108 | Query = 1, /// Query id, query settings, stage up to which the query must be executed, |
109 | /// whether the compression must be used, |
110 | /// query text (without data for INSERTs). |
111 | Data = 2, /// A block of data (compressed or not). |
112 | Cancel = 3, /// Cancel the query execution. |
113 | Ping = 4, /// Check that connection to the server is alive. |
114 | TablesStatusRequest = 5, /// Check status of tables on the server. |
115 | KeepAlive = 6, /// Keep the connection alive |
116 | Scalar = 7 /// A block of data (compressed or not). |
117 | }; |
118 | |
119 | inline const char * toString(UInt64 packet) |
120 | { |
121 | static const char * data[] = { "Hello" , "Query" , "Data" , "Cancel" , "Ping" , "TablesStatusRequest" , "KeepAlive" }; |
122 | return packet < 7 |
123 | ? data[packet] |
124 | : "Unknown packet" ; |
125 | } |
126 | } |
127 | |
128 | /// Whether the compression must be used. |
129 | enum class Compression |
130 | { |
131 | Disable = 0, |
132 | Enable = 1, |
133 | }; |
134 | |
135 | /// Whether the ssl must be used. |
136 | enum class Secure |
137 | { |
138 | Disable = 0, |
139 | Enable = 1, |
140 | }; |
141 | |
142 | } |
143 | |
144 | } |
145 | |