1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339 |
- #pragma once
- ///
- /// @file yt/cpp/mapreduce/interface/common.h
- ///
- /// Header containing miscellaneous structs and classes used in library.
- #include "fwd.h"
- #include <library/cpp/type_info/type_info.h>
- #include <library/cpp/yson/node/node.h>
- #include <util/generic/guid.h>
- #include <util/generic/map.h>
- #include <util/generic/maybe.h>
- #include <util/generic/ptr.h>
- #include <util/generic/vector.h>
- #include <google/protobuf/message.h>
- #include <initializer_list>
- #include <type_traits>
- namespace NYT {
- ////////////////////////////////////////////////////////////////////////////////
- /// @cond Doxygen_Suppress
- #define FLUENT_FIELD(type, name) \
- type name##_; \
- TSelf& name(const type& value) \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- static_assert(true)
- #define FLUENT_FIELD_ENCAPSULATED(type, name) \
- private: \
- type name##_; \
- public: \
- TSelf& name(const type& value) & \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- TSelf name(const type& value) && \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- const type& name() const & \
- { \
- return name##_; \
- } \
- type name() && \
- { \
- return name##_; \
- } \
- static_assert(true)
- #define FLUENT_FIELD_OPTION(type, name) \
- TMaybe<type> name##_; \
- TSelf& name(const type& value) \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- static_assert(true)
- #define FLUENT_FIELD_OPTION_ENCAPSULATED(type, name) \
- private: \
- TMaybe<type> name##_; \
- public: \
- TSelf& name(const type& value) & \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- TSelf name(const type& value) && \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- TSelf& Reset##name() & \
- { \
- name##_ = Nothing(); \
- return static_cast<TSelf&>(*this); \
- } \
- TSelf Reset##name() && \
- { \
- name##_ = Nothing(); \
- return static_cast<TSelf&>(*this); \
- } \
- const TMaybe<type>& name() const& \
- { \
- return name##_; \
- } \
- TMaybe<type> name() && \
- { \
- return name##_; \
- } \
- static_assert(true)
- #define FLUENT_FIELD_DEFAULT(type, name, defaultValue) \
- type name##_ = defaultValue; \
- TSelf& name(const type& value) \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- static_assert(true)
- #define FLUENT_FIELD_DEFAULT_ENCAPSULATED(type, name, defaultValue) \
- private: \
- type name##_ = defaultValue; \
- public: \
- TSelf& name(const type& value) & \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- TSelf name(const type& value) && \
- { \
- name##_ = value; \
- return static_cast<TSelf&>(*this); \
- } \
- const type& name() const & \
- { \
- return name##_; \
- } \
- type name() && \
- { \
- return name##_; \
- } \
- static_assert(true)
- #define FLUENT_VECTOR_FIELD(type, name) \
- TVector<type> name##s_; \
- TSelf& Add##name(const type& value) \
- { \
- name##s_.push_back(value); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf& name##s(TVector<type> values) \
- { \
- name##s_ = std::move(values); \
- return static_cast<TSelf&>(*this);\
- } \
- static_assert(true)
- #define FLUENT_OPTIONAL_VECTOR_FIELD_ENCAPSULATED(type, name) \
- private: \
- TMaybe<TVector<type>> name##s_; \
- public: \
- const TMaybe<TVector<type>>& name##s() const & { \
- return name##s_; \
- } \
- TMaybe<TVector<type>>& name##s() & { \
- return name##s_; \
- } \
- TMaybe<TVector<type>> name##s() && { \
- return std::move(name##s_); \
- } \
- TSelf& Add##name(const type& value) & \
- { \
- if (name##s_.Empty()) { \
- name##s_.ConstructInPlace(); \
- } \
- name##s_->push_back(value); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf Add##name(const type& value) && \
- { \
- if (name##s_.Empty()) { \
- name##s_.ConstructInPlace(); \
- } \
- name##s_->push_back(value); \
- return static_cast<TSelf&&>(*this);\
- } \
- TSelf& name##s(TVector<type> values) & \
- { \
- name##s_ = std::move(values); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf name##s(TVector<type> values) && \
- { \
- name##s_ = std::move(values); \
- return static_cast<TSelf&&>(*this);\
- } \
- TSelf& name##s(TNothing) & \
- { \
- name##s_ = Nothing(); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf name##s(TNothing) && \
- { \
- name##s_ = Nothing(); \
- return static_cast<TSelf&&>(*this);\
- } \
- TSelf& Reset##name##s() & \
- { \
- name##s_ = Nothing(); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf Reset##name##s() && \
- { \
- name##s_ = Nothing(); \
- return static_cast<TSelf&&>(*this);\
- } \
- static_assert(true)
- #define FLUENT_VECTOR_FIELD_ENCAPSULATED(type, name) \
- private: \
- TVector<type> name##s_; \
- public: \
- TSelf& Add##name(const type& value) & \
- { \
- name##s_.push_back(value); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf Add##name(const type& value) && \
- { \
- name##s_.push_back(value); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf& name##s(TVector<type> value) & \
- { \
- name##s_ = std::move(value); \
- return static_cast<TSelf&>(*this);\
- } \
- TSelf name##s(TVector<type> value) && \
- { \
- name##s_ = std::move(value); \
- return static_cast<TSelf&>(*this);\
- } \
- const TVector<type>& name##s() const & \
- { \
- return name##s_; \
- } \
- TVector<type> name##s() && \
- { \
- return name##s_; \
- } \
- static_assert(true)
- #define FLUENT_MAP_FIELD(keytype, valuetype, name) \
- TMap<keytype,valuetype> name##_; \
- TSelf& Add##name(const keytype& key, const valuetype& value) \
- { \
- name##_.emplace(key, value); \
- return static_cast<TSelf&>(*this);\
- } \
- static_assert(true)
- /// @endcond
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Convenience class that keeps sequence of items.
- ///
- /// Designed to be used as function parameter.
- ///
- /// Users of such function can then pass:
- /// - single item,
- /// - initializer list of items,
- /// - vector of items;
- /// as argument to this function.
- ///
- /// Example:
- /// ```
- /// void Foo(const TOneOrMany<int>& arg);
- /// ...
- /// Foo(1); // ok
- /// Foo({1, 2, 3}); // ok
- /// ```
- template <class T, class TDerived>
- struct TOneOrMany
- {
- /// @cond Doxygen_Suppress
- using TSelf = std::conditional_t<std::is_void_v<TDerived>, TOneOrMany, TDerived>;
- /// @endcond
- /// Initialize with empty sequence.
- TOneOrMany() = default;
- // Initialize from initializer list.
- template<class U>
- TOneOrMany(std::initializer_list<U> il)
- {
- Parts_.assign(il.begin(), il.end());
- }
- /// Put arguments to sequence
- template <class U, class... TArgs>
- requires std::is_convertible_v<U, T>
- TOneOrMany(U&& arg, TArgs&&... args)
- {
- Add(arg, std::forward<TArgs>(args)...);
- }
- /// Initialize from vector.
- TOneOrMany(TVector<T> args)
- : Parts_(std::move(args))
- { }
- /// @brief Order is defined the same way as in TVector
- bool operator==(const TOneOrMany& rhs) const
- {
- // N.B. We would like to make this method to be `= default`,
- // but this breaks MSVC compiler for the cases when T doesn't
- // support comparison.
- return Parts_ == rhs.Parts_;
- }
- ///
- /// @{
- ///
- /// @brief Add all arguments to sequence
- template <class U, class... TArgs>
- requires std::is_convertible_v<U, T>
- TSelf& Add(U&& part, TArgs&&... args) &
- {
- Parts_.push_back(std::forward<U>(part));
- if constexpr (sizeof...(args) > 0) {
- [[maybe_unused]] int dummy[sizeof...(args)] = {(Parts_.push_back(std::forward<TArgs>(args)), 0) ... };
- }
- return static_cast<TSelf&>(*this);
- }
- template <class U, class... TArgs>
- requires std::is_convertible_v<U, T>
- TSelf Add(U&& part, TArgs&&... args) &&
- {
- return std::move(Add(std::forward<U>(part), std::forward<TArgs>(args)...));
- }
- /// @}
- /// Content of sequence.
- TVector<T> Parts_;
- };
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Type of the value that can occur in YT table.
- ///
- /// @ref NYT::TTableSchema
- /// https://ytsaurus.tech/docs/en/user-guide/storage/data-types
- enum EValueType : int
- {
- /// Int64, signed integer of 64 bits.
- VT_INT64,
- /// Uint64, unsigned integer of 64 bits.
- VT_UINT64,
- /// Double, floating point number of double precision (64 bits).
- VT_DOUBLE,
- /// Boolean, `true` or `false`.
- VT_BOOLEAN,
- /// String, arbitrary byte sequence.
- VT_STRING,
- /// Any, arbitrary yson document.
- VT_ANY,
- /// Int8, signed integer of 8 bits.
- VT_INT8,
- /// Int16, signed integer of 16 bits.
- VT_INT16,
- /// Int32, signed integer of 32 bits.
- VT_INT32,
- /// Uint8, unsigned integer of 8 bits.
- VT_UINT8,
- /// Uint16, unsigned integer of 16 bits.
- VT_UINT16,
- /// Uint32, unsigned integer of 32 bits.
- VT_UINT32,
- /// Utf8, byte sequence that is valid utf8.
- VT_UTF8,
- /// Null, absence of value (almost never used in schemas)
- VT_NULL,
- /// Void, absence of value (almost never used in schemas) the difference between null, and void is yql-specific.
- VT_VOID,
- /// Date, number of days since Unix epoch (unsigned)
- VT_DATE,
- /// Datetime, number of seconds since Unix epoch (unsigned)
- VT_DATETIME,
- /// Timestamp, number of milliseconds since Unix epoch (unsigned)
- VT_TIMESTAMP,
- /// Interval, difference between two timestamps (signed)
- VT_INTERVAL,
- /// Float, floating point number (32 bits)
- VT_FLOAT,
- /// Json, sequence of bytes that is valid json.
- VT_JSON,
- // Date32, number of days shifted from Unix epoch, which is 0 (signed)
- VT_DATE32,
- // Datetime64, number of seconds shifted from Unix epoch, which is 0 (signed)
- VT_DATETIME64,
- // Timestamp64, number of milliseconds shifted from Unix epoch, which is 0 (signed)
- VT_TIMESTAMP64,
- // Interval64, difference between two timestamps64 (signed)
- VT_INTERVAL64,
- // Universally unique identifier according to RFC-4122.
- VT_UUID,
- };
- ///
- /// @brief Sort order.
- ///
- /// @ref NYT::TTableSchema
- enum ESortOrder : int
- {
- /// Ascending sort order.
- SO_ASCENDING /* "ascending" */,
- /// Descending sort order.
- SO_DESCENDING /* "descending" */,
- };
- ///
- /// @brief Value of "optimize_for" attribute.
- ///
- /// @ref NYT::TRichYPath
- enum EOptimizeForAttr : i8
- {
- /// Optimize for scan
- OF_SCAN_ATTR /* "scan" */,
- /// Optimize for lookup
- OF_LOOKUP_ATTR /* "lookup" */,
- };
- ///
- /// @brief Value of "erasure_codec" attribute.
- ///
- /// @ref NYT::TRichYPath
- enum EErasureCodecAttr : i8
- {
- /// @cond Doxygen_Suppress
- EC_NONE_ATTR /* "none" */,
- EC_REED_SOLOMON_6_3_ATTR /* "reed_solomon_6_3" */,
- EC_LRC_12_2_2_ATTR /* "lrc_12_2_2" */,
- EC_ISA_LRC_12_2_2_ATTR /* "isa_lrc_12_2_2" */,
- /// @endcond
- };
- ///
- /// @brief Value of "schema_modification" attribute.
- ///
- /// @ref NYT::TRichYPath
- enum ESchemaModificationAttr : i8
- {
- SM_NONE_ATTR /* "none" */,
- SM_UNVERSIONED_UPDATE /* "unversioned_update" */,
- };
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Table key column description.
- ///
- /// The description includes column name and sort order.
- ///
- /// @anchor TSortOrder_backward_compatibility
- /// @note
- /// Many functions that use `TSortOrder` as argument used to take `TString`
- /// (the only allowed sort order was "ascending" and user didn't have to specify it).
- /// @note
- /// This class is designed to provide backward compatibility for such code and therefore
- /// objects of this class can be constructed and assigned from TString-like objects only.
- ///
- /// @see NYT::TSortOperationSpec
- class TSortColumn
- {
- public:
- /// @cond Doxygen_Suppress
- using TSelf = TSortColumn;
- /// @endcond
- /// Column name
- FLUENT_FIELD_ENCAPSULATED(TString, Name);
- /// Sort order
- FLUENT_FIELD_DEFAULT_ENCAPSULATED(ESortOrder, SortOrder, ESortOrder::SO_ASCENDING);
- ///
- /// @{
- ///
- /// @brief Construct object from name and sort order
- ///
- /// Constructors are intentionally implicit so `TSortColumn` can be compatible with old code.
- /// @ref TSortOrder_backward_compatibility
- TSortColumn(TStringBuf name = {}, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
- TSortColumn(const TString& name, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
- TSortColumn(const char* name, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
- /// @}
- /// Check that sort order is ascending, throw exception otherwise.
- const TSortColumn& EnsureAscending() const;
- /// @brief Convert sort to yson representation as YT API expects it.
- TNode ToNode() const;
- /// @brief Comparison is default and checks both name and sort order.
- bool operator == (const TSortColumn& rhs) const = default;
- ///
- /// @{
- ///
- /// @brief Assign object from column name, and set sort order to `ascending`.
- ///
- /// This is backward compatibility methods.
- ///
- /// @ref TSortOrder_backward_compatibility
- TSortColumn& operator = (TStringBuf name);
- TSortColumn& operator = (const TString& name);
- TSortColumn& operator = (const char* name);
- /// @}
- bool operator == (const TStringBuf rhsName) const;
- bool operator == (const TString& rhsName) const;
- bool operator == (const char* rhsName) const;
- // Intentionally implicit conversions.
- operator TString() const;
- operator TStringBuf() const;
- operator std::string() const;
- Y_SAVELOAD_DEFINE(Name_, SortOrder_);
- };
- ///
- /// @brief List of @ref TSortColumn
- ///
- /// Contains a bunch of helper methods such as constructing from single object.
- class TSortColumns
- : public TOneOrMany<TSortColumn, TSortColumns>
- {
- public:
- using TOneOrMany<TSortColumn, TSortColumns>::TOneOrMany;
- /// Construct empty list.
- TSortColumns();
- ///
- /// @{
- ///
- /// @brief Construct list of ascending sort order columns by their names.
- ///
- /// Required for backward compatibility.
- ///
- /// @ref TSortOrder_backward_compatibility
- TSortColumns(const TVector<TString>& names);
- TSortColumns(const TColumnNames& names);
- /// @}
- ///
- /// @brief Implicit conversion to column list.
- ///
- /// If all columns has ascending sort order return list of their names.
- /// Throw exception otherwise.
- ///
- /// Required for backward compatibility.
- ///
- /// @ref TSortOrder_backward_compatibility
- operator TColumnNames() const;
- /// Make sure that all columns are of ascending sort order.
- const TSortColumns& EnsureAscending() const;
- /// Get list of column names.
- TVector<TString> GetNames() const;
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// Helper function to create new style type from old style one.
- NTi::TTypePtr ToTypeV3(EValueType type, bool required);
- ///
- /// @brief Single column description
- ///
- /// Each field describing column has setter and getter.
- ///
- /// Example reading field:
- /// ```
- /// ... columnSchema.Name() ...
- /// ```
- ///
- /// Example setting field:
- /// ```
- /// columnSchema.Name("my-column").Type(VT_INT64); // set name and type
- /// ```
- ///
- /// @ref https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
- class TColumnSchema
- {
- public:
- /// @cond Doxygen_Suppress
- using TSelf = TColumnSchema;
- /// @endcond
- ///
- /// @brief Construct empty column schemas
- ///
- /// @note
- /// Such schema cannot be used in schema as it it doesn't have name.
- TColumnSchema();
- ///
- /// @{
- ///
- /// @brief Copy and move constructors are default.
- TColumnSchema(const TColumnSchema&) = default;
- TColumnSchema& operator=(const TColumnSchema&) = default;
- /// @}
- FLUENT_FIELD_ENCAPSULATED(TString, Name);
- ///
- /// @brief Functions to work with type in old manner.
- ///
- /// @deprecated New code is recommended to work with types using @ref NTi::TTypePtr from type_info library.
- TColumnSchema& Type(EValueType type) &;
- TColumnSchema Type(EValueType type) &&;
- EValueType Type() const;
- /// @brief Set and get column type.
- /// @{
- TColumnSchema& Type(const NTi::TTypePtr& type) &;
- TColumnSchema Type(const NTi::TTypePtr& type) &&;
- TColumnSchema& TypeV3(const NTi::TTypePtr& type) &;
- TColumnSchema TypeV3(const NTi::TTypePtr& type) &&;
- NTi::TTypePtr TypeV3() const;
- /// @}
- /// Column sort order
- FLUENT_FIELD_OPTION_ENCAPSULATED(ESortOrder, SortOrder);
- ///
- /// @brief Lock group name
- ///
- /// @ref https://ytsaurus.tech/docs/en/user-guide/dynamic-tables/sorted-dynamic-tables#locking-rows
- FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Lock);
- /// Expression defining column value
- FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Expression);
- /// Aggregating function name
- FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Aggregate);
- ///
- /// @brief Storage group name
- ///
- /// @ref https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
- FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Group);
- // StableName for renamed and deleted columns.
- FLUENT_FIELD_OPTION_ENCAPSULATED(TString, StableName);
- /// Deleted column
- FLUENT_FIELD_OPTION_ENCAPSULATED(bool, Deleted);
- ///
- /// @brief Column requiredness.
- ///
- /// Required columns doesn't accept NULL values.
- /// Usually if column is required it means that it has Optional<...> type
- bool Required() const;
- ///
- /// @{
- ///
- /// @brief Set type in old-style manner
- TColumnSchema& Type(EValueType type, bool required) &;
- TColumnSchema Type(EValueType type, bool required) &&;
- /// @}
- ///
- /// @{
- ///
- /// @brief Raw yson representation of column type
- /// @deprecated Prefer to use `TypeV3` methods.
- const TMaybe<TNode>& RawTypeV3() const;
- TColumnSchema& RawTypeV3(TNode rawTypeV3)&;
- TColumnSchema RawTypeV3(TNode rawTypeV3)&&;
- /// @}
- private:
- friend void Deserialize(TColumnSchema& columnSchema, const TNode& node);
- NTi::TTypePtr TypeV3_;
- TMaybe<TNode> RawTypeV3_;
- };
- /// Equality check checks all fields of column schema.
- bool operator==(const TColumnSchema& lhs, const TColumnSchema& rhs);
- ///
- /// @brief Description of table schema
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
- class TTableSchema
- {
- public:
- /// @cond Doxygen_Suppress
- using TSelf = TTableSchema;
- /// @endcond
- /// Column schema
- FLUENT_VECTOR_FIELD_ENCAPSULATED(TColumnSchema, Column);
- ///
- /// @brief Strictness of the schema
- ///
- /// Strict schemas are not allowed to have columns not described in schema.
- /// Nonstrict schemas are allowed to have such columns, all such missing columns are assumed to have
- /// type any (or optional<yson> in type_v3 terminology).
- FLUENT_FIELD_DEFAULT_ENCAPSULATED(bool, Strict, true);
- ///
- /// @brief Whether keys are unique
- ///
- /// This flag can be set only for schemas that have sorted columns.
- /// If flag is set table cannot have multiple rows with same key.
- FLUENT_FIELD_DEFAULT_ENCAPSULATED(bool, UniqueKeys, false);
- /// Get modifiable column list
- TVector<TColumnSchema>& MutableColumns();
- /// Check if schema has any described column
- [[nodiscard]] bool Empty() const;
- /// Add column
- TTableSchema& AddColumn(const TString& name, const NTi::TTypePtr& type, ESortOrder sortOrder) &;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
- TTableSchema AddColumn(const TString& name, const NTi::TTypePtr& type, ESortOrder sortOrder) &&;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
- TTableSchema& AddColumn(const TString& name, const NTi::TTypePtr& type) &;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
- TTableSchema AddColumn(const TString& name, const NTi::TTypePtr& type) &&;
- /// Add optional column of specified type
- TTableSchema& AddColumn(const TString& name, EValueType type, ESortOrder sortOrder) &;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
- TTableSchema AddColumn(const TString& name, EValueType type, ESortOrder sortOrder) &&;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
- TTableSchema& AddColumn(const TString& name, EValueType type) &;
- /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
- TTableSchema AddColumn(const TString& name, EValueType type) &&;
- ///
- /// @brief Make table schema sorted by specified columns
- ///
- /// Resets old key columns if any
- TTableSchema& SortBy(const TSortColumns& columns) &;
- /// @copydoc NYT::TTableSchema::SortBy(const TSortColumns&)&;
- TTableSchema SortBy(const TSortColumns& columns) &&;
- /// Get yson description of table schema
- [[nodiscard]] TNode ToNode() const;
- /// Parse schema from yson node
- static NYT::TTableSchema FromNode(const TNode& node);
- friend void Deserialize(TTableSchema& tableSchema, const TNode& node);
- };
- /// Check for equality of all columns and all schema attributes
- bool operator==(const TTableSchema& lhs, const TTableSchema& rhs);
- // Pretty printer for unittests
- void PrintTo(const TTableSchema& schema, std::ostream* out);
- /// Create table schema by protobuf message descriptor
- TTableSchema CreateTableSchema(
- const ::google::protobuf::Descriptor& messageDescriptor,
- const TSortColumns& sortColumns = TSortColumns(),
- bool keepFieldsWithoutExtension = true);
- /// Create table schema by protobuf message type
- template <class TProtoType, typename = std::enable_if_t<std::is_base_of_v<::google::protobuf::Message, TProtoType>>>
- inline TTableSchema CreateTableSchema(
- const TSortColumns& sortColumns = TSortColumns(),
- bool keepFieldsWithoutExtension = true)
- {
- static_assert(
- std::is_base_of_v<::google::protobuf::Message, TProtoType>,
- "Template argument must be derived from ::google::protobuf::Message");
- return CreateTableSchema(
- *TProtoType::descriptor(),
- sortColumns,
- keepFieldsWithoutExtension);
- }
- ///
- /// @brief Create strict table schema from `struct` type.
- ///
- /// Names and types of columns are taken from struct member names and types.
- /// `Strict` flag is set to true, all other attribute of schema and columns
- /// are left with default values
- TTableSchema CreateTableSchema(NTi::TTypePtr type);
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Enumeration describing comparison operation used in key bound.
- ///
- /// ERelation is a part of @ref NYT::TKeyBound that can be used as
- /// lower or upper key limit in @ref TReadLimit.
- ///
- /// Relations `Less` and `LessOrEqual` are for upper limit and
- /// relations `Greater` and `GreaterOrEqual` are for lower limit.
- ///
- /// It is a error to use relation in the limit of wrong kind.
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/storage/ypath#rich_ypath
- enum class ERelation
- {
- ///
- /// @brief Relation "less"
- ///
- /// Specifies range of keys that are before specified key.
- /// Can only be used in upper limit.
- Less /* "<" */,
- ///
- /// @brief Relation "less or equal"
- ///
- /// Specifies range of keys that are before or equal specified key.
- /// Can only be used in upper limit.
- LessOrEqual /* "<=" */,
- ///
- /// @brief Relation "greater"
- ///
- /// Specifies range of keys that are after specified key.
- /// Can only be used in lower limit.
- Greater /* ">" */,
- ///
- /// @brief Relation "greater or equal"
- ///
- /// Specifies range of keys that are after or equal than specified key.
- /// Can only be used in lower limit.
- GreaterOrEqual /* ">=" */,
- };
- ///
- /// @brief Key with relation specifying interval of keys in lower or upper limit of @ref NYT::TReadRange
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
- struct TKeyBound
- {
- /// @cond Doxygen_Suppress
- using TSelf = TKeyBound;
- explicit TKeyBound(ERelation relation = ERelation::Less, TKey key = TKey{});
- FLUENT_FIELD_DEFAULT_ENCAPSULATED(ERelation, Relation, ERelation::Less);
- FLUENT_FIELD_DEFAULT_ENCAPSULATED(TKey, Key, TKey{});
- /// @endcond
- };
- ///
- /// @brief Description of the read limit.
- ///
- /// It is actually a variant and must store exactly one field.
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
- struct TReadLimit
- {
- /// @cond Doxygen_Suppress
- using TSelf = TReadLimit;
- /// @endcond
- ///
- /// @brief KeyBound specifies table key and whether to include it
- ///
- /// It can be used in lower or upper limit when reading tables.
- FLUENT_FIELD_OPTION(TKeyBound, KeyBound);
- ///
- /// @brief Table key
- ///
- /// It can be used in exact, lower or upper limit when reading tables.
- FLUENT_FIELD_OPTION(TKey, Key);
- ///
- /// @brief Row index
- ///
- /// It can be used in exact, lower or upper limit when reading tables.
- FLUENT_FIELD_OPTION(i64, RowIndex);
- ///
- /// @brief File offset
- ///
- /// It can be used in lower or upper limit when reading files.
- FLUENT_FIELD_OPTION(i64, Offset);
- ///
- /// @brief Tablet index
- ///
- /// It can be used in lower or upper limit in dynamic table operations
- FLUENT_FIELD_OPTION(i64, TabletIndex);
- };
- ///
- /// @brief Range of a table or a file
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
- struct TReadRange
- {
- using TSelf = TReadRange;
- ///
- /// @brief Lower limit of the range
- ///
- /// It is usually inclusive (except when @ref NYT::TKeyBound with relation @ref NYT::ERelation::Greater is used).
- FLUENT_FIELD(TReadLimit, LowerLimit);
- ///
- /// @brief Lower limit of the range
- ///
- /// It is usually exclusive (except when @ref NYT::TKeyBound with relation @ref NYT::ERelation::LessOrEqual is used).
- FLUENT_FIELD(TReadLimit, UpperLimit);
- /// Exact key or row index.
- FLUENT_FIELD(TReadLimit, Exact);
- /// Create read range from row indexes.
- static TReadRange FromRowIndices(i64 lowerLimit, i64 upperLimit)
- {
- return TReadRange()
- .LowerLimit(TReadLimit().RowIndex(lowerLimit))
- .UpperLimit(TReadLimit().RowIndex(upperLimit));
- }
- /// Create read range from keys.
- static TReadRange FromKeys(const TKey& lowerKeyInclusive, const TKey& upperKeyExclusive)
- {
- return TReadRange()
- .LowerLimit(TReadLimit().Key(lowerKeyInclusive))
- .UpperLimit(TReadLimit().Key(upperKeyExclusive));
- }
- };
- ///
- /// @brief Path with additional attributes.
- ///
- /// Allows to specify additional attributes for path used in some operations.
- ///
- /// @see https://ytsaurus.tech/docs/en/user-guide/storage/ypath#rich_ypath
- struct TRichYPath
- {
- /// @cond Doxygen_Suppress
- using TSelf = TRichYPath;
- /// @endcond
- /// Path itself.
- FLUENT_FIELD(TYPath, Path);
- /// Specifies that path should be appended not overwritten
- FLUENT_FIELD_OPTION(bool, Append);
- /// @deprecated Deprecated attribute.
- FLUENT_FIELD_OPTION(bool, PartiallySorted);
- /// Specifies that path is expected to be sorted by these columns.
- FLUENT_FIELD(TSortColumns, SortedBy);
- /// Add range to read.
- TRichYPath& AddRange(TReadRange range)
- {
- if (!Ranges_) {
- Ranges_.ConstructInPlace();
- }
- Ranges_->push_back(std::move(range));
- return *this;
- }
- TRichYPath& ResetRanges()
- {
- Ranges_.Clear();
- return *this;
- }
- ///
- /// @{
- ///
- /// Return ranges to read.
- ///
- /// NOTE: Nothing (in TMaybe) and empty TVector are different ranges.
- /// Nothing represents universal range (reader reads all table rows).
- /// Empty TVector represents empty range (reader returns empty set of rows).
- const TMaybe<TVector<TReadRange>>& GetRanges() const
- {
- return Ranges_;
- }
- TMaybe<TVector<TReadRange>>& MutableRanges()
- {
- return Ranges_;
- }
- ///
- /// @{
- ///
- /// Get range view, that is a convenient way to iterate through all ranges.
- TArrayRef<TReadRange> MutableRangesView()
- {
- if (Ranges_.Defined()) {
- return TArrayRef(Ranges_->data(), Ranges_->size());
- } else {
- return {};
- }
- }
- TArrayRef<const TReadRange> GetRangesView() const
- {
- if (Ranges_.Defined()) {
- return TArrayRef(Ranges_->data(), Ranges_->size());
- } else {
- return {};
- }
- }
- /// @}
- /// @{
- ///
- /// Get range by index.
- const TReadRange& GetRange(ssize_t i) const
- {
- return Ranges_.GetRef()[i];
- }
- TReadRange& MutableRange(ssize_t i)
- {
- return Ranges_.GetRef()[i];
- }
- /// @}
- ///
- /// @brief Specifies columns that should be read.
- ///
- /// If it's set to Nothing then all columns will be read.
- /// If empty TColumnNames is specified then each read row will be empty.
- FLUENT_FIELD_OPTION(TColumnNames, Columns);
- FLUENT_FIELD_OPTION(bool, Teleport);
- FLUENT_FIELD_OPTION(bool, Primary);
- FLUENT_FIELD_OPTION(bool, Foreign);
- FLUENT_FIELD_OPTION(i64, RowCountLimit);
- FLUENT_FIELD_OPTION(TString, FileName);
- /// Specifies original path to be shown in Web UI
- FLUENT_FIELD_OPTION(TYPath, OriginalPath);
- ///
- /// @brief Specifies that this path points to executable file
- ///
- /// Used in operation specs.
- FLUENT_FIELD_OPTION(bool, Executable);
- ///
- /// @brief Specify format to use when loading table.
- ///
- /// Used in operation specs.
- FLUENT_FIELD_OPTION(TNode, Format);
- /// @brief Specifies table schema that will be set on the path
- FLUENT_FIELD_OPTION(TTableSchema, Schema);
- /// Specifies compression codec that will be set on the path
- FLUENT_FIELD_OPTION(TString, CompressionCodec);
- /// Specifies erasure codec that will be set on the path
- FLUENT_FIELD_OPTION(EErasureCodecAttr, ErasureCodec);
- /// Specifies schema modification that will be set on the path
- FLUENT_FIELD_OPTION(ESchemaModificationAttr, SchemaModification);
- /// Specifies optimize_for attribute that will be set on the path
- FLUENT_FIELD_OPTION(EOptimizeForAttr, OptimizeFor);
- ///
- /// @brief Do not put file used in operation into node cache
- ///
- /// If BypassArtifactCache == true, file will be loaded into the job's sandbox bypassing the cache on the YT node.
- /// It helps jobs that use tmpfs to start faster,
- /// because files will be loaded into tmpfs directly bypassing disk cache
- FLUENT_FIELD_OPTION(bool, BypassArtifactCache);
- ///
- /// @brief Timestamp of dynamic table.
- ///
- /// NOTE: it is _not_ unix timestamp
- /// (instead it's transaction timestamp, that is more complex structure).
- FLUENT_FIELD_OPTION(i64, Timestamp);
- ///
- /// @brief Specify transaction that should be used to access this path.
- ///
- /// Allows to start cross-transactional operations.
- FLUENT_FIELD_OPTION(TTransactionId, TransactionId);
- ///
- /// @brief Wether to create operation output path.
- ///
- /// If set to `true` output path is created by YT server.
- /// If set to `false` output path is not created explicitly (and operation will fail if it doesn't exist)
- /// If attribute is not set output path is created by this library using explicit master call.
- FLUENT_FIELD_OPTION(bool, Create);
- using TRenameColumnsDescriptor = THashMap<TString, TString>;
- /// Specifies columnar mapping which will be applied to columns before transfer to job.
- FLUENT_FIELD_OPTION(TRenameColumnsDescriptor, RenameColumns);
- /// Specifies cluster for the YPath
- FLUENT_FIELD_OPTION(TString, Cluster);
- /// Create empty path with no attributes
- TRichYPath()
- { }
- ///
- /// @{
- ///
- /// @brief Create path from string
- TRichYPath(const char* path)
- : Path_(path)
- { }
- TRichYPath(const TYPath& path)
- : Path_(path)
- { }
- /// @}
- private:
- TMaybe<TVector<TReadRange>> Ranges_;
- };
- ///
- /// @ref Create copy of @ref NYT::TRichYPath with schema derived from proto message.
- ///
- ///
- template <typename TProtoType>
- TRichYPath WithSchema(const TRichYPath& path, const TSortColumns& sortBy = TSortColumns())
- {
- static_assert(std::is_base_of_v<::google::protobuf::Message, TProtoType>, "TProtoType must be Protobuf message");
- auto schemedPath = path;
- if (!schemedPath.Schema_) {
- schemedPath.Schema(CreateTableSchema<TProtoType>(sortBy));
- }
- return schemedPath;
- }
- ///
- /// @brief Create copy of @ref NYT::TRichYPath with schema derived from TRowType if possible.
- ///
- /// If TRowType is protobuf message schema is derived from it and set to returned path.
- /// Otherwise schema of original path is left unchanged (and probably unset).
- template <typename TRowType>
- TRichYPath MaybeWithSchema(const TRichYPath& path, const TSortColumns& sortBy = TSortColumns())
- {
- if constexpr (std::is_base_of_v<::google::protobuf::Message, TRowType>) {
- return WithSchema<TRowType>(path, sortBy);
- } else {
- return path;
- }
- }
- ///
- /// @brief Get the list of ranges related to path in compatibility mode.
- ///
- /// - If path is missing ranges, empty list is returned.
- /// - If path has associated range list and the list is not empty, function returns this list.
- /// - If path has associated range list and this list is empty, exception is thrown.
- ///
- /// Before YT-17683 RichYPath didn't support empty range list and empty range actually meant universal range.
- /// This function emulates this old behavior.
- ///
- /// @see https://st.yandex-team.ru/YT-17683
- const TVector<TReadRange>& GetRangesCompat(const TRichYPath& path);
- ////////////////////////////////////////////////////////////////////////////////
- /// Statistics about table columns.
- struct TTableColumnarStatistics
- {
- /// Total data weight for all chunks for each of requested columns.
- THashMap<TString, i64> ColumnDataWeight;
- /// Estimated number of unique elements for each column.
- THashMap<TString, ui64> ColumnEstimatedUniqueCounts;
- /// Total weight of all old chunks that don't keep columnar statistics.
- i64 LegacyChunksDataWeight = 0;
- /// Timestamps total weight (only for dynamic tables).
- TMaybe<i64> TimestampTotalWeight;
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// Description of a partition.
- struct TMultiTablePartition
- {
- struct TStatistics
- {
- i64 ChunkCount = 0;
- i64 DataWeight = 0;
- i64 RowCount = 0;
- };
- /// Ranges of input tables for this partition.
- TVector<TRichYPath> TableRanges;
- /// Aggregate statistics of all the table ranges in the partition.
- TStatistics AggregateStatistics;
- };
- /// Table partitions from GetTablePartitions command.
- struct TMultiTablePartitions
- {
- /// Disjoint partitions into which the input tables were divided.
- TVector<TMultiTablePartition> Partitions;
- };
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Contains information about tablet
- ///
- /// @see NYT::IClient::GetTabletInfos
- struct TTabletInfo
- {
- ///
- /// @brief Indicates the total number of rows added to the tablet (including trimmed ones).
- ///
- /// Currently only provided for ordered tablets.
- i64 TotalRowCount = 0;
- ///
- /// @brief Contains the number of front rows that are trimmed and are not guaranteed to be accessible.
- ///
- /// Only makes sense for ordered tablet.
- i64 TrimmedRowCount = 0;
- ///
- /// @brief Tablet cell barrier timestamp, which lags behind the current timestamp
- ///
- /// It is guaranteed that all transactions with commit timestamp not exceeding the barrier are fully committed;
- /// e.g. all their added rows are visible (and are included in @ref NYT::TTabletInfo::TotalRowCount).
- /// Mostly makes sense for ordered tablets.
- ui64 BarrierTimestamp;
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// List of attributes to retrieve in operations like @ref NYT::ICypressClient::Get
- struct TAttributeFilter
- {
- /// @cond Doxygen_Suppress
- using TSelf = TAttributeFilter;
- /// @endcond
- /// List of attributes.
- FLUENT_VECTOR_FIELD(TString, Attribute);
- };
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Check if none of the fields of @ref NYT::TReadLimit is set.
- ///
- /// @return true if any field of readLimit is set and false otherwise.
- bool IsTrivial(const TReadLimit& readLimit);
- /// Convert yson node type to table schema type
- EValueType NodeTypeToValueType(TNode::EType nodeType);
- ////////////////////////////////////////////////////////////////////////////////
- ///
- /// @brief Enumeration for specifying how reading from master is performed.
- ///
- /// Used in operations like NYT::ICypressClient::Get
- enum class EMasterReadKind : int
- {
- ///
- /// @brief Reading from leader.
- ///
- /// Should almost never be used since it's expensive and for regular uses has no difference from
- /// "follower" read.
- Leader /* "leader" */,
- /// @brief Reading from master follower (default).
- Follower /* "follower" */,
- Cache /* "cache" */,
- MasterCache /* "master_cache" */,
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// @cond Doxygen_Suppress
- namespace NDetail {
- // MUST NOT BE USED BY CLIENTS
- // TODO: we should use default GENERATE_ENUM_SERIALIZATION
- TString ToString(EValueType type);
- } // namespace NDetail
- /// @endcond
- ////////////////////////////////////////////////////////////////////////////////
- } // namespace NYT
|