1# Data Types 2 3[`CassDataType`] objects are useful for describing the different values that can 4be stored in Cassandra, from primitive types to more complex composite types, 5such as, UDTs (user-defined types), tuples and collections. Data types can be retrieved from existing 6metadata found in schema, results, values or prepared statements, or they can be 7constructed programmatically. 8 9The following code snippets use the following type schema: 10 11```cql 12CREATE TYPE person (name text, 13 // Street address, zip code, state/province, and country 14 address frozen<tuple<text, int, text, text>>, 15 // Type and number 16 phone_numbers frozen<map<text, int>>); 17``` 18 19## Retrieving an Existing Data Type 20 21**Important**: Any `const CassDataType*` object doesn't need to be freed. Its 22lifetime is bound to the object it came from. 23 24UDT data types can be retrieved using a [`CassSchemaMeta`] object. The resulting 25data type object can be used to construct a new [`CassUserType`] object using 26[`cass_user_type_new_from_data_type()`]. 27 28```c 29void get_person_data_type_from_keyspace(CassSession* session) { 30 /* Get schema object (this should be cached) */ 31 const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session); 32 33 /* Get the keyspace for the user-defined type. It doesn't need to be freed */ 34 const CassKeyspaceMeta* keyspace_meta = 35 cass_schema_meta_keyspace_by_name(schema_meta, "examples"); 36 37 /* This data type object doesn't need to be freed */ 38 const CassDataType* person_data_type = 39 cass_keyspace_meta_user_type_by_name(keyspace_meta, "person"); 40 41 /* ... */ 42 43 /* Schema object must be freed */ 44 cass_schema_meta_free(schema_meta); 45} 46``` 47 48Data types can also be retrieved from [`CassResult`], [`CassPrepared`], and 49[`CassValue`] objects. 50 51* [`cass_result_column_data_type()`] can be used to get the 52 data type of a column for a [`CassResult`]. 53 * [`cass_prepared_parameter_data_type()`] can be used to get the data type of 54 the parameters for a [`CassPrepared`] object. There are also functions to get 55 the data type of a prepared parameter by name. 56* [`cass_value_data_type()`] can be used to get the data type represented by a 57 [`CassValue`] object. 58 59## Building a Data Type Programmatically 60 61Data types could be constructed programmatically. This is useful for application that may 62have schema metatdata disabled. 63 64```c 65CassDataType* address_data_type = cass_data_type_new_type(4); 66CassDataType* phone_numbers_data_type = cass_data_type_new(2); 67CassDataType* person_data_type = cass_data_type_new_udt(3); 68 69/* Street address, zip code, state/province, and country */ 70cass_data_type_add_sub_value_type(address_data_type, CASS_VALUE_TYPE_TEXT); 71cass_data_type_add_sub_value_type(address_data_type, CASS_VALUE_TYPE_INT); 72cass_data_type_add_sub_value_type(address_data_type, CASS_VALUE_TYPE_TEXT); 73cass_data_type_add_sub_value_type(address_data_type, CASS_VALUE_TYPE_TEXT); 74 75/* Phone type and number*/ 76cass_data_type_add_sub_value_type(phone_numbers_data_type, CASS_VALUE_TYPE_TEXT); 77cass_data_type_add_sub_value_type(phone_numbers_data_type, CASS_VALUE_TYPE_INT); 78 79/* Add fields to the person data type */ 80cass_data_type_add_sub_value_type_by_name(person_data_type, "name", CASS_VALUE_TYPE_TEXT); 81cass_data_type_add_sub_data_type_by_name(person_data_type, "address", address_data_type); 82cass_data_type_add_sub_value_type_by_name(person_data_type, "phone_numbers", phone_numbers_data_type); 83 84/* ... */ 85 86/* Data types must be freed */ 87cass_data_type_free(address_data_type); 88cass_data_type_free(phone_numbers_data_type); 89cass_data_type_free(person_data_type); 90``` 91 92## Creating UDTs, Tuples and Collections Using Data Types 93 94After the user type object is retrieved or created manually, it can be used to 95construct composite data types. The subtypes of a data type can be used to 96construct other nested types. 97 98```c 99CassDataType* person_data_type = NULL; 100 101/* Construct or lookup data type */ 102 103/* Construct a new UDT from a data type */ 104CassUserType* person = cass_user_type_new_from_data_type(person_data_type); 105 106/* ... */ 107 108/* Construct a new tuple from a nested data type */ 109CassTuple* address = 110 cass_tuple_new_from_data_type( 111 cass_data_type_sub_data_type_by_name(person_data_type, "address")); 112 113/* ... */ 114 115/* Construct a new map collection from a nested data type */ 116CassCollection* phone_numbers = 117 cass_collection_new_from_data_type( 118 cass_data_type_sub_data_type_by_name(person_data_type, "phone_numbers"), 2); 119 120/* ... */ 121 122/* Add fields to the UDT */ 123cass_user_type_set_string_byte_by_name(person, "name", "Bob"); 124cass_user_type_set_user_type_by_name(person, "address", address); 125cass_user_type_set_collection_by_name(person, "phone_numbers", phone_numbers); 126 127/* ... */ 128 129/* UDT, tuple, and collection objects must be freed */ 130cass_user_type_free(person); 131cass_tuple_free(address); 132cass_collection_free(phone_numbers); 133``` 134 135[`CassDataType`]: http://datastax.github.io/cpp-driver/api/struct.CassDataType/ 136[`CassUserType`]: http://datastax.github.io/cpp-driver/api/struct.CassUserType/ 137[`CassPrepared`]: http://datastax.github.io/cpp-driver/api/struct.CassPrepared/ 138[`CassResult`]: http://datastax.github.io/cpp-driver/api/struct.CassResult/ 139[`CassValue`]: http://datastax.github.io/cpp-driver/api/struct.CassValue/ 140[`CassSchemaMeta`]: http://datastax.github.io/cpp-driver/api/struct.CassSchemaMeta/ 141[`cass_user_type_new_from_data_type()`]: http://datastax.github.io/cpp-driver/api/struct.CassUserType/#cass-user-type-new-from-data-type 142[`cass_result_column_data_type()`]: http://datastax.github.io/cpp-driver/api/struct.CassResult/#cass-result-column-data-type 143[`cass_prepared_parameter_data_type()`]: http://datastax.github.io/cpp-driver/api/struct.CassPrepared/#cass-prepared-parameter-data-type 144[`cass_value_data_type()`]: http://datastax.github.io/cpp-driver/api/struct.CassValue/#cass-value-data-type 145