Node.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * https://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include <cmath>
  19. #include <unordered_set>
  20. #include "Node.hh"
  21. namespace avro {
  22. using std::string;
  23. Node::~Node() = default;
  24. struct Name::Aliases {
  25. std::vector<std::string> raw;
  26. std::unordered_set<std::string> fullyQualified;
  27. };
  28. Name::Name() = default;
  29. Name::Name(const std::string &name) {
  30. fullname(name);
  31. }
  32. Name::Name(std::string simpleName, std::string ns) : ns_(std::move(ns)), simpleName_(std::move(simpleName)) {
  33. check();
  34. }
  35. Name::Name(const Name &other) {
  36. *this = other;
  37. }
  38. Name &Name::operator=(const Name &other) {
  39. if (this != &other) {
  40. ns_ = other.ns_;
  41. simpleName_ = other.simpleName_;
  42. if (other.aliases_) {
  43. aliases_ = std::make_unique<Aliases>(*other.aliases_);
  44. }
  45. }
  46. return *this;
  47. }
  48. Name::Name(Name &&other) = default;
  49. Name &Name::operator=(Name &&other) = default;
  50. Name::~Name() = default;
  51. string Name::fullname() const {
  52. return ns_.empty() ? simpleName_ : ns_ + "." + simpleName_;
  53. }
  54. void Name::fullname(const string &name) {
  55. string::size_type n = name.find_last_of('.');
  56. if (n == string::npos) {
  57. simpleName_ = name;
  58. ns_.clear();
  59. } else {
  60. ns_ = name.substr(0, n);
  61. simpleName_ = name.substr(n + 1);
  62. }
  63. check();
  64. }
  65. const std::vector<std::string> &Name::aliases() const {
  66. static const std::vector<std::string> emptyAliases;
  67. return aliases_ ? aliases_->raw : emptyAliases;
  68. }
  69. void Name::addAlias(const std::string &alias) {
  70. if (!aliases_) {
  71. aliases_ = std::make_unique<Aliases>();
  72. }
  73. aliases_->raw.push_back(alias);
  74. if (!ns_.empty() && alias.find_last_of('.') == string::npos) {
  75. aliases_->fullyQualified.emplace(ns_ + "." + alias);
  76. } else {
  77. aliases_->fullyQualified.insert(alias);
  78. }
  79. }
  80. bool Name::operator<(const Name &n) const {
  81. return (ns_ < n.ns_) || (!(n.ns_ < ns_) && (simpleName_ < n.simpleName_));
  82. }
  83. static bool invalidChar1(char c) {
  84. return !isalnum(c) && c != '_' && c != '.' && c != '$';
  85. }
  86. static bool invalidChar2(char c) {
  87. return !isalnum(c) && c != '_';
  88. }
  89. void Name::check() const {
  90. if (!ns_.empty() && (ns_[0] == '.' || ns_[ns_.size() - 1] == '.' || std::find_if(ns_.begin(), ns_.end(), invalidChar1) != ns_.end())) {
  91. throw Exception("Invalid namespace: " + ns_);
  92. }
  93. if (simpleName_.empty()
  94. || std::find_if(simpleName_.begin(), simpleName_.end(), invalidChar2) != simpleName_.end()) {
  95. throw Exception("Invalid name: " + simpleName_);
  96. }
  97. }
  98. bool Name::operator==(const Name &n) const {
  99. return ns_ == n.ns_ && simpleName_ == n.simpleName_;
  100. }
  101. bool Name::equalOrAliasedBy(const Name &n) const {
  102. return *this == n || (n.aliases_ && n.aliases_->fullyQualified.find(fullname()) != n.aliases_->fullyQualified.end());
  103. }
  104. void Name::clear() {
  105. ns_.clear();
  106. simpleName_.clear();
  107. aliases_.reset();
  108. }
  109. void Node::setLogicalType(LogicalType logicalType) {
  110. checkLock();
  111. // Check that the logical type is applicable to the node type.
  112. switch (logicalType.type()) {
  113. case LogicalType::NONE: break;
  114. case LogicalType::DECIMAL: {
  115. if (type_ != AVRO_BYTES && type_ != AVRO_FIXED) {
  116. throw Exception("DECIMAL logical type can annotate "
  117. "only BYTES or FIXED type");
  118. }
  119. if (type_ == AVRO_FIXED) {
  120. // Max precision that can be supported by the current size of
  121. // the FIXED type.
  122. auto maxPrecision = static_cast<int32_t>(floor(log10(2.0) * (8.0 * static_cast<double>(fixedSize()) - 1)));
  123. if (logicalType.precision() > maxPrecision) {
  124. throw Exception(
  125. "DECIMAL precision {} is too large for the "
  126. "FIXED type of size {}, precision cannot be "
  127. "larger than {}",
  128. logicalType.precision(), fixedSize(), maxPrecision);
  129. }
  130. }
  131. if (logicalType.scale() > logicalType.precision()) {
  132. throw Exception("DECIMAL scale cannot exceed precision");
  133. }
  134. break;
  135. }
  136. case LogicalType::DATE:
  137. if (type_ != AVRO_INT) {
  138. throw Exception("DATE logical type can only annotate INT type");
  139. }
  140. break;
  141. case LogicalType::TIME_MILLIS:
  142. if (type_ != AVRO_INT) {
  143. throw Exception("TIME-MILLIS logical type can only annotate "
  144. "INT type");
  145. }
  146. break;
  147. case LogicalType::TIME_MICROS:
  148. if (type_ != AVRO_LONG) {
  149. throw Exception("TIME-MICROS logical type can only annotate "
  150. "LONG type");
  151. }
  152. break;
  153. case LogicalType::TIMESTAMP_MILLIS:
  154. if (type_ != AVRO_LONG) {
  155. throw Exception("TIMESTAMP-MILLIS logical type can only annotate "
  156. "LONG type");
  157. }
  158. break;
  159. case LogicalType::TIMESTAMP_MICROS:
  160. if (type_ != AVRO_LONG) {
  161. throw Exception("TIMESTAMP-MICROS logical type can only annotate "
  162. "LONG type");
  163. }
  164. break;
  165. case LogicalType::DURATION:
  166. if (type_ != AVRO_FIXED || fixedSize() != 12) {
  167. throw Exception("DURATION logical type can only annotate "
  168. "FIXED type of size 12");
  169. }
  170. break;
  171. case LogicalType::UUID:
  172. if (type_ != AVRO_STRING) {
  173. throw Exception("UUID logical type can only annotate "
  174. "STRING type");
  175. }
  176. break;
  177. }
  178. logicalType_ = logicalType;
  179. }
  180. } // namespace avro