ovsdb: Make scalars and 1-element sets interchangeable.
authorBen Pfaff <blp@nicira.com>
Tue, 9 Feb 2010 00:37:49 +0000 (16:37 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 9 Feb 2010 00:37:49 +0000 (16:37 -0800)
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.

lib/ovsdb-data.c
lib/ovsdb-types.c
ovsdb/SPECS
tests/ovsdb-condition.at
tests/ovsdb-data.at
tests/ovsdb-mutation.at
tests/ovsdb-row.at

index 47d1ea7462bd450838c4d225aabe754998125bfc..08d623a51a967ec176b59e87baf6a006d92d72a0 100644 (file)
@@ -897,26 +897,17 @@ ovsdb_datum_from_json(struct ovsdb_datum *datum,
 {
     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;
@@ -974,6 +965,17 @@ ovsdb_datum_from_json(struct ovsdb_datum *datum,
     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;
     }
 }
 
@@ -983,7 +985,7 @@ ovsdb_datum_to_json(const struct ovsdb_datum *datum,
 {
     /* 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;
index 2cefd4d7e5c291d400baa52b5c2f9eb0e248228b..5b7e7d8f68d37793607b53d12c831a123f9f0082 100644 (file)
@@ -566,7 +566,8 @@ ovsdb_type_is_valid(const struct ovsdb_type *type)
             && 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 *
index 1d55b1b5a9b9aed853878ad7aa67445b7f08d88a..ff4015c2749e8c8ddef5230d3d083630afece96d 100644 (file)
@@ -547,7 +547,8 @@ Notation for the Wire Protocol
 
 <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.
index a94f1dc7f31823e07ae687dc4b5da10824666d92..80961cc5d6a314b87267b9507d2b7f79b49347a0 100644 (file)
@@ -149,22 +149,22 @@ OVSDB_CHECK_POSITIVE([conditions on sets],
                 ["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"]]]]]]],
index 708ed9055b8ab9078d4964ed5c9eae0fded7a027..5ca23cf15ee049f76357748f1e220f28a3cdac15 100644 (file)
@@ -350,7 +350,7 @@ constraint violation: "abc" length 3 is greater than maximum allowed length 2
 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])
@@ -363,7 +363,7 @@ OVSDB_CHECK_POSITIVE([integer string datum],
 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])
@@ -375,7 +375,7 @@ OVSDB_CHECK_POSITIVE([real string datum],
 -1.25])
 
 OVSDB_CHECK_POSITIVE([boolean JSON datum],
-  [[parse-data '["boolean"]' '[true]' '[false]' ]],
+  [[parse-data '["boolean"]' '["set", [true]]' '[false]' ]],
   [true
 false])
 
@@ -385,7 +385,7 @@ OVSDB_CHECK_POSITIVE([boolean string datum],
 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"])
@@ -401,11 +401,11 @@ AT_BANNER([OVSDB -- set data])
 
 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])
 
@@ -422,12 +422,14 @@ false
 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]]
@@ -452,10 +454,12 @@ OVSDB_CHECK_POSITIVE([string set of 0 or more integers],
 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],
@@ -470,11 +474,13 @@ 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"]]]])
 
index cf4ca01100bc77b9a2d34e9fc1c3c9e30eb65da0..4308dd3059f3763ef9be9f6f3821d54c1d30403d 100644 (file)
@@ -143,11 +143,11 @@ OVSDB_CHECK_POSITIVE([mutations on sets],
 [["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])
 
@@ -449,13 +449,13 @@ OVSDB_CHECK_POSITIVE([executing mutations on integer sets],
       {"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]]}
 
@@ -478,7 +478,7 @@ row 2: no change
 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
@@ -492,7 +492,7 @@ row 3: {"i":["set",[0,1,2,3]]}
 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:
@@ -512,52 +512,52 @@ OVSDB_CHECK_POSITIVE([executing mutations on real sets],
       [["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]]}
@@ -565,7 +565,7 @@ 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:
@@ -589,13 +589,13 @@ OVSDB_CHECK_POSITIVE([executing mutations on boolean sets],
       {"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
@@ -610,13 +610,13 @@ mutation  3:
 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
@@ -639,13 +639,13 @@ OVSDB_CHECK_POSITIVE([executing mutations on string sets],
       {"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
@@ -659,13 +659,13 @@ 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:
@@ -689,19 +689,19 @@ OVSDB_CHECK_POSITIVE([executing mutations on uuid sets],
       {"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
index e631f6f80c6ca101dbbe9b4e9ae43f298d807954..d5bfcda25716ff3f8eda4a44739aae235fb4c523 100644 (file)
@@ -84,7 +84,7 @@ OVSDB_CHECK_POSITIVE([row with set of 1 to 2 elements],
   [[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],
@@ -108,10 +108,10 @@ OVSDB_CHECK_POSITIVE([row with several columns],
          "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])