/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/ptree/pt_create_type.cc
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 | | // Treenode definitions for CREATE TYPE statements. |
16 | | //-------------------------------------------------------------------------------------------------- |
17 | | |
18 | | #include "yb/yql/cql/ql/ptree/pt_create_type.h" |
19 | | |
20 | | #include "yb/yql/cql/ql/ptree/pt_option.h" |
21 | | #include "yb/yql/cql/ql/ptree/sem_context.h" |
22 | | #include "yb/yql/cql/ql/ptree/sem_state.h" |
23 | | #include "yb/yql/cql/ql/ptree/yb_location.h" |
24 | | |
25 | | DECLARE_bool(use_cassandra_authentication); |
26 | | |
27 | | namespace yb { |
28 | | namespace ql { |
29 | | |
30 | | //-------------------------------------------------------------------------------------------------- |
31 | | |
32 | | PTTypeField::PTTypeField(MemoryContext *memctx, |
33 | | YBLocation::SharedPtr loc, |
34 | | const MCSharedPtr<MCString>& name, |
35 | | const PTBaseType::SharedPtr& datatype) |
36 | | : TreeNode(memctx, loc), |
37 | | name_(name), |
38 | 130 | datatype_(datatype) { |
39 | 130 | } |
40 | | |
41 | 103 | PTTypeField::~PTTypeField() { |
42 | 103 | } |
43 | | |
44 | | |
45 | 126 | CHECKED_STATUS PTTypeField::Analyze(SemContext *sem_context) { |
46 | | |
47 | | // Save context state, and set "this" as current type field in the context. |
48 | 126 | SymbolEntry cached_entry = *sem_context->current_processing_id(); |
49 | 126 | sem_context->set_current_type_field(this); |
50 | | |
51 | | // Add field to symbol table (checks for duplicate entries) |
52 | 126 | RETURN_NOT_OK(sem_context->MapSymbol(*name_, this)); |
53 | | |
54 | | // Check that the type of the field is valid. |
55 | 124 | RETURN_NOT_OK(datatype_->Analyze(sem_context)); |
56 | | |
57 | 119 | if (datatype_->ql_type()->IsCollection()) { |
58 | 5 | return sem_context->Error(this, "UDT field types cannot be (un-frozen) collections", |
59 | 5 | ErrorCode::INVALID_TYPE_DEFINITION); |
60 | 5 | } |
61 | | |
62 | 114 | if (!datatype_->ql_type()->GetUserDefinedTypeIds().empty() && !datatype_->ql_type()->IsFrozen()) { |
63 | 4 | return sem_context->Error(this, "A user-defined type cannot contain non-frozen UDTs", |
64 | 4 | ErrorCode::FEATURE_NOT_SUPPORTED); |
65 | 4 | } |
66 | | |
67 | | // Restore the context value as we are done with this colummn. |
68 | 110 | sem_context->set_current_processing_id(cached_entry); |
69 | | |
70 | 110 | return Status::OK(); |
71 | 110 | } |
72 | | |
73 | | //-------------------------------------------------------------------------------------------------- |
74 | | |
75 | | PTCreateType::PTCreateType(MemoryContext *memctx, |
76 | | YBLocation::SharedPtr loc, |
77 | | const PTQualifiedName::SharedPtr& name, |
78 | | const PTTypeFieldListNode::SharedPtr& fields, |
79 | | bool create_if_not_exists) |
80 | | : TreeNode(memctx, loc), |
81 | | name_(name), |
82 | | fields_(fields), |
83 | 84 | create_if_not_exists_(create_if_not_exists) { |
84 | 84 | } |
85 | | |
86 | 57 | PTCreateType::~PTCreateType() { |
87 | 57 | } |
88 | | |
89 | 84 | CHECKED_STATUS PTCreateType::Analyze(SemContext *sem_context) { |
90 | 84 | SemState sem_state(sem_context); |
91 | | |
92 | | // Processing type name. |
93 | 84 | RETURN_NOT_OK(name_->AnalyzeName(sem_context, ObjectType::TYPE)); |
94 | | |
95 | 84 | if (FLAGS_use_cassandra_authentication) { |
96 | 36 | if (!sem_context->CheckHasAllKeyspacesPermission(loc(), |
97 | 20 | PermissionType::CREATE_PERMISSION).ok()) { |
98 | 20 | RETURN_NOT_OK(sem_context->CheckHasKeyspacePermission(loc(), |
99 | 20 | PermissionType::CREATE_PERMISSION, yb_type_name().namespace_name())); |
100 | 20 | } |
101 | 36 | } |
102 | | |
103 | | // Save context state, and set "this" as current column in the context. |
104 | 80 | SymbolEntry cached_entry = *sem_context->current_processing_id(); |
105 | 80 | sem_context->set_current_create_type_stmt(this); |
106 | | |
107 | | // Processing statement elements (type fields) |
108 | 80 | sem_context->set_current_create_type_stmt(this); |
109 | 80 | RETURN_NOT_OK(fields_->Analyze(sem_context)); |
110 | | |
111 | 64 | if (VLOG_IS_ON(3)) { |
112 | 0 | PrintSemanticAnalysisResult(sem_context); |
113 | 0 | } |
114 | | |
115 | | // Restore the context value as we are done with this colummn. |
116 | 64 | sem_context->set_current_processing_id(cached_entry); |
117 | | |
118 | 64 | return Status::OK(); |
119 | 80 | } |
120 | | |
121 | 0 | void PTCreateType::PrintSemanticAnalysisResult(SemContext *sem_context) { |
122 | 0 | MCString sem_output("\tType ", sem_context->PTempMem()); |
123 | 0 | sem_output += yb_type_name().ToString().c_str(); |
124 | 0 | sem_output += "("; |
125 | |
|
126 | 0 | bool is_first = true; |
127 | 0 | for (auto field : fields_->node_list()) { |
128 | 0 | if (is_first) { |
129 | 0 | is_first = false; |
130 | 0 | } else { |
131 | 0 | sem_output += ", "; |
132 | 0 | } |
133 | 0 | sem_output += field->yb_name(); |
134 | 0 | sem_output += " <Type = "; |
135 | 0 | sem_output += field->ql_type()->ToString().c_str(); |
136 | 0 | sem_output += ">"; |
137 | 0 | } |
138 | |
|
139 | 0 | sem_output += ")"; |
140 | 0 | VLOG(3) << "SEMANTIC ANALYSIS RESULT (" << *loc_ << "):\n" << sem_output; |
141 | 0 | } |
142 | | |
143 | | } // namespace ql |
144 | | } // namespace yb |