1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#pragma once
#include <Core/UUID.h>
#include <Poco/Net/SocketAddress.h>
#include <base/types.h>
#include <Common/OpenTelemetryTraceContext.h>
#include <Common/VersionNumber.h>
#include <boost/algorithm/string/trim.hpp>
namespace DB
{
class WriteBuffer;
class ReadBuffer;
/** Information about client for query.
* Some fields are passed explicitly from client and some are calculated automatically.
*
* Contains info about initial query source, for tracing distributed queries
* (where one query initiates many other queries).
*/
class ClientInfo
{
public:
enum class Interface : uint8_t
{
TCP = 1,
HTTP = 2,
GRPC = 3,
MYSQL = 4,
POSTGRESQL = 5,
LOCAL = 6,
TCP_INTERSERVER = 7,
};
enum class HTTPMethod : uint8_t
{
UNKNOWN = 0,
GET = 1,
POST = 2,
OPTIONS = 3
};
enum class QueryKind : uint8_t
{
NO_QUERY = 0, /// Uninitialized object.
INITIAL_QUERY = 1,
SECONDARY_QUERY = 2, /// Query that was initiated by another query for distributed or ON CLUSTER query execution.
};
QueryKind query_kind = QueryKind::NO_QUERY;
/// Current values are not serialized, because it is passed separately.
String current_user;
String current_query_id;
Poco::Net::SocketAddress current_address;
/// When query_kind == INITIAL_QUERY, these values are equal to current.
String initial_user;
String initial_query_id;
Poco::Net::SocketAddress initial_address;
time_t initial_query_start_time{};
Decimal64 initial_query_start_time_microseconds{};
/// OpenTelemetry trace context we received from client, or which we are going to send to server.
OpenTelemetry::TracingContext client_trace_context;
/// All below are parameters related to initial query.
Interface interface = Interface::TCP;
bool is_secure = false;
String certificate;
/// For tcp
String os_user;
String client_hostname;
String client_name;
UInt64 client_version_major = 0;
UInt64 client_version_minor = 0;
UInt64 client_version_patch = 0;
unsigned client_tcp_protocol_version = 0;
/// In case of distributed query, client info for query is actually a client info of client.
/// In order to get a version of server-initiator, use connection_ values.
/// Also for tcp only.
UInt64 connection_client_version_major = 0;
UInt64 connection_client_version_minor = 0;
UInt64 connection_client_version_patch = 0;
unsigned connection_tcp_protocol_version = 0;
/// For http
HTTPMethod http_method = HTTPMethod::UNKNOWN;
String http_user_agent;
String http_referer;
/// For mysql and postgresql
UInt64 connection_id = 0;
/// Comma separated list of forwarded IP addresses (from X-Forwarded-For for HTTP interface).
/// It's expected that proxy appends the forwarded address to the end of the list.
/// The element can be trusted only if you trust the corresponding proxy.
/// NOTE This field can also be reused in future for TCP interface with PROXY v1/v2 protocols.
String forwarded_for;
String getLastForwardedFor() const
{
if (forwarded_for.empty())
return {};
String last = forwarded_for.substr(forwarded_for.find_last_of(',') + 1);
boost::trim(last);
return last;
}
/// Common
String quota_key;
UInt64 distributed_depth = 0;
bool is_replicated_database_internal = false;
/// For parallel processing on replicas
bool collaborate_with_initiator{false};
UInt64 count_participating_replicas{0};
UInt64 number_of_current_replica{0};
bool empty() const { return query_kind == QueryKind::NO_QUERY; }
/** Serialization and deserialization.
* Only values that are not calculated automatically or passed separately are serialized.
* Revisions are passed to use format that server will understand or client was used.
*/
void write(WriteBuffer & out, UInt64 server_protocol_revision) const;
void read(ReadBuffer & in, UInt64 client_protocol_revision);
/// Initialize parameters on client initiating query.
void setInitialQuery();
bool clientVersionEquals(const ClientInfo & other, bool compare_patch) const;
String getVersionStr() const;
VersionNumber getVersionNumber() const;
private:
void fillOSUserHostNameAndVersionInfo();
};
String toString(ClientInfo::Interface interface);
}
|