1# Tuples
2
3**Note**: Cassandra 2.1+ is required.
4
5Tuples are fixed-length sets of values. They are similar to UDTs in that they
6can contain different types of values, but unlike UDTs tuples can only be
7accessed by position and not by name.
8
9## Creating a Tuple
10
11Creating a [`CassTuple`] is done by allocating a new tuple object with the
12number of items that will be contained in it. Items can the be set in the tuple
13using their position.
14
15```c
16/* The number of items must be set properly */
17CassTuple* tuple = cass_tuple_new(2);
18
19/* Items are set by position */
20cass_tuple_set_string(tuple, 0, "abc");
21cass_tuple_set_int64(tuple, 1, 123);
22
23/* ... */
24
25/* Tuples must be freed */
26cass_tuple_free(tuple);
27```
28
29## Create a Tuple using a Data Type
30
31A tuple can also be created using a [`CassDataType`] that comes from schema
32metadata or is manually constructed. However, this is not a necessary step as
33a tuple can be created without a data type. A typed tuple will not allow invalid
34type to be added to it. [`cass_tuple_set_*()`] functions will return an error
35code if the incorrect type is added to a position.
36
37```c
38/* Creata new tuple data type */
39CassDataType* data_type = cass_data_type_new_tuple(2);
40
41/* Add a string at position 0 and an 64-bit integer at position 1 */
42cass_data_type_add_sub_value_type(data_type, CASS_VALUE_TYPE_TEXT);
43cass_data_type_add_sub_value_type(data_type, CASS_VALUE_TYPE_BIGINT);
44
45/* Create a new tuple using data type */
46CassTuple* tuple = cass_tuple_new_from_data_type(data_type);
47
48/* This will now return an error because the data type of the first item is
49 * a string not an integer
50 */
51CassError rc = cass_tuple_set_int32(tuple, 0, 123);
52
53assert(rc != CASS_OK);
54
55/* These are the correct types */
56cass_tuple_set_string(tuple, 0, "abc");
57cass_tuple_set_int64(tuple, 1, 123);
58
59/* ... */
60
61/* Constructed data types must be freed */
62cass_data_type_free(data_type);
63
64/* Tuples must be freed */
65cass_tuple_free(tuple);
66```
67
68## Consuming values from a Tuple result
69
70[`CassTuple`]s are consumed using an iterator.
71
72```c
73void iterate_tuple(const CassRow* row) {
74  /* Retrieve tuple value from column */
75  const CassValue* tuple_value = cass_row_get_column_by_name(row, "value1");
76
77  /* Create an iterator for the UDT value */
78  CassIterator* tuple_iterator = cass_iterator_from_tuple(tuple_value);
79
80  /* Iterate over the tuple fields */
81  while (cass_iterator_next(tuple_iterator)) {
82    const char* field_name;
83    size_t field_name_length;
84    /* Get tuple value */
85    const CassValue* value = cass_iterator_get_value(tuple_iterator);
86
87    /* ... */
88  }
89
90  /* The tuple iterator needs to be freed */
91  cass_iterator_free(tuple_iterator);
92}
93```
94
95[`CassTuple`]: http://datastax.github.io/cpp-driver/api/struct.CassTuple/
96[`CassUserType`]: http://datastax.github.io/cpp-driver/api/struct.CassUserType/
97[`cass_tuple_set_*()`]: http://datastax.github.io/cpp-driver/api/struct.CassTuple/#cass-tuple-set-null
98