It is natural to write "abc" in place of ["set",["abc"]] and vice versa.
I cannot think of a reason not to support this, and it can make reading
and writing OVSDB files and transactions easier, so support it.
{
struct ovsdb_error *error;
- if (ovsdb_type_is_scalar(type)) {
- datum->n = 1;
- datum->keys = xmalloc(sizeof *datum->keys);
- datum->values = NULL;
-
- error = ovsdb_atom_from_json(&datum->keys[0], &type->key,
- json, symtab);
- if (error) {
- free(datum->keys);
- }
- return error;
- } else {
+ if (ovsdb_type_is_map(type)
+ || (json->type == JSON_ARRAY
+ && json->u.array.n > 0
+ && json->u.array.elems[0]->type == JSON_STRING
+ && !strcmp(json->u.array.elems[0]->u.string, "set"))) {
bool is_map = ovsdb_type_is_map(type);
const char *class = is_map ? "map" : "set";
const struct json *inner;
unsigned int i;
size_t n;
- assert(is_map || ovsdb_type_is_set(type));
-
error = unwrap_json(json, class, JSON_ARRAY, &inner);
if (error) {
return error;
error:
ovsdb_datum_destroy(datum, type);
return error;
+ } else {
+ datum->n = 1;
+ datum->keys = xmalloc(sizeof *datum->keys);
+ datum->values = NULL;
+
+ error = ovsdb_atom_from_json(&datum->keys[0], &type->key,
+ json, symtab);
+ if (error) {
+ free(datum->keys);
+ }
+ return error;
}
}
{
/* These tests somewhat tolerate a 'datum' that does not exactly match
* 'type', in particular a datum with 'n' not in the allowed range. */
- if (datum->n == 1 && ovsdb_type_is_scalar(type)) {
+ if (datum->n == 1 && !ovsdb_type_is_map(type)) {
return ovsdb_atom_to_json(&datum->keys[0], type->key.type);
} else if (type->value.type == OVSDB_TYPE_VOID) {
struct json **elems;
&& ovsdb_base_type_is_valid(&type->key)
&& ovsdb_base_type_is_valid(&type->value)
&& type->n_min <= 1
- && type->n_min <= type->n_max);
+ && type->n_min <= type->n_max
+ && type->n_max >= 1);
}
static struct ovsdb_error *
<set>
- A 2-element JSON array that represents a database set value. The
+ Either an <atom>, representing a set with exactly one element, or
+ a 2-element JSON array that represents a database set value. The
first element of the array must be the string "set" and the second
element must be an array of zero or more <atom>s giving the values
in the set. All of the <atom>s must have the same type.
["uuid", "62315898-64e0-40b9-b26f-ff74225303e6"]]]]]' \
]],
[[[["i","==",["set",[]]]]
-[["i","!=",["set",[1]]]]
+[["i","!=",1]]
[["i","includes",["set",[1,2]]]]
[["i","excludes",["set",[1,2,3]]]]
[["r","==",["set",[]]]]
-[["r","!=",["set",[1.5]]]]
+[["r","!=",1.5]]
[["r","includes",["set",[1.5,2.5]]]]
[["r","excludes",["set",[1.5,2.5,3.5]]]]
-[["b","==",["set",[true]]]]
-[["b","!=",["set",[false]]]]
-[["b","includes",["set",[false]]]]
+[["b","==",true]]
+[["b","!=",false]]
+[["b","includes",false]]
[["b","excludes",["set",[false,true]]]]
-[["s","==",["set",["a"]]]]
+[["s","==","a"]]
[["s","!=",["set",["a","b"]]]]
-[["s","includes",["set",["c"]]]]
+[["s","includes","c"]]
[["s","excludes",["set",["c","d"]]]]
-[["u","==",["set",[["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]
+[["u","==",["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]
[["u","==",["set",[["uuid","9179ca6d-6d65-400a-b455-3ad92783a099"],["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]
[["u","includes",["set",[["uuid","9179ca6d-6d65-400a-b455-3ad92783a099"],["uuid","ad0fa355-8b84-4a36-a4b5-b2c1bfd91758"],["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]
[["u","excludes",["set",[["uuid","62315898-64e0-40b9-b26f-ff74225303e6"],["uuid","9179ca6d-6d65-400a-b455-3ad92783a099"],["uuid","ad0fa355-8b84-4a36-a4b5-b2c1bfd91758"],["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]]],
AT_BANNER([OSVDB -- simple data])
OVSDB_CHECK_POSITIVE([integer JSON datum],
- [[parse-data '["integer"]' '[0]' '[1]' '[-1]']],
+ [[parse-data '["integer"]' '[0]' '["set",[1]]' '[-1]']],
[0
1
-1])
1])
OVSDB_CHECK_POSITIVE([real JSON datum],
- [[parse-data '["real"]' '[0]' '[1.0]' '[-1.25]']],
+ [[parse-data '["real"]' '[0]' '["set",[1.0]]' '[-1.25]']],
[0
1
-1.25])
-1.25])
OVSDB_CHECK_POSITIVE([boolean JSON datum],
- [[parse-data '["boolean"]' '[true]' '[false]' ]],
+ [[parse-data '["boolean"]' '["set", [true]]' '[false]' ]],
[true
false])
false])
OVSDB_CHECK_POSITIVE([string JSON datum],
- [[parse-data '["string"]' '[""]' '["true"]' '["\"\\\/\b\f\n\r\t"]']],
+ [[parse-data '["string"]' '["set",[""]]' '["true"]' '["\"\\\/\b\f\n\r\t"]']],
[""
"true"
"\"\\/\b\f\n\r\t"])
OVSDB_CHECK_POSITIVE([JSON optional boolean],
[[parse-data '{"key": "boolean", "min": 0}' \
- '["set", [true]]' \
+ '[true]' \
'["set", [false]]' \
'["set", []]']],
- [[["set",[true]]
-["set",[false]]
+ [[true
+false
["set",[]]]],
[set])
OVSDB_CHECK_POSITIVE([JSON set of 0 or more integers],
[[parse-data '{"key": "integer", "min": 0, "max": "unlimited"}' \
'["set", [0]]' \
+ '[1]' \
'["set", [0, 1]]' \
'["set", [0, 1, 2]]' \
'["set", [0, 1, 2, 3, 4, 5]]' \
'["set", [0, 1, 2, 3, 4, 5, 6, 7, 8]]' \
'["set", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]']],
- [[["set",[0]]
+ [[0
+1
["set",[0,1]]
["set",[0,1,2]]
["set",[0,1,2,3,4,5]]
OVSDB_CHECK_POSITIVE([JSON set of 1 to 3 uuids],
[[parse-data '{"key": "uuid", "min": 1, "max": 3}' \
'["set", [["uuid", "550e8400-e29b-41d4-a716-446655440000"]]]' \
+ '["uuid", "b5078be0-7664-4299-b836-8bcc03ef941f"]' \
'["set", [["uuid", "c5051240-30ff-43ed-b4b9-93cf3f050813"],
["uuid", "90558331-09af-4d2f-a572-509cad2e9088"],
["uuid", "550e8400-e29b-41d4-a716-446655440000"]]]']],
- [[["set",[["uuid","550e8400-e29b-41d4-a716-446655440000"]]]
+ [[["uuid","550e8400-e29b-41d4-a716-446655440000"]
+["uuid","b5078be0-7664-4299-b836-8bcc03ef941f"]
["set",[["uuid","550e8400-e29b-41d4-a716-446655440000"],["uuid","90558331-09af-4d2f-a572-509cad2e9088"],["uuid","c5051240-30ff-43ed-b4b9-93cf3f050813"]]]]])
OVSDB_CHECK_POSITIVE([string set of 1 to 3 uuids],
OVSDB_CHECK_POSITIVE([JSON set of 0 to 3 strings],
[[parse-data '{"key": "string", "min": 0, "max": 3}' \
'["set", []]' \
+ '["a longer string"]' \
'["set", ["a relatively long string"]]' \
'["set", ["short string", "a relatively long string"]]' \
'["set", ["zzz", "short string", "a relatively long string"]]']],
[[["set",[]]
-["set",["a relatively long string"]]
+"a longer string"
+"a relatively long string"
["set",["a relatively long string","short string"]]
["set",["a relatively long string","short string","zzz"]]]])
[["r","/=",4]]
[["r","insert",["set",[1,2]]]]
[["r","delete",["set",[1,2,3]]]]
-[["b","insert",["set",[true]]]]
-[["b","delete",["set",[false]]]]
-[["s","insert",["set",["a"]]]]
+[["b","insert",true]]
+[["b","delete",false]]
+[["s","insert","a"]]
[["s","delete",["set",["a","b"]]]]
-[["u","insert",["set",[["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]
+[["u","insert",["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]
[["u","delete",["set",[["uuid","9179ca6d-6d65-400a-b455-3ad92783a099"],["uuid","b10d28f7-af18-4a67-9e78-2a6394516c59"]]]]]]],
[mutation])
{"i": ["set", [0, 1, 2]]}']]],
[[mutation 0:
row 0: no change
-row 1: {"i":["set",[1]]}
+row 1: {"i":1}
row 2: {"i":["set",[1,2]]}
row 3: {"i":["set",[1,2,3]]}
mutation 1:
row 0: no change
-row 1: {"i":["set",[-2]]}
+row 1: {"i":-2}
row 2: {"i":["set",[-2,-1]]}
row 3: {"i":["set",[-2,-1,0]]}
row 3: constraint violation: Result of "%=" operation contains duplicates.
mutation 5:
-row 0: {"i":["set",[1]]}
+row 0: {"i":1}
row 1: {"i":["set",[0,1]]}
row 2: no change
row 3: no change
mutation 7:
row 0: no change
row 1: no change
-row 2: {"i":["set",[0]]}
+row 2: {"i":0}
row 3: {"i":["set",[0,2]]}
mutation 8:
[["r", "*=", 2.5]],
[["r", "/=", 4]],
[["r", "*=", 0]],
- [["r", "insert", ["set", [1.5]]]],
- [["r", "insert", ["set", [3]]]],
+ [["r", "insert", 1.5]],
+ [["r", "insert", 3]],
[["r", "delete", ["set", [1.5, 3.5]]]],
[["r", "delete", ["set", [0.5, 1.5, 2.5]]]]]' \
'[{"r": ["set", []]},
- {"r": ["set", [0.5]]},
+ {"r": 0.5},
{"r": ["set", [0.5, 1.5]]},
{"r": ["set", [0.5, 1.5, 2.5]]}']]],
[[mutation 0:
row 0: no change
-row 1: {"r":["set",[1]]}
+row 1: {"r":1}
row 2: {"r":["set",[1,2]]}
row 3: {"r":["set",[1,2,3]]}
mutation 1:
row 0: no change
-row 1: {"r":["set",[-1]]}
+row 1: {"r":-1}
row 2: {"r":["set",[-1,0]]}
row 3: {"r":["set",[-1,0,1]]}
mutation 2:
row 0: no change
-row 1: {"r":["set",[1.25]]}
+row 1: {"r":1.25}
row 2: {"r":["set",[1.25,3.75]]}
row 3: constraint violation: 6.25 is greater than maximum allowed value 6
mutation 3:
row 0: no change
-row 1: {"r":["set",[0.125]]}
+row 1: {"r":0.125}
row 2: {"r":["set",[0.125,0.375]]}
row 3: {"r":["set",[0.125,0.375,0.625]]}
mutation 4:
row 0: no change
-row 1: {"r":["set",[0]]}
+row 1: {"r":0}
row 2: constraint violation: Result of "*=" operation contains duplicates.
row 3: constraint violation: Result of "*=" operation contains duplicates.
mutation 5:
-row 0: {"r":["set",[1.5]]}
+row 0: {"r":1.5}
row 1: {"r":["set",[0.5,1.5]]}
row 2: no change
row 3: no change
mutation 6:
-row 0: {"r":["set",[3]]}
+row 0: {"r":3}
row 1: {"r":["set",[0.5,3]]}
row 2: {"r":["set",[0.5,1.5,3]]}
row 3: {"r":["set",[0.5,1.5,2.5,3]]}
mutation 7:
row 0: no change
row 1: no change
-row 2: {"r":["set",[0.5]]}
+row 2: {"r":0.5}
row 3: {"r":["set",[0.5,2.5]]}
mutation 8:
{"b": ["set", [true]]},
{"b": ["set", [false, true]]}']]],
[[mutation 0:
-row 0: {"b":["set",[false]]}
+row 0: {"b":false}
row 1: no change
row 2: {"b":["set",[false,true]]}
row 3: no change
mutation 1:
-row 0: {"b":["set",[true]]}
+row 0: {"b":true}
row 1: {"b":["set",[false,true]]}
row 2: no change
row 3: no change
row 0: no change
row 1: {"b":["set",[]]}
row 2: no change
-row 3: {"b":["set",[true]]}
+row 3: {"b":true}
mutation 4:
row 0: no change
row 1: no change
row 2: {"b":["set",[]]}
-row 3: {"b":["set",[false]]}
+row 3: {"b":false}
mutation 5:
row 0: no change
{"s": ["set", ["a", "b"]]},
{"s": ["set", ["a", "b", "c", "d"]]}']]],
[[mutation 0:
-row 0: {"s":["set",["a"]]}
+row 0: {"s":"a"}
row 1: no change
row 2: no change
row 3: no change
mutation 1:
-row 0: {"s":["set",["b"]]}
+row 0: {"s":"b"}
row 1: {"s":["set",["a","b"]]}
row 2: no change
row 3: no change
mutation 3:
row 0: no change
row 1: {"s":["set",[]]}
-row 2: {"s":["set",["b"]]}
+row 2: {"s":"b"}
row 3: {"s":["set",["b","c","d"]]}
mutation 4:
row 0: no change
row 1: no change
-row 2: {"s":["set",["a"]]}
+row 2: {"s":"a"}
row 3: {"s":["set",["a","c","d"]]}
mutation 5:
{"u": ["set", [["uuid", "a60fe7ff-317b-4568-9106-892b37445313"]]]},
{"u": ["set", [["uuid", "2607d30e-e652-4927-9fec-8bbf1b60c7e9"]]]}']]],
[[mutation 0:
-row 0: {"u":["set",[["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]]]}
+row 0: {"u":["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]}
row 1: no change
row 2: {"u":["set",[["uuid","a60fe7ff-317b-4568-9106-892b37445313"],["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]]]}
row 3: {"u":["set",[["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"],["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]]]}
mutation 1:
-row 0: {"u":["set",[["uuid","a60fe7ff-317b-4568-9106-892b37445313"]]]}
+row 0: {"u":["uuid","a60fe7ff-317b-4568-9106-892b37445313"]}
row 1: {"u":["set",[["uuid","a60fe7ff-317b-4568-9106-892b37445313"],["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]]]}
row 2: no change
row 3: {"u":["set",[["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"],["uuid","a60fe7ff-317b-4568-9106-892b37445313"]]]}
mutation 2:
-row 0: {"u":["set",[["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"]]]}
+row 0: {"u":["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"]}
row 1: {"u":["set",[["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"],["uuid","ddd9e79d-7782-414c-8b22-1046c60b6ec2"]]]}
row 2: {"u":["set",[["uuid","2607d30e-e652-4927-9fec-8bbf1b60c7e9"],["uuid","a60fe7ff-317b-4568-9106-892b37445313"]]]}
row 3: no change
[[parse-rows \
'{"columns": {"myset": {"type": {"key": "integer", "min": 1, "max": 2}}}}' \
'{}']],
- [{RESERVED_COLUMNS,["myset":["set",[0]]]}
+ [{RESERVED_COLUMNS,["myset":0]}
<none>])
OVSDB_CHECK_POSITIVE([row with map of 1 to 2 elements],
"snoops": {"type": {"key": "uuid", "min": 0, "max": "unlimited"}}}}' \
'{"vswitch": ["uuid", "1a5c7280-0d4c-4e34-9ec7-c772339f7774"],
"name": "br0",
- "datapath_id": ["set", ["000ae4256bb0"]],
+ "datapath_id": "000ae4256bb0",
"hwaddr": "00:0a:e4:25:6b:b0"}' \
'{}']],
- [{RESERVED_COLUMNS,["controller":["set",[]],"datapath_id":["set",["000ae4256bb0"]],"hwaddr":"00:0a:e4:25:6b:b0","listeners":["set",[]],"mirrors":["set",[]],"name":"br0","netflows":["set",[]],"snoops":["set",[]],"vswitch":["uuid","1a5c7280-0d4c-4e34-9ec7-c772339f7774"]]}
+ [{RESERVED_COLUMNS,["controller":["set",[]],"datapath_id":"000ae4256bb0","hwaddr":"00:0a:e4:25:6b:b0","listeners":["set",[]],"mirrors":["set",[]],"name":"br0","netflows":["set",[]],"snoops":["set",[]],"vswitch":["uuid","1a5c7280-0d4c-4e34-9ec7-c772339f7774"]]}
datapath_id, hwaddr, name, vswitch
{RESERVED_COLUMNS,["controller":["set",[]],"datapath_id":["set",[]],"hwaddr":"","listeners":["set",[]],"mirrors":["set",[]],"name":"","netflows":["set",[]],"snoops":["set",[]],"vswitch":["uuid","00000000-0000-0000-0000-000000000000"]]}
<none>], [], [2.64])