1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef SRC_TRACE_PROCESSOR_SQLITE_SQLITE_UTILS_H_
18 #define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_UTILS_H_
19
20 #include <sqlite3.h>
21 #include <bitset>
22 #include <cstddef>
23 #include <cstdint>
24 #include <cstring>
25 #include <functional>
26 #include <optional>
27 #include <string>
28 #include <utility>
29 #include <vector>
30
31 #include "perfetto/base/logging.h"
32 #include "perfetto/base/status.h"
33 #include "perfetto/ext/base/status_or.h"
34 #include "perfetto/trace_processor/basic_types.h"
35 #include "src/trace_processor/sqlite/bindings/sqlite_result.h"
36
37 // Analogous to ASSIGN_OR_RETURN macro. Returns an sqlite error.
38 #define SQLITE_RETURN_IF_ERROR(vtab, expr) \
39 do { \
40 const base::Status& status_macro_internal_status = (expr); \
41 if (!status_macro_internal_status.ok()) \
42 return sqlite::utils::SetError((vtab), status_macro_internal_status); \
43 } while (0)
44
45 // Analogous to ASSIGN_OR_RETURN macro. Returns an sqlite error.
46 #define SQLITE_ASSIGN_OR_RETURN(vtab, lhs, rhs) \
47 PERFETTO_INTERNAL_MACRO_CONCAT(auto status_or, __LINE__) = rhs; \
48 SQLITE_RETURN_IF_ERROR( \
49 vtab, PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__).status()); \
50 lhs = std::move(PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__).value())
51
52 namespace perfetto::trace_processor::sqlite::utils {
53
54 const auto kSqliteStatic = reinterpret_cast<sqlite3_destructor_type>(0);
55 const auto kSqliteTransient = reinterpret_cast<sqlite3_destructor_type>(-1);
56
IsOpEq(int op)57 inline bool IsOpEq(int op) {
58 return op == SQLITE_INDEX_CONSTRAINT_EQ;
59 }
IsOpLe(int op)60 inline bool IsOpLe(int op) {
61 return op == SQLITE_INDEX_CONSTRAINT_LE;
62 }
IsOpLt(int op)63 inline bool IsOpLt(int op) {
64 return op == SQLITE_INDEX_CONSTRAINT_LT;
65 }
IsOpGe(int op)66 inline bool IsOpGe(int op) {
67 return op == SQLITE_INDEX_CONSTRAINT_GE;
68 }
IsOpGt(int op)69 inline bool IsOpGt(int op) {
70 return op == SQLITE_INDEX_CONSTRAINT_GT;
71 }
72
SqliteTypeToSqlValueType(int sqlite_type)73 inline SqlValue::Type SqliteTypeToSqlValueType(int sqlite_type) {
74 switch (sqlite_type) {
75 case SQLITE_NULL:
76 return SqlValue::Type::kNull;
77 case SQLITE_BLOB:
78 return SqlValue::Type::kBytes;
79 case SQLITE_INTEGER:
80 return SqlValue::Type::kLong;
81 case SQLITE_FLOAT:
82 return SqlValue::Type::kDouble;
83 case SQLITE_TEXT:
84 return SqlValue::Type::kString;
85 }
86 PERFETTO_FATAL("Unknown SQLite type %d", sqlite_type);
87 }
88
SqliteValueToSqlValue(sqlite3_value * value)89 inline SqlValue SqliteValueToSqlValue(sqlite3_value* value) {
90 SqlValue sql_value;
91 switch (sqlite3_value_type(value)) {
92 case SQLITE_INTEGER:
93 sql_value.type = SqlValue::Type::kLong;
94 sql_value.long_value = sqlite3_value_int64(value);
95 break;
96 case SQLITE_FLOAT:
97 sql_value.type = SqlValue::Type::kDouble;
98 sql_value.double_value = sqlite3_value_double(value);
99 break;
100 case SQLITE_TEXT:
101 sql_value.type = SqlValue::Type::kString;
102 sql_value.string_value =
103 reinterpret_cast<const char*>(sqlite3_value_text(value));
104 break;
105 case SQLITE_BLOB:
106 sql_value.type = SqlValue::Type::kBytes;
107 sql_value.bytes_value = sqlite3_value_blob(value);
108 sql_value.bytes_count = static_cast<size_t>(sqlite3_value_bytes(value));
109 break;
110 }
111 return sql_value;
112 }
113
SqlValueToString(SqlValue value)114 inline std::optional<std::string> SqlValueToString(SqlValue value) {
115 switch (value.type) {
116 case SqlValue::Type::kString:
117 return value.AsString();
118 case SqlValue::Type::kDouble:
119 return std::to_string(value.AsDouble());
120 case SqlValue::Type::kLong:
121 return std::to_string(value.AsLong());
122 case SqlValue::Type::kBytes:
123 case SqlValue::Type::kNull:
124 return std::nullopt;
125 }
126 PERFETTO_FATAL("For GCC");
127 }
128
129 inline void ReportSqlValue(
130 sqlite3_context* ctx,
131 const SqlValue& value,
132 sqlite3_destructor_type string_destructor = kSqliteTransient,
133 sqlite3_destructor_type bytes_destructor = kSqliteTransient) {
134 switch (value.type) {
135 case SqlValue::Type::kLong:
136 sqlite::result::Long(ctx, value.long_value);
137 break;
138 case SqlValue::Type::kDouble:
139 sqlite::result::Double(ctx, value.double_value);
140 break;
141 case SqlValue::Type::kString: {
142 sqlite::result::RawString(ctx, value.string_value, string_destructor);
143 break;
144 }
145 case SqlValue::Type::kBytes:
146 sqlite::result::RawBytes(ctx, value.bytes_value,
147 static_cast<int>(value.bytes_count),
148 bytes_destructor);
149 break;
150 case SqlValue::Type::kNull:
151 sqlite::result::Null(ctx);
152 break;
153 }
154 }
155
SetError(sqlite3_vtab * tab,const char * status)156 inline int SetError(sqlite3_vtab* tab, const char* status) {
157 sqlite3_free(tab->zErrMsg);
158 tab->zErrMsg = sqlite3_mprintf("%s", status);
159 return SQLITE_ERROR;
160 }
161
SetError(sqlite3_context * ctx,const char * status)162 inline void SetError(sqlite3_context* ctx, const char* status) {
163 sqlite::result::Error(ctx, status);
164 }
165
SetError(sqlite3_vtab * tab,base::Status s)166 inline int SetError(sqlite3_vtab* tab, base::Status s) {
167 return SetError(tab, s.c_message());
168 }
169
SetError(sqlite3_context * ctx,const base::Status & status)170 inline void SetError(sqlite3_context* ctx, const base::Status& status) {
171 PERFETTO_CHECK(!status.ok());
172 sqlite::result::Error(ctx, status.c_message());
173 }
174
SetError(sqlite3_context * ctx,const std::string & function_name,const base::Status & status)175 inline void SetError(sqlite3_context* ctx,
176 const std::string& function_name,
177 const base::Status& status) {
178 SetError(ctx, base::ErrStatus("%s: %s", function_name.c_str(),
179 status.c_message()));
180 }
181
182 // For a given |sqlite3_index_info| struct received in a BestIndex call, returns
183 // whether all |arg_count| arguments (with |is_arg_column| indicating whether a
184 // given column is a function argument) have exactly one equality constraint
185 // associated with them.
186 //
187 // If so, the associated constraint is omitted and the argvIndex is mapped to
188 // the corresponding argument's index.
ValidateFunctionArguments(sqlite3_index_info * info,size_t arg_count,const std::function<bool (size_t)> & is_arg_column)189 inline base::Status ValidateFunctionArguments(
190 sqlite3_index_info* info,
191 size_t arg_count,
192 const std::function<bool(size_t)>& is_arg_column) {
193 std::vector<bool> present;
194 size_t present_count = 0;
195 for (int i = 0; i < info->nConstraint; ++i) {
196 const auto& in = info->aConstraint[i];
197 if (!in.usable) {
198 continue;
199 }
200 auto cs_col = static_cast<size_t>(in.iColumn);
201 if (!is_arg_column(cs_col)) {
202 continue;
203 }
204 if (!IsOpEq(in.op)) {
205 return base::ErrStatus(
206 "Unexpected non equality constraints for column %zu", cs_col);
207 }
208 if (cs_col >= present.size()) {
209 present.resize(cs_col + 1);
210 }
211 if (present[cs_col]) {
212 return base::ErrStatus("Unexpected multiple constraints for column %zu",
213 cs_col);
214 }
215 present[cs_col] = true;
216 present_count++;
217
218 auto& out = info->aConstraintUsage[i];
219 out.argvIndex = static_cast<int>(present_count);
220 out.omit = true;
221 }
222 if (present_count != arg_count) {
223 return base::ErrStatus(
224 "Unexpected missing argument: expected %zu, actual %zu", arg_count,
225 present_count);
226 }
227 return base::OkStatus();
228 }
229
SqlValueTypeToString(SqlValue::Type type)230 inline const char* SqlValueTypeToString(SqlValue::Type type) {
231 switch (type) {
232 case SqlValue::Type::kString:
233 return "STRING";
234 case SqlValue::Type::kDouble:
235 return "DOUBLE";
236 case SqlValue::Type::kLong:
237 return "LONG";
238 case SqlValue::Type::kBytes:
239 return "BYTES";
240 case SqlValue::Type::kNull:
241 return "NULL";
242 }
243 PERFETTO_FATAL("For GCC");
244 }
245
246 // Converts the given SqlValue type to the type string SQLite understands.
SqlValueTypeToSqliteTypeName(SqlValue::Type type)247 inline std::string SqlValueTypeToSqliteTypeName(SqlValue::Type type) {
248 switch (type) {
249 case SqlValue::Type::kString:
250 return "TEXT";
251 case SqlValue::Type::kLong:
252 return "BIGINT";
253 case SqlValue::Type::kDouble:
254 return "DOUBLE";
255 case SqlValue::Type::kBytes:
256 return "BLOB";
257 case SqlValue::Type::kNull:
258 // Default to BIGINT for columns which contains only NULLs - if we don't
259 // specify the type, sqlite will default to BLOB, which is going to trip
260 // a number of various checks.
261 return "BIGINT";
262 }
263 PERFETTO_FATAL("Not reached"); // For gcc
264 }
265
266 // Exracts the given type from the SqlValue if |value| can fit
267 // in the provided optional. Note that SqlValue::kNull will always
268 // succeed and cause std::nullopt to be set.
269 //
270 // Returns base::ErrStatus if the type does not match or does not
271 // fit in the width of the provided optional type (i.e. int64 value
272 // not fitting in int32 optional).
273 base::Status ExtractFromSqlValue(const SqlValue& value,
274 std::optional<int64_t>&);
275 base::Status ExtractFromSqlValue(const SqlValue& value,
276 std::optional<int32_t>&);
277 base::Status ExtractFromSqlValue(const SqlValue& value,
278 std::optional<uint32_t>&);
279 base::Status ExtractFromSqlValue(const SqlValue& value, std::optional<double>&);
280 base::Status ExtractFromSqlValue(const SqlValue& value,
281 std::optional<const char*>&);
282
283 // Returns the column names for the table named by |raw_table_name|.
284 base::Status GetColumnsForTable(
285 sqlite3* db,
286 const std::string& raw_table_name,
287 std::vector<std::pair<SqlValue::Type, std::string>>& columns);
288
289 // Reads a `SQLITE_TEXT` value and returns it as a wstring (UTF-16) in the
290 // default byte order. `value` must be a `SQLITE_TEXT`.
291 std::wstring SqliteValueToWString(sqlite3_value* value);
292
293 // Given an SqlValue::Type, converts it to a human-readable string.
294 // This should really only be used for debugging messages.
295 const char* SqliteTypeToFriendlyString(SqlValue::Type type);
296
297 // Verifies if |argc| matches |expected_argc| and returns an appropriate error
298 // message if they don't match.
299 base::Status CheckArgCount(const char* function_name,
300 size_t argc,
301 size_t expected_argc);
302
303 // Type-safe helpers to extract an arg value from a sqlite3_value*, returning an
304 // appropriate message if it fails.
305 base::StatusOr<int64_t> ExtractIntArg(const char* function_name,
306 const char* arg_name,
307 sqlite3_value* value);
308 base::StatusOr<double> ExtractDoubleArg(const char* function_name,
309 const char* arg_name,
310 sqlite3_value* value);
311 base::StatusOr<std::string> ExtractStringArg(const char* function_name,
312 const char* arg_name,
313 sqlite3_value* value);
314
315 // Verifies if |value| has the type represented by |expected_type|.
316 // Returns base::OkStatus if it does or an base::ErrStatus with an
317 // appropriate error mesage (incorporating |expected_type_str| if specified).
318 base::Status TypeCheckSqliteValue(sqlite3_value* value,
319 SqlValue::Type expected_type);
320 base::Status TypeCheckSqliteValue(sqlite3_value* value,
321 SqlValue::Type expected_type,
322 const char* expected_type_str);
323
324 namespace internal {
325
326 static_assert(sizeof(size_t) * 8 > SqlValue::kLastType);
327 using ExpectedTypesSet = std::bitset<SqlValue::kLastType + 1>;
328
329 template <typename... args>
ToExpectedTypesSet(args...expected_type_args)330 constexpr ExpectedTypesSet ToExpectedTypesSet(args... expected_type_args) {
331 ExpectedTypesSet set;
332 for (const SqlValue::Type t : {expected_type_args...}) {
333 set.set(static_cast<size_t>(t));
334 }
335 return set;
336 }
337
338 base::StatusOr<SqlValue> ExtractArgument(size_t argc,
339 sqlite3_value** argv,
340 const char* argument_name,
341 size_t arg_index,
342 ExpectedTypesSet expected_types);
343 base::Status InvalidArgumentTypeError(const char* argument_name,
344 size_t arg_index,
345 SqlValue::Type actual_type,
346 ExpectedTypesSet expected_types);
347 } // namespace internal
348
349 template <typename... args>
InvalidArgumentTypeError(const char * argument_name,size_t arg_index,SqlValue::Type actual_type,SqlValue::Type expected_type,args...expected_type_args)350 base::Status InvalidArgumentTypeError(const char* argument_name,
351 size_t arg_index,
352 SqlValue::Type actual_type,
353 SqlValue::Type expected_type,
354 args... expected_type_args) {
355 return internal::InvalidArgumentTypeError(
356 argument_name, arg_index, actual_type,
357 internal::ToExpectedTypesSet(expected_type, expected_type_args...));
358 }
359
360 base::Status MissingArgumentError(const char* argument_name);
361
362 base::Status ToInvalidArgumentError(const char* argument_name,
363 size_t arg_index,
364 const base::Status& error);
365
366 template <typename... args>
ExtractArgument(size_t argc,sqlite3_value ** argv,const char * argument_name,size_t arg_index,SqlValue::Type expected_type,args...expected_type_args)367 base::StatusOr<SqlValue> ExtractArgument(size_t argc,
368 sqlite3_value** argv,
369 const char* argument_name,
370 size_t arg_index,
371 SqlValue::Type expected_type,
372 args... expected_type_args) {
373 return internal::ExtractArgument(
374 argc, argv, argument_name, arg_index,
375 internal::ToExpectedTypesSet(expected_type, expected_type_args...));
376 }
377
378 } // namespace perfetto::trace_processor::sqlite::utils
379
380 #endif // SRC_TRACE_PROCESSOR_SQLITE_SQLITE_UTILS_H_
381