aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2022-08-06 22:56:13 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2022-08-06 22:56:13 +0300
commit70baf158abf286f22e94c698595e2be355066d11 (patch)
tree416fc729f74cdf4d85fea6c8dabb3e853c228be6
parentf35a9d317f1d3dc209a73a44829632640f5db6fa (diff)
downloadydb-70baf158abf286f22e94c698595e2be355066d11.tar.gz
Update contrib/libs/apache/avro to 1.11.1
-rw-r--r--contrib/libs/apache/avro/CMakeLists.linux.txt2
-rw-r--r--contrib/libs/apache/avro/api/CustomFields.hh55
-rw-r--r--contrib/libs/apache/avro/api/Node.hh7
-rw-r--r--contrib/libs/apache/avro/api/NodeImpl.hh100
-rw-r--r--contrib/libs/apache/avro/api/Schema.hh4
-rw-r--r--contrib/libs/apache/avro/impl/Compiler.cc38
-rw-r--r--contrib/libs/apache/avro/impl/CustomFields.cc59
-rw-r--r--contrib/libs/apache/avro/impl/DataFile.cc6
-rw-r--r--contrib/libs/apache/avro/impl/NodeImpl.cc17
-rw-r--r--contrib/libs/apache/avro/impl/Schema.cc8
10 files changed, 260 insertions, 36 deletions
diff --git a/contrib/libs/apache/avro/CMakeLists.linux.txt b/contrib/libs/apache/avro/CMakeLists.linux.txt
index c8e8d9066fa..8d242601068 100644
--- a/contrib/libs/apache/avro/CMakeLists.linux.txt
+++ b/contrib/libs/apache/avro/CMakeLists.linux.txt
@@ -10,6 +10,7 @@
add_library(libs-apache-avro)
target_compile_options(libs-apache-avro PRIVATE
-DAVRO_SOURCE
+ -DAVRO_VERSION="1.11.1"
-DBOOST_ALL_NO_LIB
-DBOOST_ATOMIC_DYN_LINK
-DBOOST_FILESYSTEM_DYN_LINK
@@ -34,6 +35,7 @@ target_sources(libs-apache-avro PRIVATE
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/BinaryDecoder.cc
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/BinaryEncoder.cc
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/Compiler.cc
+ ${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/CustomFields.cc
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/DataFile.cc
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/FileStream.cc
${CMAKE_SOURCE_DIR}/contrib/libs/apache/avro/impl/Generic.cc
diff --git a/contrib/libs/apache/avro/api/CustomFields.hh b/contrib/libs/apache/avro/api/CustomFields.hh
new file mode 100644
index 00000000000..01468ff4a0b
--- /dev/null
+++ b/contrib/libs/apache/avro/api/CustomFields.hh
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef avro_CustomFields_hh__
+#define avro_CustomFields_hh__
+
+#include <iostream>
+
+#include "../impl/json/JsonDom.hh"
+
+namespace avro {
+
+// CustomFields class stores avro custom attributes.
+// Each field is represented by a unique name and value.
+// User is supposed to create CustomFields object and then add it to Schema.
+class AVRO_DECL CustomFields {
+ public:
+ // Retrieves the custom field json entity for that fieldName, returns an
+ // null Entity if the field doesn't exist.
+ json::Entity getField(const std::string &fieldName) const;
+
+ // Adds a custom field. If the field already exists, throw an exception.
+ void addField(const std::string &fieldName, const json::Entity &fieldValue);
+ void addField(const std::string &fieldName, const std::string &fieldValue);
+
+ // Provides a way to iterate over the custom fields or check field size.
+ const std::map<std::string, json::Entity> &fields() const {
+ return fields_;
+ }
+
+ // Prints the json string for the specific field.
+ void printJson(std::ostream& os, const std::string &fieldName) const;
+
+ private:
+ std::map<std::string, json::Entity> fields_;
+};
+
+} // namespace avro
+
+#endif
diff --git a/contrib/libs/apache/avro/api/Node.hh b/contrib/libs/apache/avro/api/Node.hh
index 3c9389da50a..c9af126f1ac 100644
--- a/contrib/libs/apache/avro/api/Node.hh
+++ b/contrib/libs/apache/avro/api/Node.hh
@@ -26,6 +26,7 @@
#include <memory>
#include <utility>
+#include "CustomFields.hh"
#include "Exception.hh"
#include "LogicalType.hh"
#include "SchemaResolution.hh"
@@ -153,6 +154,11 @@ public:
}
virtual size_t fixedSize() const = 0;
+ void addCustomAttributesForField(const CustomFields& customAttributes) {
+ checkLock();
+ doAddCustomAttribute(customAttributes);
+ }
+
virtual bool isValid() const = 0;
virtual SchemaResolution resolve(const Node &reader) const = 0;
@@ -185,6 +191,7 @@ protected:
virtual void doAddLeaf(const NodePtr &newLeaf) = 0;
virtual void doAddName(const std::string &name) = 0;
virtual void doSetFixedSize(size_t size) = 0;
+ virtual void doAddCustomAttribute(const CustomFields& customFields) = 0;
private:
const Type type_;
diff --git a/contrib/libs/apache/avro/api/NodeImpl.hh b/contrib/libs/apache/avro/api/NodeImpl.hh
index c74d39e6b8b..62e62eb6536 100644
--- a/contrib/libs/apache/avro/api/NodeImpl.hh
+++ b/contrib/libs/apache/avro/api/NodeImpl.hh
@@ -32,6 +32,7 @@
#include "Node.hh"
#include "NodeConcepts.hh"
+#include "CustomFields.hh"
namespace avro {
@@ -42,6 +43,7 @@ template<
class NameConcept,
class LeavesConcept,
class LeafNamesConcept,
+ class MultiAttributesConcept,
class SizeConcept>
class NodeImpl : public Node {
@@ -51,17 +53,20 @@ protected:
docAttribute_(),
leafAttributes_(),
leafNameAttributes_(),
+ customAttributes_(),
sizeAttribute_() {}
NodeImpl(Type type,
const NameConcept &name,
const LeavesConcept &leaves,
const LeafNamesConcept &leafNames,
+ const MultiAttributesConcept &customAttributes,
const SizeConcept &size) : Node(type),
nameAttribute_(name),
docAttribute_(),
leafAttributes_(leaves),
leafNameAttributes_(leafNames),
+ customAttributes_(customAttributes),
sizeAttribute_(size) {}
// Ctor with "doc"
@@ -70,11 +75,13 @@ protected:
const concepts::SingleAttribute<std::string> &doc,
const LeavesConcept &leaves,
const LeafNamesConcept &leafNames,
+ const MultiAttributesConcept &customAttributes,
const SizeConcept &size) : Node(type),
nameAttribute_(name),
docAttribute_(doc),
leafAttributes_(leaves),
leafNameAttributes_(leafNames),
+ customAttributes_(customAttributes),
sizeAttribute_(size) {}
void swap(NodeImpl &impl) {
@@ -83,6 +90,7 @@ protected:
std::swap(leafAttributes_, impl.leafAttributes_);
std::swap(leafNameAttributes_, impl.leafNameAttributes_);
std::swap(sizeAttribute_, impl.sizeAttribute_);
+ std::swap(customAttributes_, impl.customAttributes_);
std::swap(nameIndex_, impl.nameIndex_);
}
@@ -152,6 +160,10 @@ protected:
void setLeafToSymbolic(size_t index, const NodePtr &node) override;
+ void doAddCustomAttribute(const CustomFields &customfields) override {
+ customAttributes_.add(customfields);
+ }
+
SchemaResolution furtherResolution(const Node &reader) const {
SchemaResolution match = RESOLVE_NO_MATCH;
@@ -195,6 +207,7 @@ protected:
LeavesConcept leafAttributes_;
LeafNamesConcept leafNameAttributes_;
+ MultiAttributesConcept customAttributes_;
SizeConcept sizeAttribute_;
concepts::NameIndexConcept<LeafNamesConcept> nameIndex_;
};
@@ -210,19 +223,21 @@ using MultiLeaves = concepts::MultiAttribute<NodePtr>;
using NoLeafNames = concepts::NoAttribute<std::string>;
using LeafNames = concepts::MultiAttribute<std::string>;
+using MultiAttributes = concepts::MultiAttribute<CustomFields>;
+using NoAttributes = concepts::NoAttribute<CustomFields>;
using NoSize = concepts::NoAttribute<int>;
using HasSize = concepts::SingleAttribute<int>;
-using NodeImplPrimitive = NodeImpl<NoName, NoLeaves, NoLeafNames, NoSize>;
-using NodeImplSymbolic = NodeImpl<HasName, NoLeaves, NoLeafNames, NoSize>;
+using NodeImplPrimitive = NodeImpl<NoName, NoLeaves, NoLeafNames, MultiAttributes, NoSize>;
+using NodeImplSymbolic = NodeImpl<HasName, NoLeaves, NoLeafNames, NoAttributes, NoSize>;
-using NodeImplRecord = NodeImpl<HasName, MultiLeaves, LeafNames, NoSize>;
-using NodeImplEnum = NodeImpl<HasName, NoLeaves, LeafNames, NoSize>;
-using NodeImplArray = NodeImpl<NoName, SingleLeaf, NoLeafNames, NoSize>;
-using NodeImplMap = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoSize>;
-using NodeImplUnion = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoSize>;
-using NodeImplFixed = NodeImpl<HasName, NoLeaves, NoLeafNames, HasSize>;
+using NodeImplRecord = NodeImpl<HasName, MultiLeaves, LeafNames, MultiAttributes, NoSize>;
+using NodeImplEnum = NodeImpl<HasName, NoLeaves, LeafNames, NoAttributes, NoSize>;
+using NodeImplArray = NodeImpl<NoName, SingleLeaf, NoLeafNames, NoAttributes, NoSize>;
+using NodeImplMap = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoAttributes, NoSize>;
+using NodeImplUnion = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoAttributes, NoSize>;
+using NodeImplFixed = NodeImpl<HasName, NoLeaves, NoLeafNames, NoAttributes, HasSize>;
class AVRO_DECL NodePrimitive : public NodeImplPrimitive {
public:
@@ -245,9 +260,9 @@ class AVRO_DECL NodeSymbolic : public NodeImplSymbolic {
public:
NodeSymbolic() : NodeImplSymbolic(AVRO_SYMBOLIC) {}
- explicit NodeSymbolic(const HasName &name) : NodeImplSymbolic(AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoSize()) {}
+ explicit NodeSymbolic(const HasName &name) : NodeImplSymbolic(AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoAttributes(), NoSize()) {}
- NodeSymbolic(const HasName &name, const NodePtr &n) : NodeImplSymbolic(AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoSize()), actualNode_(n) {}
+ NodeSymbolic(const HasName &name, const NodePtr &n) : NodeImplSymbolic(AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoAttributes(), NoSize()), actualNode_(n) {}
SchemaResolution resolve(const Node &reader) const override;
void printJson(std::ostream &os, size_t depth) const override;
@@ -289,15 +304,27 @@ public:
NodeRecord(const HasName &name, const HasDoc &doc, const MultiLeaves &fields,
const LeafNames &fieldsNames,
- std::vector<GenericDatum> dv) : NodeImplRecord(AVRO_RECORD, name, doc, fields, fieldsNames, NoSize()),
+ std::vector<GenericDatum> dv) : NodeImplRecord(AVRO_RECORD, name, doc, fields, fieldsNames, MultiAttributes(), NoSize()),
defaultValues(std::move(dv)) {
- for (size_t i = 0; i < leafNameAttributes_.size(); ++i) {
- if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
- throw Exception(boost::format(
- "Cannot add duplicate field: %1%")
- % leafNameAttributes_.get(i));
- }
- }
+ leafNameCheck();
+ }
+
+ NodeRecord(const HasName &name, const MultiLeaves &fields,
+ const LeafNames &fieldsNames,
+ const std::vector<GenericDatum>& dv,
+ const MultiAttributes &customAttributes) :
+ NodeImplRecord(AVRO_RECORD, name, fields, fieldsNames, customAttributes, NoSize()),
+ defaultValues(dv) {
+ leafNameCheck();
+ }
+
+ NodeRecord(const HasName &name, const HasDoc &doc, const MultiLeaves &fields,
+ const LeafNames &fieldsNames,
+ const std::vector<GenericDatum>& dv,
+ const MultiAttributes &customAttributes) :
+ NodeImplRecord(AVRO_RECORD, name, doc, fields, fieldsNames, customAttributes, NoSize()),
+ defaultValues(dv) {
+ leafNameCheck();
}
void swap(NodeRecord &r) {
@@ -310,7 +337,10 @@ public:
void printJson(std::ostream &os, size_t depth) const override;
bool isValid() const override {
- return ((nameAttribute_.size() == 1) && (leafAttributes_.size() == leafNameAttributes_.size()));
+ return ((nameAttribute_.size() == 1) &&
+ (leafAttributes_.size() == leafNameAttributes_.size()) &&
+ (customAttributes_.size() == 0 ||
+ customAttributes_.size() == leafAttributes_.size()));
}
const GenericDatum &defaultValueAt(size_t index) override {
@@ -318,13 +348,25 @@ public:
}
void printDefaultToJson(const GenericDatum &g, std::ostream &os, size_t depth) const override;
+
+private:
+ // check if leaf name is valid Name and is not duplicate
+ void leafNameCheck() {
+ for (size_t i = 0; i < leafNameAttributes_.size(); ++i) {
+ if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
+ throw Exception(boost::format(
+ "Cannot add duplicate field: %1%")
+ % leafNameAttributes_.get(i));
+ }
+ }
+ }
};
class AVRO_DECL NodeEnum : public NodeImplEnum {
public:
NodeEnum() : NodeImplEnum(AVRO_ENUM) {}
- NodeEnum(const HasName &name, const LeafNames &symbols) : NodeImplEnum(AVRO_ENUM, name, NoLeaves(), symbols, NoSize()) {
+ NodeEnum(const HasName &name, const LeafNames &symbols) : NodeImplEnum(AVRO_ENUM, name, NoLeaves(), symbols, NoAttributes(), NoSize()) {
for (size_t i = 0; i < leafNameAttributes_.size(); ++i) {
if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
throw Exception(boost::format("Cannot add duplicate enum: %1%") % leafNameAttributes_.get(i));
@@ -348,7 +390,7 @@ class AVRO_DECL NodeArray : public NodeImplArray {
public:
NodeArray() : NodeImplArray(AVRO_ARRAY) {}
- explicit NodeArray(const SingleLeaf &items) : NodeImplArray(AVRO_ARRAY, NoName(), items, NoLeafNames(), NoSize()) {}
+ explicit NodeArray(const SingleLeaf &items) : NodeImplArray(AVRO_ARRAY, NoName(), items, NoLeafNames(), NoAttributes(), NoSize()) {}
SchemaResolution resolve(const Node &reader) const override;
@@ -365,7 +407,7 @@ class AVRO_DECL NodeMap : public NodeImplMap {
public:
NodeMap();
- explicit NodeMap(const SingleLeaf &values) : NodeImplMap(AVRO_MAP, NoName(), MultiLeaves(values), NoLeafNames(), NoSize()) {
+ explicit NodeMap(const SingleLeaf &values) : NodeImplMap(AVRO_MAP, NoName(), MultiLeaves(values), NoLeafNames(), NoAttributes(), NoSize()) {
// need to add the key for the map too
NodePtr key(new NodePrimitive(AVRO_STRING));
doAddLeaf(key);
@@ -389,7 +431,7 @@ class AVRO_DECL NodeUnion : public NodeImplUnion {
public:
NodeUnion() : NodeImplUnion(AVRO_UNION) {}
- explicit NodeUnion(const MultiLeaves &types) : NodeImplUnion(AVRO_UNION, NoName(), types, NoLeafNames(), NoSize()) {}
+ explicit NodeUnion(const MultiLeaves &types) : NodeImplUnion(AVRO_UNION, NoName(), types, NoLeafNames(), NoAttributes(), NoSize()) {}
SchemaResolution resolve(const Node &reader) const override;
@@ -458,7 +500,7 @@ class AVRO_DECL NodeFixed : public NodeImplFixed {
public:
NodeFixed() : NodeImplFixed(AVRO_FIXED) {}
- NodeFixed(const HasName &name, const HasSize &size) : NodeImplFixed(AVRO_FIXED, name, NoLeaves(), NoLeafNames(), size) {}
+ NodeFixed(const HasName &name, const HasSize &size) : NodeImplFixed(AVRO_FIXED, name, NoLeaves(), NoLeafNames(), NoAttributes(), size) {}
SchemaResolution resolve(const Node &reader) const override;
@@ -472,9 +514,9 @@ public:
void printDefaultToJson(const GenericDatum &g, std::ostream &os, size_t depth) const override;
};
-template<class A, class B, class C, class D>
+template<class A, class B, class C, class D, class E>
inline void
-NodeImpl<A, B, C, D>::setLeafToSymbolic(size_t index, const NodePtr &node) {
+NodeImpl<A, B, C, D, E>::setLeafToSymbolic(size_t index, const NodePtr &node) {
if (!B::hasAttribute) {
throw Exception("Cannot change leaf node for nonexistent leaf");
}
@@ -490,15 +532,15 @@ NodeImpl<A, B, C, D>::setLeafToSymbolic(size_t index, const NodePtr &node) {
replaceNode = symbol;
}
-template<class A, class B, class C, class D>
+template<class A, class B, class C, class D, class E>
inline void
-NodeImpl<A, B, C, D>::printBasicInfo(std::ostream &os) const {
+NodeImpl<A, B, C, D, E>::printBasicInfo(std::ostream &os) const {
os << type();
if (hasName()) {
os << ' ' << nameAttribute_.get();
}
- if (D::hasAttribute) {
+ if (E::hasAttribute) {
os << " " << sizeAttribute_.get();
}
os << '\n';
diff --git a/contrib/libs/apache/avro/api/Schema.hh b/contrib/libs/apache/avro/api/Schema.hh
index abd646f9fc7..fa504815ad2 100644
--- a/contrib/libs/apache/avro/api/Schema.hh
+++ b/contrib/libs/apache/avro/api/Schema.hh
@@ -21,6 +21,7 @@
#include "Config.hh"
#include "NodeImpl.hh"
+#include "CustomFields.hh"
#include <string>
/// \file
@@ -100,6 +101,9 @@ class AVRO_DECL RecordSchema : public Schema {
public:
explicit RecordSchema(const std::string &name);
void addField(const std::string &name, const Schema &fieldSchema);
+ // Add a field with custom attributes
+ void addField(const std::string &name, const Schema &fieldSchema,
+ const CustomFields &customFields);
std::string getDoc() const;
void setDoc(const std::string &);
diff --git a/contrib/libs/apache/avro/impl/Compiler.cc b/contrib/libs/apache/avro/impl/Compiler.cc
index d76546f317d..014229e11ac 100644
--- a/contrib/libs/apache/avro/impl/Compiler.cc
+++ b/contrib/libs/apache/avro/impl/Compiler.cc
@@ -17,9 +17,12 @@
*/
#include <boost/algorithm/string/replace.hpp>
#include <sstream>
+#include <unordered_set>
#include <utility>
#include "Compiler.hh"
+#include "CustomFields.hh"
+#include "NodeConcepts.hh"
#include "Schema.hh"
#include "Stream.hh"
#include "Types.hh"
@@ -146,7 +149,8 @@ struct Field {
const string name;
const NodePtr schema;
const GenericDatum defaultValue;
- Field(string n, NodePtr v, GenericDatum dv) : name(std::move(n)), schema(std::move(v)), defaultValue(std::move(dv)) {}
+ const CustomFields customFields;
+ Field(string n, NodePtr v, GenericDatum dv, const CustomFields& cf) : name(std::move(n)), schema(std::move(v)), defaultValue(std::move(dv)), customFields(std::move(cf)) {}
};
static void assertType(const Entity &e, EntityType et) {
@@ -256,6 +260,26 @@ static GenericDatum makeGenericDatum(NodePtr n,
}
}
+static const std::unordered_set<std::string>& getKnownFields() {
+ // return known fields
+ static const std::unordered_set<std::string> kKnownFields =
+ {"name", "type", "default", "doc", "size", "logicalType",
+ "values", "precision", "scale", "namespace"};
+ return kKnownFields;
+}
+
+static void getCustomAttributes(const Object& m, CustomFields &customAttributes)
+{
+ // Don't add known fields on primitive type and fixed type into custom
+ // fields.
+ const std::unordered_set<std::string>& kKnownFields = getKnownFields();
+ for (const auto &entry : m) {
+ if (kKnownFields.find(entry.first) == kKnownFields.end()) {
+ customAttributes.addField(entry.first, entry.second);
+ }
+ }
+}
+
static Field makeField(const Entity &e, SymbolTable &st, const string &ns) {
const Object &m = e.objectValue();
const string &n = getStringField(e, m, "name");
@@ -266,7 +290,11 @@ static Field makeField(const Entity &e, SymbolTable &st, const string &ns) {
node->setDoc(getDocField(e, m));
}
GenericDatum d = (it2 == m.end()) ? GenericDatum() : makeGenericDatum(node, it2->second, st);
- return Field(n, node, d);
+ // Get custom attributes
+ CustomFields customAttributes;
+ getCustomAttributes(m, customAttributes);
+
+ return Field(n, node, d, customAttributes);
}
// Extended makeRecordNode (with doc).
@@ -276,6 +304,7 @@ static NodePtr makeRecordNode(const Entity &e, const Name &name,
const Array &v = getArrayField(e, m, "fields");
concepts::MultiAttribute<string> fieldNames;
concepts::MultiAttribute<NodePtr> fieldValues;
+ concepts::MultiAttribute<CustomFields> customAttributes;
vector<GenericDatum> defaultValues;
for (const auto &it : v) {
@@ -283,14 +312,15 @@ static NodePtr makeRecordNode(const Entity &e, const Name &name,
fieldNames.add(f.name);
fieldValues.add(f.schema);
defaultValues.push_back(f.defaultValue);
+ customAttributes.add(f.customFields);
}
NodeRecord *node;
if (doc == nullptr) {
node = new NodeRecord(asSingleAttribute(name), fieldValues, fieldNames,
- defaultValues);
+ defaultValues, customAttributes);
} else {
node = new NodeRecord(asSingleAttribute(name), asSingleAttribute(*doc),
- fieldValues, fieldNames, defaultValues);
+ fieldValues, fieldNames, defaultValues, customAttributes);
}
return NodePtr(node);
}
diff --git a/contrib/libs/apache/avro/impl/CustomFields.cc b/contrib/libs/apache/avro/impl/CustomFields.cc
new file mode 100644
index 00000000000..04541daae50
--- /dev/null
+++ b/contrib/libs/apache/avro/impl/CustomFields.cc
@@ -0,0 +1,59 @@
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "CustomFields.hh"
+#include <map>
+#include <memory>
+#include "Exception.hh"
+
+namespace avro {
+
+using json::Entity;
+
+Entity CustomFields::getField(const std::string &fieldName) const {
+ std::map<std::string, Entity>::const_iterator iter =
+ fields_.find(fieldName);
+ if (iter == fields_.end()) {
+ return Entity();
+ }
+ return iter->second;
+}
+
+void CustomFields::addField(const std::string& fieldName,
+ const std::string& fieldValue) {
+ addField(fieldName,
+ json::Entity(std::make_shared<std::string>(fieldValue)));
+}
+
+void CustomFields::addField(const std::string& fieldName,
+ const Entity& fieldValue) {
+ auto iter_and_find =
+ fields_.insert(std::pair<std::string, Entity>(fieldName, fieldValue));
+ if (!iter_and_find.second) {
+ throw Exception(fieldName + " already exists and cannot be added");
+ }
+}
+
+void CustomFields::printJson(std::ostream& os,
+ const std::string& fieldName) const {
+ if (fields_.find(fieldName) == fields_.end()) {
+ throw Exception(fieldName + " doesn't exist");
+ }
+ os << "\"" << fieldName << "\": " << fields_.at(fieldName).toString();
+}
+} // namespace avro
diff --git a/contrib/libs/apache/avro/impl/DataFile.cc b/contrib/libs/apache/avro/impl/DataFile.cc
index 18fb3f61a68..966eff8538b 100644
--- a/contrib/libs/apache/avro/impl/DataFile.cc
+++ b/contrib/libs/apache/avro/impl/DataFile.cc
@@ -232,9 +232,8 @@ void DataFileWriterBase::flush() {
sync();
}
-boost::mt19937 random(static_cast<uint32_t>(time(nullptr)));
-
DataFileSync DataFileWriterBase::makeSync() {
+ boost::mt19937 random(static_cast<uint32_t>(time(nullptr)));
DataFileSync sync;
std::generate(sync.begin(), sync.end(), random);
return sync;
@@ -392,6 +391,9 @@ void DataFileReaderBase::readDataBlock() {
compressed_.insert(compressed_.end(), data, data + len);
}
len = compressed_.size();
+ if (len < 4)
+ throw Exception("Cannot read compressed data, expected at least 4 bytes, got " + std::to_string(len));
+
int b1 = compressed_[len - 4] & 0xFF;
int b2 = compressed_[len - 3] & 0xFF;
int b3 = compressed_[len - 2] & 0xFF;
diff --git a/contrib/libs/apache/avro/impl/NodeImpl.cc b/contrib/libs/apache/avro/impl/NodeImpl.cc
index 810e1641ed9..37c855505c0 100644
--- a/contrib/libs/apache/avro/impl/NodeImpl.cc
+++ b/contrib/libs/apache/avro/impl/NodeImpl.cc
@@ -83,6 +83,17 @@ std::ostream &operator<<(std::ostream &os, indent x) {
return os;
}
+void printCustomFields(const CustomFields& customFields, int depth,
+ std::ostream &os) {
+ std::map<std::string, json::Entity>::const_iterator iter =
+ customFields.fields().begin();
+ while (iter != customFields.fields().end()) {
+ os << ",\n" << indent(depth);
+ customFields.printJson(os, iter->first);
+ ++iter;
+ }
+}
+
} // anonymous namespace
const int kByteStringSize = 6;
@@ -254,6 +265,7 @@ void NodeRecord::printJson(std::ostream &os, size_t depth) const {
++depth;
// Serialize "default" field:
assert(defaultValues.empty() || (defaultValues.size() == fields));
+ assert(customAttributes_.size() == 0 || customAttributes_.size() == fields);
for (size_t i = 0; i < fields; ++i) {
if (i > 0) {
os << ',';
@@ -274,6 +286,9 @@ void NodeRecord::printJson(std::ostream &os, size_t depth) const {
depth);
}
}
+ if(customAttributes_.size() == fields) {
+ printCustomFields(customAttributes_.get(i), depth, os);
+ }
os << '\n';
os << indent(--depth) << '}';
}
@@ -412,7 +427,7 @@ void NodeRecord::printDefaultToJson(const GenericDatum &g, std::ostream &os,
NodeRecord::NodeRecord(const HasName &name,
const MultiLeaves &fields,
const LeafNames &fieldsNames,
- std::vector<GenericDatum> dv) : NodeImplRecord(AVRO_RECORD, name, fields, fieldsNames, NoSize()),
+ std::vector<GenericDatum> dv) : NodeImplRecord(AVRO_RECORD, name, fields, fieldsNames, MultiAttributes(), NoSize()),
defaultValues(std::move(dv)) {
for (size_t i = 0; i < leafNameAttributes_.size(); ++i) {
if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
diff --git a/contrib/libs/apache/avro/impl/Schema.cc b/contrib/libs/apache/avro/impl/Schema.cc
index 42245292e67..fa90d3422ce 100644
--- a/contrib/libs/apache/avro/impl/Schema.cc
+++ b/contrib/libs/apache/avro/impl/Schema.cc
@@ -19,6 +19,7 @@
#include <utility>
#include "Schema.hh"
+#include "CustomFields.hh"
namespace avro {
@@ -27,11 +28,18 @@ RecordSchema::RecordSchema(const std::string &name) : Schema(new NodeRecord) {
}
void RecordSchema::addField(const std::string &name, const Schema &fieldSchema) {
+ const CustomFields emptyCustomField;
+ addField(name, fieldSchema, emptyCustomField);
+}
+
+void RecordSchema::addField(const std::string &name, const Schema &fieldSchema, const CustomFields &customFields) {
// add the name first. it will throw if the name is a duplicate, preventing
// the leaf from being added
node_->addName(name);
node_->addLeaf(fieldSchema.root());
+
+ node_->addCustomAttributesForField(customFields);
}
std::string RecordSchema::getDoc() const {