Updating set-type collections with multiple elements. Is it possible?

1,084 views
Skip to first unread message

Yi Zhou

unread,
May 3, 2015, 7:36:18 AM5/3/15
to cpp-dri...@lists.datastax.com
From the CQL documentation, all the examples incrementally update the set collections, one element at a time : http://docs.datastax.com/en/cql/3.1/cql/ddl/ddl_updating_collection_c.html

Is it possible to specify all the new values for your set collection in one query?

Previously I tried this prepared query :
"UPDATE social.events SET attending_userids = attending_userids + (?) WHERE event_id = (?);"

Attending_userids is set<bigint>
I tried binding a set<bigint> collection (CASS_COLLECTION_TYPE_SET) to the first (?) but I got the error : Error: Invalid tuple type literal for attending_userids of type set<bigint>

Is there a problem with my prepared query, or the multi-item set insert is not possible with cql?
If we can insert only one item at a time, does that mean instead of binding set<bigint> I need to SET attending_userids = attending_userids + {(?)} , where (?) is binded by bigint?

Thanks.

Michael Penick

unread,
May 4, 2015, 5:54:00 PM5/4/15
to cpp-dri...@lists.datastax.com
Unfortunately, I don't this this is supported by the CQL syntax. When I try:

1)
Query:
"UPDATE examples.test_set SET value = value + {?} WHERE key = ?" 
Result: 
"Invalid set literal for value: bind variables are not supported inside collection literals"


2)
Query: 
"UPDATE examples.test_set SET value = value + ? WHERE key = ?"

Result: 
"Expected 4 or 0 byte int (16)"

I think you need to dynamically build a query with the correct number of "?" in the set/map literal. For example, a two items update would need to have a set of two items: "UPDATE examples.test_set SET value = value + {?, ?} WHERE key = ?", then use multiple calls to "cass_statement_bind_*()".

Mike

PS:
Here's my the code I used to try this:

#include <stdio.h>
#include <cassandra.h>

/* Schema:
 * CREATE KEYSPACE examples WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 2 };
 * CREATE TABLE test_set(key int PRIMARY KEY, value set<text>);
 *
 * Precondition:
 * INSERT INTO test_set (key, value) VALUES (1, {'item1', 'item2'});
 */

int main() {
  /* Setup and connect to cluster */
  CassCluster* cluster = cass_cluster_new();
  CassSession* session = cass_session_new();

  /* Add contact points */
  cass_cluster_set_contact_points(cluster, "127.0.0.1,127.0.0.2,127.0.0.3");

  CassFuture* connect_future = cass_session_connect(session, cluster);
  if (cass_future_error_code(connect_future) == CASS_OK) {
    /* These don't work */
    /*CassString query = cass_string_init("UPDATE examples.test_set SET value = value + {?} WHERE key = ?");*/
    CassString query = cass_string_init("UPDATE examples.test_set SET value = value + ? WHERE key = ?");
    CassStatement* statement = cass_statement_new(query, 2);
    CassCollection* coll = cass_collection_new(CASS_COLLECTION_TYPE_SET, 2);

    cass_statement_bind_int32(statement, 0, 1);

    cass_collection_append_string(coll, cass_string_init("item3"));
    cass_collection_append_string(coll, cass_string_init("item4"));
    cass_statement_bind_collection(statement, 1, coll);
    cass_collection_free(coll);

    CassFuture* future = cass_session_execute(session, statement);

    if (cass_future_error_code(future) == CASS_OK) {
      printf("Success!\n");
    } else {
      CassString message = cass_future_error_message(future);
      fprintf(stderr, "Error running query: %.*s\n", (int)message.length, message.data);
    }

    cass_statement_free(statement);
  } else {
    CassString message = cass_future_error_message(connect_future);
    fprintf(stderr, "Error connectin: %.*s\n", (int)message.length, message.data);
  }
  cass_future_free(connect_future);
  cass_session_free(session);

  cass_cluster_free(cluster);

  return 0;
}



To unsubscribe from this group and stop receiving emails from it, send an email to cpp-driver-us...@lists.datastax.com.

Reply all
Reply to author
Forward
0 new messages