SET search_path TO documentdb_api,documentdb_core,documentdb_api_catalog;
SET documentdb.next_collection_id TO 2000;
SET documentdb.next_collection_index_id TO 2000;

-- replace document scenarios
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1}', '{ "": { "_id": 1, "b": 2 } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- allow updating ID if it's type compatible
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1}', '{ "": { "_id": 1.0, "b": 2 } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- ID mismatch not allowed: error
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1}', '{ "": { "_id": 2.0, "b": 2 } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- ID not specified - pick the ID from the source document
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1}', '{ "": { "b": 2 } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- upsert case: Creates a new document.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "_id": 2.0, "b": 2 } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- upsert case: no id specified creates a new ID
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{}', NULL, NULL, NULL) @? '{ "_id" : 1 }';

-- upsert case: no id specified creates from filter
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$and": [ { "a": 1, "_id": 2.0 }]}', NULL, NULL, NULL) as update_bson_document;

-- upsert case: no id specified autogenerates when _id filter is not $eq.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$and": [ { "a": 1, "_id": { "$gt": 2.0 } }]}', NULL, NULL, NULL) @? '{ "_id" : 1 }';
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$and": [ { "a": 1, "_id": { "$lt": 2.0 } }]}', NULL, NULL, NULL) @? '{ "_id" : 1 }';
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$or": [ { "a": 1, "_id": 2.0 } ]}', NULL, NULL, NULL) @? '{ "_id" : 1 }';
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$or": [ { "a": 1 }, { "_id": 3 } ] }', NULL, NULL, NULL) @? '{ "_id" : 1 }';

-- would be nice to use the $type function.
SELECT bson_get_value(documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$or": [ { "a": 1, "_id": 2.0 } ]}', NULL, NULL, NULL), '_id') @=  '{ "" : 2.0 }';
SELECT bson_get_value(documentdb_api_internal.update_bson_document('{}', '{ "": { "b": 2 } }', '{"$or": [ { "a": 1 }, { "_id": 3 } ] }', NULL, NULL, NULL), '_id') @!= '{ "" : 3 }';

-- upsert case: $comment in the query predicate is request-only metadata. By default the
-- enableSkipCommentFieldOnUpsert flag is on, so $comment is skipped and never persisted
-- onto the generated document.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "dropbox-users" } } }', '{ "id": "g1", "appId": 11627, "$comment": "ctx=trace", "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- By default $comment nested within $and is likewise not persisted, while sibling fields are.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "dropbox-users" } } }', '{ "$and": [ { "id": "g1", "appId": 11627, "_id": 5 }, { "$comment": "ctx=trace" } ] }', NULL, NULL, NULL) as update_bson_document;

-- With the flag disabled, $comment is materialized into the generated document,
-- preserving the historical behavior for existing customers that rely on it.
SET documentdb.enableSkipCommentFieldOnUpsert TO off;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "dropbox-users" } } }', '{ "id": "g1", "appId": 11627, "$comment": "ctx=trace", "_id": 5 }', NULL, NULL, NULL) as update_bson_document;
RESET documentdb.enableSkipCommentFieldOnUpsert;

-- upsert case: filter-only query operators are never persisted onto the generated document.
-- $alwaysTrue at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$alwaysTrue": 1, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $alwaysFalse at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$alwaysFalse": 1, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $text at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$text": { "$search": "hello" }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $where at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$where": "true", "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $jsonSchema at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$jsonSchema": { "required": ["a"] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $sampleRate at top level is skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$sampleRate": 0.5, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- Filter-only operators nested within $and are also skipped.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$and": [ { "a": 1, "_id": 5 }, { "$alwaysTrue": 1 } ] }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$and": [ { "a": 1, "_id": 5 }, { "$alwaysFalse": 1 } ] }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$and": [ { "a": 1, "_id": 5 }, { "$where": "true" } ] }', NULL, NULL, NULL) as update_bson_document;

-- Multiple filter-only operators combined with regular fields.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$alwaysTrue": 1, "$alwaysFalse": 0, "a": 1, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $expr at top level still errors on upsert.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$expr": { "$eq": ["$a", 1] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $expr within $and also errors on upsert.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "$and": [ { "_id": 5 }, { "$expr": { "$eq": ["$a", 1] } } ] }', NULL, NULL, NULL) as update_bson_document;

-- Field-level comparison operators are not equality, so they do NOT contribute
-- values to the upsert document. Only $eq, $all, and single-element $in do.

-- $bitsAllClear is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$bitsAllClear": [1, 5] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $bitsAllSet is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$bitsAllSet": [1, 5] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $bitsAnyClear is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$bitsAnyClear": [1, 5] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $bitsAnySet is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$bitsAnySet": [1, 5] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $exists is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$exists": true }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $type is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$type": "int" }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $mod is a filter — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$mod": [2, 0] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $gt/$lt are filters — field "a" is not persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$gt": 5, "$lt": 10 }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $eq contributes equality — field "a" IS persisted.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$eq": 42 }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

-- $eq combined with $bitsAllClear — only $eq value contributes.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "name": "test" } } }', '{ "a": { "$eq": 42, "$bitsAllClear": [1] }, "_id": 5 }', NULL, NULL, NULL) as update_bson_document;

SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "_id": 3, "b": 2 } }', '{"$and": [ { "a": 1, "_id": 2.0 }]}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$setOnInsert": {"_id.b": 1}, "$set":{ "_id": 1 } } }', '{"_id.a": 4}', NULL, NULL, NULL);

-- _id specified twice, failure for update.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "_id": 3, "b": 2 } }', '{"$and": [ { "a": 1 }, {"_id": 2.0 }, { "_id": 3.0 }]}', NULL, NULL, NULL);

-- update scenario tests: $set
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1 }', '{ "": { "$set": { "a": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$set": { "a": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$set": { "a.1": "somePath" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": { "c": 3 }} }', '{ "": { "$set": { "a.b.c": "somePath" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [1, 2, 3 ]} }', '{ "": { "$set": { "a.b.7": 9, "a.b.10": 13 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [1, 2, 3 ]} }', '{ "": { "$set": { "a.b.7": 9, "a.b.10": 13 }, "$unset": { "a.b.6": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [1, 2, 3 ]} }', '{ "": { "$set": { "a.b.1": { "sub": "1234" }, "a.b.5": [1, 2, 3 ] } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 2 }', '{ "": { "$set": { "b.c.d": { "sub": "1234" } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": { "c": 3 }} }', '{ "": { "$set": { "a.b.c": "somePath", "a.b.c": false } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [] }', '{ "": { "$set": { "a.2.b": 1, "a.2.c": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [] }', '{ "": { "$set": { "a.1500001": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- update scenario tests: $inc
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$inc": { "a.b": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": { "c": 3 }} }', '{ "": { "$set": { "a.b.c": "somePath", "a.b.c": 10 }, "$inc": { "a.b.c": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 2 }', '{ "": { "$set": { "b.c": 10 }, "$inc": { "b.c": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 2 }', '{ "": { "$inc": { "b.c": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [ 1, 2, 3 ] }', '{ "": { "$inc": { "a.2": 2, "a.6": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberLong": "9223372036854775807"} }', '{ "": { "$inc": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberLong": "-9223372036854775808"} }', '{ "": { "$inc": { "a": -1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id":{"$oid":"5d505646cf6d4fe581014ab2"}, "a": {"$numberLong": "9223372036854775807"} }', '{ "": { "$inc": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberDouble": "9223372036854775807"} }', '{ "": { "$inc": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- update scenario tests: $min
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.b": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.b": true } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.b": null } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.b": [1, 2, 3 ] } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.c": [1, 2, 3 ] } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$min": { "a.1": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$min": { "a.1": 3 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$set": { "a.1": -1 }, "$min": { "a.1": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$min": { "a.b": {"$numberDecimal": "9.99e-100"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- update scenario tests: $max
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.b": 3 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.b": true } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.b": null } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.b": [1, 2, 3 ] } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.c": [1, 2, 3 ] } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$max": { "a.1": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$max": { "a.1": 3 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1, 2, 3 ] }', '{ "": { "$set": { "a.1": 3 }, "$max": { "a.1": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$max": { "a.b": {"$numberDecimal": "9.99e100"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- update scenario tests: $bit
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : {  "and" : 10 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :3}', '{ "": { "$bit": { "expdata" : {  "or" : 5 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :1}', '{ "": { "$bit": { "expdata" : {  "xor" : 5 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :[13,3,1]}', '{ "": { "$bit": { "expdata.0" : { "and" :10 }  }  }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : { "and" : 0, "or" : 10 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : { "or" : 10, "xor" : 10 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1}', '{ "": { "$bit": { "expdata" : { "or" : 10 }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": { "x": { "y": [ 100, 200 ]}}, "f": 12 }', '{ "": { "$bit": {"key.x.y.0": {"and": 10}, "f": {"and": 10 }}}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": { "x": { "y": 10 }}, "f": 1}', '{ "": { "$bit": { "key.x.y": { "xor": 10 } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": { "y": [100 , 200 ] } }, "f": 1 } ', '{ "": { "$bit": { "key.x.y.0": { "and": 10 } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": 1 , "f": 1 } ', '{ "": { "$bit": { "x": { "and": { "$numberLong": "1" } } } } }', '{}', NULL, NULL, NULL) as update_bson_document;


-- update scenario negative tests: $bit
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :"abc"}', '{ "": { "$bit": { "expdata" : { "or" :10 }  }  }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : { "or" :10.0 }  }  }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : { "ors" :10 }  }  }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :[1,2,3]}', '{ "": { "$bit": { "expdata" : { "or" :10 }  }  }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "expdata" :13}', '{ "": { "$bit": { "expdata" : {  }} }}', '{}', NULL, NULL, NULL);
/* TODO: Make the error compatible with mongo: "errmsg" : "Cannot create field 'y' in element {x: [ { y: 10 } ]}"  */
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": [ { "y": 10 } ] }}', '{ "": { "$bit": { "key.x.y": { "and": 0 }}}}', '{}', NULL, NULL, NULL);


-- update scenario tests: $addToSet
SELECT documentdb_api_internal.update_bson_document('{"_id":1 }', '{ "": {"$addToSet": { "letters": "a" } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1 }', '{ "": {"$addToSet": { "letters": {"a":"b", "c":"d"} } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1 }', '{ "": {"$addToSet": { "letters": {"$each" : ["a", "b","c"]} } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "letters": {"c":"d", "e":"f", "g":"h" }} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "letters": "c" } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "letters": ["c", "d"] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "letters": "a" } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "letters": ["a", "b"] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a", "b"]}', '{ "": {"$addToSet": { "c":123456} }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "colors": "blue, green, red" }', '{ "": { "$addToSet": { "newColors": "mauve" } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "colors": ["blue, green, red"] }', '{ "": { "$addToSet": { "colors": {} } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "colors": ["blue, green, red", { }] }', '{ "": { "$addToSet": { "colors": {} } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$each": ["c", "d"]}}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$each": [ { } ]}}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "numbers": [44,78,80,80,80] }', '{ "": { "$addToSet": { "numbers": 80 }} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$each" : ["c","d","c","d","c","e","d","e"] }}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b","e"] }', '{ "": { "$addToSet": { "letters": { "$each" : ["a","b","c","d","e"] }}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "numbers": [1,2,5] }', '{ "": { "$addToSet": { "numbers": { "$each" : [1,2,3,4,5,5,4,3,2,1] }}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": { "y": [100 , 200 ] } }, "f": 1 } ', '{ "": { "$addToSet": { "key.x.y": { "$each": [3, 5, 6] } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": { "y": [100 , 200, "a" ] } }, "f": 1 } ', '{ "": { "$addToSet": { "key.x.y": { "$each": [3, 5, 6, 7,8,9,"a","b","a",7,8] } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": { "x": { "y": [ 100,3,6 ]}}, "f": [1,3] }', '{ "": { "$addToSet": {"key.x.y": {"$each": [1, 3, 6, 9,"b","a"]}, "f": {"$each": [1,2,4] }}}}', '{}', NULL, NULL, NULL) as update_bson_document;



-- Update scenario for some complex items: $addToSet
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$addToSet": { "letters": { "$each": [1,3,4] } } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$addToSet": { "letters": { "$each": [[1,3,4]] } } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$addToSet": { "letters.0": { "$each": [1,3,4] } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": {"$addToSet": { "letters.0": { "$each": [1,3,4, { "a":2}, {"a":3} ] } }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": {"$addToSet": { "letters.0": { "$each": [4,{"a":3} ] }, "letters.1.a": { "$each": [4, {"a":2}] }  } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$addToSet" : {"a.3": 4 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$addToSet" : {"a.7": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],[3]]}', '{ "": { "$addToSet" : {"a.0.5": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],3]}', '{ "": { "$addToSet" : {"a.2.5": 7 } } }', '{}', NULL, NULL, NULL);

-- $addToSet with empty $each and $set - test duplicate field fix
SET documentdb.enableDuplicateFieldFix TO off;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [], "x": 0}', '{ "": {"$addToSet":{"arr":{"$each":[]}}, "$set":{"x":1}} }', '{}', NULL, NULL, NULL) as update_bson_document;

SET documentdb.enableDuplicateFieldFix TO on;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [], "x": 0}', '{ "": {"$addToSet":{"arr":{"$each":[]}}, "$set":{"x":1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
RESET documentdb.enableDuplicateFieldFix;

-- $addToSet with $each must reject $position/$slice/$sort ($push-only modifiers are invalid here)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$each": [3,4], "$position": 1 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$each": [3,4], "$slice": 2 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$each": [3,4], "$sort": 1 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$position": 1, "$each": [3,4] } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $addToSet with no $each: dollar-prefixed key is treated as a literal value to add
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$position": 1 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- GUC off path: lenient mode preserved (no error, modifier silently ignored)
SET documentdb.enableStrictAddToSetModifierValidation TO off;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1,2]}', '{ "": { "$addToSet": { "key": { "$each": [3,4], "$position": 1 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
RESET documentdb.enableStrictAddToSetModifierValidation;

-- update scenario negative tests: $inc
SELECT documentdb_api_internal.update_bson_document('{"_id": 5, "a": [1,2] }', '{ "": { "$inc": { "a": 30 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 5, "a": {"x":1} }', '{ "": { "$inc": { "a": 30 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 5, "a": "b" }', '{ "": { "$inc": { "a": 30 } } }', '{}', NULL, NULL, NULL);

-- update scenario negative tests: $addToSet
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "colors": "blue, green, red" }', '{ "": { "$addToSet": { "colors": "mauve" } }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$each": "c"}}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$each" : {} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "letters": ["a","b"] }', '{ "": { "$addToSet": { "letters": { "$ach": ["c"]}}} }', '{}', NULL, NULL, NULL);


-- update scenario tests: $unset
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$unset": { "a.b": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2, "c": 3 }, "d": 1 }', '{ "": { "$unset": { "a.b": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [ 1, 2, 3 ] } }', '{ "": { "$unset": { "a.b.1": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [ 1, 2, 3 ] } }', '{ "": { "$unset": { "a.b.5": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1 }', '{ "": { "$unset": { "a": 1, "b.c": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;


-- update scenario tests: $rename
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$rename": { "a.b": "c.d" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$rename": { "a.b": "a.c" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$rename": { "a": "c" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1 }', '{ "" : { "$rename": { "b": "c" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1, "c": 4}', '{ "": { "$rename": { "b": "c.d" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- $rename when rename source node doesn't exist but target node exist, this should be a no-op
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1, "c": 4}', '{ "": { "$rename": { "b": "a" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": {"b": 1, "d": 2}}', '{ "": { "$rename": { "a.b": "c" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": {"b": 1}}', '{ "": { "$rename": { "a.b": "d" } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1}', '{ "": { "$rename": { "b": "a" }, "$set": {"x" : 1} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "a": 1, "x": 1}', '{ "": { "$rename": { "b": "a" }, "$inc": {"x" : 1} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "b": 1, "x": 1}', '{ "": { "$rename": { "a": "b", "x": "y" } } }', '{}', NULL, NULL, NULL) as update_bson_document;


-- update scenario tests: $mul
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble" : "2.0"} } }', '{ "": { "$mul": { "a.b": 0 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt" : "2" } } }', '{ "": { "$mul": { "a.b": 0 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong" : "2" } } }', '{ "": { "$mul": { "a.b": 0 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong" : "9223372036854775807" } } }', '{ "": { "$mul": { "a.b": {"$numberLong": "0"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble" : "0.0"} } }', '{ "": { "$mul": { "a.b": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt" : "0" } } }', '{ "": { "$mul": { "a.b": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong" : "0" } } }', '{ "": { "$mul": { "a.b": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": -10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": {"$numberDouble": "+1.0"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": 1.1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": -1.1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.c": {"$numberInt": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.c": {"$numberLong": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.c": {"$numberDouble": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.c": {"$numberDecimal": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt": "100"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "500"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt": "2147483647"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "2147483647"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt": "2147483647"} } }', '{ "": { "$mul": { "a.b": {"$numberLong": "2147483647"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt": "2147483647"} } }', '{ "": { "$mul": { "a.b": {"$numberDouble": "2.0"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "2147483647"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "-2147483647"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "2147483647"} } }', '{ "": { "$mul": { "a.b": {"$numberLong": "-2147483647"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "9223372036854775807"} } }', '{ "": { "$mul": { "a.b": {"$numberDouble": "2.0"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble": "10.0"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble": "10.0"} } }', '{ "": { "$mul": { "a.b": {"$numberLong": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble": "10.0"} } }', '{ "": { "$mul": { "a.b": {"$numberDouble": "2.0"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": NaN } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": NaN } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDecimal": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberInt": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberDecimal": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDecimal": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberLong": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberDecimal": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDecimal": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberDouble": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberDouble": "10"} } }', '{ "": { "$mul": { "a.b": {"$numberDecimal": "2"} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- int64 overflow should coerce to double: $mul
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "9223372036854775807"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "2"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {"$numberLong": "-9223372036854775807"} } }', '{ "": { "$mul": { "a.b": {"$numberInt": "2"} } } }', '{}', NULL, NULL, NULL);

-- update scenario error tests: $mul
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$mul": { "a.b": "Hello" } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": "Text" } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [1,2,3] } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": {} } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": null } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": true } }', '{ "": { "$mul": { "a.b": 2 } } }', '{}', NULL, NULL, NULL);


-- $pullAll operator- positive testcases
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : [ 0, 2, 5, 5, 1, 0 ] }', '{ "": { "$pullAll": { "scores": [0,5] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$pullAll": { "letters": [1,3,4] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$pullAll": { "letters.0": [1,3,4] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : [ 0, 2, 5, 5, 1, 0 ] }', '{ "": { "$pullAll": { } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : [ 0, 2, 5, 5, 1, 0 ] }', '{ "": { "$pullAll": { "score": [0,5] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : [ 0, 2, 5, 5, 1, 0 ] }', '{ "": { "$pullAll": { "a.b": [0,5] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : {} }', '{ "": { "$pullAll": { "scores.top": [0,5] } }}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : {"top": [0,5,10,11]} }', '{ "": { "$pullAll": { "scores.top": [0,5] } }}', '{}', NULL, NULL, NULL) as update_bson_document;


-- $pullAll operator- negative testcases
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : [ 0, 2, 5, 5, 1, 0 ] }', '{ "": { "$pullAll": { "scores": 0 } }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "scores" : "a" }', '{ "": { "$pullAll": { "scores": [0] } }}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "letters" : [ [ 1, { "a" : 2 } ], { "a" : [ 1, 2 ] } ] }', '{ "": { "$pullAll": { "letters.1": [1,3,4] } }}', '{}', NULL, NULL, NULL);


-- rename overwrites.
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2, "c": 1 } }', '{ "": { "$rename": { "a.b": "a.c" } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- update scenario tests: $setOnInsert (non-upsert)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": 2 } }', '{ "": { "$setOnInsert": { "a.b": 1, "c": 2, "d": 4 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- upsert:
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "_id": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2 } } }', '{ "_id": 1 }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2 } } }', '{ "_id": { "$eq": 1 } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "h": 6 } } }', '{ "_id": { "$eq": 1 }, "f": 3, "g": 4, "h": 5 }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "h": 6 } } }', '{ "$and": [ { "_id": { "$eq": 1 }}, {"f": 3 }, { "g": 4 }, { "h": 5 } ] }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "h": 6 } } }', '{ "_id": { "$eq": 1 }, "$or": [ { "_id": { "$eq": 1 }}, {"f": 3 }, { "g": 4 }, { "h": 5 } ] }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "h": 6 } } }', '{ "_id": { "$eq": 1 }, "$or": [ { "g": 4 } ] }', NULL, NULL, NULL) as update_bson_document;

--upsert querySpec has document
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 5, "_id": 1 } } }', '{"a.x.y":10}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.y": 5, "_id": 1 } } }', '{"a.x":{"c":"d"}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.y": 10, "_id": 1 } } }', '{"a": {"x":5}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": {"b":5}, "_id": 1 } } }', '{"a.c":8}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": {"x":{"z":10}}, "_id": 1} }}', '{"a":{"x":{"y":5}}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.x.z": 10, "_id": 1 } } }', '{"a":{"x":{"y":5}}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": {"x":{"z":10}}, "_id": 1 } } }', '{"a.x.y":10}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.x.z":10, "_id": 1 } } }', '{"a.x.y":10}', NULL, NULL, NULL) as update_bson_document;


--upsert querySpec has array
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.11":11, "_id": 1 } } }', '{"a":[0,1,2,3,4,5,6,7,8,9,10]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.0":0, "a.6":6, "_id": 1 } } }', '{"a":[8,1,2,3]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.0":1, "a.1":2, "_id": 1 } } }', '{"a":[{"x":1},{"x":2},{"x":3}]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.0.1": 5 , "_id": 1} } }', '{"a":[[1,2],[3,4]]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a.0.x": 10 , "_id": 1} } }', '{"a":[{"x":1},{"x":2}]}', NULL, NULL, NULL) as update_bson_document;

--upsert $rename cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a": "b"}, "$set":{ "_id": 1 } } }', '{"b":1}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "b": "a"}, "$set":{ "_id": 1 } } }', '{"b":1}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a.b": "a.c"}, "$set":{ "_id": 1 } } }', '{"a.b":10}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a.b": "a.c"}, "$set":{ "_id": 1 } } }', '{"a":{"b":10}}', NULL, NULL, NULL) as update_bson_document;
--upsert querySpec with $gt, $lt, $gte, $lte
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id":1} } }', '{"a.1":{"$gt": 100},"a.2":{"x":10}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id":1} } }', '{"a.x":{"$lt": 100},"a.y":{"x":10}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id":1} } }', '{"a.x":{"$gte": 100},"a.y":{"x":10}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id":1} } }', '{"a.x":{"$lte": 100},"a.y":{"x":10}}', NULL, NULL, NULL) as update_bson_document;

-- upsert querySpec with implicit AND - valid cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$eq": 2, "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document; 
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$eq": 2, "$gt": 20, "$lt": 40 } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$all": [ 2 ], "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$all": [ 2 ], "$ne": 40 } }', NULL, NULL, NULL) as update_bson_document;

-- upsert querySpec with implicit AND - Invalid cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$eq": 2, "$all": [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$eq": 2, "$all": [ 2 ], "$in" : [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$all": [ 2, 1 ], "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": 1, "a": 1} } }', '{"b": { "$all": [ 2, 1 ], "$in": [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;

-- upsert querySpec with implicit AND on "_id" - valid cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$eq": 2, "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document; 
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$eq": 2, "$gt": 20, "$lt": 40 } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$all": [ 2 ], "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$all": [ 2 ], "$ne": 40 } }', NULL, NULL, NULL) as update_bson_document;

-- upsert querySpec with implicit AND on "_id" - Invalid cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$eq": 2, "$all": [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$eq": 2, "$all": [ 2 ], "$in" : [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$all": [ 2, 1 ], "$in": [ 1, 2 ] } }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 1} } }', '{"_id": { "$all": [ 2, 1 ], "$in": [ 2 ] } }', NULL, NULL, NULL) as update_bson_document;


-- cannot modify id cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "_id": 2 } } }', '{ "_id": 1 }', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1 }', '{ "": { "$set": { "_id": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1 }', '{ "": { "$inc": { "_id": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1 }', '{ "": { "$max": { "_id": 2 } } }', '{}', NULL, NULL, NULL);

-- Multiple operators: no-op
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {}, "x": 0 }', '{ "": { "$pullAll": { "a.b": [0] }, "$unset": { "d": 1 }, "$mul": { "x": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {}, "x": 0 }', '{ "": { "$pullAll": { "a.b": [0] }, "$unset": { "d": 1 }, "$bit": { "x": { "and": 0 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- Multiple operators at least one update
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [0,0,0,0,4], "x": 0 }', '{ "": { "$pullAll": { "a": [0] }, "$unset": { "d": 1 }, "$mul": { "x": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [0,0,0,0,4], "x": 10 }', '{ "": { "$pullAll": { "b": [0] }, "$unset": { "a": 1 }, "$mul": { "x": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"b": [0,0,0,0,0,1,1,1,2]}, "x": 10 }', '{ "": { "$pullAll": { "a.b": [0,1] }, "$set": { "d": 1 }, "$mul": { "x": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- aggregation pipeline: project & unset

-- -- simple case for project
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$project": { "a": 1, "c": { "$literal": 2.0 }} }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$project": { "b": 0 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;

SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "x": 1, "y": [{ "z": 1, "foo": 1 }] }', '{ "": [ { "$unset": ["x", "y.z"] } ] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 2, "title": "Bees Babble", "isbn": "999999999333", "author": { "last": "Bumble", "first": "Bee" }, "copies": [{ "warehouse": "A", "qty": 2 }, { "warehouse": "B", "qty": 5 }] }', '{ "": [ { "$unset": "copies" } ] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 2, "title": "Bees Babble", "isbn": "999999999333", "author": { "last": "Bumble", "first": "Bee" }, "copies": [{ "warehouse": "A", "qty": 2 }, { "warehouse": "B", "qty": 5 }] }', '{ "": [ { "$unset": ["isbn", "author.first", "copies.warehouse"] } ] }', '{}', NULL, NULL, NULL) as update_bson_document;

SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$project": { "_id": 1, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL) as update_bson_document;

-- -- project with upsert uses fields from query
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": [ { "$project": { "b": { "$literal": 2.0 }, "d": 1 } }] }', '{ "d" : 1, "_id": 2.0 }', NULL, NULL, NULL) as update_bson_document;

-- -- project and unset (shoudl just project _id )
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$unset": "b" }, { "$project": { "b": 1 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;

-- project and unset silently ignore removing the _id field.
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$unset": "_id" }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$project": { "_id": 0 } } ] }', '{}', NULL, NULL, NULL) as update_bson_document;

-- -- simple case for addFields
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$addFields": { "a": 1, "c": { "$literal": 2.0 }} }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$addFields": { "b": 0 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$addFields": { "_id": 1, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$addFields": { "_id": 10, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$addFields": { "_id": 30.5, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$addFields": { "_id": false, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$addFields": { "_id": "someString", "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": [ { "$addFields": { "b": { "$literal": 2.0 }, "d": 1 } }] }', '{ "d" : 1, "_id": 2.0 }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$unset": "b" }, { "$addFields": { "b": 1 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;


-- -- simple case for set
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$set": { "a": 1, "c": { "$literal": 2.0 }} }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$set": { "b": 0 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$set": { "_id": 1, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$set": { "_id": 10, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$set": { "_id": 30.5, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$set": { "_id": false, "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 1, "name": "John Doe" }', '{ "": [ { "$set": { "_id": "someString", "name": 1 } }, { "$unset": "name" } ] }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": [ { "$set": { "b": { "$literal": 2.0 }, "d": 1 } }] }', '{ "d" : 1, "_id": 2.0 }', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$unset": "b" }, { "$set": { "b": 1 } }] }', '{}', NULL, NULL, NULL) as update_bson_document;

-- simple case for replaceRoot
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$replaceRoot" : { "newRoot": { "a_key" : "$a" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceRoot" : { "newRoot": { "a_b_key" : "$a.b" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceRoot" : { "newRoot": { "a_b_key" : "$a.b", "a_key" : "$a", "a_b_arr_key" : "$a.b.arr" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceRoot" : { "newRoot": "$a.b" }}]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceRoot" : { "newRoot":  {"$mergeObjects":  [ { "dogs": 0, "cats": 0, "birds": 0, "fish": 0 }, "$a.b" ] } }}]}', '{}', NULL, NULL, NULL) as update_bson_document;

-- simple case for replaceWith
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "b": 2 }', '{ "": [ { "$replaceWith" : { "newRoot": { "a_key" : "$a" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b" : 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceWith" : { "newRoot": { "a_b_key" : "$a.b" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceWith" : { "newRoot": { "a_b_key" : "$a.b", "a_key" : "$a", "a_b_arr_key" : "$a.b.arr" }} }]}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "a": { "b": {"arr" : [1, 2, 3, {}], "a" : {"b": 1}, "int" : 1} }, "b": 2 }', '{ "": [ { "$replaceWith" : { "newRoot": "$a.b" }}]}', '{}', NULL, NULL, NULL) as update_bson_document;

-- update: Error cases:
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b": [1, 2, 3 ]} }', '{ "": { "$set": { "a.b.7": 9, "a.b.10": 13 }, "$unset": { "a.b.7": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [ { "b": 2 } ] }', '{ "": { "$rename": { "a.0": "b" } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [ { "b": 2 } ] }', '{ "": { "$rename": { "a.0.b": "a.1.c" } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "a": 2, "h": 6 } } }', '{ "_id": { "$eq": 1 }, "c": 3, "$and": [ { "c": 4 } ] }', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"a": [1], "b": {"c": [2]}, "d": [{"e": 3}], "f": 4}', '{ "": { "$rename" :{"f":"d.e"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"a": [1], "b": {"c": [2]}, "d": [{"e": 3}], "f": 4}', '{ "": { "$rename" :{"f":"d.e"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"a": [1], "b": {"c": [2]}, "d": [{"e": 3}], "f": 4}', '{ "": { "$rename" :{"d.e":"d.c"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"a": [1], "b": {"c": [2]}, "d": [{"e": 3}], "f": 4}', '{ "": { "$rename" :{"f":"a.0"}} }', '{}', NULL, NULL, NULL);

-- $push top level input validation with all modifiers
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberInt" : "2"}}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberLong" : "2"}}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberDouble" : "2.0"}}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"b" : [1,2,3]}}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": false}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": NaN}', '{ "": { "$push" :{"a":"0"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": "6" }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": 6 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": {"a": 6} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$slice": 1.1 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$slice": "2" }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$slice": true }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$slice": [1,2,3] }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": 0 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": -2 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": 2 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": 1.1 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": {"a.b": -2} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": {"a.": -2} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": {".b.c": -2} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": {"": 1} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$sort": {} }}} }', '{}', NULL, NULL, NULL);
-- TODO: Make the error compatible with mongo: "errmsg" : "Cannot create field 'y' in element {x: [ { y: 1 } ]}"
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": [{"y": [1]}, {"y": [2]}]}}', '{ "": { "$push" :{"key.x.y": 1 }}}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": [{"y": [1]}, {"y": [2]}]}}', '{ "": { "$push" :{ "key.x": { "$each": [], "badplugin": 1} }}}', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": -0.1 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": 1.1 }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": "start" }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": false }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": {"a.b": -2} }}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$each": [], "$position": [1,2,3] }}} }', '{}', NULL, NULL, NULL);

-- $push valid cases when modifiers are not persent
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" : {"a": 6} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" : {"a": {"another": 6}} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a": false} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a": [5,6,7]} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a": 1.21} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": 1, "scores": [44,78,38,80], "a": {"scores": [1,2]}}', '{ "": { "$push" : {"scores": 1, "a.scores": 10} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with $each modifier in non-dotted path
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a": { "$each" : [1,2,"3", {"four": 4}] }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with array indices as dotted path
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a.3": 4 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a.7": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],[3]]}', '{ "": { "$push" : {"a.0.5": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],[3]]}', '{ "": { "$push" : {"a.0.5": { "$each": [10,9,8], "$sort" : 1 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],3]}', '{ "": { "$push" : {"a.2.5": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with $each & $slice modifier in non-dotted path
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": 5 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": -6 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": 20 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": -11 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with $slice: 0 must empty a previously non-empty array (not a no-op)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": 0 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" : {"a": { "$each" : [6,7,8], "$sort": -1, "$slice": 0 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- $push with $slice: 0 on an already-empty array is a no-op (result unchanged)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": []}', '{ "": { "$push" : {"a": { "$each" : [], "$slice": 0 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- $push with $each and $slice: 0 on an empty array stays empty (result equals source, no-op)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": []}', '{ "": { "$push" : {"a": { "$each" : [1,2], "$slice": 0 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- $push with $slice: 0 on a nested/dotted path empties the array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"key2": {"key3": {"key4": [1,2,3,4,5]}}}}', '{ "": { "$push" : {"key.key2.key3.key4": { "$each" : [6,7,8], "$sort": -1, "$slice": 0 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with $each & $position modifier in non-dotted path
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [-1, 0], "$position": 20 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [-1, 0], "$position": -20 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [-1, 0], "$position": 6 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$push" : {"a": { "$each" : [-1, 0], "$position": -8 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with $sort modifier in non-dotted path
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3]}', '{ "": { "$push" : {"a": { "$each" : [1,2,"3", {"four": 4}, false, [3,1,2]], "$sort": -1 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"wk": 1, "scores": 85}, {"wk": 3, "scores": 30}, {"wk": 2, "scores": 75}, {"wk": 5, "scores": 99}]}', '{ "": { "$push" : {"a": { "$each" : [{"wk": 2, "scores": 70}], "$sort": 1 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"wk": 1, "scores": 85}, {"wk": 3, "scores": 30}, {"wk": 2, "scores": 75}, {"wk": 5, "scores": 99}]}', '{ "": { "$push" : {"a": { "$each" : [{"wk": 2, "scores": 70}], "$sort": { "scores" : -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- Sort spec dotted path contains intermediate array, sort spec path not found so same sort order
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": [{"c": 5}]},{"b": [{"c": 10}]},{"b": [{"c": 3}]},{"b": [{"c": 2}]}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "b.c" : 1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": [{"c": 5}]},{"b": [{"c": 10}]},{"b": [{"c": 3}]},{"b": [{"c": 2}]}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "b.c" : -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- Sort spec dotted path doesn't exist, same sort order
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": [{"c": 5}]},{"b": [{"c": 10}]},{"b": [{"c": 3}]},{"b": [{"c": 2}]}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "c" : -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- Sort spec with array and valid index element
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": [{"c": 5}]},{"b": [{"c": 10}]},{"b": [{"c": 3}]},{"b": [{"c": 2}]}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "b.0" : -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
-- Multiple Sort spec with existing or non exisiting paths
SELECT documentdb_api_internal.update_bson_document('{"_id":1,"key":1,"a":[{"a":5,"b":10},{"a":2,"b":2},{"a":8,"b":3},{"a":4,"b":1},{"a":2,"b":5},{"a":2,"b":1}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "a" : 1, "b": -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id":1,"key":1,"a":[{"a":5,"b":10},{"a":2,"b":2},{"a":8,"b":3},{"a":4,"b":1},{"a":2,"b":5},{"a":2,"b":1}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "a" : 1, "b": -1, "c": 1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id":1,"key":1,"a":[{"a":5,"b":10},{"a":2,"b":2},{"a":8,"b":3},{"a":4,"b":1},{"a":2,"b":5},{"a":2,"b":1}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "d" : 1, "e": -1, "f": 1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- Sort spec with only some elements having sort path, other elements treat missing path as NULL
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": 1}, {"a": 10, "b": 0}, {"b": 5}, {"b": 3}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "a" : 1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1,"key": 1,"a": [{"b": 1}, {"a": 10, "b": 0}, {"b": 5}, {"b": 3}]}', '{ "": { "$push" : {"a": { "$each" : [], "$sort": { "a" : -1 } }} } }', '{}', NULL, NULL, NULL) as update_bson_document;


-- $push with combinations of other modifiers e.g $slice, $sort
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [{"a": 1, "b": 10}, {"a": 2, "b": 8}, {"a": 3, "b": 5}, {"a": 4, "b": 6}]}', '{ "": { "$push" : {"arr": { "$each" : [{"a": 5, "b": 8}, {"a": 6, "b": 7}, {"a": 7, "b": 6}], "$sort": { "b" : -1 }, "$slice": 3 }} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push & modifiers with dotted paths
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"b": {"c": [1,2,3,4,5,6,7,8,9,10]}}}', '{"" : {"$push": {"a.b.c": 11}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"b": {"c": [1,2,3,4,5,6,7,8,9,10]}}}', '{"" : {"$push": {"a.b.c": {"$each": [11,12], "$slice": -6, "$sort": -1, "$position": 4}}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with absent fields
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "scores": {"a": {"b": [1]}}, "key": 1}', '{"" : {"$push": {"scores.a.c": {"x": [{"z": 1}]}}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "scores": {"a": {"b": [1]}}, "key": 1}', '{"" : {"$push": {"scores.a.c": {"$each": [5,4,3,2,1], "$slice": 3, "$sort": 1}}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with key having dots
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "scores": {"a": {"b": [1]}}, "key": 1}', '{"" : {"$push": {"scores.a.b": {"x": [{"z.a": 1}]}}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push with NaN and Infinity values
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"$numberDecimal": "100"}, {"$numberDouble": "NaN"}, {"$numberDecimal": "2"}, {"$numberDecimal": "NaN"}, {"$numberDecimal": "23"}]}', '{ "": { "$push" : {"a": { "$each": [], "$sort" : 1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"$numberDecimal": "Infinity"}, {"$numberDouble": "NaN"}, {"$numberDecimal": "332"}, {"$numberDecimal": "NaN"}, {"$numberDecimal": "23"}]}', '{ "": { "$push" : {"a": { "$each": [], "$sort" : -1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"$numberDecimal": "NaN"}, {"$numberDouble": "NaN"}, {"$numberDecimal": "Infinity"}, {"$numberDecimal": "23"}]}', '{ "": { "$push" : {"a": { "$each": [], "$sort" : 1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"$numberDecimal": "NaN"}, {"$numberDouble": "NaN"}, {"$numberDecimal": "Infinity"}, {"$numberDecimal": "23"}]}', '{ "": { "$push" : {"a": { "$each": [], "$sort" : -1 } } } }', '{}', NULL, NULL, NULL);

-- $push without $each but with other modifiers works on mongo5.0, $ is now supported in key names.
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": {"x": [{"y": [1]}, {"y": [2]}]}}', '{ "": { "$push" :{ "key.x": { "$eachh": [], "$position": 1, "$sort" : 1} }}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$push" :{"a": { "$position": 5, "$slice": 3, "$sort": -1 }}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- test conflicting update operator paths
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a.b": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$inc": {"a": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$inc": {"a.b": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$inc": {"a.b.c": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$inc": {"a.b.c.d.e": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a.b.c.d.e": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c": 1} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b": 1} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": 1} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.k.d": 1} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d.e": 1} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": { "e": 1 } } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": { "e.f": 1 } } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": { "k.f": 1 } } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": { "f.k": 1 } } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a": {"b.c.d": { "e.f": {"g": 1} } } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a.b.c.d": { "e": 1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a.b.c": { "d.e": 1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b": {"c": { "d.e.f": "1"} } }, "$unset": {"a.b": { "c.d.e": 1 } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b.c.d.e": 1 }, "$unset": {"a.b": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b.c.d.e": 1 }, "$unset": {"a.b.c.d.e.f": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"data": "data"}', '{ "": { "$set": { "a.b.c.d.e": 1 }, "$inc": {"a.b": 1 } } }', '{}', NULL, NULL, NULL);

-- update scenario tests: $currentDate

-- -- Function that extracts date / timestamp value of a given key in a json obj, and returns the equivalent epoch in ms
CREATE OR REPLACE FUNCTION get_epochms_from_key(obj json, qkey text, is_date bool)
RETURNS bigint
AS $$
DECLARE
    k text;
    qarr text[];
    epoch_seconds bigint;
    nanoseconds_in_second bigint;
    epoch_milliseconds bigint;
    tmp bool;
BEGIN
    SELECT string_to_array(qkey, '.') into qarr;    -- convert the nested keys in keys array (e.g. "a.b.c" to [a,b,c] )
    FOREACH k IN ARRAY qarr
    LOOP
        IF obj->k IS NULL THEN
            RETURN 0;
        END IF;
        SELECT obj->k into obj;
    END LOOP;

    IF is_date THEN
        IF (obj->'$date' IS NULL) OR (obj->'$date'->'$numberLong' IS NULL) THEN
            RETURN 0;
        END IF;
        SELECT obj->'$date'->>'$numberLong' into epoch_milliseconds;
    ELSE
        IF (obj->'$timestamp' IS NULL) OR (obj ->'$timestamp'->'t' IS NULL) OR (obj->'$timestamp'->'i' IS NULL) THEN
            RETURN 0;
        END IF;
        SELECT obj->'$timestamp'->>'t' into epoch_seconds;
        SELECT obj->'$timestamp'->>'i' into nanoseconds_in_second;
        epoch_milliseconds := (epoch_seconds * 1000) + ROUND(nanoseconds_in_second::float8 / (1000 * 1000));
    END IF;

    RETURN epoch_milliseconds;
END
$$
LANGUAGE plpgsql;

-- -- Function to test that on updating a doc with $currentDate, the date/timestamp value lies between the timestamp values of just before & after calling the update api
CREATE OR REPLACE FUNCTION test_update_currentDate(doc bson, updateSpec bson, querySpec bson, qDates text[] DEFAULT '{}'::text[], qTimestamps text[] DEFAULT '{}'::text[])
RETURNS text
AS $$
DECLARE
    obj             json;
    bgn_epoch       numeric;
    end_epoch       numeric;
    qKey            text;
    epoch_msec      bigint;
    bgn_epoch_msec  bigint;
    end_epoch_msec  bigint;
BEGIN
    SELECT extract(epoch from clock_timestamp()) into bgn_epoch;    -- get time just before the $currentDate execution. (e.g 1709721220.205436)
    SELECT documentdb_api_internal.update_bson_document(doc, updateSpec, querySpec, NULL, NULL, NULL) into obj;
    SELECT extract(epoch from clock_timestamp()) into end_epoch;    -- get time just after the $currentDate execution.

    -- convert the epoch to milliseconds (e.g. 1709721220.205436 -> 1709721220205)
    -- Also adjust begin and end epochs by 1 ms to eliminate any rounding error and reduce flakyness.
    bgn_epoch_msec := FLOOR(bgn_epoch * 1000) - 1;
    end_epoch_msec := CEIL(end_epoch * 1000) + 1;

    IF array_length(qDates, 1) != 0 THEN
        FOREACH qKey IN ARRAY qDates
        LOOP
            SELECT get_epochms_from_key(obj, qKey, true) into epoch_msec;
            IF epoch_msec NOT BETWEEN bgn_epoch_msec AND end_epoch_msec THEN
                RETURN 'TEST FAILED : Updated date "' || qkey || '" : ' || epoch_msec || ' should be between ' || bgn_epoch_msec || ' and ' || end_epoch_msec;
            END IF;
        END LOOP;
    END IF;

    IF array_length(qTimestamps, 1) != 0 THEN
        FOREACH qKey IN ARRAY qTimestamps
        LOOP
            SELECT get_epochms_from_key(obj, qKey, false) into epoch_msec;
            IF epoch_msec NOT BETWEEN bgn_epoch_msec AND end_epoch_msec THEN
                RETURN 'TEST FAILED : Updated timestamp "' || qkey || '" : ' || epoch_msec || ' should be between ' || bgn_epoch_msec || ' and ' || end_epoch_msec;
            END IF;
        END LOOP;
    END IF;

    RETURN 'TEST PASSED';
END;
$$
LANGUAGE plpgsql;

-- -- tests to update existing field to current timestamp using { "$type" : "timestamp" }
SELECT test_update_currentDate('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"} } } }', '{}', ARRAY[]::text[], ARRAY['a']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"} } } }', '{}', ARRAY[]::text[], ARRAY['a']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"} } } }', '{}', ARRAY[]::text[], ARRAY['a']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": 2 }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"} } } }', '{}', ARRAY[]::text[], ARRAY['a']::text[]);

-- -- tests to update existing field to current date using { true }
SELECT test_update_currentDate('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": true} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": true} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": true} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": 2 }', '{ "": { "$currentDate": { "a": true} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);

-- -- tests to update existing field to current date using { false }
SELECT test_update_currentDate('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": false} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": false} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": false} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": 2 }', '{ "": { "$currentDate": { "a": false} } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);

-- -- tests to update existing field to current date using { "$$type" : "date" }
-- -- Note: Due to a bug in libbson, parsing of { "$type" : "date" } fails. So temporarily the DocumentdbApi $currentDate impl also supports {"$$type" : "date" }
-- -- Once the bug is fixed, these tests need to be updated from "$$type" to "$type"
SELECT test_update_currentDate('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$$type" : "date"} } } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { "$$type" : "date"} } } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$$type" : "date"} } } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": 2 }', '{ "": { "$currentDate": { "a": { "$$type" : "date"} } } } ', '{}', ARRAY['a']::text[], ARRAY[]::text[]);

-- -- tests to update existing field to timestamp, and add new fields with current date / timestamp
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"}, "b.c" : { "$type" : "timestamp"} } } } ', '{}', ARRAY[]::text[], ARRAY['a','b.c']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"}, "b.c" : { "$$type" : "date"} } } } ', '{}', ARRAY['b.c']::text[], ARRAY['a']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"}, "b.c" : true } } } ', '{}', ARRAY['b.c']::text[], ARRAY['a']::text[]);
SELECT test_update_currentDate('{"_id": 1, "a": "Hello" }', '{ "": { "$currentDate": { "a": { "$type" : "timestamp"}, "b.c" : false } } } ', '{}', ARRAY['b.c']::text[], ARRAY['a']::text[]);

-- -- these tests should give error messages

SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": {"$numberInt" : "1"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": {"$numberLong" : "1"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": {"$numberDouble" : "1.0"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": "Hello" } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": NaN } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { "$type" : "Hello" } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { "$$type" : true } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$timestamp": { "t": 1234567890, "i": 1 }}}', '{ "": { "$currentDate": { "a": { "$$type" : 2 } } } }', '{}', NULL, NULL, NULL);

SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": {"$numberInt" : "1"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": {"$numberLong" : "1"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": {"$numberDouble" : "1.0"} } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": "Hello" } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": NaN } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$type" : "Hello" } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$$type" : true } } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$$type" : 2 } } } }', '{}', NULL, NULL, NULL);

-- -- Note : This test intenionally provides { "$type" : "date" } instead of { "$$type" : "date" }
-- -- The API call returns Error due to a Bug in libbson library that fails to parse { "$type" : "date" }
-- -- If this test starts failing (i.e. api call does't return error), it may mean that the libbson bug has been fixed.
-- -- In that case $currentDate implementation in DocumentdbApi needs a fix as well (i.e. remove support for "$$type" since "$type" will work OK)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$date": { "$numberLong" : "1234567890000" }}}', '{ "": { "$currentDate": { "a": { "$type" : "date" } } } }', '{}', NULL, NULL, NULL);

-- --Empty UpdateSpec check
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4] }', '{ "": { "$inc": { "": 11} } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4] }', '{ "": { "$mul": { "a.": 11} } }', '{}', NULL, NULL, NULL);

-- update scenario tests: $pop
-- -- $pop from begin of array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" :{"a": -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1]}', '{ "": { "$pop" :{"a": -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": []}', '{ "": { "$pop" :{"a": -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [1,2,3,4,5] }} }', '{ "": { "$pop" :{"a.b.c": -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9] }', '{ "": { "$pop" :{"a": -1, "b": -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9] }', '{ "": { "$pop" :{"a": -1, "b": -1, "c" : -1}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- -- $pop from end of array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" :{"a": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [5]}', '{ "": { "$pop" :{"a": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": []}', '{ "": { "$pop" :{"a": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [1,2,3,4,5] }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9] }', '{ "": { "$pop" :{"a": 1, "b": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9] }', '{ "": { "$pop" :{"a": 1, "b": 1, "c" : 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- -- $pop from begin and end of array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9]}', '{ "": { "$pop" :{"a": -1, "b": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5], "b" : [6,7,8,9]}', '{ "": { "$pop" :{"z": 1, "a": -1, "b": 1}} }', '{}', NULL, NULL, NULL) as update_bson_document;
  -- For below test, the spec parsing func (ParseDotPathAndGetTreeNode) throws error, but mongoDB 5.0 doesn't. TODO : Fix ParseDotPathAndGetTreeNode
  -- SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" :{"a": -1, "a": 1}} }', '{}', NULL, NULL, NULL);

-- -- Empty $pop document. Should not pop anything
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {}} }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": []}', '{ "": { "$pop" : {}} }', '{}', NULL, NULL, NULL) as update_bson_document;

-- -- Error Cases : $pop on Non-Array Fields
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : {"$numberInt" : "2"} }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : {"$numberLong" : "2"} }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : {"$numberDouble" : "2.0"} }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : "Hello" }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : false }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : NaN }} }', '{ "": { "$pop" :{"a.b.c": 1}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [5,6,7,8], "d" : "Hello" }} }', '{ "": { "$pop" :{"a.b.c": 1, "a.b.d": -1 }} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [5,6,7,8], "d" : "Hello" }} }', '{ "": { "$pop" :{"a" : {"b" : { "c": 1 ,  "d": -1} }} } }', '{}', NULL, NULL, NULL);

-- -- Error Cases : $pop's key's value is neither -1 nor 1
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": "Hello"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": true}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": NaN}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": []}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": {}}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": {"$numberInt" : "2"}}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"a": {"$numberDouble" : "-1.5"}}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [5,6,7,8]}} }', '{ "": { "$pop" : {"a.b.c": 2 }} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [5,6,7,8], "d" : "Hello" }} }', '{ "": { "$pop" :{"a.b.c": 25, "a.b.d": -1 }} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "b" : { "c" : [5,6,7,8], "d" : "Hello" }} }', '{ "": { "$pop" :{"a.b.c": 1, "a.b.d": -25 }} }', '{}', NULL, NULL, NULL);

-- -- Error Cases : $pop is not a document
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : []} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : [{"a" : 1}]} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : "Hello"} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : false} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : NaN} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"$numberInt" : "1"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"$numberLong" : "-1"}} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pop" : {"$numberDouble" : "2.5"}} }', '{}', NULL, NULL, NULL);
-- --Update the Field with Periods (.) and Dollar Signs ($)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": { "$b": 2 } }', '{ "": { "$inc": { "a.$b": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "$a": { "b": 2 } }', '{ "": { "$inc": { "$a.c": 2 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "$a": { "$b": { "c" :  2 } } }', '{ "": { "$inc": { "$a.$b.c": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- --Negative scenarios for field names with Dollar Signs ($)
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1}', '{ "": { "$set": { "$a": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "_id" : 1, "$set": { "$a": 2 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id" : 1, "a" : 1 }', '{ "": { "_id" : 1, "$b" : 2} }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "$a": { "$b": { "c" :  2 } } }', '{ "": { "$set": { "$a": { "$b" : { "$d": 1 } } } } } ', '{}', NULL, NULL, NULL);

-- more scenarios for update field names with $ signs

-- $ paths not allowed when it's not an upsert
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": "1" }', '{ "": { "$set": { "$secret.agent.x": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "$secret": { "agent": 1 } }', '{ "": { "$set": { "$secret.agent.x": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "$secret": { "agent": { "y": 1 } } }', '{ "": { "$set": { "$secret.agent.x": 1 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{ "_id": 5 }', '{ "": { "$set": { "$inc": 5 } } }', '{}', NULL, NULL, NULL);

-- allowed on upsert.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "$secret.agent.x": 1, "_id": 6 } } }', '{}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "$secret.agent.x": 1 } } }', '{"_id": 2 }', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "$secret.agent.x": 1 } } }', '{"a": 3, "_id": 4 }', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "$inc": 5 } } }', '{"_id": 5 }', NULL, NULL, NULL);

-- $pull invalid cases
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": "text"}', '{ "": { "$pull": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1}', '{ "": { "$pull": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": true}', '{ "": { "$pull": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"$numberDecimal": "1.23"}}', '{ "": { "$pull": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": {"b": 2}}', '{ "": { "$pull": { "a": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"b": 1, "c": 1}, {"b": 2, "c": 2}, {"b": 3, "c": 3}]}', '{ "": { "$pull": { "a.0": {"b": 2, "c":2} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"b": [1], "c": [1]}, {"b": [2], "c": [2]}, {"b": [3], "c": [3]}]}', '{ "": { "$pull": { "a.b": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pull": { "a": {"$lte": 2, "b": 2} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pull": { "a": {"b": 2, "$lte": 2} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- valid $pull without expressions in arrays and array of arrays
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pull": { "a": 3 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"b": 1, "c": 1}, {"b": 2, "c": 2}, {"b": 3, "c": 3}]}', '{ "": { "$pull": { "a": {"b": 2, "c":2} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1,2,3,4,5], [6,7,8,9,10]]}', '{ "": { "$pull": { "a.0": 4 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[{"b": 1, "c": 1}, {"b": 2, "c": 2}, {"b": 3, "c": 3}], [{"b": 4, "c": 4}, {"b": 5, "c": 5}, {"b": 6, "c": 6}]]}', '{ "": { "$pull": { "a.1": {"b": 4, "c": 4} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- valid $pull with expressions in arrays and array of arrays
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$pull": { "a": {"$gte": 2, "$lte": 5} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]}', '{ "": { "$pull": { "a": {"$gte": 5} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$pull": { "a": {"$gte": 5, "$ne": 8} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$pull": { "a": {"$in": [3,6,9]} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$pull": { "a": {"$nin": [3,6,9]} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5,6,7,8,9,10]}', '{ "": { "$pull": { "a": { "$not": {"$gt": 5 } } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id":1,"fruits":[ "apples", "pears", "oranges", "grapes", "bananas" ],"vegetables":[ "carrots", "celery", "squash", "carrots" ]}', '{"":{"$pull":{"fruits":{"$in":["apples","oranges"]},"vegetables":"carrots"}}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id":2,"fruits":[ "plums", "kiwis", "oranges", "bananas", "apples" ],"vegetables":[ "broccoli", "zucchini", "carrots", "onions" ]}', '{"":{"$pull":{"fruits":{"$in":["apples","oranges"]},"vegetables":"carrots"}}}', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{ "item": "A", "score": 5 }, { "item": "B", "score": 8 }, { "item": "C", "score": 8 }, { "item": "B", "score": 4 }]}', '{ "": { "$pull": { "a": { "score": 8 , "item": "B" } } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "results": [{ "item": "A", "score": 5, "answers": [ { "q": 1, "a": 4 }, { "q": 2, "a": 6 } ] }, { "item": "B", "score": 8, "answers": [ { "q": 1, "a": 8 }, { "q": 2, "a": 9 } ]}, { "item": "C", "score": 8, "answers": [ { "q": 1, "a": 8 }, { "q": 2, "a": 7 } ] }, { "item": "B", "score": 4, "answers": [ { "q": 1, "a": 0 }, { "q": 2, "a": 8 } ] }]}', '{ "": { "$pull": { "results": { "answers": {"$elemMatch": { "q": 2, "a": { "$gte": 8 } } } } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- First level of nested array is supported in native mongo only when pull spec value is expression
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]}', '{ "": { "$pull": { "a": {"$gte": 5} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [[{"a": 1, "b" : 1}], [{"a": 2, "b": 2}], [{"a": 3, "b": 3}]]}', '{ "": { "$pull": { "arr":  {"$eq": {"a": 1, "b": 1} } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $pull with $eq:[array] must remove nested array elements matching the whole array value
-- [1] should be removed (exact match), scalar 1 and [1,2] should not be removed
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, [1], [1, 2]]}', '{"": {"$pull": {"key": {"$eq": [1]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Binary nested array: [Binary] should be removed, plain Binary and [Binary,"other"] should not
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [{"$binary":{"base64":"pmajuNcUhjGdgg==","subType":"00"}}, [{"$binary":{"base64":"pmajuNcUhjGdgg==","subType":"00"}}], [{"$binary":{"base64":"pmajuNcUhjGdgg==","subType":"00"}}, "other"]]}', '{"": {"$pull": {"key": {"$eq": [{"$binary":{"base64":"pmajuNcUhjGdgg==","subType":"00"}}]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Object inside nested array: [{"a":1}] should be removed, plain {"a":1} and [{"a":1},{"a":2}] should not
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [{"a": 1}, [{"a": 1}], [{"a": 1}, {"a": 2}]]}', '{"": {"$pull": {"key": {"$eq": [{"a": 1}]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Dotted-path: key.0.a resolves to scalar 1 (not array) -> error, matches mongo
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [{"a": 1}, [{"a": 1}], [{"a": 1}, {"a": 2}]]}', '{"": {"$pull": {"key.0.a": 1}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Dotted-path: key.a traverses array with field name -> error, matches mongo
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [{"a": 1}, [{"a": 1}], [{"a": 1}, {"a": 2}]]}', '{"": {"$pull": {"key.a": 1}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Doubly-nested: $eq:[1] recurses one level; both [1] and [[1],2] removed (inner [1] matches), scalar 1 kept
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, [1], [[1], 2]]}', '{"": {"$pull": {"key": {"$eq": [1]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- Literal [1] form on same input does NOT recurse: only exact [1] removed, [[1],2] kept
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, [1], [[1], 2]]}', '{"": {"$pull": {"key": [1]}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- $eq:[1,2] multi-value: order-sensitive whole-array equality; only exact [1,2] removed
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, 2, [1,2], [1,2,3], [2,1], 3]}', '{"": {"$pull": {"key": {"$eq": [1,2]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- $eq:[1,2,3] across nested arrays: only exact [1,2,3] removed, subset/reversed/superset kept
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [[1,2,3], [1,2], [2,1], [1,2,3,4]]}', '{"": {"$pull": {"key": {"$eq": [1,2,3]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- $in with mixed scalars and nested arrays: recursion makes nested arrays match if any inner element matches
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, [1,2], [1,2,3], [1,2,3,4], 2, 3, [2,3], 4, [1,2,3,4], [5,6]]}', '{"": {"$pull": {"key": {"$in": [1,2,3]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- $in:[1] removes all elements: scalar 1, [1] (recursion), [1,2] (recursion finds 1)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [1, [1], [1,2]]}', '{"": {"$pull": {"key": {"$in": [1]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;
-- $eq:[1] with deeper nesting: only one level of recursion; [[[1]]] is kept
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": [[1], [[1]], [[[1]]]]}', '{"": {"$pull": {"key": {"$eq": [1]}}}}', '{}', NULL, NULL, NULL) as update_bson_document;

-- First level of nested array is not recursed if $pull spec value is plain value
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]}', '{ "": { "$pull": { "a":  5 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "arr": [[{"a": 1, "b" : 1}], [{"a": 2, "b": 2}], [{"a": 3, "b": 3}]]}', '{ "": { "$pull": { "arr":  {"a": 1, "b": 1} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- Second and more are not supported
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [[[1,2]], [[3,4]]]}', '{ "": { "$pull": { "a": {"$gte": 3} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $pull no ops for no match
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{"b": 1, "c": 1}, {"b": 2, "c": 2}, {"b": 3, "c": 3}]}', '{ "": { "$pull": { "a": {"b": 2, "c":3} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pull": { "c": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [1,2,3,4,5]}', '{ "": { "$pull": { "a": {"$gt": 5} } } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": [{ "item": "A", "score": 5 }, { "item": "B", "score": 8 }, { "item": "C", "score": 8 }, { "item": "B", "score": 4 }]}', '{ "": { "$pull": { "a": { "$elemMatch": { "score": 8 , "item": "B" } } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- validate _id
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$set": { "_id": {"$b": 2, "c":3} } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- replaceRoot/replaceWith with dotted paths.
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": [ { "$replaceWith": { "_id": 1, "a.b.c": 3 } } ] }', '{}', NULL, NULL, NULL) as update_bson_document;

--upsert when querySpec has $all
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"_id": 10, "x": { "$all" : {}}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"_id": 11, "x": { "$all" : [1]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":12}}}', '{"x": { "$all" : [2]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":13}}}', '{"x": { "$all" : [[3]]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":14}}}', '{"x": { "$all" : [{"x":11}]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":15}}}', '{"_id": { "$all" : [15]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":16}}}', '{"_id": { "$all" : [{"x": 16}]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":17}}}', '{"_id": { "$all" : [[13]]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":18}}}', '{"x": { "$all" : [1,2,3]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":19}}}', '{"_id": { "$all" : [15,16,17]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {}}', '{"_id": { "$all" : [[15]]}}', NULL, NULL, NULL) as update_bson_document;

--upsert when querySpec has $in
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"_id": 21, "x": { "$in" : {}}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"_id": 22, "x": { "$in" : [1]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":23}}}', '{"x": { "$in" : [3423]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":24}}}', '{"x": { "$in" : [[2]]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":25}}}', '{"x": { "$in" : [{"y":2}]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":26}}}', '{"x": { "$in" : [10,20,30]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":27}}}', '{"_id": { "$in" : [25]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":28}}}', '{"_id": { "$in" : [{"y":26}]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"x":29}}}', '{"_id": { "$in" : [[26]]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":30}}}', '{"_id": { "$in" : [27]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"_id":31}}}', '{"_id": { "$in" : [27,28,29]}}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"_id": { "$in" : [[27]]}}', NULL, NULL, NULL) as update_bson_document;
SELECT bson_dollar_project(documentdb_api_internal.update_bson_document('{}', '{ "": {"$set":{"y":31}}}','{"_id": { "$in" : [27,28,29]}}', NULL, NULL, NULL), '{ "_id": 0 }') as newDocument;

-- $nor operator in query spec
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"_id": 1, "b": 3} }', '{"$nor": [ { "_id": { "$eq" : 2}}]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"_id": 1, "b": 3} }', '{"$nor": [ { "a": { "$eq" : 2}}]}', NULL, NULL, NULL) as update_bson_document;

--miscellaneous tests with multiple fields in queySpec
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {} }', '{"$and": [{"_id": 1}, {"_id": 1}]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set": {"a": 1}} }', '{"_id.x": 1 , "_id.y": 2}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set": {"a": 1}} }', '{"$and": [{"x": 1}, {"x": 1}]}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set": {"a": 1}} }', '{"x": 1, "x.x": 1}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": {"$set": {"a": 1}} }', '{"x.x": 1, "x": 1}', NULL, NULL, NULL) as update_bson_document;

-- show that we never crash due to passing one of the arguments as NULL
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1}', '{"": {"a": 2}}', null, NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1}', null, '{"b": 1}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document(null, '{"": {"a": 1}}', '{"c": 1}', NULL, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1}', '{"": {"a": 2}}', '{"b": 1}', null, NULL, NULL);
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1}', '{"": {"a": 2}}', '{"b": 1}', '{"a": 1}', NULL, NULL);

-- $rename Negative/No-Op cases
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a.": "b"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "$.": "b"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "$[].0": "b"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a": "b."} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a": "$"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{}', '{ "": { "$rename": { "a": "$[]"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"a": 1, "f": 1}', '{ "": { "$rename": { "a": "f.g"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"a": 1, "f": 1}', '{ "": { "$rename": { "f.g": "a"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "a": 1, "f": 1}', '{ "": { "$rename": { "x": "f.g"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"a" : 1, "f" : 1, "b" : { "c" : { "d" : 1 } }}', '{ "": { "$rename": { "b.c.d.f": "t.k"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"key": 1,"key2": 2,"f": {"g": 1, "h": 1},"j": 1,"k": 1}', '{ "": { "$rename": { "f.g": "k.m","f.h":"j.m"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"key": 1,"key2": 2,"f": {"g": 1, "h": 1},"j": {},"k": 1}', '{ "": { "$rename": { "f.g": "k.m","f.h":"j.m"} } }', '{}', NULL, NULL, NULL) as update_bson_document;

--$rename working complex cases
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "key": 1,"key2": 2,"f": {"g": 1, "h": 1},"h":1}', '{ "": { "$rename": { "key": "f.g"} } }', '{}', NULL, NULL, NULL) as update_bson_document;
SELECT documentdb_api_internal.update_bson_document('{"_id": 2, "key": 2,"x": {"y": 1, "z": 2}}', '{ "": { "$rename": { "key": "newName","x.y":"z","x.z":"k"} } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- Padded zero array indices in dot notation
-- "x.0000" should be treated as array index 0
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [true, -1061940109]}', '{ "": { "$set": { "x.0000": false } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- "x.0000010" should be treated as array index 10
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [true, -1061940109]}', '{ "": { "$set": { "x.0000010": 999 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- Combined padded zero indices in a single update
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [true, -1061940109]}', '{ "": { "$set": { "x.0000010": 999, "x.0000": false } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- "x.01" should be treated as array index 1
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": ["a", "b", "c"]}', '{ "": { "$set": { "x.01": "updated" } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $unset with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [10, 20, 30]}', '{ "": { "$unset": { "x.002": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $inc with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [10, 20, 30]}', '{ "": { "$inc": { "x.001": 5 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $pull with padded zero index on nested array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [[1,2,3], [4,5,6]]}', '{ "": { "$pull": { "x.001": 5 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $push into nested array via padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [{"subarr": [1,2]}, {"subarr": [3,4]}]}', '{ "": { "$push": { "x.0001.subarr": 99 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $mul with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [2, 3, 4]}', '{ "": { "$mul": { "x.002": 10 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $min with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [10, 20, 30]}', '{ "": { "$min": { "x.002": 5 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $max with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [10, 20, 30]}', '{ "": { "$max": { "x.001": 99 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $addToSet with padded zero index on nested array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [[1,2,3], [4,5,6]]}', '{ "": { "$addToSet": { "x.001": 7 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $pop with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [[1,2,3], [4,5,6]]}', '{ "": { "$pop": { "x.001": 1 } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $bit with padded zero index
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [13, 7, 5]}', '{ "": { "$bit": { "x.001": { "and": 3 } } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $pullAll with padded zero index on nested array
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [[1,2,3], [4,5,6,7]]}', '{ "": { "$pullAll": { "x.001": [5, 7] } } }', '{}', NULL, NULL, NULL) as update_bson_document;

-- $currentDate with padded zero index: verify x[1] was changed (not null, indicating update was applied)
SELECT documentdb_api_internal.update_bson_document('{"_id": 1, "x": [1, 2, 3]}', '{ "": { "$currentDate": { "x.001": true } } }', '{}', NULL, NULL, NULL) IS NOT NULL as update_bson_document;