• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_QUERY_CONSTRAINTS_H_
18 #define SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_
19 
20 #include <sqlite3.h>
21 
22 #include <limits>
23 #include <vector>
24 
25 #include "perfetto/ext/base/scoped_file.h"
26 
27 namespace perfetto {
28 namespace trace_processor {
29 
30 // This class stores the constraints (including the order-by information) for
31 // a query on a sqlite3 virtual table and handles their de/serialization into
32 // strings.
33 // This is because the constraint columns and the order-by clauses are passed
34 // to the xBestIndex method but the constraint values are available only in the
35 // xFilter method. Unfortunately sqlite vtable API don't give any hint about
36 // the validity of the constraints (i.e. constraints passed to xBestIndex can
37 // be used by future xFilter calls in the far future). The only mechanism
38 // offered by sqlite is the idxStr string which is returned by the vtable
39 // in the xBestIndex call and passed to each corresponding xFilter call.
40 class QueryConstraints {
41  public:
42   struct Constraint {
43     // Column this constraint refers to.
44     int column;
45 
46     // SQLite op for the constraint.
47     int op;
48 
49     // The original index of this constraint in the aConstraint array.
50     // Used internally by SqliteTable for xBestIndex - this should not be
51     // read or modified by subclasses of SqliteTable.
52     int a_constraint_idx;
53   };
54 
55   using OrderBy = sqlite3_index_info::sqlite3_index_orderby;
56 
57   static int FreeSqliteString(char* resource);
58 
59   using SqliteString = base::ScopedResource<char*, FreeSqliteString, nullptr>;
60 
61   explicit QueryConstraints(
62       uint64_t cols_used = std::numeric_limits<uint64_t>::max());
63   ~QueryConstraints();
64   QueryConstraints(QueryConstraints&&) noexcept;
65   QueryConstraints& operator=(QueryConstraints&&) noexcept;
66 
67   // Two QueryConstraints with the same constraint and orderby vectors
68   // are equal.
69   bool operator==(const QueryConstraints& other) const;
70 
71   void AddConstraint(int column, unsigned char op, int aconstraint_idx);
72 
73   void AddOrderBy(int column, unsigned char desc);
74 
ClearOrderBy()75   void ClearOrderBy() { order_by_.clear(); }
76 
77   // Converts the constraints and order by information to a string for
78   // use by sqlite.
79   SqliteString ToNewSqlite3String() const;
80 
81   // Deserializes the string into QueryConstraints. String given is in the form
82   // C{# of constraints},col1,op1,col2,op2...,O{# of order by},col1,desc1...
83   // For example C1,0,3,O2,1,0,4,1
84   static QueryConstraints FromString(const char* idxStr);
85 
order_by()86   const std::vector<OrderBy>& order_by() const { return order_by_; }
87 
constraints()88   const std::vector<Constraint>& constraints() const { return constraints_; }
89 
mutable_order_by()90   std::vector<OrderBy>* mutable_order_by() { return &order_by_; }
91 
mutable_constraints()92   std::vector<Constraint>* mutable_constraints() { return &constraints_; }
93 
cols_used()94   uint64_t cols_used() const { return cols_used_; }
95 
96  private:
97   QueryConstraints(const QueryConstraints&) = delete;
98   QueryConstraints& operator=(const QueryConstraints&) = delete;
99 
100   std::vector<OrderBy> order_by_;
101   std::vector<Constraint> constraints_;
102 
103   // Stores information about which column is used by this query.
104   // If the lowest bit of is set, the first column is used. The second lowest
105   // bit corresponds to the second column etc. If the most significant bit is
106   // set, that means that any column after the first 63 columns could be used.
107   uint64_t cols_used_ = std::numeric_limits<uint64_t>::max();
108 };
109 
110 }  // namespace trace_processor
111 }  // namespace perfetto
112 
113 #endif  // SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_
114