aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/vespa/document/datatype/datatype.h
blob: 8deca98eb742b92c9de0a706a3d82316faae5094 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
 * \class document::DataType
 * \ingroup datatype
 *
 * \brief Specifies what is legal to store in a given field value.
 */
#pragma once

#include <vespa/document/util/printable.h>
#include <vespa/vespalib/stllike/string.h>
#include <memory>
#include <vector>

namespace document {

class FieldValue;
class Field;
class FieldPath;

class ArrayDataType;
class CollectionDataType;
class DocumentType;
class MapDataType;
class NumericDataType;
class PrimitiveDataType;
class ReferenceDataType;
class TensorDataType;
class WeightedSetDataType;

class DataType : public Printable
{
    int _dataTypeId;
    vespalib::string _name;

protected:
    /**
     * Creates a datatype. Note that datatypes must be configured to work with
     * the entire system, you can't just create them on the fly and expect
     * everyone to be able to use them. Only tests and the type manager reading
     * config should need to create datatypes.
     */
    DataType(vespalib::stringref name, int dataTypeId) noexcept;

    /**
     * Creates a datatype using the hash of name as the id.
     */
    explicit DataType(vespalib::stringref name) noexcept;

public:
    ~DataType() override;
    using UP = std::unique_ptr<DataType>;
    using SP = std::shared_ptr<DataType>;

    /**
     * Enumeration of primitive data type identifiers. (Complex types uses
     * hashed identifiers.
     *
     * <b>NOTE:</b> These types are also defined in the java source (in file
     * "document/src/java/com/yahoo/document/DataType.java". Changes done
     * here must also be applied there.
     */
    enum Type {
        T_INT         =  0,
        T_FLOAT       =  1,
        T_STRING      =  2,
        T_RAW         =  3,
        T_LONG        =  4,
        T_DOUBLE      =  5,
        T_BOOL        =  6,
        T_DOCUMENT    =  8, // Type of super document type Document.0 that all documents inherit.
        // T_TIMESTAMP   =  9,  // Not used anymore, Id should probably not be reused
        T_URI         = 10,
        // T_EXACTSTRING = 11,  // Not used anymore, Id should probably not be reused
        // T_CONTENT     = 12,  // Not used anymore, Id should probably not be reused
        // T_CONTENTMETA = 13,  // Not used anymore, Id should probably not be reused
        // T_MAILADDRESS = 14,  // Not used anymore, Id should probably not be reused
        // T_TERMBOOST   = 15,  // Not used anymore, Id should probably not be reused
        T_BYTE        = 16,
        T_TAG         = 18,
        T_SHORT       = 19,
        T_PREDICATE   = 20,
        T_TENSOR      = 21,
        MAX
    };

    static const DataType *const BYTE;
    static const DataType *const SHORT;
    static const DataType *const INT;
    static const DataType *const LONG;
    static const DataType *const FLOAT;
    static const DataType *const DOUBLE;
    static const DataType *const BOOL;
    static const DataType *const STRING;
    static const DataType *const RAW;
    static const DocumentType *const DOCUMENT;
    static const DataType *const TAG;
    static const DataType *const URI;
    static const DataType *const PREDICATE;
    static const DataType *const TENSOR;

    /** Used by type manager to fetch default types to register. */
    static std::vector<const DataType *> getDefaultDataTypes();

    const vespalib::string& getName() const noexcept { return _name; }
    int getId() const noexcept { return _dataTypeId; }
    bool isValueType(const FieldValue & fv) const;

    /**
     * Create a field value using this datatype.
     */
    virtual std::unique_ptr<FieldValue> createFieldValue() const = 0;

    virtual bool isWeightedSet() const noexcept { return false; }
    virtual bool isArray() const noexcept { return false; }
    virtual bool isDocument() const noexcept { return false; }
    virtual bool isTensor() const noexcept { return false; }
    virtual bool isPrimitive() const noexcept { return false; }
    virtual bool isNumeric() const noexcept { return false; }
    virtual bool isStructured() const noexcept { return false; }
    virtual const CollectionDataType * cast_collection() const noexcept { return nullptr; }
    virtual const MapDataType * cast_map() const noexcept { return nullptr; }
    virtual const ReferenceDataType * cast_reference() const noexcept { return nullptr; }
    virtual const TensorDataType* cast_tensor() const noexcept { return nullptr; }
    bool isMap() const { return cast_map() != nullptr; }

    /**
     * Whether another datatype is a supertype of this one. Document types may
     * be due to inheritance. For other types, they must be identical for this
     * to match.
     */
    virtual bool isA(const DataType& other) const { return equals(other); }

    virtual bool equals(const DataType & other) const noexcept {
        return _dataTypeId == other._dataTypeId;
    }

    bool operator == (const DataType & other) const noexcept {
        return equals(other);
    }
    int cmpId(const DataType& b) const {
        return (_dataTypeId < b._dataTypeId)
               ? -1
               : (b._dataTypeId < _dataTypeId)
                 ? 1
                 : 0;
    }

    /**
     * This takes a . separated fieldname and gives you back the path of
     * fields you have to apply to get to your leaf.
     * @param remainFieldName. The remaining part of the fieldname that you want the path of.
     *                         MUST be null-terminated.
     * @return pointer to field path or null if an error occured
     */
    void buildFieldPath(FieldPath & fieldPath, vespalib::stringref remainFieldName) const;

    /** @throws FieldNotFoundException if field does not exist. */
    virtual const Field& getField(int fieldId) const;
private:
    virtual void onBuildFieldPath(FieldPath & fieldPath, vespalib::stringref remainFieldName) const = 0;
};

} // document