YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/ptree/pt_keyspace_property.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include <set>
15
#include "yb/client/schema.h"
16
#include "yb/yql/cql/ql/ptree/pt_keyspace_property.h"
17
#include "yb/yql/cql/ql/ptree/sem_context.h"
18
#include "yb/yql/cql/ql/ptree/yb_location.h"
19
20
#include "yb/util/logging.h"
21
#include "yb/util/string_case.h"
22
23
namespace yb {
24
namespace ql {
25
26
using strings::Substitute;
27
using client::YBColumnSchema;
28
29
PTKeyspaceProperty::PTKeyspaceProperty(MemoryContext *memctx,
30
                                       YBLocation::SharedPtr loc,
31
                                       const MCSharedPtr<MCString>& lhs,
32
                                       const PTExprPtr& rhs)
33
    : PTProperty(memctx, loc, lhs, rhs),
34
374
      property_type_(KeyspacePropertyType::kKVProperty) {
35
374
}
36
37
PTKeyspaceProperty::PTKeyspaceProperty(MemoryContext *memctx,
38
                                       YBLocation::SharedPtr loc)
39
172
    : PTProperty(memctx, loc) {
40
172
}
41
42
288
PTKeyspaceProperty::~PTKeyspaceProperty() {
43
288
}
44
45
0
CHECKED_STATUS PTKeyspaceProperty::Analyze(SemContext *sem_context) {
46
0
  return Status::OK();
47
0
}
48
49
0
void PTKeyspaceProperty::PrintSemanticAnalysisResult(SemContext *sem_context) {
50
0
  VLOG(3) << "SEMANTIC ANALYSIS RESULT (" << *loc_ << "):\n" << "Not yet avail";
51
0
}
52
53
171
CHECKED_STATUS PTKeyspacePropertyListNode::Analyze(SemContext *sem_context) {
54
171
  bool has_replication = false;
55
56
  // If the statement has properties, 'replication' property must be present. Check this before
57
  // checking anything else.
58
171
  for (PTKeyspaceProperty::SharedPtr tnode : node_list()) {
59
171
    const auto property_name = string(tnode->lhs()->c_str());
60
171
    if (property_name == "replication") {
61
163
      has_replication = true;
62
163
      break;
63
163
    }
64
171
  }
65
171
  if (!has_replication) {
66
8
    return sem_context->Error(this, "Missing mandatory replication strategy class",
67
8
                              ErrorCode::INVALID_ARGUMENTS);
68
8
  }
69
70
193
  
for (PTKeyspaceProperty::SharedPtr tnode : node_list())163
{
71
193
    const auto property_name = string(tnode->lhs()->c_str());
72
193
    if (property_name == "durable_writes") {
73
30
      bool val = false;
74
30
      RETURN_SEM_CONTEXT_ERROR_NOT_OK(PTProperty::GetBoolValueFromExpr(tnode->rhs(),
75
30
                                                                       "durable_writes", &val));
76
163
    } else if (property_name == "replication") {
77
163
      if (tnode->property_type() != KeyspacePropertyType::kPropertyMap) {
78
0
        return sem_context->Error(this,
79
0
                                  "Invalid value for property 'replication'. It should be a map",
80
0
                                  ErrorCode::INVALID_ARGUMENTS);
81
0
      }
82
163
      RETURN_SEM_CONTEXT_ERROR_NOT_OK(tnode->Analyze(sem_context));
83
163
    } else {
84
0
      return sem_context->Error(this,
85
0
                                Substitute("Invalid property $0", property_name).c_str(),
86
0
                                ErrorCode::INVALID_ARGUMENTS);
87
0
    }
88
193
  }
89
128
  return Status::OK();
90
163
}
91
92
PTKeyspacePropertyMap::PTKeyspacePropertyMap(MemoryContext *memctx,
93
                                             YBLocation::SharedPtr loc)
94
172
    : PTKeyspaceProperty(memctx, loc) {
95
172
  property_type_ = KeyspacePropertyType::kPropertyMap;
96
172
  map_elements_ = TreeListNode<PTKeyspaceProperty>::MakeShared(memctx, loc);
97
172
}
98
99
86
PTKeyspacePropertyMap::~PTKeyspacePropertyMap() {
100
86
}
101
102
194
CHECKED_STATUS PTKeyspacePropertyMap::Analyze(SemContext *sem_context) {
103
194
  DCHECK_ONLY_NOTNULL(lhs_.get());
104
  // Verify we have a valid property name in the lhs.
105
194
  const auto property_name = string(lhs_->c_str());
106
194
  DCHECK_EQ(property_name, "replication");
107
  // Find 'class' subproperty.
108
194
  std::unique_ptr<string> class_name = nullptr;
109
194
  std::unique_ptr<int64_t> replication_factor = nullptr;
110
194
  vector<PTKeyspaceProperty::SharedPtr> other_subproperties;
111
112
378
  for (const auto &map_element : map_elements_->node_list()) {
113
378
    string subproperty_name;
114
378
    ToLowerCase(map_element->lhs()->c_str(), &subproperty_name);
115
116
378
    if (subproperty_name == "class") {
117
194
      class_name.reset(new string());
118
194
      RETURN_NOT_OK(GetStringValueFromExpr(map_element->rhs(), false, "class", class_name.get()));
119
194
    } else 
if (184
subproperty_name == "replication_factor"184
) {
120
164
      replication_factor.reset(new int64_t);
121
164
      RETURN_NOT_OK(GetIntValueFromExpr(map_element->rhs(), "replication_factor",
122
164
                                        replication_factor.get()));
123
164
    } else {
124
20
      other_subproperties.push_back(map_element);
125
20
    }
126
378
  }
127
128
162
  if (class_name == nullptr) {
129
0
    return sem_context->Error(this, "Missing mandatory replication strategy class",
130
0
                              ErrorCode::INVALID_ARGUMENTS);
131
0
  }
132
133
162
  if (*class_name != "SimpleStrategy" && 
*class_name != "NetworkTopologyStrategy"28
) {
134
10
    return sem_context->Error(this,
135
10
        Substitute("Unable to find replication strategy class 'org.apache.cassandra.locator.$0",
136
10
                   *class_name).c_str(),
137
10
        ErrorCode::INVALID_ARGUMENTS);
138
10
  }
139
152
  if (*class_name == "NetworkTopologyStrategy") {
140
18
    if (replication_factor != nullptr) {
141
8
      return sem_context->Error(this,
142
8
          "replication_factor is an option for SimpleStrategy, not NetworkTopologyStrategy",
143
8
          ErrorCode::INVALID_ARGUMENTS);
144
8
    }
145
146
    // Verify that all subproperties have integer values.
147
10
    int64_t val = 0;
148
12
    for (const auto& subproperty : other_subproperties) {
149
12
      RETURN_NOT_OK(GetIntValueFromExpr(subproperty->rhs(), subproperty->lhs()->c_str(), &val));
150
12
    }
151
134
  } else {
152
134
    if (!other_subproperties.empty()) {
153
4
      return sem_context->Error(this,
154
4
                                Substitute(
155
4
                                    "Unrecognized strategy option $0 passed to SimpleStrategy",
156
4
                                    other_subproperties.front()->lhs()->c_str()).c_str(),
157
4
                                ErrorCode::INVALID_ARGUMENTS);
158
159
4
    }
160
130
    if (replication_factor == nullptr) {
161
4
      return sem_context->Error(this,
162
4
                                "SimpleStrategy requires a replication_factor strategy option",
163
4
                                ErrorCode::INVALID_ARGUMENTS);
164
4
    }
165
130
  }
166
167
132
  return Status::OK();
168
152
}
169
170
0
void PTKeyspacePropertyMap::PrintSemanticAnalysisResult(SemContext *sem_context) {
171
0
  VLOG(3) << "SEMANTIC ANALYSIS RESULT (" << *loc_ << "):\n" << "Not yet avail";
172
0
}
173
174
} // namespace ql
175
} // namespace yb