19
#include "mongo/pch.h"
20
#include "bson/bsontypes.h"
22
#include "util/intrusive_counter.h"
23
#include "util/optime.h"
19
#include "mongo/db/pipeline/value_internal.h"
32
public IntrusiveCounterUnsigned {
34
virtual ~ValueIterator();
37
Ask if there are more fields to return.
39
@returns true if there are more fields, false otherwise
41
virtual bool more() const = 0;
44
Move the iterator to point to the next field and return it.
46
@returns the next field's <name, Value>
48
virtual intrusive_ptr<const Value> next() = 0;
53
Values are immutable, so these are passed around as
54
intrusive_ptr<const Value>.
25
/** A variant type that can hold any type of data representable in BSON
27
* Small values are stored inline, but some values, such as large strings,
28
* are heap allocated. It has smart pointer capabilities built-in so it is
29
* safe and recommended to pass these around and return them by value.
31
* Values are immutable, but can be assigned. This means that once you have
32
* a Value, you can be assured that none of the data in that Value will
33
* change. However if you have a non-const Value you replace it with
34
* operator=. These rules are the same as BSONObj, and similar to
35
* shared_ptr<const Object> with stronger guarantees of constness. This is
36
* also the same as Java's String type.
38
* Thread-safety: A single Value instance can be safely shared between
39
* threads as long as there are no writers while other threads are
40
* accessing the object. Any number of threads can read from a Value
41
* concurrently. There are no restrictions on how threads access Value
42
* instances exclusively owned by them, even if they reference the same
43
* storage as Value in other threads.
57
public IntrusiveCounterUnsigned {
62
Construct a Value from a BSONElement.
64
This ignores the name of the element, and only uses the value,
67
@returns a new Value initialized from the bsonElement
69
static intrusive_ptr<const Value> createFromBsonElement(
70
BSONElement *pBsonElement);
73
Construct an integer-valued Value.
75
For commonly used values, consider using one of the singleton
76
instances defined below.
78
@param value the value
79
@returns a Value with the given value
81
static intrusive_ptr<const Value> createInt(int value);
84
Construct a long or interger-valued Value.
85
Used when preforming arithmetic operations with int where the result may be too large
86
and need to be stored as long. The Value will be an int if value fits, otherwise it
89
@param value the value
90
@returns a Value with the given value
92
static intrusive_ptr<const Value> createIntOrLong(long long value);
95
Construct an long(long)-valued Value.
97
For commonly used values, consider using one of the singleton
98
instances defined below.
100
@param value the value
101
@returns a Value with the given value
103
static intrusive_ptr<const Value> createLong(long long value);
106
Construct a double-valued Value.
108
@param value the value
109
@returns a Value with the given value
111
static intrusive_ptr<const Value> createDouble(double value);
114
Construct a string-valued Value.
116
@param value the value
117
@returns a Value with the given value
119
static intrusive_ptr<const Value> createString(const string &value);
122
Construct a date-valued Value.
124
@param value the value
125
@returns a Value with the given value
127
static intrusive_ptr<const Value> createDate(const long long &value);
129
static intrusive_ptr<const Value> createTimestamp(const OpTime& value);
132
Construct a document-valued Value.
134
@param value the value
135
@returns a Value with the given value
137
static intrusive_ptr<const Value> createDocument(
138
const intrusive_ptr<Document> &pDocument);
141
Construct an array-valued Value.
143
@param value the value
144
@returns a Value with the given value
146
static intrusive_ptr<const Value> createArray(
147
const vector<intrusive_ptr<const Value> > &vpValue);
150
Get the BSON type of the field.
152
If the type is jstNULL, no value getter will work.
154
@return the BSON type of the field.
156
BSONType getType() const;
161
@returns the Value's value; asserts if the requested value type is
49
* All types not listed will be rejected rather than converted (see private for why)
51
* Note: Currently these are all explicit conversions.
52
* I'm not sure if we want implicit or not.
56
Value(): _storage() {} // "Missing" value
57
explicit Value(bool value) : _storage(Bool, value) {}
58
explicit Value(int value) : _storage(NumberInt, value) {}
59
explicit Value(long long value) : _storage(NumberLong, value) {}
60
explicit Value(double value) : _storage(NumberDouble, value) {}
61
explicit Value(const OpTime& value) : _storage(Timestamp, value.asDate()) {}
62
explicit Value(const OID& value) : _storage(jstOID, value) {}
63
explicit Value(const StringData& value) : _storage(String, value) {}
64
explicit Value(const string& value) : _storage(String, StringData(value)) {}
65
explicit Value(const char* value) : _storage(String, StringData(value)) {}
66
explicit Value(const Document& doc) : _storage(Object, doc) {}
67
explicit Value(const BSONObj& obj);// : _storage(Object, Document(obj)) {} // in cpp
68
explicit Value(const vector<Value>& vec) : _storage(Array, new RCVector(vec)) {}
69
explicit Value(const BSONBinData& bd) : _storage(BinData, bd) {}
70
explicit Value(const BSONRegEx& re) : _storage(RegEx, re) {}
71
explicit Value(const BSONCodeWScope& cws) : _storage(CodeWScope, cws) {}
72
explicit Value(const BSONDBRef& dbref) : _storage(DBRef, dbref) {}
73
explicit Value(const BSONSymbol& sym) : _storage(Symbol, sym.symbol) {}
74
explicit Value(const BSONCode& code) : _storage(Code, code.code) {}
75
explicit Value(const NullLabeler&) : _storage(jstNULL) {} // BSONNull
76
explicit Value(const UndefinedLabeler&) : _storage(Undefined) {} // BSONUndefined
77
explicit Value(const MinKeyLabeler&) : _storage(MinKey) {} // MINKEY
78
explicit Value(const MaxKeyLabeler&) : _storage(MaxKey) {} // MAXKEY
79
explicit Value(const Date_t& date)
80
: _storage(Date, static_cast<long long>(date.millis)) // millis really signed
83
/** Creates an empty or zero value of specified type.
84
* This is currently the only way to create Undefined or Null Values.
86
explicit Value(BSONType type);
88
// TODO: add an unsafe version that can share storage with the BSONElement
89
/// Deep-convert from BSONElement to Value
90
explicit Value(const BSONElement& elem);
92
/** Construct a long or integer-valued Value.
94
* Used when preforming arithmetic operations with int where the
95
* result may be too large and need to be stored as long. The Value
96
* will be an int if value fits, otherwise it will be a long.
98
static Value createIntOrLong(long long value);
100
/** A "missing" value indicates the lack of a Value.
101
* This is similar to undefined/null but should not appear in output to BSON.
102
* Missing Values are returned by Document when accessing non-existent fields.
104
bool missing() const { return _storage.type == EOO; }
106
/// true if missing() or type is jstNULL or Undefined
107
bool nullish() const {
109
|| _storage.type == jstNULL
110
|| _storage.type == Undefined;
113
/// true if type represents a number
114
bool numeric() const {
115
return _storage.type == NumberDouble
116
|| _storage.type == NumberLong
117
|| _storage.type == NumberInt;
120
/// Get the BSON type of the field.
121
BSONType getType() const { return _storage.bsonType(); }
123
/** Exact type getters.
124
* Asserts if the requested value type is not exactly correct.
125
* See coerceTo methods below for a more type-flexible alternative.
164
127
double getDouble() const;
165
128
string getString() const;
166
intrusive_ptr<Document> getDocument() const;
167
intrusive_ptr<ValueIterator> getArray() const;
129
Document getDocument() const;
168
130
OID getOid() const;
169
131
bool getBool() const;
170
long long getDate() const;
132
long long getDate() const; // in milliseconds
171
133
OpTime getTimestamp() const;
172
string getRegex() const;
134
const char* getRegex() const;
135
const char* getRegexFlags() const;
173
136
string getSymbol() const;
137
string getCode() const;
174
138
int getInt() const;
175
139
long long getLong() const;
178
Get the length of an array value.
180
@returns the length of the array, if this is array-valued; otherwise
140
const vector<Value>& getArray() const { return _storage.getArray(); }
183
141
size_t getArrayLength() const;
186
Add this value to the BSON object under construction.
188
void addToBsonObj(BSONObjBuilder *pBuilder, string fieldName) const;
191
Add this field to the BSON array under construction.
193
As part of an array, the Value's name will be ignored.
195
void addToBsonArray(BSONArrayBuilder *pBuilder) const;
198
Get references to singleton instances of commonly used field values.
200
static intrusive_ptr<const Value> getUndefined();
201
static intrusive_ptr<const Value> getNull();
202
static intrusive_ptr<const Value> getTrue();
203
static intrusive_ptr<const Value> getFalse();
204
static intrusive_ptr<const Value> getMinusOne();
205
static intrusive_ptr<const Value> getZero();
206
static intrusive_ptr<const Value> getOne();
209
* Coerce (cast) a value to a native bool using BSONElement::trueValue() rules, but with
210
* some types unsupported. SERVER-6120
211
* @return the bool value
143
/// Access an element of a subarray. Returns Value() if missing or getType() != Array
144
Value operator[] (size_t index) const;
146
/// Access a field of a subdocument. Returns Value() if missing or getType() != Object
147
Value operator[] (StringData name) const;
149
/// Add this value to the BSON object under construction.
150
void addToBsonObj(BSONObjBuilder* pBuilder, StringData fieldName) const;
152
/// Add this field to the BSON array under construction.
153
void addToBsonArray(BSONArrayBuilder* pBuilder) const;
155
// Support BSONObjBuilder and BSONArrayBuilder "stream" API
156
friend BSONObjBuilder& operator << (BSONObjBuilderValueStream& builder, const Value& val);
158
/** Coerce a value to a bool using BSONElement::trueValue() rules.
159
* Some types unsupported. SERVER-6120
213
161
bool coerceToBool() const;
216
Coerce (cast) a value to an int, using JSON rules.
218
@returns the int value
163
/** Coercion operators to extract values with fuzzy type logic.
165
* These currently assert if called on an unconvertible type.
166
* TODO: decided how to handle unsupported types.
168
string coerceToString() const;
220
169
int coerceToInt() const;
223
Coerce (cast) a value to a long long, using JSON rules.
225
@returns the long value
227
170
long long coerceToLong() const;
230
Coerce (cast) a value to a double, using JSON rules.
232
@returns the double value
234
171
double coerceToDouble() const;
237
Coerce (cast) a value to a date, using JSON rules.
239
@returns the date value
172
OpTime coerceToTimestamp() const;
241
173
long long coerceToDate() const;
242
174
time_t coerceToTimeT() const;
243
175
tm coerceToTm() const; // broken-out time struct (see man gmtime)
245
OpTime coerceToTimestamp() const;
248
Coerce (cast) a value to a string, using JSON rules.
250
@returns the date value
252
string coerceToString() const;
258
@param rR right value
259
@returns an integer less than zero, zero, or an integer greater than
260
zero, depending on whether rL < rR, rL == rR, or rL > rR
262
static int compare(const intrusive_ptr<const Value> &rL,
263
const intrusive_ptr<const Value> &rR);
267
Figure out what the widest of two numeric types is.
269
Widest can be thought of as "most capable," or "able to hold the
270
largest or most precise value." The progression is Int, Long, Double.
273
@param rR right value
274
@returns a BSONType of NumberInt, NumberLong, or NumberDouble
178
/** Compare two Values.
179
* @returns an integer less than zero, zero, or an integer greater than
180
* zero, depending on whether lhs < rhs, lhs == rhs, or lhs > rhs
181
* Warning: may return values other than -1, 0, or 1
183
static int compare(const Value& lhs, const Value& rhs);
186
bool operator==(const Value& v1, const Value& v2) {
187
if (v1._storage.identical(v2._storage)) {
191
return (Value::compare(v1, v2) == 0);
194
/// This is for debugging, logging, etc. See getString() for how to extract a string.
195
string toString() const;
196
friend ostream& operator << (ostream& out, const Value& v);
198
void swap(Value& rhs) {
199
_storage.swap(rhs._storage);
202
/** Figure out what the widest of two numeric types is.
204
* Widest can be thought of as "most capable," or "able to hold the
205
* largest or most precise value." The progression is Int, Long, Double.
276
207
static BSONType getWidestNumeric(BSONType lType, BSONType rType);
279
Get the approximate storage size of the value, in bytes.
281
@returns approximate storage size of the value.
209
/// Get the approximate memory size of the value, in bytes. Includes sizeof(Value)
283
210
size_t getApproximateSize() const;
286
Calculate a hash value.
288
Meant to be used to create composite hashes suitable for
289
boost classes such as unordered_map<>.
291
@param seed value to augment with this' hash
293
void hash_combine(size_t &seed) const;
296
struct Hash is defined to enable the use of Values as
297
keys in boost::unordered_map<>.
299
Values are always referenced as immutables in the form
300
intrusive_ptr<const Value>, so these operate on that construction.
303
unary_function<intrusive_ptr<const Value>, size_t> {
304
size_t operator()(const intrusive_ptr<const Value> &rV) const;
212
/** Calculate a hash value.
214
* Meant to be used to create composite hashes suitable for
215
* hashed container classes such as unordered_map<>.
217
void hash_combine(size_t& seed) const;
219
/// struct Hash is defined to enable the use of Values as keys in unordered_map.
220
struct Hash : unary_function<const Value&, size_t> {
221
size_t operator()(const Value& rV) const;
308
Value(); // creates null value
309
Value(BSONType type); // creates an empty (unitialized value) of type
310
// mostly useful for Undefined
311
Value(bool boolValue);
224
/// Call this after memcpying to update ref counts if needed
225
void memcpyed() const { _storage.memcpyed(); }
227
// LEGACY creation functions
228
static Value createFromBsonElement(const BSONElement* pBsonElement);
229
static Value createInt(int value) { return Value(value); }
230
static Value createLong(long long value) { return Value(value); }
231
static Value createDouble(double value) { return Value(value); }
232
static Value createTimestamp(const OpTime& value) { return Value(value); }
233
static Value createString(const string& value) { return Value(value); }
234
static Value createDocument(const Document& doc) { return Value(doc); }
235
static Value createArray(const vector<Value>& vec) { return Value(vec); }
236
static Value createDate(const long long value);
315
Value(BSONElement *pBsonElement);
317
Value(long long longValue);
318
Value(double doubleValue);
319
Value(const OpTime& timestampValue);
320
Value(const string &stringValue);
321
Value(const intrusive_ptr<Document> &pDocument);
322
Value(const vector<intrusive_ptr<const Value> > &vpValue);
324
void addToBson(Builder *pBuilder) const;
328
// store values that don't need a ctor/dtor in one of these
334
ReplTime timestampValue;
335
unsigned char oidValue[12];
336
// The member below is redundant, but useful for clarity and searchability.
340
string stringValue; // String, Regex, Symbol
341
intrusive_ptr<Document> pDocumentValue;
342
vector<intrusive_ptr<const Value> > vpValue; // for arrays
345
These are often used as the result of boolean or comparison
348
These are obtained via public static getters defined above.
350
static const intrusive_ptr<const Value> pFieldUndefined;
351
static const intrusive_ptr<const Value> pFieldNull;
352
static const intrusive_ptr<const Value> pFieldTrue;
353
static const intrusive_ptr<const Value> pFieldFalse;
354
static const intrusive_ptr<const Value> pFieldMinusOne;
355
static const intrusive_ptr<const Value> pFieldZero;
356
static const intrusive_ptr<const Value> pFieldOne;
358
/* this implementation is used for getArray() */
360
public ValueIterator {
362
// virtuals from ValueIterator
364
virtual bool more() const;
365
virtual intrusive_ptr<const Value> next();
369
vi(const intrusive_ptr<const Value> &pSource,
370
const vector<intrusive_ptr<const Value> > *pvpValue);
374
const vector<intrusive_ptr<const Value> > *pvpValue;
380
Equality operator for values.
382
Useful for unordered_map<>, etc.
384
inline bool operator==(const intrusive_ptr<const Value> &v1,
385
const intrusive_ptr<const Value> &v2) {
386
return (Value::compare(v1, v2) == 0);
390
For performance reasons, there are various sharable static values
391
defined in class Value, obtainable by methods such as getUndefined(),
392
getTrue(), getOne(), etc. We don't want these to go away as they are
393
used by a multitude of threads evaluating pipelines. In order to avoid
394
having to use atomic integers in the intrusive reference counter, this
395
class overrides the reference counting methods to do nothing, making it
396
safe to use for static Values.
398
At this point, only the constructors necessary for the static Values in
399
common use have been defined. The remainder can be defined if necessary.
404
// virtuals from IntrusiveCounterUnsigned
405
virtual void addRef() const;
406
virtual void release() const;
410
ValueStatic(BSONType type);
411
ValueStatic(bool boolValue);
412
ValueStatic(int intValue);
239
/** This is a "honeypot" to prevent unexpected implicit conversions to the accepted argument
240
* types. bool is especially bad since without this it will accept any pointer.
242
* Template argument name was chosen to make produced error easier to read.
244
template <typename InvalidArgumentType>
245
explicit Value(const InvalidArgumentType& invalidArgument);
247
// does no type checking
248
StringData getStringData() const; // May contain embedded NUL bytes
250
ValueStorage _storage;
251
friend class MutableValue; // gets and sets _storage.genericRCPtr
253
BOOST_STATIC_ASSERT(sizeof(Value) == 16);
257
// This is used by std::sort and others
259
inline void swap(mongo::Value& lhs, mongo::Value& rhs) { lhs.swap(rhs); }
416
262
/* ======================= INLINED IMPLEMENTATIONS ========================== */
418
264
namespace mongo {
420
inline BSONType Value::getType() const {
424
266
inline size_t Value::getArrayLength() const {
425
267
verify(getType() == Array);
426
return vpValue.size();
429
inline intrusive_ptr<const Value> Value::getUndefined() {
430
return pFieldUndefined;
433
inline intrusive_ptr<const Value> Value::getNull() {
437
inline intrusive_ptr<const Value> Value::getTrue() {
441
inline intrusive_ptr<const Value> Value::getFalse() {
445
inline intrusive_ptr<const Value> Value::getMinusOne() {
446
return pFieldMinusOne;
449
inline intrusive_ptr<const Value> Value::getZero() {
453
inline intrusive_ptr<const Value> Value::getOne() {
457
inline size_t Value::Hash::operator()(
458
const intrusive_ptr<const Value> &rV) const {
268
return getArray().size();
271
inline size_t Value::Hash::operator()(const Value& v) const {
459
272
size_t seed = 0xf0afbeef;
460
rV->hash_combine(seed);
273
v.hash_combine(seed);
464
inline ValueStatic::ValueStatic():
468
inline ValueStatic::ValueStatic(BSONType type):
472
inline ValueStatic::ValueStatic(bool boolValue):
476
inline ValueStatic::ValueStatic(int intValue):
277
inline StringData Value::getStringData() const {
278
return _storage.getString();
281
inline string Value::getString() const {
282
verify(getType() == String);
283
return _storage.getString().toString();
286
inline OID Value::getOid() const {
287
verify(getType() == jstOID);
288
return OID(_storage.oid);
291
inline bool Value::getBool() const {
292
verify(getType() == Bool);
293
return _storage.boolValue;
296
inline long long Value::getDate() const {
297
verify(getType() == Date);
298
return _storage.dateValue;
301
inline OpTime Value::getTimestamp() const {
302
verify(getType() == Timestamp);
303
return _storage.timestampValue;
306
inline const char* Value::getRegex() const {
307
verify(getType() == RegEx);
308
return _storage.getString().rawData(); // this is known to be NUL terminated
310
inline const char* Value::getRegexFlags() const {
311
verify(getType() == RegEx);
312
const char* pattern = _storage.getString().rawData(); // this is known to be NUL terminated
313
const char* flags = pattern + strlen(pattern) + 1; // first byte after pattern's NUL
314
dassert(flags + strlen(flags) == pattern + _storage.getString().size());
318
inline string Value::getSymbol() const {
319
verify(getType() == Symbol);
320
return _storage.getString().toString();
322
inline string Value::getCode() const {
323
verify(getType() == Code);
324
return _storage.getString().toString();
327
inline int Value::getInt() const {
328
verify(getType() == NumberInt);
329
return _storage.intValue;
332
inline long long Value::getLong() const {
333
BSONType type = getType();
334
if (type == NumberInt)
335
return _storage.intValue;
337
verify(type == NumberLong);
338
return _storage.longValue;