+ const struct ovsdb_column *c = mt->columns[i].column;
+ const struct ovsdb_datum *src = &row->fields[c->index];
+ struct ovsdb_datum *dst = &data[i];
+ const struct ovsdb_type *type = &c->type;
+
+ ovsdb_datum_clone(dst, src, type);
+ }
+ return data;
+}
+
+/* Replaces the mt->n_columns ovsdb_datums in row[] by copies of the data from
+ * in 'row' drawn from the columns represented by mt->columns[]. */
+static void
+update_monitor_row_data(const struct ovsdb_jsonrpc_monitor_table *mt,
+ const struct ovsdb_row *row,
+ struct ovsdb_datum *data)
+{
+ size_t i;
+
+ for (i = 0; i < mt->n_columns; i++) {
+ const struct ovsdb_column *c = mt->columns[i].column;
+ const struct ovsdb_datum *src = &row->fields[c->index];
+ struct ovsdb_datum *dst = &data[i];
+ const struct ovsdb_type *type = &c->type;
+
+ if (!ovsdb_datum_equals(src, dst, type)) {
+ ovsdb_datum_destroy(dst, type);
+ ovsdb_datum_clone(dst, src, type);
+ }
+ }
+}
+
+/* Frees all of the mt->n_columns ovsdb_datums in data[], using the types taken
+ * from mt->columns[], plus 'data' itself. */
+static void
+free_monitor_row_data(const struct ovsdb_jsonrpc_monitor_table *mt,
+ struct ovsdb_datum *data)
+{
+ if (data) {
+ size_t i;