netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / ovsdb / condition.c
index 0342b8e..4baf1bb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,11 +52,10 @@ ovsdb_function_to_string(enum ovsdb_function function)
     return NULL;
 }
 
-
-static WARN_UNUSED_RESULT struct ovsdb_error *
+static OVS_WARN_UNUSED_RESULT struct ovsdb_error *
 ovsdb_clause_from_json(const struct ovsdb_table_schema *ts,
                        const struct json *json,
-                       const struct ovsdb_symbol_table *symtab,
+                       struct ovsdb_symbol_table *symtab,
                        struct ovsdb_clause *clause)
 {
     const struct json_array *array;
@@ -94,12 +93,12 @@ 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)
-            || (type.key_type != OVSDB_TYPE_INTEGER
-                && type.key_type != OVSDB_TYPE_REAL)) {
+        /* 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);
             error = ovsdb_syntax_error(
                 json, NULL, "Type mismatch: \"%s\" operator may not be "
@@ -168,7 +167,7 @@ compare_clauses_3way(const void *a_, const void *b_)
 struct ovsdb_error *
 ovsdb_condition_from_json(const struct ovsdb_table_schema *ts,
                           const struct json *json,
-                          const struct ovsdb_symbol_table *symtab,
+                          struct ovsdb_symbol_table *symtab,
                           struct ovsdb_condition *cnd)
 {
     const struct json_array *array = json_array(json);
@@ -218,55 +217,78 @@ ovsdb_condition_to_json(const struct ovsdb_condition *cnd)
     return json_array_create(clauses, cnd->n_clauses);
 }
 
-bool
-ovsdb_condition_evaluate(const struct ovsdb_row *row,
-                         const struct ovsdb_condition *cnd)
+static bool
+ovsdb_clause_evaluate(const struct ovsdb_row *row,
+                      const struct ovsdb_clause *c)
 {
-    size_t i;
+    const struct ovsdb_datum *field = &row->fields[c->column->index];
+    const struct ovsdb_datum *arg = &c->arg;
+    const struct ovsdb_type *type = &c->column->type;
 
-    for (i = 0; i < cnd->n_clauses; i++) {
-        const struct ovsdb_clause *c = &cnd->clauses[i];
-        const struct ovsdb_datum *field = &row->fields[c->column->index];
-        const struct ovsdb_datum *arg = &cnd->clauses[i].arg;
-        const struct ovsdb_type *type = &c->column->type;
-
-        if (ovsdb_type_is_scalar(type)) {
-            int cmp = ovsdb_atom_compare_3way(&field->keys[0], &arg->keys[0],
-                                              type->key_type);
-            switch (c->function) {
+    if (ovsdb_type_is_optional_scalar(type) && field->n == 0) {
+        switch (c->function) {
             case OVSDB_F_LT:
-                return cmp < 0;
             case OVSDB_F_LE:
-                return cmp <= 0;
             case OVSDB_F_EQ:
-            case OVSDB_F_INCLUDES:
-                return cmp == 0;
-            case OVSDB_F_NE:
-            case OVSDB_F_EXCLUDES:
-                return cmp != 0;
             case OVSDB_F_GE:
-                return cmp >= 0;
             case OVSDB_F_GT:
-                return cmp > 0;
-            }
-        } else {
-            switch (c->function) {
-            case OVSDB_F_EQ:
-                return ovsdb_datum_equals(field, arg, type);
-            case OVSDB_F_NE:
-                return !ovsdb_datum_equals(field, arg, type);
             case OVSDB_F_INCLUDES:
-                return ovsdb_datum_includes_all(arg, field, type);
+                return false;
+            case OVSDB_F_NE:
             case OVSDB_F_EXCLUDES:
-                return ovsdb_datum_excludes_all(arg, field, type);
-            case OVSDB_F_LT:
-            case OVSDB_F_LE:
-            case OVSDB_F_GE:
-            case OVSDB_F_GT:
-                NOT_REACHED();
-            }
+                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) {
+        case OVSDB_F_LT:
+            return cmp < 0;
+        case OVSDB_F_LE:
+            return cmp <= 0;
+        case OVSDB_F_EQ:
+        case OVSDB_F_INCLUDES:
+            return cmp == 0;
+        case OVSDB_F_NE:
+        case OVSDB_F_EXCLUDES:
+            return cmp != 0;
+        case OVSDB_F_GE:
+            return cmp >= 0;
+        case OVSDB_F_GT:
+            return cmp > 0;
+        }
+    } else {
+        switch (c->function) {
+        case OVSDB_F_EQ:
+            return ovsdb_datum_equals(field, arg, type);
+        case OVSDB_F_NE:
+            return !ovsdb_datum_equals(field, arg, type);
+        case OVSDB_F_INCLUDES:
+            return ovsdb_datum_includes_all(arg, field, type);
+        case OVSDB_F_EXCLUDES:
+            return ovsdb_datum_excludes_all(arg, field, type);
+        case OVSDB_F_LT:
+        case OVSDB_F_LE:
+        case OVSDB_F_GE:
+        case OVSDB_F_GT:
+            OVS_NOT_REACHED();
+        }
+    }
+
+    OVS_NOT_REACHED();
+}
+
+bool
+ovsdb_condition_evaluate(const struct ovsdb_row *row,
+                         const struct ovsdb_condition *cnd)
+{
+    size_t i;
+
+    for (i = 0; i < cnd->n_clauses; i++) {
+        if (!ovsdb_clause_evaluate(row, &cnd->clauses[i])) {
+            return false;
         }
-        NOT_REACHED();
     }
 
     return true;