/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/ptree/sem_state.cc
Line | Count | Source |
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 | | |
16 | | #include "yb/client/table.h" |
17 | | #include "yb/common/index.h" |
18 | | #include "yb/yql/cql/ql/ptree/column_desc.h" |
19 | | #include "yb/yql/cql/ql/ptree/pt_column_definition.h" |
20 | | #include "yb/yql/cql/ql/ptree/pt_dml.h" |
21 | | #include "yb/yql/cql/ql/ptree/pt_select.h" |
22 | | #include "yb/yql/cql/ql/ptree/sem_state.h" |
23 | | #include "yb/yql/cql/ql/ptree/sem_context.h" |
24 | | |
25 | | namespace yb { |
26 | | namespace ql { |
27 | | |
28 | | using std::shared_ptr; |
29 | | using client::YBTable; |
30 | | |
31 | | //-------------------------------------------------------------------------------------------------- |
32 | | |
33 | | SemState::SemState(SemContext *sem_context, |
34 | | const std::shared_ptr<QLType>& expected_ql_type, |
35 | | InternalType expected_internal_type, |
36 | | const MCSharedPtr<MCString>& bindvar_name, |
37 | | const ColumnDesc *lhs_col, |
38 | | NullIsAllowed allow_null) |
39 | | : sem_context_(sem_context), |
40 | | expected_ql_type_(expected_ql_type), |
41 | | allow_null_ql_type_(allow_null), |
42 | | expected_internal_type_(expected_internal_type), |
43 | | bindvar_name_(bindvar_name), |
44 | 1.84M | lhs_col_(lhs_col) { |
45 | | // Passing down state variables that stay the same until they are set or reset. |
46 | 1.84M | if (sem_context->sem_state() != nullptr) { |
47 | | // Must forward "current_dml_stmt_", so we always know what tree is being analyzed. |
48 | | // |
49 | | // TODO(neil) Change this name to root_node_ and use it for all statements including DML. |
50 | | // Currently, the statement roots are set in SemContext and should have been moved to SemState |
51 | | // to support "nested / index" statement. |
52 | 1.51M | current_dml_stmt_ = sem_context->current_dml_stmt(); |
53 | | |
54 | | // Index analysis states. |
55 | 1.51M | scan_state_ = sem_context->scan_state(); |
56 | 1.51M | selecting_from_index_ = sem_context_->selecting_from_index(); |
57 | 1.51M | index_select_prefix_length_ = sem_context_->index_select_prefix_length(); |
58 | 1.51M | void_primary_key_condition_ = sem_context_->void_primary_key_condition(); |
59 | | |
60 | | // Clause analysis states. |
61 | | // TODO(neil) Need to find reason why WhereExprState and IfExprState are not passed forward |
62 | | // and add comments on that here. |
63 | 1.51M | processing_if_clause_ = sem_context_->processing_if_clause(); |
64 | 1.51M | validate_orderby_expr_ = sem_context->validate_orderby_expr(); |
65 | 1.51M | processing_set_clause_ = sem_context_->processing_set_clause(); |
66 | 1.51M | idx_predicate_state_ = sem_context->idx_predicate_state(); |
67 | | |
68 | | // Operator states. |
69 | 1.51M | processing_assignee_ = sem_context_->processing_assignee(); |
70 | 1.51M | allowing_column_refs_ = sem_context_->allowing_column_refs(); |
71 | 1.51M | } |
72 | | |
73 | | // Use this new state for semantic analysis. |
74 | 1.84M | sem_context_->set_sem_state(this, &previous_state_); |
75 | 1.84M | } |
76 | | |
77 | 1.84M | SemState::~SemState() { |
78 | | // Reset the state. |
79 | 1.84M | ResetContextState(); |
80 | 1.84M | } |
81 | | |
82 | 2.11M | void SemState::ResetContextState() { |
83 | | // Reset state if it has not been reset. |
84 | 2.11M | if (!was_reset) { |
85 | 1.84M | sem_context_->reset_sem_state(previous_state_); |
86 | 1.84M | was_reset = true; |
87 | 1.84M | } |
88 | 2.11M | } |
89 | | |
90 | | void SemState::SetExprState(const std::shared_ptr<QLType>& ql_type, |
91 | | InternalType internal_type, |
92 | | const MCSharedPtr<MCString>& bindvar_name, |
93 | | const ColumnDesc *lhs_col, |
94 | 303k | NullIsAllowed allow_null) { |
95 | 303k | expected_ql_type_ = ql_type; |
96 | 303k | allow_null_ql_type_ = allow_null; |
97 | 303k | expected_internal_type_ = internal_type; |
98 | 303k | bindvar_name_ = bindvar_name; |
99 | 303k | lhs_col_ = lhs_col; |
100 | 303k | } |
101 | | |
102 | 4.92k | void SemState::CopyPreviousStates() { |
103 | 4.92k | if (previous_state_ != nullptr) { |
104 | 4.92k | expected_ql_type_ = previous_state_->expected_ql_type_; |
105 | 4.92k | allow_null_ql_type_ = previous_state_->allow_null_ql_type_; |
106 | 4.92k | expected_internal_type_ = previous_state_->expected_internal_type_; |
107 | 4.92k | bindvar_name_ = previous_state_->bindvar_name_; |
108 | 4.92k | where_state_ = previous_state_->where_state_; |
109 | 4.92k | } |
110 | 4.92k | } |
111 | | |
112 | 294k | void SemState::CopyPreviousWhereState() { |
113 | 294k | if (previous_state_ != nullptr) { |
114 | 294k | where_state_ = previous_state_->where_state_; |
115 | 294k | } |
116 | 294k | } |
117 | | |
118 | 294k | void SemState::CopyPreviousIfState() { |
119 | 294k | if (previous_state_ != nullptr) { |
120 | 294k | if_state_ = previous_state_->if_state_; |
121 | 294k | } |
122 | 294k | } |
123 | | |
124 | 2.29k | void SemState::set_bindvar_name(std::string name) { |
125 | 2.29k | bindvar_name_ = MCMakeShared<MCString>(sem_context_->PSemMem(), name.data(), name.size()); |
126 | 2.29k | } |
127 | | |
128 | 1.90k | void SemState::add_index_column_ref(int32_t col_id) { |
129 | 1.90k | index_column_->AddIndexedRef(col_id); |
130 | 1.90k | } |
131 | | |
132 | 409 | bool SemState::is_uncovered_index_select() const { |
133 | 409 | if (current_dml_stmt_ == nullptr || |
134 | 409 | current_dml_stmt_->opcode() != TreeNodeOpcode::kPTSelectStmt) { |
135 | 10 | return false; |
136 | 10 | } |
137 | | // Applicable to SELECT statement only. |
138 | 399 | const auto* select_stmt = static_cast<const PTSelectStmt*>(current_dml_stmt_); |
139 | 399 | return !select_stmt->index_id().empty() && !select_stmt->covers_fully(); |
140 | 399 | } |
141 | | |
142 | 90 | bool SemState::is_partial_index_select() const { |
143 | 90 | if (current_dml_stmt_ == nullptr || |
144 | 90 | current_dml_stmt_->opcode() != TreeNodeOpcode::kPTSelectStmt) { |
145 | 10 | return false; |
146 | 10 | } |
147 | | // Applicable to SELECT statement only. |
148 | 80 | const auto* select_stmt = static_cast<const PTSelectStmt*>(current_dml_stmt_); |
149 | 80 | if (select_stmt->index_id().empty()) return false; |
150 | | |
151 | 64 | std::shared_ptr<client::YBTable> table = select_stmt->table(); |
152 | 64 | const IndexInfo& idx_info = table->index_info(); |
153 | 64 | return idx_info.where_predicate_spec() != nullptr; |
154 | 64 | } |
155 | | |
156 | 16.2k | const ColumnDesc *SemState::hash_col() const { |
157 | 16.2k | return lhs_col_ != nullptr && lhs_col_->is_hash() ? lhs_col_ : nullptr; |
158 | 16.2k | } |
159 | | |
160 | 1.42M | const QLTypePtr& SemState::DefaultQLType() { |
161 | 1.42M | static const auto result = QLType::Create(UNKNOWN_DATA); |
162 | 1.42M | return result; |
163 | 1.42M | } |
164 | | |
165 | | } // namespace ql} // namespace ql |
166 | | } // namespace yb |