This allows things like initiating a wait request on an interface
ofport being set.

When the optional field is empty and operation is != or excludes
then the result is true; otherwise it is false. If the field is
set then the field is compared normally for its type.

Signed-off-by: Terry Wilson <twil...@redhat.com>
---
 lib/ovsdb-types.h        |  9 ++++++
 ovsdb/condition.c        | 24 +++++++++++---
 tests/ovsdb-condition.at | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/lib/ovsdb-types.h b/lib/ovsdb-types.h
index efd83a7..5b6b0f0 100644
--- a/lib/ovsdb-types.h
+++ b/lib/ovsdb-types.h
@@ -152,6 +152,8 @@ bool ovsdb_type_is_valid(const struct ovsdb_type *);
 
 static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *);
 static inline bool ovsdb_type_is_optional(const struct ovsdb_type *);
+static inline bool ovsdb_type_is_optional_scalar(
+    const struct ovsdb_type *);
 static inline bool ovsdb_type_is_composite(const struct ovsdb_type *);
 static inline bool ovsdb_type_is_set(const struct ovsdb_type *);
 static inline bool ovsdb_type_is_map(const struct ovsdb_type *);
@@ -202,6 +204,13 @@ static inline bool ovsdb_type_is_optional(const struct 
ovsdb_type *type)
     return type->n_min == 0;
 }
 
+static inline bool ovsdb_type_is_optional_scalar(
+    const struct ovsdb_type *type)
+{
+    return (type->value.type == OVSDB_TYPE_VOID
+            && type->n_min == 0 && type->n_max == 1);
+}
+
 static inline bool ovsdb_type_is_composite(const struct ovsdb_type *type)
 {
     return type->n_max > 1;
diff --git a/ovsdb/condition.c b/ovsdb/condition.c
index 8e67c88..570f14d 100644
--- a/ovsdb/condition.c
+++ b/ovsdb/condition.c
@@ -93,10 +93,10 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts,
     case OVSDB_F_LE:
     case OVSDB_F_GT:
     case OVSDB_F_GE:
-        /* XXX should we also allow these operators for types with n_min == 0,
-         * n_max == 1?  (They would always be "false" if the value was
-         * missing.) */
-        if (!ovsdb_type_is_scalar(&type)
+        /* Allow these operators for types with n_min == 0, n_max == 1.
+         * (They will always be "false" if the value is missing.) */
+        if (!(ovsdb_type_is_scalar(&type)
+            || ovsdb_type_is_optional_scalar(&type))
             || (type.key.type != OVSDB_TYPE_INTEGER
                 && type.key.type != OVSDB_TYPE_REAL)) {
             char *s = ovsdb_type_to_english(&type);
@@ -225,7 +225,21 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row,
     const struct ovsdb_datum *arg = &c->arg;
     const struct ovsdb_type *type = &c->column->type;
 
-    if (ovsdb_type_is_scalar(type)) {
+    if (ovsdb_type_is_optional_scalar(type) && field->n == 0) {
+        switch (c->function) {
+            case OVSDB_F_LT:
+            case OVSDB_F_LE:
+            case OVSDB_F_EQ:
+            case OVSDB_F_GE:
+            case OVSDB_F_GT:
+            case OVSDB_F_INCLUDES:
+                return false;
+            case OVSDB_F_NE:
+            case OVSDB_F_EXCLUDES:
+                return true;
+        }
+    } else if (ovsdb_type_is_scalar(type)
+               || ovsdb_type_is_optional_scalar(type)) {
         int cmp = ovsdb_atom_compare_3way(&field->keys[0], &arg->keys[0],
                                           type->key.type);
         switch (c->function) {
diff --git a/tests/ovsdb-condition.at b/tests/ovsdb-condition.at
index d3d7d83..ab54b1c 100644
--- a/tests/ovsdb-condition.at
+++ b/tests/ovsdb-condition.at
@@ -576,3 +576,84 @@ condition 29: T-TTT ---T- -----
 condition 30: TTT-T -T-T- T----
 condition 31: T-T-T ---T- -----
 condition 32: ----- T---- ---T-], [condition])
+
+OVSDB_CHECK_POSITIVE([evaluating conditions on optional integers],
+  [[evaluate-conditions \
+    '{"columns": {"i": {"type": {"key": "integer", "min": 0, "max": 1}}}}' \
+    '[[["i", "<", 1]],
+      [["i", "<=", 1]],
+      [["i", "==", 1]],
+      [["i", "!=", 1]],
+      [["i", ">=", 1]],
+      [["i", ">", 1]],
+      [["i", "includes", 1]],
+      [["i", "excludes", 1]],
+      [["i", ">", 0], ["i", "<", 2]]]' \
+    '[{"i": ["set", []]},
+      {"i": ["set", [0]]},
+      {"i": ["set", [1]]},
+      {"i": ["set", [2]]}]']],
+  [dnl
+condition  0: -T--
+condition  1: -TT-
+condition  2: --T-
+condition  3: TT-T
+condition  4: --TT
+condition  5: ---T
+condition  6: --T-
+condition  7: TT-T
+condition  8: --T-], [condition])
+
+OVSDB_CHECK_POSITIVE([evaluating conditions on optional strings],
+  [[evaluate-conditions \
+    '{"columns": {"s": {"type": {"key": "string", "min": 0, "max": 1}}}}' \
+    '[[["s", "==", ""]],
+      [["s", "!=", ""]],
+      [["s", "includes", ""]],
+      [["s", "excludes", ""]],
+      [["s", "==", "foo"]],
+      [["s", "!=", "foo"]],
+      [["s", "includes", "foo"]],
+      [["s", "excludes", "foo"]],
+      [["s", "!=", "foo"], ["s", "!=", ""]]]' \
+    '[{"s": ["set", [""]]},
+      {"s": ["set", ["foo"]]},
+      {"s": ["set", ["xxx"]]},
+      {"s": ["set", []]}]']],
+  [dnl
+condition  0: T---
+condition  1: -TTT
+condition  2: T---
+condition  3: -TTT
+condition  4: -T--
+condition  5: T-TT
+condition  6: -T--
+condition  7: T-TT
+condition  8: --TT], [condition])
+
+OVSDB_CHECK_POSITIVE([evaluating conditions on optional reals],
+  [[evaluate-conditions \
+    '{"columns": {"r": {"type": {"key": "real", "min": 0, "max": 1}}}}' \
+    '[[["r", "<", 5.0]],
+      [["r", "<=", 5.0]],
+      [["r", "==", 5.0]],
+      [["r", "!=", 5.0]],
+      [["r", ">=", 5.0]],
+      [["r", ">", 5.0]],
+      [["r", "includes", 5.0]],
+      [["r", "excludes", 5.0]],
+      [["r", "!=", 0], ["r", "!=", 5.1]]]' \
+    '[{"r": ["set", [0]]},
+      {"r": ["set", [5.0]]},
+      {"r": ["set", [5.1]]},
+      {"r": ["set", []]}]']],
+  [dnl
+condition  0: T---
+condition  1: TT--
+condition  2: -T--
+condition  3: T-TT
+condition  4: -TT-
+condition  5: --T-
+condition  6: -T--
+condition  7: T-TT
+condition  8: -T-T], [condition])
-- 
1.9.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to