/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/ptree/sem_context.h
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | // Entry point for the semantic analytical process. |
16 | | //-------------------------------------------------------------------------------------------------- |
17 | | |
18 | | #ifndef YB_YQL_CQL_QL_PTREE_SEM_CONTEXT_H_ |
19 | | #define YB_YQL_CQL_QL_PTREE_SEM_CONTEXT_H_ |
20 | | |
21 | | #include "yb/client/client_fwd.h" |
22 | | |
23 | | #include "yb/common/common_types.pb.h" |
24 | | #include "yb/common/ql_datatype.h" |
25 | | |
26 | | #include "yb/yql/cql/ql/ptree/ptree_fwd.h" |
27 | | #include "yb/yql/cql/ql/ptree/process_context.h" |
28 | | |
29 | | namespace yb { |
30 | | namespace ql { |
31 | | |
32 | | //-------------------------------------------------------------------------------------------------- |
33 | | |
34 | | struct SymbolEntry { |
35 | | // Parse tree node for column. It's used for table creation. |
36 | | PTColumnDefinition *column_ = nullptr; |
37 | | |
38 | | // Parse tree node for column alterations. |
39 | | PTAlterColumnDefinition *alter_column_ = nullptr; |
40 | | |
41 | | // Parse tree node for table. It's used for table creation. |
42 | | PTCreateTable *create_table_ = nullptr; |
43 | | PTAlterTable *alter_table_ = nullptr; |
44 | | |
45 | | // Parser tree node for user-defined type. It's used for creating types. |
46 | | PTCreateType *create_type_ = nullptr; |
47 | | PTTypeField *type_field_ = nullptr; |
48 | | |
49 | | // Column description. It's used for DML statements including select. |
50 | | // Not part of a parse tree, but it is allocated within the parse tree pool because it is |
51 | | // persistent metadata. It represents a column during semantic and execution phases. |
52 | | // |
53 | | // TODO(neil) Add "column_read_count_" and potentially "column_write_count_" and use them for |
54 | | // error check wherever needed. Symbol tables and entries are destroyed after compilation, so |
55 | | // data that are used during compilation but not execution should be declared here. |
56 | | ColumnDesc *column_desc_ = nullptr; |
57 | | }; |
58 | | |
59 | | //-------------------------------------------------------------------------------------------------- |
60 | | |
61 | | class SemContext : public ProcessContext { |
62 | | public: |
63 | | //------------------------------------------------------------------------------------------------ |
64 | | // Public types. |
65 | | typedef std::unique_ptr<SemContext> UniPtr; |
66 | | typedef std::unique_ptr<const SemContext> UniPtrConst; |
67 | | |
68 | | //------------------------------------------------------------------------------------------------ |
69 | | // Constructor & destructor. |
70 | | SemContext(ParseTreePtr parse_tree, QLEnv *ql_env); |
71 | | virtual ~SemContext(); |
72 | | |
73 | | // Memory pool for semantic analysis of the parse tree of a statement. |
74 | | MemoryContext *PSemMem() const; |
75 | | |
76 | | //------------------------------------------------------------------------------------------------ |
77 | | // Symbol table support. |
78 | | CHECKED_STATUS MapSymbol(const MCString& name, PTColumnDefinition *entry); |
79 | | CHECKED_STATUS MapSymbol(const MCString& name, PTAlterColumnDefinition *entry); |
80 | | CHECKED_STATUS MapSymbol(const MCString& name, PTCreateTable *entry); |
81 | | CHECKED_STATUS MapSymbol(const MCString& name, ColumnDesc *entry); |
82 | | CHECKED_STATUS MapSymbol(const MCString& name, PTTypeField *entry); |
83 | | |
84 | | // Access functions to current processing symbol. |
85 | 8.40k | SymbolEntry *current_processing_id() { |
86 | 8.40k | return ¤t_processing_id_; |
87 | 8.40k | } |
88 | 8.10k | void set_current_processing_id(const SymbolEntry& new_id) { |
89 | 8.10k | current_processing_id_ = new_id; |
90 | 8.10k | } |
91 | | |
92 | | //------------------------------------------------------------------------------------------------ |
93 | | // Load table schema into symbol table. |
94 | | CHECKED_STATUS LookupTable(const client::YBTableName& name, |
95 | | const YBLocation& loc, |
96 | | bool write_table, |
97 | | const PermissionType permission_type, |
98 | | std::shared_ptr<client::YBTable>* table, |
99 | | bool* is_system, |
100 | | MCVector<ColumnDesc>* col_descs = nullptr); |
101 | | |
102 | | //------------------------------------------------------------------------------------------------ |
103 | | // Access functions to current processing table and column. |
104 | 288 | PTColumnDefinition *current_column() { |
105 | 288 | return current_processing_id_.column_; |
106 | 288 | } |
107 | 4.92k | void set_current_column(PTColumnDefinition *column) { |
108 | 4.92k | current_processing_id_.column_ = column; |
109 | 4.92k | } |
110 | | |
111 | 337k | PTCreateTable *current_create_table_stmt() { |
112 | 337k | return current_processing_id_.create_table_; |
113 | 337k | } |
114 | | |
115 | 2.39k | void set_current_create_table_stmt(PTCreateTable *table) { |
116 | 2.39k | current_processing_id_.create_table_ = table; |
117 | 2.39k | } |
118 | | |
119 | | PTCreateIndex *current_create_index_stmt(); |
120 | | |
121 | | void set_current_create_index_stmt(PTCreateIndex *index); |
122 | | |
123 | 410 | PTAlterTable *current_alter_table() { |
124 | 410 | return current_processing_id_.alter_table_; |
125 | 410 | } |
126 | | |
127 | 69 | void set_current_alter_table(PTAlterTable *table) { |
128 | 69 | current_processing_id_.alter_table_ = table; |
129 | 69 | } |
130 | | |
131 | 0 | PTCreateType *current_create_type_stmt() { |
132 | 0 | return current_processing_id_.create_type_; |
133 | 0 | } |
134 | | |
135 | 160 | void set_current_create_type_stmt(PTCreateType *type) { |
136 | 160 | current_processing_id_.create_type_ = type; |
137 | 160 | } |
138 | | |
139 | 0 | PTTypeField *current_type_field() { |
140 | 0 | return current_processing_id_.type_field_; |
141 | 0 | } |
142 | | |
143 | 126 | void set_current_type_field(PTTypeField *field) { |
144 | 126 | current_processing_id_.type_field_ = field; |
145 | 126 | } |
146 | | |
147 | | // Find table descriptor from metadata server. |
148 | | std::shared_ptr<client::YBTable> GetTableDesc(const client::YBTableName& table_name); |
149 | | |
150 | | // Find table descriptor from metadata server. |
151 | | std::shared_ptr<client::YBTable> GetTableDesc(const TableId& table_id); |
152 | | |
153 | | // Get (user-defined) type from metadata server. |
154 | | std::shared_ptr<QLType> GetUDType(const std::string &keyspace_name, const std::string &type_name); |
155 | | |
156 | | // Find column descriptor from symbol table. |
157 | | PTColumnDefinition *GetColumnDefinition(const MCString& col_name); |
158 | | |
159 | | // Find column descriptor from symbol table. From the context, the column value will be marked to |
160 | | // be read if necessary when executing the QL statement. |
161 | | const ColumnDesc *GetColumnDesc(const MCString& col_name) const; |
162 | | |
163 | | // Check if the lhs_type is convertible to rhs_type. |
164 | | bool IsConvertible(const std::shared_ptr<QLType>& lhs_type, |
165 | | const std::shared_ptr<QLType>& rhs_type) const; |
166 | | |
167 | | // Check if two types are comparable -- parametric types are never comparable so we only take |
168 | | // DataType not QLType as arguments |
169 | | bool IsComparable(DataType lhs_type, DataType rhs_type) const; |
170 | | |
171 | | std::string CurrentKeyspace() const; |
172 | | |
173 | | std::string CurrentRoleName() const; |
174 | | |
175 | | // Access function to cache_used. |
176 | 923 | bool cache_used() const { return cache_used_; } |
177 | | |
178 | | // Acess functions for semantic states. |
179 | 2.11M | SemState *sem_state() const { |
180 | 2.11M | return sem_state_; |
181 | 2.11M | } |
182 | | |
183 | | const std::shared_ptr<QLType>& expr_expected_ql_type() const; |
184 | | |
185 | | NullIsAllowed expected_ql_type_accepts_null() const; |
186 | | |
187 | | InternalType expr_expected_internal_type() const; |
188 | | |
189 | | SelectScanInfo *scan_state() const; |
190 | | |
191 | | bool void_primary_key_condition() const; |
192 | | |
193 | | WhereExprState *where_state() const; |
194 | | |
195 | | IfExprState *if_state() const; |
196 | | |
197 | | bool validate_orderby_expr() const; |
198 | | |
199 | | IdxPredicateState *idx_predicate_state() const; |
200 | | |
201 | | bool selecting_from_index() const; |
202 | | |
203 | | size_t index_select_prefix_length() const; |
204 | | |
205 | | bool processing_column_definition() const; |
206 | | |
207 | | const MCSharedPtr<MCString>& bindvar_name() const; |
208 | | |
209 | | const ColumnDesc *hash_col() const; |
210 | | |
211 | | const ColumnDesc *lhs_col() const; |
212 | | |
213 | | bool processing_set_clause() const; |
214 | | |
215 | | bool processing_assignee() const; |
216 | | |
217 | | bool processing_if_clause() const; |
218 | | |
219 | | bool allowing_aggregate() const; |
220 | | |
221 | | bool allowing_column_refs() const; |
222 | | |
223 | 1.84M | void set_sem_state(SemState *new_state, SemState **existing_state_holder) { |
224 | 1.84M | *existing_state_holder = sem_state_; |
225 | 1.84M | sem_state_ = new_state; |
226 | 1.84M | } |
227 | | |
228 | 1.84M | void reset_sem_state(SemState *previous_state) { |
229 | 1.84M | sem_state_ = previous_state; |
230 | 1.84M | } |
231 | | |
232 | | PTDmlStmt *current_dml_stmt() const; |
233 | | |
234 | | void set_current_dml_stmt(PTDmlStmt *stmt); |
235 | | |
236 | | void set_void_primary_key_condition(bool val); |
237 | | |
238 | | CHECKED_STATUS HasKeyspacePermission(const PermissionType permission, |
239 | | const NamespaceName& keyspace_name); |
240 | | |
241 | | // Check whether the current role has the specified permission on the keyspace. Returns an |
242 | | // UNAUTHORIZED error message if not found. |
243 | | CHECKED_STATUS CheckHasKeyspacePermission(const YBLocation& loc, |
244 | | const PermissionType permission, |
245 | | const NamespaceName& keyspace_name); |
246 | | |
247 | | // Check whether the current role has the specified permission on the keyspace or table. Returns |
248 | | // an UNAUTHORIZED error message if not found. |
249 | | CHECKED_STATUS CheckHasTablePermission(const YBLocation& loc, |
250 | | const PermissionType permission, |
251 | | const NamespaceName& keyspace_name, |
252 | | const TableName& table_name); |
253 | | |
254 | | // Convenience method. |
255 | | CHECKED_STATUS CheckHasTablePermission(const YBLocation& loc, |
256 | | const PermissionType permission, |
257 | | client::YBTableName table_name); |
258 | | |
259 | | // Check whether the current role has the specified permission on the role. Returns an |
260 | | // UNAUTHORIZED error message if not found. |
261 | | CHECKED_STATUS CheckHasRolePermission(const YBLocation& loc, |
262 | | const PermissionType permission, |
263 | | const RoleName& role_name); |
264 | | |
265 | | // Check whether the current role has the specified permission on 'ALL KEYSPACES'. |
266 | | CHECKED_STATUS CheckHasAllKeyspacesPermission(const YBLocation& loc, |
267 | | const PermissionType permission); |
268 | | |
269 | | // Check whether the current role has the specified permission on 'ALL ROLES'. |
270 | | CHECKED_STATUS CheckHasAllRolesPermission(const YBLocation& loc, |
271 | | const PermissionType permission); |
272 | | |
273 | | bool IsUncoveredIndexSelect() const; |
274 | | |
275 | | bool IsPartialIndexSelect() const; |
276 | | |
277 | | private: |
278 | | CHECKED_STATUS LoadSchema(const std::shared_ptr<client::YBTable>& table, |
279 | | MCVector<ColumnDesc>* col_descs = nullptr); |
280 | | |
281 | | // Find symbol. |
282 | | const SymbolEntry *SeekSymbol(const MCString& name) const; |
283 | | |
284 | | // Symbol table. |
285 | | MCMap<MCString, SymbolEntry> symtab_; |
286 | | |
287 | | // Current processing symbol. |
288 | | SymbolEntry current_processing_id_; |
289 | | |
290 | | // Session. |
291 | | QLEnv *ql_env_; |
292 | | |
293 | | // Is metadata cache used? |
294 | | bool cache_used_ = false; |
295 | | |
296 | | // sem_state_ consists of state variables that are used to process one tree node. It is generally |
297 | | // set and reset at the beginning and end of the semantic analysis of one treenode. |
298 | | SemState *sem_state_ = nullptr; |
299 | | }; |
300 | | |
301 | | } // namespace ql |
302 | | } // namespace yb |
303 | | #endif // YB_YQL_CQL_QL_PTREE_SEM_CONTEXT_H_ |