static void parse_db_string_column(const struct ovsdb *db, const char *name_, const struct ovsdb_table **tablep, const struct ovsdb_column **columnp) { char *name, *table_name, *column_name; const struct ovsdb_column *column; const struct ovsdb_table *table; char *save_ptr = NULL; name = xstrdup(name_); strtok_r(name, ":", &save_ptr); /* "db:" */ table_name = strtok_r(NULL, ",", &save_ptr); column_name = strtok_r(NULL, ",", &save_ptr); if (!table_name || !column_name) { ovs_fatal(0, "\"%s\": invalid syntax", name_); } table = ovsdb_get_table(db, table_name); if (!table) { ovs_fatal(0, "\"%s\": no table named %s", name_, table_name); } column = ovsdb_table_schema_get_column(table->schema, column_name); if (!column) { ovs_fatal(0, "\"%s\": table \"%s\" has no column \"%s\"", name_, table_name, column_name); } free(name); if (column->type.key.type != OVSDB_TYPE_STRING || column->type.value.type != OVSDB_TYPE_VOID) { ovs_fatal(0, "\"%s\": table \"%s\" column \"%s\" is " "not string or set of strings", name_, table->schema->name, column->name); } *columnp = column; *tablep = table; }
static WARN_UNUSED_RESULT struct ovsdb_error * ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, const struct json *json, struct ovsdb_symbol_table *symtab, struct ovsdb_clause *clause) { const struct json_array *array; struct ovsdb_error *error; const char *function_name; const char *column_name; struct ovsdb_type type; if (json->type != JSON_ARRAY || json->u.array.n != 3 || json->u.array.elems[0]->type != JSON_STRING || json->u.array.elems[1]->type != JSON_STRING) { return ovsdb_syntax_error(json, NULL, "Parse error in condition."); } array = json_array(json); column_name = json_string(array->elems[0]); clause->column = ovsdb_table_schema_get_column(ts, column_name); if (!clause->column) { return ovsdb_syntax_error(json, "unknown column", "No column %s in table %s.", column_name, ts->name); } type = clause->column->type; function_name = json_string(array->elems[1]); error = ovsdb_function_from_string(function_name, &clause->function); if (error) { return error; } /* Type-check and relax restrictions on 'type' if appropriate. */ switch (clause->function) { case OVSDB_F_LT: 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)) { char *s = ovsdb_type_to_english(&type); error = ovsdb_syntax_error( json, NULL, "Type mismatch: \"%s\" operator may not be " "applied to column %s of type %s.", ovsdb_function_to_string(clause->function), clause->column->name, s); free(s); return error; } break; case OVSDB_F_EQ: case OVSDB_F_NE: break; case OVSDB_F_EXCLUDES: if (!ovsdb_type_is_scalar(&type)) { type.n_min = 0; type.n_max = UINT_MAX; } break; case OVSDB_F_INCLUDES: if (!ovsdb_type_is_scalar(&type)) { type.n_min = 0; } break; } return ovsdb_datum_from_json(&clause->arg, &type, array->elems[2], symtab); }