From c15914f761c722d31f72524fe468d6275bdddf47 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 17 Aug 2012 21:13:20 +0400 Subject: Initial commit for Cassandra storage engine. --- mysql-test/include/have_cassandra.inc | 10 + mysql-test/include/have_cassandra.opt | 1 + mysql-test/r/cassandra.result | 20 + mysql-test/t/cassandra.test | 68 + storage/cassandra/CMakeLists.txt | 22 + storage/cassandra/cassandra_se.cc | 271 + storage/cassandra/cassandra_se.h | 57 + storage/cassandra/gen-cpp/Cassandra.cpp | 12871 +++++++++++++++++++ storage/cassandra/gen-cpp/Cassandra.h | 5466 ++++++++ .../gen-cpp/Cassandra_server.skeleton.cpp | 219 + storage/cassandra/gen-cpp/cassandra_constants.cpp | 18 + storage/cassandra/gen-cpp/cassandra_constants.h | 26 + storage/cassandra/gen-cpp/cassandra_types.cpp | 3512 +++++ storage/cassandra/gen-cpp/cassandra_types.h | 2149 ++++ storage/cassandra/ha_cassandra.cc | 727 ++ storage/cassandra/ha_cassandra.h | 218 + 16 files changed, 25655 insertions(+) create mode 100644 mysql-test/include/have_cassandra.inc create mode 100644 mysql-test/include/have_cassandra.opt create mode 100644 mysql-test/r/cassandra.result create mode 100644 mysql-test/t/cassandra.test create mode 100644 storage/cassandra/CMakeLists.txt create mode 100644 storage/cassandra/cassandra_se.cc create mode 100644 storage/cassandra/cassandra_se.h create mode 100644 storage/cassandra/gen-cpp/Cassandra.cpp create mode 100644 storage/cassandra/gen-cpp/Cassandra.h create mode 100644 storage/cassandra/gen-cpp/Cassandra_server.skeleton.cpp create mode 100644 storage/cassandra/gen-cpp/cassandra_constants.cpp create mode 100644 storage/cassandra/gen-cpp/cassandra_constants.h create mode 100644 storage/cassandra/gen-cpp/cassandra_types.cpp create mode 100644 storage/cassandra/gen-cpp/cassandra_types.h create mode 100644 storage/cassandra/ha_cassandra.cc create mode 100644 storage/cassandra/ha_cassandra.h diff --git a/mysql-test/include/have_cassandra.inc b/mysql-test/include/have_cassandra.inc new file mode 100644 index 00000000000..d358e2ecc26 --- /dev/null +++ b/mysql-test/include/have_cassandra.inc @@ -0,0 +1,10 @@ +# +# suite.pm will make sure that all tests including this file +# will be skipped unless innodb or xtradb is enabled +# +# The test below is redundant + +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'cassandra' AND support IN ('YES', 'DEFAULT', 'ENABLED')`) +{ + --skip Test requires Cassandra. +} diff --git a/mysql-test/include/have_cassandra.opt b/mysql-test/include/have_cassandra.opt new file mode 100644 index 00000000000..92d642a5e4c --- /dev/null +++ b/mysql-test/include/have_cassandra.opt @@ -0,0 +1 @@ +--cassandra=on diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result new file mode 100644 index 00000000000..6dbf08651d8 --- /dev/null +++ b/mysql-test/r/cassandra.result @@ -0,0 +1,20 @@ +drop table if exists t0, t1; +create table t1 (a int) engine=cassandra +thrift_host='localhost' keyspace='foo' column_family='colfam'; +ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' +create table t1 (a int primary key, b int) engine=cassandra +thrift_host='localhost' keyspace='foo' column_family='colfam'; +ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra +thrift_host='127.0.0.2' keyspace='foo' column_family='colfam'; +ERROR HY000: Unable to connect to foreign data source: connect() failed: Connection refused [1] +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra +thrift_host='localhost' keyspace='no_such_keyspace' column_family='colfam'; +ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace no_such_keyspace does not exist] +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra +thrift_host='localhost' keyspace='no_such_keyspace'; +ERROR HY000: Can't create table 'test.t1' (errno: 140) +create table t1 (rowkey char(36) primary key, column1 char(60)) engine=cassandra +thrift_host='localhost' keyspace='mariadbtest' column_family='cf1'; +insert into t1 values ('key0', 'data1'); +drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test new file mode 100644 index 00000000000..34a6909af38 --- /dev/null +++ b/mysql-test/t/cassandra.test @@ -0,0 +1,68 @@ +# +# Tests for cassandra storage engine +# +--source include/have_cassandra.inc + +--disable_warnings +drop table if exists t0, t1; +--enable_warnings + +# Test various errors on table creation. +--error ER_WRONG_COLUMN_NAME +create table t1 (a int) engine=cassandra + thrift_host='localhost' keyspace='foo' column_family='colfam'; + +--error ER_WRONG_COLUMN_NAME +create table t1 (a int primary key, b int) engine=cassandra + thrift_host='localhost' keyspace='foo' column_family='colfam'; + +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra + thrift_host='127.0.0.2' keyspace='foo' column_family='colfam'; + +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra + thrift_host='localhost' keyspace='no_such_keyspace' column_family='colfam'; + +# No column family specified +--error ER_CANT_CREATE_TABLE +create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra + thrift_host='localhost' keyspace='no_such_keyspace'; + +############################################################################ +## Cassandra initialization: +############################################################################ +--disable_parsing + +./cqlsh --cql3 + +CREATE KEYSPACE mariadbtest + WITH strategy_class = 'org.apache.cassandra.locator.SimpleStrategy' + AND strategy_options:replication_factor='1'; + +USE mariadbtest; +create columnfamily cf1 ( pk varchar primary key, data1 varchar); + +--enable_parsing +############################################################################ +## Cassandra initialization ends +############################################################################ + +# Now, create a table for real and insert data +create table t1 (rowkey char(36) primary key, column1 char(60)) engine=cassandra + thrift_host='localhost' keyspace='mariadbtest' column_family='cf1'; + +insert into t1 values ('key0', 'data1'); + +drop table t1; + +############################################################################ +## Cassandra cleanup +############################################################################ +--disable_parsing +drop columnfamily cf1; +--enable_parsing +############################################################################ +## Cassandra cleanup ends +############################################################################ + diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt new file mode 100644 index 00000000000..7986b0244bb --- /dev/null +++ b/storage/cassandra/CMakeLists.txt @@ -0,0 +1,22 @@ + +SET(cassandra_sources + ha_cassandra.cc + ha_cassandra.h + cassandra_se.h + cassandra_se.cc + gen-cpp/Cassandra.cpp + gen-cpp/cassandra_types.h + gen-cpp/cassandra_types.cpp + gen-cpp/cassandra_constants.h + gen-cpp/cassandra_constants.cpp + gen-cpp/Cassandra.h) + +#INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/) +# +STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +#LINK_DIRECTORIES(/home/psergey/cassandra/thrift/lib) + +MYSQL_ADD_PLUGIN(cassandra ${cassandra_sources} STORAGE_ENGINE LINK_LIBRARIES thrift) +# was: STORAGE_ENGINE MANDATORY diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc new file mode 100644 index 00000000000..1bc799d09c6 --- /dev/null +++ b/storage/cassandra/cassandra_se.cc @@ -0,0 +1,271 @@ + +// Cassandra includes: +#include +#include +#include +#include +#include + +#include "Thrift.h" +#include "transport/TSocket.h" +#include "transport/TTransport.h" +#include "transport/TBufferTransports.h" +#include "protocol/TProtocol.h" +#include "protocol/TBinaryProtocol.h" +#include "gen-cpp/Cassandra.h" +// cassandra includes end + +#include "cassandra_se.h" + +using namespace std; +using namespace apache::thrift; +using namespace apache::thrift::transport; +using namespace apache::thrift::protocol; +using namespace org::apache::cassandra; + +void Cassandra_se_interface::print_error(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + // it's not a problem if output was truncated + vsnprintf(err_buffer, sizeof(err_buffer), format, ap); + va_end(ap); +} + +/* + Implementation of connection to one Cassandra column family (ie., table) +*/ +class Cassandra_se_impl: public Cassandra_se_interface +{ + CassandraClient *cass; /* Connection to cassandra */ + ConsistencyLevel::type cur_consistency_level; + + std::string column_family; + std::string keyspace; + + /* DDL checks */ + KsDef ks_def; /* KeySpace we're using (TODO: put this in table->share) */ + CfDef cf_def; /* Column family we're using (TODO: put in table->share)*/ + std::vector::iterator column_ddl_it; + + /* The list that was returned by the last key lookup */ + std::vector col_supercol_vec; + +public: + + Cassandra_se_impl() : cass(NULL) {} + virtual ~Cassandra_se_impl(){ delete cass; } + + bool connect(const char *host, const char *keyspace); + + virtual void set_column_family(const char *cfname) + { + column_family.assign(cfname); + } + + virtual bool insert(NameAndValue *fields); + virtual bool get_slice(char *key, size_t key_len, NameAndValue *row, bool *found); + + + /* Functions to enumerate ColumnFamily's DDL data */ + bool setup_ddl_checks(); + void first_ddl_column(); + bool next_ddl_column(char **name, int *name_len, char **value, int *value_len); +}; + + +Cassandra_se_interface *get_cassandra_se() +{ + return new Cassandra_se_impl; +} + +#define CASS_TRY(x) try { \ + x; \ + }catch(TTransportException te){ \ + print_error("%s [%d]", te.what(), te.getType()); \ + }catch(InvalidRequestException ire){ \ + print_error("%s [%s]", ire.what(), ire.why.c_str()); \ + }catch(NotFoundException nfe){ \ + print_error("%s", nfe.what()); \ + } catch(...) { \ + print_error("Unknown Exception"); \ + } + +bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) +{ + bool res= true; + + keyspace.assign(keyspace_arg); + + try { + boost::shared_ptr socket = + boost::shared_ptr(new TSocket(host, 9160)); + boost::shared_ptr tr = + boost::shared_ptr(new TFramedTransport (socket)); + boost::shared_ptr p = + boost::shared_ptr(new TBinaryProtocol(tr)); + + cass= new CassandraClient(p); + tr->open(); + cass->set_keyspace(keyspace_arg); + + res= false; // success + }catch(TTransportException te){ + print_error("%s [%d]", te.what(), te.getType()); + }catch(InvalidRequestException ire){ + print_error("%s [%s]", ire.what(), ire.why.c_str()); + }catch(NotFoundException nfe){ + print_error("%s", nfe.what()); + } + catch(...) { + print_error("Unknown Exception"); + } + + // For now: + cur_consistency_level= ConsistencyLevel::ONE; + + if (setup_ddl_checks()) + res= true; + return res; +} + + +bool Cassandra_se_impl::setup_ddl_checks() +{ + try { + cass->describe_keyspace(ks_def, keyspace); + + std::vector::iterator it; + for (it= ks_def.cf_defs.begin(); it < ks_def.cf_defs.end(); it++) + { + cf_def= *it; + if (!cf_def.name.compare(column_family)) + return false; + } + + print_error("describe_keyspace() didn't return our column family"); + + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (NotFoundException nfe) { + print_error("keyspace not found: %s", nfe.what()); + } + return true; +} + + +void Cassandra_se_impl::first_ddl_column() +{ + column_ddl_it= cf_def.column_metadata.begin(); +} + + +bool Cassandra_se_impl::next_ddl_column(char **name, int *name_len, + char **type, int *type_len) +{ + if (column_ddl_it == cf_def.column_metadata.end()) + return true; + + *name= (char*)(*column_ddl_it).name.c_str(); + *name_len= (*column_ddl_it).name.length(); + + *type= (char*)(*column_ddl_it).validation_class.c_str(); + *type_len= (*column_ddl_it).validation_class.length(); + + column_ddl_it++; + return false; +} + + +bool Cassandra_se_impl::insert(NameAndValue *fields) +{ + ColumnParent cparent; + cparent.column_family= column_family; + + Column c; + struct timeval td; + gettimeofday(&td, NULL); + int64_t ms = td.tv_sec; + ms = ms * 1000; + int64_t usec = td.tv_usec; + usec = usec / 1000; + ms += usec; + c.timestamp = ms; + c.__isset.timestamp = true; + + std::string key; + key.assign(fields->value, fields->value_len); + fields++; + + bool res= false; + try { + /* TODO: switch to batch_mutate(). Or, even to CQL? */ + + // TODO: what should INSERT table (co1, col2) VALUES ('foo', 'bar') mean? + // in SQL, it sets all columns.. what should it mean here? can we have + // it to work only for specified columns? (if yes, what do for + // VALUES()?) + c.__isset.value= true; + for(;fields->name; fields++) + { + c.name.assign(fields->name); + c.value.assign(fields->value, fields->value_len); + cass->insert(key, cparent, c, ConsistencyLevel::ONE); + } + + } catch (...) { + res= true; + } + return res; +} + + +bool Cassandra_se_impl::get_slice(char *key, size_t key_len, NameAndValue *row, bool *found) +{ + ColumnParent cparent; + cparent.column_family= column_family; + + std::string rowkey_str; + rowkey_str.assign(key, key_len); + + SlicePredicate slice_pred; + SliceRange sr; + sr.start = ""; + sr.finish = ""; + slice_pred.__set_slice_range(sr); + + try { + std::vector &res= col_supercol_vec; + cass->get_slice(res, rowkey_str, cparent, slice_pred, ConsistencyLevel::ONE); + *found= true; + + std::vector::iterator it; + if (res.size() == 0) + { + /* + No columns found. Cassandra doesn't allow records without any column => + this means the seach key doesn't exist + */ + *found= false; + return false; + } + for (it= res.begin(); it < res.end(); it++) + { + ColumnOrSuperColumn cs= *it; + if (!cs.__isset.column) + return true; + row->name= (char*)cs.column.name.c_str(); + row->value= (char*)cs.column.value.c_str(); + row->value_len= cs.column.value.length(); + row++; + } + row->name= NULL; + } catch (InvalidRequestException ire) { + return true; + } catch (UnavailableException ue) { + return true; + } catch (TimedOutException te) { + return true; + } + return false; +} diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h new file mode 100644 index 00000000000..1ab14c39602 --- /dev/null +++ b/storage/cassandra/cassandra_se.h @@ -0,0 +1,57 @@ + +/* + This file is a "bridge" interface between cassandra+Thrift and MariaDB. + + It is #included by both sides, so it must itself include neither (including + both together causes compile errors due to conflicts). +*/ + + +/* + Storage for (name,value) pairs. name==NULL means 'non-object'. + + This should be used for + - shipping data from sql to cassandra for INSERTs + - shipping data from cassandra to SQL for record reads. + +*/ +class NameAndValue +{ +public: + char *name; + char *value; + size_t value_len; +}; + +/* + Interface to one cassandra column family, i.e. one 'table' +*/ +class Cassandra_se_interface +{ +public: + Cassandra_se_interface() { err_buffer[0]=0; } + + virtual ~Cassandra_se_interface(){}; + /* Init */ + virtual bool connect(const char *host, const char *port)=0; + virtual void set_column_family(const char *cfname) = 0; + + /* Check underlying DDL */ + virtual bool setup_ddl_checks()=0; + virtual void first_ddl_column()=0; + virtual bool next_ddl_column(char **name, int *name_len, char **value, + int *value_len)=0; + + /* Writes */ + virtual bool insert(NameAndValue *fields)=0; + + /* Reads */ + virtual bool get_slice(char *key, size_t key_len, NameAndValue *row, bool *found)=0 ; + + /* Passing error messages up to ha_cassandra */ + char err_buffer[512]; + const char *error_str() { return err_buffer; } + void print_error(const char *format, ...); +}; + +Cassandra_se_interface *get_cassandra_se(); diff --git a/storage/cassandra/gen-cpp/Cassandra.cpp b/storage/cassandra/gen-cpp/Cassandra.cpp new file mode 100644 index 00000000000..db1deb34c31 --- /dev/null +++ b/storage/cassandra/gen-cpp/Cassandra.cpp @@ -0,0 +1,12871 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include +#include + +#include "Cassandra.h" + +namespace org { namespace apache { namespace cassandra { + +uint32_t Cassandra_login_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_auth_request = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->auth_request.read(iprot); + isset_auth_request = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_auth_request) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_login_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_login_args"); + xfer += oprot->writeFieldBegin("auth_request", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->auth_request.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_login_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_login_pargs"); + xfer += oprot->writeFieldBegin("auth_request", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->auth_request)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_login_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->authnx.read(iprot); + this->__isset.authnx = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->authzx.read(iprot); + this->__isset.authzx = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_login_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_login_result"); + + if (this->__isset.authnx) { + xfer += oprot->writeFieldBegin("authnx", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->authnx.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.authzx) { + xfer += oprot->writeFieldBegin("authzx", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->authzx.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_login_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->authnx.read(iprot); + this->__isset.authnx = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->authzx.read(iprot); + this->__isset.authzx = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_set_keyspace_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keyspace = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->keyspace); + isset_keyspace = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keyspace) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_set_keyspace_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_set_keyspace_args"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->keyspace); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_keyspace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_set_keyspace_pargs"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->keyspace))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_keyspace_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_set_keyspace_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_set_keyspace_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_keyspace_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_path = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_path.read(iprot); + isset_column_path = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast149; + xfer += iprot->readI32(ecast149); + this->consistency_level = (ConsistencyLevel::type)ecast149; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_path) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_path.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_path)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->success.read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->nfe.read(iprot); + this->__isset.nfe = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0); + xfer += this->success.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.nfe) { + xfer += oprot->writeFieldBegin("nfe", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->nfe.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 4); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += (*(this->success)).read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->nfe.read(iprot); + this->__isset.nfe = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_slice_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_parent = false; + bool isset_predicate = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + isset_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast150; + xfer += iprot->readI32(ecast150); + this->consistency_level = (ConsistencyLevel::type)ecast150; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_slice_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_slice_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_slice_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_slice_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_slice_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size151; + ::apache::thrift::protocol::TType _etype154; + iprot->readListBegin(_etype154, _size151); + this->success.resize(_size151); + uint32_t _i155; + for (_i155 = 0; _i155 < _size151; ++_i155) + { + xfer += this->success[_i155].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_slice_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_slice_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter156; + for (_iter156 = this->success.begin(); _iter156 != this->success.end(); ++_iter156) + { + xfer += (*_iter156).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_slice_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size157; + ::apache::thrift::protocol::TType _etype160; + iprot->readListBegin(_etype160, _size157); + (*(this->success)).resize(_size157); + uint32_t _i161; + for (_i161 = 0; _i161 < _size157; ++_i161) + { + xfer += (*(this->success))[_i161].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_count_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_parent = false; + bool isset_predicate = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + isset_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast162; + xfer += iprot->readI32(ecast162); + this->consistency_level = (ConsistencyLevel::type)ecast162; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_count_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_count_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_count_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_count_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_count_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_count_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_count_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_I32, 0); + xfer += oprot->writeI32(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_count_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_multiget_slice_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keys = false; + bool isset_column_parent = false; + bool isset_predicate = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->keys.clear(); + uint32_t _size163; + ::apache::thrift::protocol::TType _etype166; + iprot->readListBegin(_etype166, _size163); + this->keys.resize(_size163); + uint32_t _i167; + for (_i167 = 0; _i167 < _size163; ++_i167) + { + xfer += iprot->readBinary(this->keys[_i167]); + } + iprot->readListEnd(); + } + isset_keys = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + isset_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast168; + xfer += iprot->readI32(ecast168); + this->consistency_level = (ConsistencyLevel::type)ecast168; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keys) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_multiget_slice_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_multiget_slice_args"); + xfer += oprot->writeFieldBegin("keys", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->keys.size())); + std::vector ::const_iterator _iter169; + for (_iter169 = this->keys.begin(); _iter169 != this->keys.end(); ++_iter169) + { + xfer += oprot->writeBinary((*_iter169)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_slice_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_multiget_slice_pargs"); + xfer += oprot->writeFieldBegin("keys", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast((*(this->keys)).size())); + std::vector ::const_iterator _iter170; + for (_iter170 = (*(this->keys)).begin(); _iter170 != (*(this->keys)).end(); ++_iter170) + { + xfer += oprot->writeBinary((*_iter170)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_slice_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->success.clear(); + uint32_t _size171; + ::apache::thrift::protocol::TType _ktype172; + ::apache::thrift::protocol::TType _vtype173; + iprot->readMapBegin(_ktype172, _vtype173, _size171); + uint32_t _i175; + for (_i175 = 0; _i175 < _size171; ++_i175) + { + std::string _key176; + xfer += iprot->readBinary(_key176); + std::vector & _val177 = this->success[_key176]; + { + _val177.clear(); + uint32_t _size178; + ::apache::thrift::protocol::TType _etype181; + iprot->readListBegin(_etype181, _size178); + _val177.resize(_size178); + uint32_t _i182; + for (_i182 = 0; _i182 < _size178; ++_i182) + { + xfer += _val177[_i182].read(iprot); + } + iprot->readListEnd(); + } + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_multiget_slice_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_multiget_slice_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast(this->success.size())); + std::map > ::const_iterator _iter183; + for (_iter183 = this->success.begin(); _iter183 != this->success.end(); ++_iter183) + { + xfer += oprot->writeBinary(_iter183->first); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(_iter183->second.size())); + std::vector ::const_iterator _iter184; + for (_iter184 = _iter183->second.begin(); _iter184 != _iter183->second.end(); ++_iter184) + { + xfer += (*_iter184).write(oprot); + } + xfer += oprot->writeListEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_slice_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + (*(this->success)).clear(); + uint32_t _size185; + ::apache::thrift::protocol::TType _ktype186; + ::apache::thrift::protocol::TType _vtype187; + iprot->readMapBegin(_ktype186, _vtype187, _size185); + uint32_t _i189; + for (_i189 = 0; _i189 < _size185; ++_i189) + { + std::string _key190; + xfer += iprot->readBinary(_key190); + std::vector & _val191 = (*(this->success))[_key190]; + { + _val191.clear(); + uint32_t _size192; + ::apache::thrift::protocol::TType _etype195; + iprot->readListBegin(_etype195, _size192); + _val191.resize(_size192); + uint32_t _i196; + for (_i196 = 0; _i196 < _size192; ++_i196) + { + xfer += _val191[_i196].read(iprot); + } + iprot->readListEnd(); + } + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_multiget_count_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keys = false; + bool isset_column_parent = false; + bool isset_predicate = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->keys.clear(); + uint32_t _size197; + ::apache::thrift::protocol::TType _etype200; + iprot->readListBegin(_etype200, _size197); + this->keys.resize(_size197); + uint32_t _i201; + for (_i201 = 0; _i201 < _size197; ++_i201) + { + xfer += iprot->readBinary(this->keys[_i201]); + } + iprot->readListEnd(); + } + isset_keys = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + isset_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast202; + xfer += iprot->readI32(ecast202); + this->consistency_level = (ConsistencyLevel::type)ecast202; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keys) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_multiget_count_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_multiget_count_args"); + xfer += oprot->writeFieldBegin("keys", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->keys.size())); + std::vector ::const_iterator _iter203; + for (_iter203 = this->keys.begin(); _iter203 != this->keys.end(); ++_iter203) + { + xfer += oprot->writeBinary((*_iter203)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_count_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_multiget_count_pargs"); + xfer += oprot->writeFieldBegin("keys", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast((*(this->keys)).size())); + std::vector ::const_iterator _iter204; + for (_iter204 = (*(this->keys)).begin(); _iter204 != (*(this->keys)).end(); ++_iter204) + { + xfer += oprot->writeBinary((*_iter204)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_count_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->success.clear(); + uint32_t _size205; + ::apache::thrift::protocol::TType _ktype206; + ::apache::thrift::protocol::TType _vtype207; + iprot->readMapBegin(_ktype206, _vtype207, _size205); + uint32_t _i209; + for (_i209 = 0; _i209 < _size205; ++_i209) + { + std::string _key210; + xfer += iprot->readBinary(_key210); + int32_t& _val211 = this->success[_key210]; + xfer += iprot->readI32(_val211); + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_multiget_count_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_multiget_count_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast(this->success.size())); + std::map ::const_iterator _iter212; + for (_iter212 = this->success.begin(); _iter212 != this->success.end(); ++_iter212) + { + xfer += oprot->writeBinary(_iter212->first); + xfer += oprot->writeI32(_iter212->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_multiget_count_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + (*(this->success)).clear(); + uint32_t _size213; + ::apache::thrift::protocol::TType _ktype214; + ::apache::thrift::protocol::TType _vtype215; + iprot->readMapBegin(_ktype214, _vtype215, _size213); + uint32_t _i217; + for (_i217 = 0; _i217 < _size213; ++_i217) + { + std::string _key218; + xfer += iprot->readBinary(_key218); + int32_t& _val219 = (*(this->success))[_key218]; + xfer += iprot->readI32(_val219); + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_range_slices_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_parent = false; + bool isset_predicate = false; + bool isset_range = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + isset_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->range.read(iprot); + isset_range = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast220; + xfer += iprot->readI32(ecast220); + this->consistency_level = (ConsistencyLevel::type)ecast220; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_range) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_range_slices_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_range_slices_args"); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->range.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_range_slices_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_range_slices_pargs"); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->range)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_range_slices_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size221; + ::apache::thrift::protocol::TType _etype224; + iprot->readListBegin(_etype224, _size221); + this->success.resize(_size221); + uint32_t _i225; + for (_i225 = 0; _i225 < _size221; ++_i225) + { + xfer += this->success[_i225].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_range_slices_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_range_slices_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter226; + for (_iter226 = this->success.begin(); _iter226 != this->success.end(); ++_iter226) + { + xfer += (*_iter226).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_range_slices_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size227; + ::apache::thrift::protocol::TType _etype230; + iprot->readListBegin(_etype230, _size227); + (*(this->success)).resize(_size227); + uint32_t _i231; + for (_i231 = 0; _i231 < _size227; ++_i231) + { + xfer += (*(this->success))[_i231].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_paged_slice_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_family = false; + bool isset_range = false; + bool isset_start_column = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->column_family); + isset_column_family = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->range.read(iprot); + isset_range = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->start_column); + isset_start_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast232; + xfer += iprot->readI32(ecast232); + this->consistency_level = (ConsistencyLevel::type)ecast232; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_family) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_range) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_start_column) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_paged_slice_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_paged_slice_args"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->column_family); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->range.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("start_column", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeBinary(this->start_column); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_paged_slice_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_paged_slice_pargs"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->column_family))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->range)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("start_column", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeBinary((*(this->start_column))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_paged_slice_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size233; + ::apache::thrift::protocol::TType _etype236; + iprot->readListBegin(_etype236, _size233); + this->success.resize(_size233); + uint32_t _i237; + for (_i237 = 0; _i237 < _size233; ++_i237) + { + xfer += this->success[_i237].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_paged_slice_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_paged_slice_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter238; + for (_iter238 = this->success.begin(); _iter238 != this->success.end(); ++_iter238) + { + xfer += (*_iter238).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_paged_slice_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size239; + ::apache::thrift::protocol::TType _etype242; + iprot->readListBegin(_etype242, _size239); + (*(this->success)).resize(_size239); + uint32_t _i243; + for (_i243 = 0; _i243 < _size239; ++_i243) + { + xfer += (*(this->success))[_i243].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_parent = false; + bool isset_index_clause = false; + bool isset_column_predicate = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->index_clause.read(iprot); + isset_index_clause = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_predicate.read(iprot); + isset_column_predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast244; + xfer += iprot->readI32(ecast244); + this->consistency_level = (ConsistencyLevel::type)ecast244; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_index_clause) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_predicate) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_indexed_slices_args"); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("index_clause", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->index_clause.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->column_predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_get_indexed_slices_pargs"); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("index_clause", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->index_clause)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->column_predicate)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size245; + ::apache::thrift::protocol::TType _etype248; + iprot->readListBegin(_etype248, _size245); + this->success.resize(_size245); + uint32_t _i249; + for (_i249 = 0; _i249 < _size245; ++_i249) + { + xfer += this->success[_i249].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_get_indexed_slices_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter250; + for (_iter250 = this->success.begin(); _iter250 != this->success.end(); ++_iter250) + { + xfer += (*_iter250).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_get_indexed_slices_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size251; + ::apache::thrift::protocol::TType _etype254; + iprot->readListBegin(_etype254, _size251); + (*(this->success)).resize(_size251); + uint32_t _i255; + for (_i255 = 0; _i255 < _size251; ++_i255) + { + xfer += (*(this->success))[_i255].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_insert_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_parent = false; + bool isset_column = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column.read(iprot); + isset_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast256; + xfer += iprot->readI32(ecast256); + this->consistency_level = (ConsistencyLevel::type)ecast256; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_insert_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_insert_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->column.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_insert_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_insert_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->column)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_insert_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_insert_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_insert_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_insert_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_add_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_parent = false; + bool isset_column = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_parent.read(iprot); + isset_column_parent = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column.read(iprot); + isset_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast257; + xfer += iprot->readI32(ecast257); + this->consistency_level = (ConsistencyLevel::type)ecast257; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_parent) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_add_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_add_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_parent.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->column.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_add_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_add_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_parent", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_parent)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += (*(this->column)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_add_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_add_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_add_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_add_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_remove_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_column_path = false; + bool isset_timestamp = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_path.read(iprot); + isset_column_path = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I64) { + xfer += iprot->readI64(this->timestamp); + isset_timestamp = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast258; + xfer += iprot->readI32(ecast258); + this->consistency_level = (ConsistencyLevel::type)ecast258; + this->__isset.consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_column_path) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_timestamp) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_remove_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_remove_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->column_path.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 3); + xfer += oprot->writeI64(this->timestamp); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_remove_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("column_path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->column_path)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 3); + xfer += oprot->writeI64((*(this->timestamp))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_remove_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_remove_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_remove_counter_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_path = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->path.read(iprot); + isset_path = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast259; + xfer += iprot->readI32(ecast259); + this->consistency_level = (ConsistencyLevel::type)ecast259; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_path) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_remove_counter_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_remove_counter_args"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->path.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_counter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_remove_counter_pargs"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->key))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("path", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += (*(this->path)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_counter_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_remove_counter_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_remove_counter_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_remove_counter_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_batch_mutate_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_mutation_map = false; + bool isset_consistency_level = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->mutation_map.clear(); + uint32_t _size260; + ::apache::thrift::protocol::TType _ktype261; + ::apache::thrift::protocol::TType _vtype262; + iprot->readMapBegin(_ktype261, _vtype262, _size260); + uint32_t _i264; + for (_i264 = 0; _i264 < _size260; ++_i264) + { + std::string _key265; + xfer += iprot->readBinary(_key265); + std::map > & _val266 = this->mutation_map[_key265]; + { + _val266.clear(); + uint32_t _size267; + ::apache::thrift::protocol::TType _ktype268; + ::apache::thrift::protocol::TType _vtype269; + iprot->readMapBegin(_ktype268, _vtype269, _size267); + uint32_t _i271; + for (_i271 = 0; _i271 < _size267; ++_i271) + { + std::string _key272; + xfer += iprot->readString(_key272); + std::vector & _val273 = _val266[_key272]; + { + _val273.clear(); + uint32_t _size274; + ::apache::thrift::protocol::TType _etype277; + iprot->readListBegin(_etype277, _size274); + _val273.resize(_size274); + uint32_t _i278; + for (_i278 = 0; _i278 < _size274; ++_i278) + { + xfer += _val273[_i278].read(iprot); + } + iprot->readListEnd(); + } + } + iprot->readMapEnd(); + } + } + iprot->readMapEnd(); + } + isset_mutation_map = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast279; + xfer += iprot->readI32(ecast279); + this->consistency_level = (ConsistencyLevel::type)ecast279; + isset_consistency_level = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_mutation_map) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_consistency_level) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_batch_mutate_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_batch_mutate_args"); + xfer += oprot->writeFieldBegin("mutation_map", ::apache::thrift::protocol::T_MAP, 1); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_MAP, static_cast(this->mutation_map.size())); + std::map > > ::const_iterator _iter280; + for (_iter280 = this->mutation_map.begin(); _iter280 != this->mutation_map.end(); ++_iter280) + { + xfer += oprot->writeBinary(_iter280->first); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast(_iter280->second.size())); + std::map > ::const_iterator _iter281; + for (_iter281 = _iter280->second.begin(); _iter281 != _iter280->second.end(); ++_iter281) + { + xfer += oprot->writeString(_iter281->first); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(_iter281->second.size())); + std::vector ::const_iterator _iter282; + for (_iter282 = _iter281->second.begin(); _iter282 != _iter281->second.end(); ++_iter282) + { + xfer += (*_iter282).write(oprot); + } + xfer += oprot->writeListEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)this->consistency_level); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_batch_mutate_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_batch_mutate_pargs"); + xfer += oprot->writeFieldBegin("mutation_map", ::apache::thrift::protocol::T_MAP, 1); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_MAP, static_cast((*(this->mutation_map)).size())); + std::map > > ::const_iterator _iter283; + for (_iter283 = (*(this->mutation_map)).begin(); _iter283 != (*(this->mutation_map)).end(); ++_iter283) + { + xfer += oprot->writeBinary(_iter283->first); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast(_iter283->second.size())); + std::map > ::const_iterator _iter284; + for (_iter284 = _iter283->second.begin(); _iter284 != _iter283->second.end(); ++_iter284) + { + xfer += oprot->writeString(_iter284->first); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(_iter284->second.size())); + std::vector ::const_iterator _iter285; + for (_iter285 = _iter284->second.begin(); _iter285 != _iter284->second.end(); ++_iter285) + { + xfer += (*_iter285).write(oprot); + } + xfer += oprot->writeListEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("consistency_level", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)(*(this->consistency_level))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_batch_mutate_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_batch_mutate_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_batch_mutate_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_batch_mutate_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_truncate_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_cfname = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->cfname); + isset_cfname = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_cfname) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_truncate_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_truncate_args"); + xfer += oprot->writeFieldBegin("cfname", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->cfname); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_truncate_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_truncate_pargs"); + xfer += oprot->writeFieldBegin("cfname", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->cfname))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_truncate_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_truncate_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_truncate_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_truncate_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_schema_versions_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_schema_versions_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->success.clear(); + uint32_t _size286; + ::apache::thrift::protocol::TType _ktype287; + ::apache::thrift::protocol::TType _vtype288; + iprot->readMapBegin(_ktype287, _vtype288, _size286); + uint32_t _i290; + for (_i290 = 0; _i290 < _size286; ++_i290) + { + std::string _key291; + xfer += iprot->readString(_key291); + std::vector & _val292 = this->success[_key291]; + { + _val292.clear(); + uint32_t _size293; + ::apache::thrift::protocol::TType _etype296; + iprot->readListBegin(_etype296, _size293); + _val292.resize(_size293); + uint32_t _i297; + for (_i297 = 0; _i297 < _size293; ++_i297) + { + xfer += iprot->readString(_val292[_i297]); + } + iprot->readListEnd(); + } + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_schema_versions_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast(this->success.size())); + std::map > ::const_iterator _iter298; + for (_iter298 = this->success.begin(); _iter298 != this->success.end(); ++_iter298) + { + xfer += oprot->writeString(_iter298->first); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(_iter298->second.size())); + std::vector ::const_iterator _iter299; + for (_iter299 = _iter298->second.begin(); _iter299 != _iter298->second.end(); ++_iter299) + { + xfer += oprot->writeString((*_iter299)); + } + xfer += oprot->writeListEnd(); + } + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_schema_versions_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + (*(this->success)).clear(); + uint32_t _size300; + ::apache::thrift::protocol::TType _ktype301; + ::apache::thrift::protocol::TType _vtype302; + iprot->readMapBegin(_ktype301, _vtype302, _size300); + uint32_t _i304; + for (_i304 = 0; _i304 < _size300; ++_i304) + { + std::string _key305; + xfer += iprot->readString(_key305); + std::vector & _val306 = (*(this->success))[_key305]; + { + _val306.clear(); + uint32_t _size307; + ::apache::thrift::protocol::TType _etype310; + iprot->readListBegin(_etype310, _size307); + _val306.resize(_size307); + uint32_t _i311; + for (_i311 = 0; _i311 < _size307; ++_i311) + { + xfer += iprot->readString(_val306[_i311]); + } + iprot->readListEnd(); + } + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_keyspaces_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_keyspaces_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size312; + ::apache::thrift::protocol::TType _etype315; + iprot->readListBegin(_etype315, _size312); + this->success.resize(_size312); + uint32_t _i316; + for (_i316 = 0; _i316 < _size312; ++_i316) + { + xfer += this->success[_i316].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_keyspaces_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter317; + for (_iter317 = this->success.begin(); _iter317 != this->success.end(); ++_iter317) + { + xfer += (*_iter317).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspaces_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size318; + ::apache::thrift::protocol::TType _etype321; + iprot->readListBegin(_etype321, _size318); + (*(this->success)).resize(_size318); + uint32_t _i322; + for (_i322 = 0; _i322 < _size318; ++_i322) + { + xfer += (*(this->success))[_i322].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_cluster_name_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_cluster_name_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_cluster_name_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_cluster_name_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_version_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_version_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_version_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_version_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_version_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_version_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_version_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_version_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_version_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_ring_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keyspace = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->keyspace); + isset_keyspace = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keyspace) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_describe_ring_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_ring_args"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->keyspace); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_ring_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_ring_pargs"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->keyspace))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_ring_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size323; + ::apache::thrift::protocol::TType _etype326; + iprot->readListBegin(_etype326, _size323); + this->success.resize(_size323); + uint32_t _i327; + for (_i327 = 0; _i327 < _size323; ++_i327) + { + xfer += this->success[_i327].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_ring_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_ring_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->success.size())); + std::vector ::const_iterator _iter328; + for (_iter328 = this->success.begin(); _iter328 != this->success.end(); ++_iter328) + { + xfer += (*_iter328).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_ring_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size329; + ::apache::thrift::protocol::TType _etype332; + iprot->readListBegin(_etype332, _size329); + (*(this->success)).resize(_size329); + uint32_t _i333; + for (_i333 = 0; _i333 < _size329; ++_i333) + { + xfer += (*(this->success))[_i333].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_token_map_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_token_map_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_token_map_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_token_map_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_token_map_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_token_map_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->success.clear(); + uint32_t _size334; + ::apache::thrift::protocol::TType _ktype335; + ::apache::thrift::protocol::TType _vtype336; + iprot->readMapBegin(_ktype335, _vtype336, _size334); + uint32_t _i338; + for (_i338 = 0; _i338 < _size334; ++_i338) + { + std::string _key339; + xfer += iprot->readString(_key339); + std::string& _val340 = this->success[_key339]; + xfer += iprot->readString(_val340); + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_token_map_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_token_map_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->success.size())); + std::map ::const_iterator _iter341; + for (_iter341 = this->success.begin(); _iter341 != this->success.end(); ++_iter341) + { + xfer += oprot->writeString(_iter341->first); + xfer += oprot->writeString(_iter341->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_token_map_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + (*(this->success)).clear(); + uint32_t _size342; + ::apache::thrift::protocol::TType _ktype343; + ::apache::thrift::protocol::TType _vtype344; + iprot->readMapBegin(_ktype343, _vtype344, _size342); + uint32_t _i346; + for (_i346 = 0; _i346 < _size342; ++_i346) + { + std::string _key347; + xfer += iprot->readString(_key347); + std::string& _val348 = (*(this->success))[_key347]; + xfer += iprot->readString(_val348); + } + iprot->readMapEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_partitioner_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_partitioner_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_partitioner_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_partitioner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_partitioner_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_partitioner_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_partitioner_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_partitioner_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_partitioner_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_snitch_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_snitch_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_snitch_args"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_snitch_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_snitch_pargs"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_snitch_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_snitch_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_snitch_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_snitch_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_keyspace_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keyspace = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->keyspace); + isset_keyspace = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keyspace) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_describe_keyspace_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_keyspace_args"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->keyspace); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_keyspace_pargs"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->keyspace))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspace_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->success.read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->nfe.read(iprot); + this->__isset.nfe = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_keyspace_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_keyspace_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0); + xfer += this->success.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.nfe) { + xfer += oprot->writeFieldBegin("nfe", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->nfe.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_keyspace_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += (*(this->success)).read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->nfe.read(iprot); + this->__isset.nfe = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_splits_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_cfName = false; + bool isset_start_token = false; + bool isset_end_token = false; + bool isset_keys_per_split = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->cfName); + isset_cfName = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->start_token); + isset_start_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->end_token); + isset_end_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->keys_per_split); + isset_keys_per_split = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_cfName) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_start_token) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_end_token) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_keys_per_split) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_describe_splits_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_splits_args"); + xfer += oprot->writeFieldBegin("cfName", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->cfName); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("start_token", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->start_token); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("end_token", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->end_token); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("keys_per_split", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32(this->keys_per_split); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_splits_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_describe_splits_pargs"); + xfer += oprot->writeFieldBegin("cfName", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->cfName))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("start_token", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString((*(this->start_token))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("end_token", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString((*(this->end_token))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("keys_per_split", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32((*(this->keys_per_split))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_splits_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->success.clear(); + uint32_t _size349; + ::apache::thrift::protocol::TType _etype352; + iprot->readListBegin(_etype352, _size349); + this->success.resize(_size349); + uint32_t _i353; + for (_i353 = 0; _i353 < _size349; ++_i353) + { + xfer += iprot->readString(this->success[_i353]); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_describe_splits_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_describe_splits_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->success.size())); + std::vector ::const_iterator _iter354; + for (_iter354 = this->success.begin(); _iter354 != this->success.end(); ++_iter354) + { + xfer += oprot->writeString((*_iter354)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_describe_splits_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + (*(this->success)).clear(); + uint32_t _size355; + ::apache::thrift::protocol::TType _etype358; + iprot->readListBegin(_etype358, _size355); + (*(this->success)).resize(_size355); + uint32_t _i359; + for (_i359 = 0; _i359 < _size355; ++_i359) + { + xfer += iprot->readString((*(this->success))[_i359]); + } + iprot->readListEnd(); + } + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_add_column_family_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_cf_def = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->cf_def.read(iprot); + isset_cf_def = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_cf_def) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_add_column_family_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_add_column_family_args"); + xfer += oprot->writeFieldBegin("cf_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->cf_def.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_column_family_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_add_column_family_pargs"); + xfer += oprot->writeFieldBegin("cf_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->cf_def)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_column_family_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_add_column_family_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_add_column_family_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_column_family_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_family = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->column_family); + isset_column_family = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_family) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_drop_column_family_args"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->column_family); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_drop_column_family_pargs"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->column_family))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_drop_column_family_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_column_family_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_ks_def = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ks_def.read(iprot); + isset_ks_def = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_ks_def) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_add_keyspace_args"); + xfer += oprot->writeFieldBegin("ks_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ks_def.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_add_keyspace_pargs"); + xfer += oprot->writeFieldBegin("ks_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->ks_def)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_add_keyspace_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_add_keyspace_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keyspace = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->keyspace); + isset_keyspace = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keyspace) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_drop_keyspace_args"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->keyspace); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_drop_keyspace_pargs"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->keyspace))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_drop_keyspace_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_drop_keyspace_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_ks_def = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ks_def.read(iprot); + isset_ks_def = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_ks_def) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_update_keyspace_args"); + xfer += oprot->writeFieldBegin("ks_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ks_def.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_update_keyspace_pargs"); + xfer += oprot->writeFieldBegin("ks_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->ks_def)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_update_keyspace_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_keyspace_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_update_column_family_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_cf_def = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->cf_def.read(iprot); + isset_cf_def = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_cf_def) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_system_update_column_family_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_update_column_family_args"); + xfer += oprot->writeFieldBegin("cf_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->cf_def.write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_column_family_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_system_update_column_family_pargs"); + xfer += oprot->writeFieldBegin("cf_def", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += (*(this->cf_def)).write(oprot); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_column_family_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->success); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_system_update_column_family_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_system_update_column_family_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0); + xfer += oprot->writeString(this->success); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_system_update_column_family_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString((*(this->success))); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_execute_cql_query_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_query = false; + bool isset_compression = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->query); + isset_query = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast360; + xfer += iprot->readI32(ecast360); + this->compression = (Compression::type)ecast360; + isset_compression = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_query) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_compression) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_execute_cql_query_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_execute_cql_query_args"); + xfer += oprot->writeFieldBegin("query", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->query); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("compression", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)this->compression); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_cql_query_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_execute_cql_query_pargs"); + xfer += oprot->writeFieldBegin("query", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->query))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("compression", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)(*(this->compression))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_cql_query_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->success.read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_execute_cql_query_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_execute_cql_query_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0); + xfer += this->success.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 4); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_cql_query_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += (*(this->success)).read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_query = false; + bool isset_compression = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->query); + isset_query = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast361; + xfer += iprot->readI32(ecast361); + this->compression = (Compression::type)ecast361; + isset_compression = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_query) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_compression) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_prepare_cql_query_args"); + xfer += oprot->writeFieldBegin("query", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->query); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("compression", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)this->compression); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_prepare_cql_query_pargs"); + xfer += oprot->writeFieldBegin("query", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary((*(this->query))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("compression", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)(*(this->compression))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->success.read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_prepare_cql_query_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0); + xfer += this->success.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_prepare_cql_query_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += (*(this->success)).read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_itemId = false; + bool isset_values = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->itemId); + isset_itemId = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->values.clear(); + uint32_t _size362; + ::apache::thrift::protocol::TType _etype365; + iprot->readListBegin(_etype365, _size362); + this->values.resize(_size362); + uint32_t _i366; + for (_i366 = 0; _i366 < _size362; ++_i366) + { + xfer += iprot->readBinary(this->values[_i366]); + } + iprot->readListEnd(); + } + isset_values = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_itemId) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_values) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_execute_prepared_cql_query_args"); + xfer += oprot->writeFieldBegin("itemId", ::apache::thrift::protocol::T_I32, 1); + xfer += oprot->writeI32(this->itemId); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("values", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->values.size())); + std::vector ::const_iterator _iter367; + for (_iter367 = this->values.begin(); _iter367 != this->values.end(); ++_iter367) + { + xfer += oprot->writeBinary((*_iter367)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_execute_prepared_cql_query_pargs"); + xfer += oprot->writeFieldBegin("itemId", ::apache::thrift::protocol::T_I32, 1); + xfer += oprot->writeI32((*(this->itemId))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("values", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast((*(this->values)).size())); + std::vector ::const_iterator _iter368; + for (_iter368 = (*(this->values)).begin(); _iter368 != (*(this->values)).end(); ++_iter368) + { + xfer += oprot->writeBinary((*_iter368)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->success.read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_execute_prepared_cql_query_result"); + + if (this->__isset.success) { + xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0); + xfer += this->success.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.ue) { + xfer += oprot->writeFieldBegin("ue", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->ue.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.te) { + xfer += oprot->writeFieldBegin("te", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->te.write(oprot); + xfer += oprot->writeFieldEnd(); + } else if (this->__isset.sde) { + xfer += oprot->writeFieldBegin("sde", ::apache::thrift::protocol::T_STRUCT, 4); + xfer += this->sde.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_execute_prepared_cql_query_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 0: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += (*(this->success)).read(iprot); + this->__isset.success = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ue.read(iprot); + this->__isset.ue = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->te.read(iprot); + this->__isset.te = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->sde.read(iprot); + this->__isset.sde = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_set_cql_version_args::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_version = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->version); + isset_version = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_version) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Cassandra_set_cql_version_args::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_set_cql_version_args"); + xfer += oprot->writeFieldBegin("version", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->version); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_cql_version_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Cassandra_set_cql_version_pargs"); + xfer += oprot->writeFieldBegin("version", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString((*(this->version))); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_cql_version_result::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Cassandra_set_cql_version_result::write(::apache::thrift::protocol::TProtocol* oprot) const { + + uint32_t xfer = 0; + + xfer += oprot->writeStructBegin("Cassandra_set_cql_version_result"); + + if (this->__isset.ire) { + xfer += oprot->writeFieldBegin("ire", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->ire.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +uint32_t Cassandra_set_cql_version_presult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->ire.read(iprot); + this->__isset.ire = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +void CassandraClient::login(const AuthenticationRequest& auth_request) +{ + send_login(auth_request); + recv_login(); +} + +void CassandraClient::send_login(const AuthenticationRequest& auth_request) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("login", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_login_pargs args; + args.auth_request = &auth_request; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_login() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("login") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_login_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.authnx) { + throw result.authnx; + } + if (result.__isset.authzx) { + throw result.authzx; + } + return; +} + +void CassandraClient::set_keyspace(const std::string& keyspace) +{ + send_set_keyspace(keyspace); + recv_set_keyspace(); +} + +void CassandraClient::send_set_keyspace(const std::string& keyspace) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("set_keyspace", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_set_keyspace_pargs args; + args.keyspace = &keyspace; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_set_keyspace() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("set_keyspace") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_set_keyspace_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + return; +} + +void CassandraClient::get(ColumnOrSuperColumn& _return, const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level) +{ + send_get(key, column_path, consistency_level); + recv_get(_return); +} + +void CassandraClient::send_get(const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_pargs args; + args.key = &key; + args.column_path = &column_path; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_get(ColumnOrSuperColumn& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_get_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.nfe) { + throw result.nfe; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get failed: unknown result"); +} + +void CassandraClient::get_slice(std::vector & _return, const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + send_get_slice(key, column_parent, predicate, consistency_level); + recv_get_slice(_return); +} + +void CassandraClient::send_get_slice(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get_slice", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_slice_pargs args; + args.key = &key; + args.column_parent = &column_parent; + args.predicate = &predicate; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_get_slice(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get_slice") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_get_slice_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get_slice failed: unknown result"); +} + +int32_t CassandraClient::get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + send_get_count(key, column_parent, predicate, consistency_level); + return recv_get_count(); +} + +void CassandraClient::send_get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get_count", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_count_pargs args; + args.key = &key; + args.column_parent = &column_parent; + args.predicate = &predicate; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +int32_t CassandraClient::recv_get_count() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get_count") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + int32_t _return; + Cassandra_get_count_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + return _return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get_count failed: unknown result"); +} + +void CassandraClient::multiget_slice(std::map > & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + send_multiget_slice(keys, column_parent, predicate, consistency_level); + recv_multiget_slice(_return); +} + +void CassandraClient::send_multiget_slice(const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("multiget_slice", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_multiget_slice_pargs args; + args.keys = &keys; + args.column_parent = &column_parent; + args.predicate = &predicate; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_multiget_slice(std::map > & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("multiget_slice") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_multiget_slice_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "multiget_slice failed: unknown result"); +} + +void CassandraClient::multiget_count(std::map & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + send_multiget_count(keys, column_parent, predicate, consistency_level); + recv_multiget_count(_return); +} + +void CassandraClient::send_multiget_count(const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("multiget_count", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_multiget_count_pargs args; + args.keys = &keys; + args.column_parent = &column_parent; + args.predicate = &predicate; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_multiget_count(std::map & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("multiget_count") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_multiget_count_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "multiget_count failed: unknown result"); +} + +void CassandraClient::get_range_slices(std::vector & _return, const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level) +{ + send_get_range_slices(column_parent, predicate, range, consistency_level); + recv_get_range_slices(_return); +} + +void CassandraClient::send_get_range_slices(const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get_range_slices", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_range_slices_pargs args; + args.column_parent = &column_parent; + args.predicate = &predicate; + args.range = ⦥ + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_get_range_slices(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get_range_slices") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_get_range_slices_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get_range_slices failed: unknown result"); +} + +void CassandraClient::get_paged_slice(std::vector & _return, const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level) +{ + send_get_paged_slice(column_family, range, start_column, consistency_level); + recv_get_paged_slice(_return); +} + +void CassandraClient::send_get_paged_slice(const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get_paged_slice", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_paged_slice_pargs args; + args.column_family = &column_family; + args.range = ⦥ + args.start_column = &start_column; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_get_paged_slice(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get_paged_slice") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_get_paged_slice_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get_paged_slice failed: unknown result"); +} + +void CassandraClient::get_indexed_slices(std::vector & _return, const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level) +{ + send_get_indexed_slices(column_parent, index_clause, column_predicate, consistency_level); + recv_get_indexed_slices(_return); +} + +void CassandraClient::send_get_indexed_slices(const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("get_indexed_slices", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_get_indexed_slices_pargs args; + args.column_parent = &column_parent; + args.index_clause = &index_clause; + args.column_predicate = &column_predicate; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_get_indexed_slices(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("get_indexed_slices") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_get_indexed_slices_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "get_indexed_slices failed: unknown result"); +} + +void CassandraClient::insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level) +{ + send_insert(key, column_parent, column, consistency_level); + recv_insert(); +} + +void CassandraClient::send_insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("insert", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_insert_pargs args; + args.key = &key; + args.column_parent = &column_parent; + args.column = &column; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_insert() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("insert") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_insert_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level) +{ + send_add(key, column_parent, column, consistency_level); + recv_add(); +} + +void CassandraClient::send_add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("add", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_add_pargs args; + args.key = &key; + args.column_parent = &column_parent; + args.column = &column; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_add() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("add") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_add_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level) +{ + send_remove(key, column_path, timestamp, consistency_level); + recv_remove(); +} + +void CassandraClient::send_remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("remove", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_remove_pargs args; + args.key = &key; + args.column_path = &column_path; + args.timestamp = ×tamp; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_remove() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("remove") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_remove_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level) +{ + send_remove_counter(key, path, consistency_level); + recv_remove_counter(); +} + +void CassandraClient::send_remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("remove_counter", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_remove_counter_pargs args; + args.key = &key; + args.path = &path; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_remove_counter() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("remove_counter") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_remove_counter_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level) +{ + send_batch_mutate(mutation_map, consistency_level); + recv_batch_mutate(); +} + +void CassandraClient::send_batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("batch_mutate", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_batch_mutate_pargs args; + args.mutation_map = &mutation_map; + args.consistency_level = &consistency_level; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_batch_mutate() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("batch_mutate") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_batch_mutate_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::truncate(const std::string& cfname) +{ + send_truncate(cfname); + recv_truncate(); +} + +void CassandraClient::send_truncate(const std::string& cfname) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("truncate", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_truncate_pargs args; + args.cfname = &cfname; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_truncate() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("truncate") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_truncate_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + return; +} + +void CassandraClient::describe_schema_versions(std::map > & _return) +{ + send_describe_schema_versions(); + recv_describe_schema_versions(_return); +} + +void CassandraClient::send_describe_schema_versions() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_schema_versions", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_schema_versions_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_schema_versions(std::map > & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_schema_versions") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_schema_versions_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_schema_versions failed: unknown result"); +} + +void CassandraClient::describe_keyspaces(std::vector & _return) +{ + send_describe_keyspaces(); + recv_describe_keyspaces(_return); +} + +void CassandraClient::send_describe_keyspaces() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_keyspaces", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_keyspaces_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_keyspaces(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_keyspaces") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_keyspaces_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_keyspaces failed: unknown result"); +} + +void CassandraClient::describe_cluster_name(std::string& _return) +{ + send_describe_cluster_name(); + recv_describe_cluster_name(_return); +} + +void CassandraClient::send_describe_cluster_name() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_cluster_name", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_cluster_name_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_cluster_name(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_cluster_name") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_cluster_name_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_cluster_name failed: unknown result"); +} + +void CassandraClient::describe_version(std::string& _return) +{ + send_describe_version(); + recv_describe_version(_return); +} + +void CassandraClient::send_describe_version() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_version", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_version_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_version(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_version") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_version_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_version failed: unknown result"); +} + +void CassandraClient::describe_ring(std::vector & _return, const std::string& keyspace) +{ + send_describe_ring(keyspace); + recv_describe_ring(_return); +} + +void CassandraClient::send_describe_ring(const std::string& keyspace) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_ring", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_ring_pargs args; + args.keyspace = &keyspace; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_ring(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_ring") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_ring_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_ring failed: unknown result"); +} + +void CassandraClient::describe_token_map(std::map & _return) +{ + send_describe_token_map(); + recv_describe_token_map(_return); +} + +void CassandraClient::send_describe_token_map() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_token_map", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_token_map_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_token_map(std::map & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_token_map") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_token_map_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_token_map failed: unknown result"); +} + +void CassandraClient::describe_partitioner(std::string& _return) +{ + send_describe_partitioner(); + recv_describe_partitioner(_return); +} + +void CassandraClient::send_describe_partitioner() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_partitioner", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_partitioner_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_partitioner(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_partitioner") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_partitioner_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_partitioner failed: unknown result"); +} + +void CassandraClient::describe_snitch(std::string& _return) +{ + send_describe_snitch(); + recv_describe_snitch(_return); +} + +void CassandraClient::send_describe_snitch() +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_snitch", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_snitch_pargs args; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_snitch(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_snitch") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_snitch_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_snitch failed: unknown result"); +} + +void CassandraClient::describe_keyspace(KsDef& _return, const std::string& keyspace) +{ + send_describe_keyspace(keyspace); + recv_describe_keyspace(_return); +} + +void CassandraClient::send_describe_keyspace(const std::string& keyspace) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_keyspace", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_keyspace_pargs args; + args.keyspace = &keyspace; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_keyspace(KsDef& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_keyspace") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_keyspace_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.nfe) { + throw result.nfe; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_keyspace failed: unknown result"); +} + +void CassandraClient::describe_splits(std::vector & _return, const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split) +{ + send_describe_splits(cfName, start_token, end_token, keys_per_split); + recv_describe_splits(_return); +} + +void CassandraClient::send_describe_splits(const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("describe_splits", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_describe_splits_pargs args; + args.cfName = &cfName; + args.start_token = &start_token; + args.end_token = &end_token; + args.keys_per_split = &keys_per_split; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_describe_splits(std::vector & _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("describe_splits") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_describe_splits_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "describe_splits failed: unknown result"); +} + +void CassandraClient::system_add_column_family(std::string& _return, const CfDef& cf_def) +{ + send_system_add_column_family(cf_def); + recv_system_add_column_family(_return); +} + +void CassandraClient::send_system_add_column_family(const CfDef& cf_def) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_add_column_family", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_add_column_family_pargs args; + args.cf_def = &cf_def; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_add_column_family(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_add_column_family") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_add_column_family_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_add_column_family failed: unknown result"); +} + +void CassandraClient::system_drop_column_family(std::string& _return, const std::string& column_family) +{ + send_system_drop_column_family(column_family); + recv_system_drop_column_family(_return); +} + +void CassandraClient::send_system_drop_column_family(const std::string& column_family) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_drop_column_family", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_drop_column_family_pargs args; + args.column_family = &column_family; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_drop_column_family(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_drop_column_family") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_drop_column_family_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_drop_column_family failed: unknown result"); +} + +void CassandraClient::system_add_keyspace(std::string& _return, const KsDef& ks_def) +{ + send_system_add_keyspace(ks_def); + recv_system_add_keyspace(_return); +} + +void CassandraClient::send_system_add_keyspace(const KsDef& ks_def) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_add_keyspace", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_add_keyspace_pargs args; + args.ks_def = &ks_def; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_add_keyspace(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_add_keyspace") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_add_keyspace_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_add_keyspace failed: unknown result"); +} + +void CassandraClient::system_drop_keyspace(std::string& _return, const std::string& keyspace) +{ + send_system_drop_keyspace(keyspace); + recv_system_drop_keyspace(_return); +} + +void CassandraClient::send_system_drop_keyspace(const std::string& keyspace) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_drop_keyspace", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_drop_keyspace_pargs args; + args.keyspace = &keyspace; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_drop_keyspace(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_drop_keyspace") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_drop_keyspace_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_drop_keyspace failed: unknown result"); +} + +void CassandraClient::system_update_keyspace(std::string& _return, const KsDef& ks_def) +{ + send_system_update_keyspace(ks_def); + recv_system_update_keyspace(_return); +} + +void CassandraClient::send_system_update_keyspace(const KsDef& ks_def) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_update_keyspace", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_update_keyspace_pargs args; + args.ks_def = &ks_def; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_update_keyspace(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_update_keyspace") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_update_keyspace_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_update_keyspace failed: unknown result"); +} + +void CassandraClient::system_update_column_family(std::string& _return, const CfDef& cf_def) +{ + send_system_update_column_family(cf_def); + recv_system_update_column_family(_return); +} + +void CassandraClient::send_system_update_column_family(const CfDef& cf_def) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("system_update_column_family", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_system_update_column_family_pargs args; + args.cf_def = &cf_def; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_system_update_column_family(std::string& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("system_update_column_family") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_system_update_column_family_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "system_update_column_family failed: unknown result"); +} + +void CassandraClient::execute_cql_query(CqlResult& _return, const std::string& query, const Compression::type compression) +{ + send_execute_cql_query(query, compression); + recv_execute_cql_query(_return); +} + +void CassandraClient::send_execute_cql_query(const std::string& query, const Compression::type compression) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("execute_cql_query", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_execute_cql_query_pargs args; + args.query = &query; + args.compression = &compression; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_execute_cql_query(CqlResult& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("execute_cql_query") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_execute_cql_query_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "execute_cql_query failed: unknown result"); +} + +void CassandraClient::prepare_cql_query(CqlPreparedResult& _return, const std::string& query, const Compression::type compression) +{ + send_prepare_cql_query(query, compression); + recv_prepare_cql_query(_return); +} + +void CassandraClient::send_prepare_cql_query(const std::string& query, const Compression::type compression) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("prepare_cql_query", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_prepare_cql_query_pargs args; + args.query = &query; + args.compression = &compression; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_prepare_cql_query(CqlPreparedResult& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("prepare_cql_query") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_prepare_cql_query_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "prepare_cql_query failed: unknown result"); +} + +void CassandraClient::execute_prepared_cql_query(CqlResult& _return, const int32_t itemId, const std::vector & values) +{ + send_execute_prepared_cql_query(itemId, values); + recv_execute_prepared_cql_query(_return); +} + +void CassandraClient::send_execute_prepared_cql_query(const int32_t itemId, const std::vector & values) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("execute_prepared_cql_query", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_execute_prepared_cql_query_pargs args; + args.itemId = &itemId; + args.values = &values; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_execute_prepared_cql_query(CqlResult& _return) +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("execute_prepared_cql_query") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_execute_prepared_cql_query_presult result; + result.success = &_return; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.success) { + // _return pointer has now been filled + return; + } + if (result.__isset.ire) { + throw result.ire; + } + if (result.__isset.ue) { + throw result.ue; + } + if (result.__isset.te) { + throw result.te; + } + if (result.__isset.sde) { + throw result.sde; + } + throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "execute_prepared_cql_query failed: unknown result"); +} + +void CassandraClient::set_cql_version(const std::string& version) +{ + send_set_cql_version(version); + recv_set_cql_version(); +} + +void CassandraClient::send_set_cql_version(const std::string& version) +{ + int32_t cseqid = 0; + oprot_->writeMessageBegin("set_cql_version", ::apache::thrift::protocol::T_CALL, cseqid); + + Cassandra_set_cql_version_pargs args; + args.version = &version; + args.write(oprot_); + + oprot_->writeMessageEnd(); + oprot_->getTransport()->writeEnd(); + oprot_->getTransport()->flush(); +} + +void CassandraClient::recv_set_cql_version() +{ + + int32_t rseqid = 0; + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + + iprot_->readMessageBegin(fname, mtype, rseqid); + if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { + ::apache::thrift::TApplicationException x; + x.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + throw x; + } + if (mtype != ::apache::thrift::protocol::T_REPLY) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + if (fname.compare("set_cql_version") != 0) { + iprot_->skip(::apache::thrift::protocol::T_STRUCT); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + } + Cassandra_set_cql_version_presult result; + result.read(iprot_); + iprot_->readMessageEnd(); + iprot_->getTransport()->readEnd(); + + if (result.__isset.ire) { + throw result.ire; + } + return; +} + +bool CassandraProcessor::process(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot, void* callContext) { + + ::apache::thrift::protocol::TProtocol* iprot = piprot.get(); + ::apache::thrift::protocol::TProtocol* oprot = poprot.get(); + std::string fname; + ::apache::thrift::protocol::TMessageType mtype; + int32_t seqid; + + iprot->readMessageBegin(fname, mtype, seqid); + + if (mtype != ::apache::thrift::protocol::T_CALL && mtype != ::apache::thrift::protocol::T_ONEWAY) { + iprot->skip(::apache::thrift::protocol::T_STRUCT); + iprot->readMessageEnd(); + iprot->getTransport()->readEnd(); + ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::INVALID_MESSAGE_TYPE); + oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return true; + } + + return process_fn(iprot, oprot, fname, seqid, callContext); +} + +bool CassandraProcessor::process_fn( ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid, void* callContext) { + std::map::iterator pfn; + pfn = processMap_.find(fname); + if (pfn == processMap_.end()) { + iprot->skip(::apache::thrift::protocol::T_STRUCT); + iprot->readMessageEnd(); + iprot->getTransport()->readEnd(); + ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'"); + oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return true; + } + (this->*(pfn->second))(seqid, iprot, oprot, callContext); + return true; +} + +void CassandraProcessor::process_login(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.login", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.login"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.login"); + } + + Cassandra_login_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.login", bytes); + } + + Cassandra_login_result result; + try { + iface_->login(args.auth_request); + } catch (AuthenticationException &authnx) { + result.authnx = authnx; + result.__isset.authnx = true; + } catch (AuthorizationException &authzx) { + result.authzx = authzx; + result.__isset.authzx = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.login"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("login", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.login"); + } + + oprot->writeMessageBegin("login", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.login", bytes); + } +} + +void CassandraProcessor::process_set_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.set_keyspace", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.set_keyspace"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.set_keyspace"); + } + + Cassandra_set_keyspace_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.set_keyspace", bytes); + } + + Cassandra_set_keyspace_result result; + try { + iface_->set_keyspace(args.keyspace); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.set_keyspace"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("set_keyspace", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.set_keyspace"); + } + + oprot->writeMessageBegin("set_keyspace", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.set_keyspace", bytes); + } +} + +void CassandraProcessor::process_get(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get"); + } + + Cassandra_get_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get", bytes); + } + + Cassandra_get_result result; + try { + iface_->get(result.success, args.key, args.column_path, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (NotFoundException &nfe) { + result.nfe = nfe; + result.__isset.nfe = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get"); + } + + oprot->writeMessageBegin("get", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get", bytes); + } +} + +void CassandraProcessor::process_get_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get_slice", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get_slice"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get_slice"); + } + + Cassandra_get_slice_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get_slice", bytes); + } + + Cassandra_get_slice_result result; + try { + iface_->get_slice(result.success, args.key, args.column_parent, args.predicate, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get_slice"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get_slice", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get_slice"); + } + + oprot->writeMessageBegin("get_slice", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get_slice", bytes); + } +} + +void CassandraProcessor::process_get_count(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get_count", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get_count"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get_count"); + } + + Cassandra_get_count_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get_count", bytes); + } + + Cassandra_get_count_result result; + try { + result.success = iface_->get_count(args.key, args.column_parent, args.predicate, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get_count"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get_count", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get_count"); + } + + oprot->writeMessageBegin("get_count", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get_count", bytes); + } +} + +void CassandraProcessor::process_multiget_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.multiget_slice", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.multiget_slice"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.multiget_slice"); + } + + Cassandra_multiget_slice_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.multiget_slice", bytes); + } + + Cassandra_multiget_slice_result result; + try { + iface_->multiget_slice(result.success, args.keys, args.column_parent, args.predicate, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.multiget_slice"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("multiget_slice", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.multiget_slice"); + } + + oprot->writeMessageBegin("multiget_slice", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.multiget_slice", bytes); + } +} + +void CassandraProcessor::process_multiget_count(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.multiget_count", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.multiget_count"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.multiget_count"); + } + + Cassandra_multiget_count_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.multiget_count", bytes); + } + + Cassandra_multiget_count_result result; + try { + iface_->multiget_count(result.success, args.keys, args.column_parent, args.predicate, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.multiget_count"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("multiget_count", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.multiget_count"); + } + + oprot->writeMessageBegin("multiget_count", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.multiget_count", bytes); + } +} + +void CassandraProcessor::process_get_range_slices(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get_range_slices", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get_range_slices"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get_range_slices"); + } + + Cassandra_get_range_slices_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get_range_slices", bytes); + } + + Cassandra_get_range_slices_result result; + try { + iface_->get_range_slices(result.success, args.column_parent, args.predicate, args.range, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get_range_slices"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get_range_slices", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get_range_slices"); + } + + oprot->writeMessageBegin("get_range_slices", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get_range_slices", bytes); + } +} + +void CassandraProcessor::process_get_paged_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get_paged_slice", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get_paged_slice"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get_paged_slice"); + } + + Cassandra_get_paged_slice_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get_paged_slice", bytes); + } + + Cassandra_get_paged_slice_result result; + try { + iface_->get_paged_slice(result.success, args.column_family, args.range, args.start_column, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get_paged_slice"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get_paged_slice", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get_paged_slice"); + } + + oprot->writeMessageBegin("get_paged_slice", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get_paged_slice", bytes); + } +} + +void CassandraProcessor::process_get_indexed_slices(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.get_indexed_slices", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.get_indexed_slices"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.get_indexed_slices"); + } + + Cassandra_get_indexed_slices_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.get_indexed_slices", bytes); + } + + Cassandra_get_indexed_slices_result result; + try { + iface_->get_indexed_slices(result.success, args.column_parent, args.index_clause, args.column_predicate, args.consistency_level); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.get_indexed_slices"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("get_indexed_slices", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.get_indexed_slices"); + } + + oprot->writeMessageBegin("get_indexed_slices", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.get_indexed_slices", bytes); + } +} + +void CassandraProcessor::process_insert(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.insert", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.insert"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.insert"); + } + + Cassandra_insert_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.insert", bytes); + } + + Cassandra_insert_result result; + try { + iface_->insert(args.key, args.column_parent, args.column, args.consistency_level); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.insert"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("insert", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.insert"); + } + + oprot->writeMessageBegin("insert", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.insert", bytes); + } +} + +void CassandraProcessor::process_add(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.add", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.add"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.add"); + } + + Cassandra_add_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.add", bytes); + } + + Cassandra_add_result result; + try { + iface_->add(args.key, args.column_parent, args.column, args.consistency_level); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.add"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("add", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.add"); + } + + oprot->writeMessageBegin("add", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.add", bytes); + } +} + +void CassandraProcessor::process_remove(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.remove", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.remove"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.remove"); + } + + Cassandra_remove_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.remove", bytes); + } + + Cassandra_remove_result result; + try { + iface_->remove(args.key, args.column_path, args.timestamp, args.consistency_level); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.remove"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("remove", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.remove"); + } + + oprot->writeMessageBegin("remove", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.remove", bytes); + } +} + +void CassandraProcessor::process_remove_counter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.remove_counter", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.remove_counter"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.remove_counter"); + } + + Cassandra_remove_counter_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.remove_counter", bytes); + } + + Cassandra_remove_counter_result result; + try { + iface_->remove_counter(args.key, args.path, args.consistency_level); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.remove_counter"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("remove_counter", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.remove_counter"); + } + + oprot->writeMessageBegin("remove_counter", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.remove_counter", bytes); + } +} + +void CassandraProcessor::process_batch_mutate(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.batch_mutate", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.batch_mutate"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.batch_mutate"); + } + + Cassandra_batch_mutate_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.batch_mutate", bytes); + } + + Cassandra_batch_mutate_result result; + try { + iface_->batch_mutate(args.mutation_map, args.consistency_level); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.batch_mutate"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("batch_mutate", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.batch_mutate"); + } + + oprot->writeMessageBegin("batch_mutate", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.batch_mutate", bytes); + } +} + +void CassandraProcessor::process_truncate(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.truncate", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.truncate"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.truncate"); + } + + Cassandra_truncate_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.truncate", bytes); + } + + Cassandra_truncate_result result; + try { + iface_->truncate(args.cfname); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.truncate"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("truncate", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.truncate"); + } + + oprot->writeMessageBegin("truncate", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.truncate", bytes); + } +} + +void CassandraProcessor::process_describe_schema_versions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_schema_versions", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_schema_versions"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_schema_versions"); + } + + Cassandra_describe_schema_versions_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_schema_versions", bytes); + } + + Cassandra_describe_schema_versions_result result; + try { + iface_->describe_schema_versions(result.success); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_schema_versions"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_schema_versions", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_schema_versions"); + } + + oprot->writeMessageBegin("describe_schema_versions", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_schema_versions", bytes); + } +} + +void CassandraProcessor::process_describe_keyspaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_keyspaces", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_keyspaces"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_keyspaces"); + } + + Cassandra_describe_keyspaces_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_keyspaces", bytes); + } + + Cassandra_describe_keyspaces_result result; + try { + iface_->describe_keyspaces(result.success); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_keyspaces"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_keyspaces", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_keyspaces"); + } + + oprot->writeMessageBegin("describe_keyspaces", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_keyspaces", bytes); + } +} + +void CassandraProcessor::process_describe_cluster_name(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_cluster_name", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_cluster_name"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_cluster_name"); + } + + Cassandra_describe_cluster_name_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_cluster_name", bytes); + } + + Cassandra_describe_cluster_name_result result; + try { + iface_->describe_cluster_name(result.success); + result.__isset.success = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_cluster_name"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_cluster_name", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_cluster_name"); + } + + oprot->writeMessageBegin("describe_cluster_name", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_cluster_name", bytes); + } +} + +void CassandraProcessor::process_describe_version(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_version", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_version"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_version"); + } + + Cassandra_describe_version_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_version", bytes); + } + + Cassandra_describe_version_result result; + try { + iface_->describe_version(result.success); + result.__isset.success = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_version"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_version", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_version"); + } + + oprot->writeMessageBegin("describe_version", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_version", bytes); + } +} + +void CassandraProcessor::process_describe_ring(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_ring", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_ring"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_ring"); + } + + Cassandra_describe_ring_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_ring", bytes); + } + + Cassandra_describe_ring_result result; + try { + iface_->describe_ring(result.success, args.keyspace); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_ring"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_ring", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_ring"); + } + + oprot->writeMessageBegin("describe_ring", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_ring", bytes); + } +} + +void CassandraProcessor::process_describe_token_map(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_token_map", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_token_map"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_token_map"); + } + + Cassandra_describe_token_map_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_token_map", bytes); + } + + Cassandra_describe_token_map_result result; + try { + iface_->describe_token_map(result.success); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_token_map"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_token_map", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_token_map"); + } + + oprot->writeMessageBegin("describe_token_map", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_token_map", bytes); + } +} + +void CassandraProcessor::process_describe_partitioner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_partitioner", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_partitioner"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_partitioner"); + } + + Cassandra_describe_partitioner_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_partitioner", bytes); + } + + Cassandra_describe_partitioner_result result; + try { + iface_->describe_partitioner(result.success); + result.__isset.success = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_partitioner"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_partitioner", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_partitioner"); + } + + oprot->writeMessageBegin("describe_partitioner", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_partitioner", bytes); + } +} + +void CassandraProcessor::process_describe_snitch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_snitch", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_snitch"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_snitch"); + } + + Cassandra_describe_snitch_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_snitch", bytes); + } + + Cassandra_describe_snitch_result result; + try { + iface_->describe_snitch(result.success); + result.__isset.success = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_snitch"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_snitch", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_snitch"); + } + + oprot->writeMessageBegin("describe_snitch", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_snitch", bytes); + } +} + +void CassandraProcessor::process_describe_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_keyspace", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_keyspace"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_keyspace"); + } + + Cassandra_describe_keyspace_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_keyspace", bytes); + } + + Cassandra_describe_keyspace_result result; + try { + iface_->describe_keyspace(result.success, args.keyspace); + result.__isset.success = true; + } catch (NotFoundException &nfe) { + result.nfe = nfe; + result.__isset.nfe = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_keyspace"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_keyspace", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_keyspace"); + } + + oprot->writeMessageBegin("describe_keyspace", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_keyspace", bytes); + } +} + +void CassandraProcessor::process_describe_splits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.describe_splits", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.describe_splits"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.describe_splits"); + } + + Cassandra_describe_splits_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.describe_splits", bytes); + } + + Cassandra_describe_splits_result result; + try { + iface_->describe_splits(result.success, args.cfName, args.start_token, args.end_token, args.keys_per_split); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.describe_splits"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("describe_splits", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.describe_splits"); + } + + oprot->writeMessageBegin("describe_splits", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.describe_splits", bytes); + } +} + +void CassandraProcessor::process_system_add_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_add_column_family", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_add_column_family"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_add_column_family"); + } + + Cassandra_system_add_column_family_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_add_column_family", bytes); + } + + Cassandra_system_add_column_family_result result; + try { + iface_->system_add_column_family(result.success, args.cf_def); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_add_column_family"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_add_column_family", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_add_column_family"); + } + + oprot->writeMessageBegin("system_add_column_family", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_add_column_family", bytes); + } +} + +void CassandraProcessor::process_system_drop_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_drop_column_family", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_drop_column_family"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_drop_column_family"); + } + + Cassandra_system_drop_column_family_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_drop_column_family", bytes); + } + + Cassandra_system_drop_column_family_result result; + try { + iface_->system_drop_column_family(result.success, args.column_family); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_drop_column_family"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_drop_column_family", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_drop_column_family"); + } + + oprot->writeMessageBegin("system_drop_column_family", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_drop_column_family", bytes); + } +} + +void CassandraProcessor::process_system_add_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_add_keyspace", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_add_keyspace"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_add_keyspace"); + } + + Cassandra_system_add_keyspace_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_add_keyspace", bytes); + } + + Cassandra_system_add_keyspace_result result; + try { + iface_->system_add_keyspace(result.success, args.ks_def); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_add_keyspace"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_add_keyspace", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_add_keyspace"); + } + + oprot->writeMessageBegin("system_add_keyspace", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_add_keyspace", bytes); + } +} + +void CassandraProcessor::process_system_drop_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_drop_keyspace", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_drop_keyspace"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_drop_keyspace"); + } + + Cassandra_system_drop_keyspace_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_drop_keyspace", bytes); + } + + Cassandra_system_drop_keyspace_result result; + try { + iface_->system_drop_keyspace(result.success, args.keyspace); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_drop_keyspace"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_drop_keyspace", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_drop_keyspace"); + } + + oprot->writeMessageBegin("system_drop_keyspace", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_drop_keyspace", bytes); + } +} + +void CassandraProcessor::process_system_update_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_update_keyspace", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_update_keyspace"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_update_keyspace"); + } + + Cassandra_system_update_keyspace_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_update_keyspace", bytes); + } + + Cassandra_system_update_keyspace_result result; + try { + iface_->system_update_keyspace(result.success, args.ks_def); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_update_keyspace"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_update_keyspace", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_update_keyspace"); + } + + oprot->writeMessageBegin("system_update_keyspace", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_update_keyspace", bytes); + } +} + +void CassandraProcessor::process_system_update_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.system_update_column_family", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.system_update_column_family"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.system_update_column_family"); + } + + Cassandra_system_update_column_family_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.system_update_column_family", bytes); + } + + Cassandra_system_update_column_family_result result; + try { + iface_->system_update_column_family(result.success, args.cf_def); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.system_update_column_family"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("system_update_column_family", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.system_update_column_family"); + } + + oprot->writeMessageBegin("system_update_column_family", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.system_update_column_family", bytes); + } +} + +void CassandraProcessor::process_execute_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.execute_cql_query", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.execute_cql_query"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.execute_cql_query"); + } + + Cassandra_execute_cql_query_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.execute_cql_query", bytes); + } + + Cassandra_execute_cql_query_result result; + try { + iface_->execute_cql_query(result.success, args.query, args.compression); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.execute_cql_query"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("execute_cql_query", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.execute_cql_query"); + } + + oprot->writeMessageBegin("execute_cql_query", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.execute_cql_query", bytes); + } +} + +void CassandraProcessor::process_prepare_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.prepare_cql_query", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.prepare_cql_query"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.prepare_cql_query"); + } + + Cassandra_prepare_cql_query_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.prepare_cql_query", bytes); + } + + Cassandra_prepare_cql_query_result result; + try { + iface_->prepare_cql_query(result.success, args.query, args.compression); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.prepare_cql_query"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("prepare_cql_query", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.prepare_cql_query"); + } + + oprot->writeMessageBegin("prepare_cql_query", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.prepare_cql_query", bytes); + } +} + +void CassandraProcessor::process_execute_prepared_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.execute_prepared_cql_query", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.execute_prepared_cql_query"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.execute_prepared_cql_query"); + } + + Cassandra_execute_prepared_cql_query_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.execute_prepared_cql_query", bytes); + } + + Cassandra_execute_prepared_cql_query_result result; + try { + iface_->execute_prepared_cql_query(result.success, args.itemId, args.values); + result.__isset.success = true; + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (UnavailableException &ue) { + result.ue = ue; + result.__isset.ue = true; + } catch (TimedOutException &te) { + result.te = te; + result.__isset.te = true; + } catch (SchemaDisagreementException &sde) { + result.sde = sde; + result.__isset.sde = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.execute_prepared_cql_query"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("execute_prepared_cql_query", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.execute_prepared_cql_query"); + } + + oprot->writeMessageBegin("execute_prepared_cql_query", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.execute_prepared_cql_query", bytes); + } +} + +void CassandraProcessor::process_set_cql_version(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext) +{ + void* ctx = NULL; + if (this->eventHandler_.get() != NULL) { + ctx = this->eventHandler_->getContext("Cassandra.set_cql_version", callContext); + } + ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Cassandra.set_cql_version"); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preRead(ctx, "Cassandra.set_cql_version"); + } + + Cassandra_set_cql_version_args args; + args.read(iprot); + iprot->readMessageEnd(); + uint32_t bytes = iprot->getTransport()->readEnd(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postRead(ctx, "Cassandra.set_cql_version", bytes); + } + + Cassandra_set_cql_version_result result; + try { + iface_->set_cql_version(args.version); + } catch (InvalidRequestException &ire) { + result.ire = ire; + result.__isset.ire = true; + } catch (const std::exception& e) { + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->handlerError(ctx, "Cassandra.set_cql_version"); + } + + ::apache::thrift::TApplicationException x(e.what()); + oprot->writeMessageBegin("set_cql_version", ::apache::thrift::protocol::T_EXCEPTION, seqid); + x.write(oprot); + oprot->writeMessageEnd(); + oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + return; + } + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->preWrite(ctx, "Cassandra.set_cql_version"); + } + + oprot->writeMessageBegin("set_cql_version", ::apache::thrift::protocol::T_REPLY, seqid); + result.write(oprot); + oprot->writeMessageEnd(); + bytes = oprot->getTransport()->writeEnd(); + oprot->getTransport()->flush(); + + if (this->eventHandler_.get() != NULL) { + this->eventHandler_->postWrite(ctx, "Cassandra.set_cql_version", bytes); + } +} + +::boost::shared_ptr< ::apache::thrift::TProcessor > CassandraProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) { + ::apache::thrift::ReleaseHandler< CassandraIfFactory > cleanup(handlerFactory_); + ::boost::shared_ptr< CassandraIf > handler(handlerFactory_->getHandler(connInfo), cleanup); + ::boost::shared_ptr< ::apache::thrift::TProcessor > processor(new CassandraProcessor(handler)); + return processor; +} +}}} // namespace + diff --git a/storage/cassandra/gen-cpp/Cassandra.h b/storage/cassandra/gen-cpp/Cassandra.h new file mode 100644 index 00000000000..2040cc63aa2 --- /dev/null +++ b/storage/cassandra/gen-cpp/Cassandra.h @@ -0,0 +1,5466 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef Cassandra_H +#define Cassandra_H + +#include +#include "cassandra_types.h" + +namespace org { namespace apache { namespace cassandra { + +class CassandraIf { + public: + virtual ~CassandraIf() {} + virtual void login(const AuthenticationRequest& auth_request) = 0; + virtual void set_keyspace(const std::string& keyspace) = 0; + virtual void get(ColumnOrSuperColumn& _return, const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level) = 0; + virtual void get_slice(std::vector & _return, const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) = 0; + virtual int32_t get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) = 0; + virtual void multiget_slice(std::map > & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) = 0; + virtual void multiget_count(std::map & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) = 0; + virtual void get_range_slices(std::vector & _return, const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level) = 0; + virtual void get_paged_slice(std::vector & _return, const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level) = 0; + virtual void get_indexed_slices(std::vector & _return, const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level) = 0; + virtual void insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level) = 0; + virtual void add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level) = 0; + virtual void remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level) = 0; + virtual void remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level) = 0; + virtual void batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level) = 0; + virtual void truncate(const std::string& cfname) = 0; + virtual void describe_schema_versions(std::map > & _return) = 0; + virtual void describe_keyspaces(std::vector & _return) = 0; + virtual void describe_cluster_name(std::string& _return) = 0; + virtual void describe_version(std::string& _return) = 0; + virtual void describe_ring(std::vector & _return, const std::string& keyspace) = 0; + virtual void describe_token_map(std::map & _return) = 0; + virtual void describe_partitioner(std::string& _return) = 0; + virtual void describe_snitch(std::string& _return) = 0; + virtual void describe_keyspace(KsDef& _return, const std::string& keyspace) = 0; + virtual void describe_splits(std::vector & _return, const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split) = 0; + virtual void system_add_column_family(std::string& _return, const CfDef& cf_def) = 0; + virtual void system_drop_column_family(std::string& _return, const std::string& column_family) = 0; + virtual void system_add_keyspace(std::string& _return, const KsDef& ks_def) = 0; + virtual void system_drop_keyspace(std::string& _return, const std::string& keyspace) = 0; + virtual void system_update_keyspace(std::string& _return, const KsDef& ks_def) = 0; + virtual void system_update_column_family(std::string& _return, const CfDef& cf_def) = 0; + virtual void execute_cql_query(CqlResult& _return, const std::string& query, const Compression::type compression) = 0; + virtual void prepare_cql_query(CqlPreparedResult& _return, const std::string& query, const Compression::type compression) = 0; + virtual void execute_prepared_cql_query(CqlResult& _return, const int32_t itemId, const std::vector & values) = 0; + virtual void set_cql_version(const std::string& version) = 0; +}; + +class CassandraIfFactory { + public: + typedef CassandraIf Handler; + + virtual ~CassandraIfFactory() {} + + virtual CassandraIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0; + virtual void releaseHandler(CassandraIf* /* handler */) = 0; +}; + +class CassandraIfSingletonFactory : virtual public CassandraIfFactory { + public: + CassandraIfSingletonFactory(const boost::shared_ptr& iface) : iface_(iface) {} + virtual ~CassandraIfSingletonFactory() {} + + virtual CassandraIf* getHandler(const ::apache::thrift::TConnectionInfo&) { + return iface_.get(); + } + virtual void releaseHandler(CassandraIf* /* handler */) {} + + protected: + boost::shared_ptr iface_; +}; + +class CassandraNull : virtual public CassandraIf { + public: + virtual ~CassandraNull() {} + void login(const AuthenticationRequest& /* auth_request */) { + return; + } + void set_keyspace(const std::string& /* keyspace */) { + return; + } + void get(ColumnOrSuperColumn& /* _return */, const std::string& /* key */, const ColumnPath& /* column_path */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void get_slice(std::vector & /* _return */, const std::string& /* key */, const ColumnParent& /* column_parent */, const SlicePredicate& /* predicate */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + int32_t get_count(const std::string& /* key */, const ColumnParent& /* column_parent */, const SlicePredicate& /* predicate */, const ConsistencyLevel::type /* consistency_level */) { + int32_t _return = 0; + return _return; + } + void multiget_slice(std::map > & /* _return */, const std::vector & /* keys */, const ColumnParent& /* column_parent */, const SlicePredicate& /* predicate */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void multiget_count(std::map & /* _return */, const std::vector & /* keys */, const ColumnParent& /* column_parent */, const SlicePredicate& /* predicate */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void get_range_slices(std::vector & /* _return */, const ColumnParent& /* column_parent */, const SlicePredicate& /* predicate */, const KeyRange& /* range */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void get_paged_slice(std::vector & /* _return */, const std::string& /* column_family */, const KeyRange& /* range */, const std::string& /* start_column */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void get_indexed_slices(std::vector & /* _return */, const ColumnParent& /* column_parent */, const IndexClause& /* index_clause */, const SlicePredicate& /* column_predicate */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void insert(const std::string& /* key */, const ColumnParent& /* column_parent */, const Column& /* column */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void add(const std::string& /* key */, const ColumnParent& /* column_parent */, const CounterColumn& /* column */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void remove(const std::string& /* key */, const ColumnPath& /* column_path */, const int64_t /* timestamp */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void remove_counter(const std::string& /* key */, const ColumnPath& /* path */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void batch_mutate(const std::map > > & /* mutation_map */, const ConsistencyLevel::type /* consistency_level */) { + return; + } + void truncate(const std::string& /* cfname */) { + return; + } + void describe_schema_versions(std::map > & /* _return */) { + return; + } + void describe_keyspaces(std::vector & /* _return */) { + return; + } + void describe_cluster_name(std::string& /* _return */) { + return; + } + void describe_version(std::string& /* _return */) { + return; + } + void describe_ring(std::vector & /* _return */, const std::string& /* keyspace */) { + return; + } + void describe_token_map(std::map & /* _return */) { + return; + } + void describe_partitioner(std::string& /* _return */) { + return; + } + void describe_snitch(std::string& /* _return */) { + return; + } + void describe_keyspace(KsDef& /* _return */, const std::string& /* keyspace */) { + return; + } + void describe_splits(std::vector & /* _return */, const std::string& /* cfName */, const std::string& /* start_token */, const std::string& /* end_token */, const int32_t /* keys_per_split */) { + return; + } + void system_add_column_family(std::string& /* _return */, const CfDef& /* cf_def */) { + return; + } + void system_drop_column_family(std::string& /* _return */, const std::string& /* column_family */) { + return; + } + void system_add_keyspace(std::string& /* _return */, const KsDef& /* ks_def */) { + return; + } + void system_drop_keyspace(std::string& /* _return */, const std::string& /* keyspace */) { + return; + } + void system_update_keyspace(std::string& /* _return */, const KsDef& /* ks_def */) { + return; + } + void system_update_column_family(std::string& /* _return */, const CfDef& /* cf_def */) { + return; + } + void execute_cql_query(CqlResult& /* _return */, const std::string& /* query */, const Compression::type /* compression */) { + return; + } + void prepare_cql_query(CqlPreparedResult& /* _return */, const std::string& /* query */, const Compression::type /* compression */) { + return; + } + void execute_prepared_cql_query(CqlResult& /* _return */, const int32_t /* itemId */, const std::vector & /* values */) { + return; + } + void set_cql_version(const std::string& /* version */) { + return; + } +}; + + +class Cassandra_login_args { + public: + + Cassandra_login_args() { + } + + virtual ~Cassandra_login_args() throw() {} + + AuthenticationRequest auth_request; + + void __set_auth_request(const AuthenticationRequest& val) { + auth_request = val; + } + + bool operator == (const Cassandra_login_args & rhs) const + { + if (!(auth_request == rhs.auth_request)) + return false; + return true; + } + bool operator != (const Cassandra_login_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_login_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_login_pargs { + public: + + + virtual ~Cassandra_login_pargs() throw() {} + + const AuthenticationRequest* auth_request; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_login_result__isset { + _Cassandra_login_result__isset() : authnx(false), authzx(false) {} + bool authnx; + bool authzx; +} _Cassandra_login_result__isset; + +class Cassandra_login_result { + public: + + Cassandra_login_result() { + } + + virtual ~Cassandra_login_result() throw() {} + + AuthenticationException authnx; + AuthorizationException authzx; + + _Cassandra_login_result__isset __isset; + + void __set_authnx(const AuthenticationException& val) { + authnx = val; + } + + void __set_authzx(const AuthorizationException& val) { + authzx = val; + } + + bool operator == (const Cassandra_login_result & rhs) const + { + if (!(authnx == rhs.authnx)) + return false; + if (!(authzx == rhs.authzx)) + return false; + return true; + } + bool operator != (const Cassandra_login_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_login_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_login_presult__isset { + _Cassandra_login_presult__isset() : authnx(false), authzx(false) {} + bool authnx; + bool authzx; +} _Cassandra_login_presult__isset; + +class Cassandra_login_presult { + public: + + + virtual ~Cassandra_login_presult() throw() {} + + AuthenticationException authnx; + AuthorizationException authzx; + + _Cassandra_login_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_set_keyspace_args { + public: + + Cassandra_set_keyspace_args() : keyspace("") { + } + + virtual ~Cassandra_set_keyspace_args() throw() {} + + std::string keyspace; + + void __set_keyspace(const std::string& val) { + keyspace = val; + } + + bool operator == (const Cassandra_set_keyspace_args & rhs) const + { + if (!(keyspace == rhs.keyspace)) + return false; + return true; + } + bool operator != (const Cassandra_set_keyspace_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_set_keyspace_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_set_keyspace_pargs { + public: + + + virtual ~Cassandra_set_keyspace_pargs() throw() {} + + const std::string* keyspace; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_set_keyspace_result__isset { + _Cassandra_set_keyspace_result__isset() : ire(false) {} + bool ire; +} _Cassandra_set_keyspace_result__isset; + +class Cassandra_set_keyspace_result { + public: + + Cassandra_set_keyspace_result() { + } + + virtual ~Cassandra_set_keyspace_result() throw() {} + + InvalidRequestException ire; + + _Cassandra_set_keyspace_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_set_keyspace_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_set_keyspace_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_set_keyspace_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_set_keyspace_presult__isset { + _Cassandra_set_keyspace_presult__isset() : ire(false) {} + bool ire; +} _Cassandra_set_keyspace_presult__isset; + +class Cassandra_set_keyspace_presult { + public: + + + virtual ~Cassandra_set_keyspace_presult() throw() {} + + InvalidRequestException ire; + + _Cassandra_set_keyspace_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_args { + public: + + Cassandra_get_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_args() throw() {} + + std::string key; + ColumnPath column_path; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_path(const ColumnPath& val) { + column_path = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_path == rhs.column_path)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_pargs { + public: + + + virtual ~Cassandra_get_pargs() throw() {} + + const std::string* key; + const ColumnPath* column_path; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_result__isset { + _Cassandra_get_result__isset() : success(false), ire(false), nfe(false), ue(false), te(false) {} + bool success; + bool ire; + bool nfe; + bool ue; + bool te; +} _Cassandra_get_result__isset; + +class Cassandra_get_result { + public: + + Cassandra_get_result() { + } + + virtual ~Cassandra_get_result() throw() {} + + ColumnOrSuperColumn success; + InvalidRequestException ire; + NotFoundException nfe; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_result__isset __isset; + + void __set_success(const ColumnOrSuperColumn& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_nfe(const NotFoundException& val) { + nfe = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(nfe == rhs.nfe)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_presult__isset { + _Cassandra_get_presult__isset() : success(false), ire(false), nfe(false), ue(false), te(false) {} + bool success; + bool ire; + bool nfe; + bool ue; + bool te; +} _Cassandra_get_presult__isset; + +class Cassandra_get_presult { + public: + + + virtual ~Cassandra_get_presult() throw() {} + + ColumnOrSuperColumn* success; + InvalidRequestException ire; + NotFoundException nfe; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_slice_args { + public: + + Cassandra_get_slice_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_slice_args() throw() {} + + std::string key; + ColumnParent column_parent; + SlicePredicate predicate; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_slice_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(predicate == rhs.predicate)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_slice_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_slice_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_slice_pargs { + public: + + + virtual ~Cassandra_get_slice_pargs() throw() {} + + const std::string* key; + const ColumnParent* column_parent; + const SlicePredicate* predicate; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_slice_result__isset { + _Cassandra_get_slice_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_slice_result__isset; + +class Cassandra_get_slice_result { + public: + + Cassandra_get_slice_result() { + } + + virtual ~Cassandra_get_slice_result() throw() {} + + std::vector success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_slice_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_slice_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_slice_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_slice_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_slice_presult__isset { + _Cassandra_get_slice_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_slice_presult__isset; + +class Cassandra_get_slice_presult { + public: + + + virtual ~Cassandra_get_slice_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_slice_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_count_args { + public: + + Cassandra_get_count_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_count_args() throw() {} + + std::string key; + ColumnParent column_parent; + SlicePredicate predicate; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_count_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(predicate == rhs.predicate)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_count_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_count_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_count_pargs { + public: + + + virtual ~Cassandra_get_count_pargs() throw() {} + + const std::string* key; + const ColumnParent* column_parent; + const SlicePredicate* predicate; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_count_result__isset { + _Cassandra_get_count_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_count_result__isset; + +class Cassandra_get_count_result { + public: + + Cassandra_get_count_result() : success(0) { + } + + virtual ~Cassandra_get_count_result() throw() {} + + int32_t success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_count_result__isset __isset; + + void __set_success(const int32_t val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_count_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_count_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_count_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_count_presult__isset { + _Cassandra_get_count_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_count_presult__isset; + +class Cassandra_get_count_presult { + public: + + + virtual ~Cassandra_get_count_presult() throw() {} + + int32_t* success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_count_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_multiget_slice_args { + public: + + Cassandra_multiget_slice_args() : consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_multiget_slice_args() throw() {} + + std::vector keys; + ColumnParent column_parent; + SlicePredicate predicate; + ConsistencyLevel::type consistency_level; + + void __set_keys(const std::vector & val) { + keys = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_multiget_slice_args & rhs) const + { + if (!(keys == rhs.keys)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(predicate == rhs.predicate)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_multiget_slice_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_multiget_slice_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_multiget_slice_pargs { + public: + + + virtual ~Cassandra_multiget_slice_pargs() throw() {} + + const std::vector * keys; + const ColumnParent* column_parent; + const SlicePredicate* predicate; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_multiget_slice_result__isset { + _Cassandra_multiget_slice_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_multiget_slice_result__isset; + +class Cassandra_multiget_slice_result { + public: + + Cassandra_multiget_slice_result() { + } + + virtual ~Cassandra_multiget_slice_result() throw() {} + + std::map > success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_multiget_slice_result__isset __isset; + + void __set_success(const std::map > & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_multiget_slice_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_multiget_slice_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_multiget_slice_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_multiget_slice_presult__isset { + _Cassandra_multiget_slice_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_multiget_slice_presult__isset; + +class Cassandra_multiget_slice_presult { + public: + + + virtual ~Cassandra_multiget_slice_presult() throw() {} + + std::map > * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_multiget_slice_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_multiget_count_args { + public: + + Cassandra_multiget_count_args() : consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_multiget_count_args() throw() {} + + std::vector keys; + ColumnParent column_parent; + SlicePredicate predicate; + ConsistencyLevel::type consistency_level; + + void __set_keys(const std::vector & val) { + keys = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_multiget_count_args & rhs) const + { + if (!(keys == rhs.keys)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(predicate == rhs.predicate)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_multiget_count_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_multiget_count_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_multiget_count_pargs { + public: + + + virtual ~Cassandra_multiget_count_pargs() throw() {} + + const std::vector * keys; + const ColumnParent* column_parent; + const SlicePredicate* predicate; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_multiget_count_result__isset { + _Cassandra_multiget_count_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_multiget_count_result__isset; + +class Cassandra_multiget_count_result { + public: + + Cassandra_multiget_count_result() { + } + + virtual ~Cassandra_multiget_count_result() throw() {} + + std::map success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_multiget_count_result__isset __isset; + + void __set_success(const std::map & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_multiget_count_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_multiget_count_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_multiget_count_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_multiget_count_presult__isset { + _Cassandra_multiget_count_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_multiget_count_presult__isset; + +class Cassandra_multiget_count_presult { + public: + + + virtual ~Cassandra_multiget_count_presult() throw() {} + + std::map * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_multiget_count_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_range_slices_args { + public: + + Cassandra_get_range_slices_args() : consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_range_slices_args() throw() {} + + ColumnParent column_parent; + SlicePredicate predicate; + KeyRange range; + ConsistencyLevel::type consistency_level; + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + } + + void __set_range(const KeyRange& val) { + range = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_range_slices_args & rhs) const + { + if (!(column_parent == rhs.column_parent)) + return false; + if (!(predicate == rhs.predicate)) + return false; + if (!(range == rhs.range)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_range_slices_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_range_slices_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_range_slices_pargs { + public: + + + virtual ~Cassandra_get_range_slices_pargs() throw() {} + + const ColumnParent* column_parent; + const SlicePredicate* predicate; + const KeyRange* range; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_range_slices_result__isset { + _Cassandra_get_range_slices_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_range_slices_result__isset; + +class Cassandra_get_range_slices_result { + public: + + Cassandra_get_range_slices_result() { + } + + virtual ~Cassandra_get_range_slices_result() throw() {} + + std::vector success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_range_slices_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_range_slices_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_range_slices_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_range_slices_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_range_slices_presult__isset { + _Cassandra_get_range_slices_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_range_slices_presult__isset; + +class Cassandra_get_range_slices_presult { + public: + + + virtual ~Cassandra_get_range_slices_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_range_slices_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_paged_slice_args { + public: + + Cassandra_get_paged_slice_args() : column_family(""), start_column(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_paged_slice_args() throw() {} + + std::string column_family; + KeyRange range; + std::string start_column; + ConsistencyLevel::type consistency_level; + + void __set_column_family(const std::string& val) { + column_family = val; + } + + void __set_range(const KeyRange& val) { + range = val; + } + + void __set_start_column(const std::string& val) { + start_column = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_paged_slice_args & rhs) const + { + if (!(column_family == rhs.column_family)) + return false; + if (!(range == rhs.range)) + return false; + if (!(start_column == rhs.start_column)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_paged_slice_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_paged_slice_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_paged_slice_pargs { + public: + + + virtual ~Cassandra_get_paged_slice_pargs() throw() {} + + const std::string* column_family; + const KeyRange* range; + const std::string* start_column; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_paged_slice_result__isset { + _Cassandra_get_paged_slice_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_paged_slice_result__isset; + +class Cassandra_get_paged_slice_result { + public: + + Cassandra_get_paged_slice_result() { + } + + virtual ~Cassandra_get_paged_slice_result() throw() {} + + std::vector success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_paged_slice_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_paged_slice_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_paged_slice_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_paged_slice_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_paged_slice_presult__isset { + _Cassandra_get_paged_slice_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_paged_slice_presult__isset; + +class Cassandra_get_paged_slice_presult { + public: + + + virtual ~Cassandra_get_paged_slice_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_paged_slice_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_get_indexed_slices_args { + public: + + Cassandra_get_indexed_slices_args() : consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_get_indexed_slices_args() throw() {} + + ColumnParent column_parent; + IndexClause index_clause; + SlicePredicate column_predicate; + ConsistencyLevel::type consistency_level; + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_index_clause(const IndexClause& val) { + index_clause = val; + } + + void __set_column_predicate(const SlicePredicate& val) { + column_predicate = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_get_indexed_slices_args & rhs) const + { + if (!(column_parent == rhs.column_parent)) + return false; + if (!(index_clause == rhs.index_clause)) + return false; + if (!(column_predicate == rhs.column_predicate)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_get_indexed_slices_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_indexed_slices_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_get_indexed_slices_pargs { + public: + + + virtual ~Cassandra_get_indexed_slices_pargs() throw() {} + + const ColumnParent* column_parent; + const IndexClause* index_clause; + const SlicePredicate* column_predicate; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_indexed_slices_result__isset { + _Cassandra_get_indexed_slices_result__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_indexed_slices_result__isset; + +class Cassandra_get_indexed_slices_result { + public: + + Cassandra_get_indexed_slices_result() { + } + + virtual ~Cassandra_get_indexed_slices_result() throw() {} + + std::vector success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_indexed_slices_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_get_indexed_slices_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_get_indexed_slices_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_get_indexed_slices_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_get_indexed_slices_presult__isset { + _Cassandra_get_indexed_slices_presult__isset() : success(false), ire(false), ue(false), te(false) {} + bool success; + bool ire; + bool ue; + bool te; +} _Cassandra_get_indexed_slices_presult__isset; + +class Cassandra_get_indexed_slices_presult { + public: + + + virtual ~Cassandra_get_indexed_slices_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_get_indexed_slices_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_insert_args { + public: + + Cassandra_insert_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_insert_args() throw() {} + + std::string key; + ColumnParent column_parent; + Column column; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_column(const Column& val) { + column = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_insert_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(column == rhs.column)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_insert_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_insert_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_insert_pargs { + public: + + + virtual ~Cassandra_insert_pargs() throw() {} + + const std::string* key; + const ColumnParent* column_parent; + const Column* column; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_insert_result__isset { + _Cassandra_insert_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_insert_result__isset; + +class Cassandra_insert_result { + public: + + Cassandra_insert_result() { + } + + virtual ~Cassandra_insert_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_insert_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_insert_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_insert_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_insert_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_insert_presult__isset { + _Cassandra_insert_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_insert_presult__isset; + +class Cassandra_insert_presult { + public: + + + virtual ~Cassandra_insert_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_insert_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_add_args { + public: + + Cassandra_add_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_add_args() throw() {} + + std::string key; + ColumnParent column_parent; + CounterColumn column; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_parent(const ColumnParent& val) { + column_parent = val; + } + + void __set_column(const CounterColumn& val) { + column = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_add_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_parent == rhs.column_parent)) + return false; + if (!(column == rhs.column)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_add_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_add_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_add_pargs { + public: + + + virtual ~Cassandra_add_pargs() throw() {} + + const std::string* key; + const ColumnParent* column_parent; + const CounterColumn* column; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_add_result__isset { + _Cassandra_add_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_add_result__isset; + +class Cassandra_add_result { + public: + + Cassandra_add_result() { + } + + virtual ~Cassandra_add_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_add_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_add_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_add_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_add_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_add_presult__isset { + _Cassandra_add_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_add_presult__isset; + +class Cassandra_add_presult { + public: + + + virtual ~Cassandra_add_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_add_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + +typedef struct _Cassandra_remove_args__isset { + _Cassandra_remove_args__isset() : consistency_level(false) {} + bool consistency_level; +} _Cassandra_remove_args__isset; + +class Cassandra_remove_args { + public: + + Cassandra_remove_args() : key(""), timestamp(0), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_remove_args() throw() {} + + std::string key; + ColumnPath column_path; + int64_t timestamp; + ConsistencyLevel::type consistency_level; + + _Cassandra_remove_args__isset __isset; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_column_path(const ColumnPath& val) { + column_path = val; + } + + void __set_timestamp(const int64_t val) { + timestamp = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_remove_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(column_path == rhs.column_path)) + return false; + if (!(timestamp == rhs.timestamp)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_remove_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_remove_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_remove_pargs { + public: + + + virtual ~Cassandra_remove_pargs() throw() {} + + const std::string* key; + const ColumnPath* column_path; + const int64_t* timestamp; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_remove_result__isset { + _Cassandra_remove_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_remove_result__isset; + +class Cassandra_remove_result { + public: + + Cassandra_remove_result() { + } + + virtual ~Cassandra_remove_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_remove_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_remove_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_remove_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_remove_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_remove_presult__isset { + _Cassandra_remove_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_remove_presult__isset; + +class Cassandra_remove_presult { + public: + + + virtual ~Cassandra_remove_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_remove_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_remove_counter_args { + public: + + Cassandra_remove_counter_args() : key(""), consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_remove_counter_args() throw() {} + + std::string key; + ColumnPath path; + ConsistencyLevel::type consistency_level; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_path(const ColumnPath& val) { + path = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_remove_counter_args & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(path == rhs.path)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_remove_counter_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_remove_counter_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_remove_counter_pargs { + public: + + + virtual ~Cassandra_remove_counter_pargs() throw() {} + + const std::string* key; + const ColumnPath* path; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_remove_counter_result__isset { + _Cassandra_remove_counter_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_remove_counter_result__isset; + +class Cassandra_remove_counter_result { + public: + + Cassandra_remove_counter_result() { + } + + virtual ~Cassandra_remove_counter_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_remove_counter_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_remove_counter_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_remove_counter_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_remove_counter_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_remove_counter_presult__isset { + _Cassandra_remove_counter_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_remove_counter_presult__isset; + +class Cassandra_remove_counter_presult { + public: + + + virtual ~Cassandra_remove_counter_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_remove_counter_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_batch_mutate_args { + public: + + Cassandra_batch_mutate_args() : consistency_level((ConsistencyLevel::type)1) { + consistency_level = (ConsistencyLevel::type)1; + + } + + virtual ~Cassandra_batch_mutate_args() throw() {} + + std::map > > mutation_map; + ConsistencyLevel::type consistency_level; + + void __set_mutation_map(const std::map > > & val) { + mutation_map = val; + } + + void __set_consistency_level(const ConsistencyLevel::type val) { + consistency_level = val; + } + + bool operator == (const Cassandra_batch_mutate_args & rhs) const + { + if (!(mutation_map == rhs.mutation_map)) + return false; + if (!(consistency_level == rhs.consistency_level)) + return false; + return true; + } + bool operator != (const Cassandra_batch_mutate_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_batch_mutate_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_batch_mutate_pargs { + public: + + + virtual ~Cassandra_batch_mutate_pargs() throw() {} + + const std::map > > * mutation_map; + const ConsistencyLevel::type* consistency_level; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_batch_mutate_result__isset { + _Cassandra_batch_mutate_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_batch_mutate_result__isset; + +class Cassandra_batch_mutate_result { + public: + + Cassandra_batch_mutate_result() { + } + + virtual ~Cassandra_batch_mutate_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_batch_mutate_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_batch_mutate_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_batch_mutate_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_batch_mutate_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_batch_mutate_presult__isset { + _Cassandra_batch_mutate_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_batch_mutate_presult__isset; + +class Cassandra_batch_mutate_presult { + public: + + + virtual ~Cassandra_batch_mutate_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_batch_mutate_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_truncate_args { + public: + + Cassandra_truncate_args() : cfname("") { + } + + virtual ~Cassandra_truncate_args() throw() {} + + std::string cfname; + + void __set_cfname(const std::string& val) { + cfname = val; + } + + bool operator == (const Cassandra_truncate_args & rhs) const + { + if (!(cfname == rhs.cfname)) + return false; + return true; + } + bool operator != (const Cassandra_truncate_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_truncate_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_truncate_pargs { + public: + + + virtual ~Cassandra_truncate_pargs() throw() {} + + const std::string* cfname; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_truncate_result__isset { + _Cassandra_truncate_result__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_truncate_result__isset; + +class Cassandra_truncate_result { + public: + + Cassandra_truncate_result() { + } + + virtual ~Cassandra_truncate_result() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_truncate_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + bool operator == (const Cassandra_truncate_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + return true; + } + bool operator != (const Cassandra_truncate_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_truncate_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_truncate_presult__isset { + _Cassandra_truncate_presult__isset() : ire(false), ue(false), te(false) {} + bool ire; + bool ue; + bool te; +} _Cassandra_truncate_presult__isset; + +class Cassandra_truncate_presult { + public: + + + virtual ~Cassandra_truncate_presult() throw() {} + + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + + _Cassandra_truncate_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_schema_versions_args { + public: + + Cassandra_describe_schema_versions_args() { + } + + virtual ~Cassandra_describe_schema_versions_args() throw() {} + + + bool operator == (const Cassandra_describe_schema_versions_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_schema_versions_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_schema_versions_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_schema_versions_pargs { + public: + + + virtual ~Cassandra_describe_schema_versions_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_schema_versions_result__isset { + _Cassandra_describe_schema_versions_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_schema_versions_result__isset; + +class Cassandra_describe_schema_versions_result { + public: + + Cassandra_describe_schema_versions_result() { + } + + virtual ~Cassandra_describe_schema_versions_result() throw() {} + + std::map > success; + InvalidRequestException ire; + + _Cassandra_describe_schema_versions_result__isset __isset; + + void __set_success(const std::map > & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_schema_versions_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_schema_versions_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_schema_versions_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_schema_versions_presult__isset { + _Cassandra_describe_schema_versions_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_schema_versions_presult__isset; + +class Cassandra_describe_schema_versions_presult { + public: + + + virtual ~Cassandra_describe_schema_versions_presult() throw() {} + + std::map > * success; + InvalidRequestException ire; + + _Cassandra_describe_schema_versions_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_keyspaces_args { + public: + + Cassandra_describe_keyspaces_args() { + } + + virtual ~Cassandra_describe_keyspaces_args() throw() {} + + + bool operator == (const Cassandra_describe_keyspaces_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_keyspaces_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_keyspaces_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_keyspaces_pargs { + public: + + + virtual ~Cassandra_describe_keyspaces_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_keyspaces_result__isset { + _Cassandra_describe_keyspaces_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_keyspaces_result__isset; + +class Cassandra_describe_keyspaces_result { + public: + + Cassandra_describe_keyspaces_result() { + } + + virtual ~Cassandra_describe_keyspaces_result() throw() {} + + std::vector success; + InvalidRequestException ire; + + _Cassandra_describe_keyspaces_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_keyspaces_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_keyspaces_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_keyspaces_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_keyspaces_presult__isset { + _Cassandra_describe_keyspaces_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_keyspaces_presult__isset; + +class Cassandra_describe_keyspaces_presult { + public: + + + virtual ~Cassandra_describe_keyspaces_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + + _Cassandra_describe_keyspaces_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_cluster_name_args { + public: + + Cassandra_describe_cluster_name_args() { + } + + virtual ~Cassandra_describe_cluster_name_args() throw() {} + + + bool operator == (const Cassandra_describe_cluster_name_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_cluster_name_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_cluster_name_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_cluster_name_pargs { + public: + + + virtual ~Cassandra_describe_cluster_name_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_cluster_name_result__isset { + _Cassandra_describe_cluster_name_result__isset() : success(false) {} + bool success; +} _Cassandra_describe_cluster_name_result__isset; + +class Cassandra_describe_cluster_name_result { + public: + + Cassandra_describe_cluster_name_result() : success("") { + } + + virtual ~Cassandra_describe_cluster_name_result() throw() {} + + std::string success; + + _Cassandra_describe_cluster_name_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + bool operator == (const Cassandra_describe_cluster_name_result & rhs) const + { + if (!(success == rhs.success)) + return false; + return true; + } + bool operator != (const Cassandra_describe_cluster_name_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_cluster_name_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_cluster_name_presult__isset { + _Cassandra_describe_cluster_name_presult__isset() : success(false) {} + bool success; +} _Cassandra_describe_cluster_name_presult__isset; + +class Cassandra_describe_cluster_name_presult { + public: + + + virtual ~Cassandra_describe_cluster_name_presult() throw() {} + + std::string* success; + + _Cassandra_describe_cluster_name_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_version_args { + public: + + Cassandra_describe_version_args() { + } + + virtual ~Cassandra_describe_version_args() throw() {} + + + bool operator == (const Cassandra_describe_version_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_version_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_version_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_version_pargs { + public: + + + virtual ~Cassandra_describe_version_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_version_result__isset { + _Cassandra_describe_version_result__isset() : success(false) {} + bool success; +} _Cassandra_describe_version_result__isset; + +class Cassandra_describe_version_result { + public: + + Cassandra_describe_version_result() : success("") { + } + + virtual ~Cassandra_describe_version_result() throw() {} + + std::string success; + + _Cassandra_describe_version_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + bool operator == (const Cassandra_describe_version_result & rhs) const + { + if (!(success == rhs.success)) + return false; + return true; + } + bool operator != (const Cassandra_describe_version_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_version_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_version_presult__isset { + _Cassandra_describe_version_presult__isset() : success(false) {} + bool success; +} _Cassandra_describe_version_presult__isset; + +class Cassandra_describe_version_presult { + public: + + + virtual ~Cassandra_describe_version_presult() throw() {} + + std::string* success; + + _Cassandra_describe_version_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_ring_args { + public: + + Cassandra_describe_ring_args() : keyspace("") { + } + + virtual ~Cassandra_describe_ring_args() throw() {} + + std::string keyspace; + + void __set_keyspace(const std::string& val) { + keyspace = val; + } + + bool operator == (const Cassandra_describe_ring_args & rhs) const + { + if (!(keyspace == rhs.keyspace)) + return false; + return true; + } + bool operator != (const Cassandra_describe_ring_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_ring_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_ring_pargs { + public: + + + virtual ~Cassandra_describe_ring_pargs() throw() {} + + const std::string* keyspace; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_ring_result__isset { + _Cassandra_describe_ring_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_ring_result__isset; + +class Cassandra_describe_ring_result { + public: + + Cassandra_describe_ring_result() { + } + + virtual ~Cassandra_describe_ring_result() throw() {} + + std::vector success; + InvalidRequestException ire; + + _Cassandra_describe_ring_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_ring_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_ring_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_ring_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_ring_presult__isset { + _Cassandra_describe_ring_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_ring_presult__isset; + +class Cassandra_describe_ring_presult { + public: + + + virtual ~Cassandra_describe_ring_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + + _Cassandra_describe_ring_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_token_map_args { + public: + + Cassandra_describe_token_map_args() { + } + + virtual ~Cassandra_describe_token_map_args() throw() {} + + + bool operator == (const Cassandra_describe_token_map_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_token_map_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_token_map_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_token_map_pargs { + public: + + + virtual ~Cassandra_describe_token_map_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_token_map_result__isset { + _Cassandra_describe_token_map_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_token_map_result__isset; + +class Cassandra_describe_token_map_result { + public: + + Cassandra_describe_token_map_result() { + } + + virtual ~Cassandra_describe_token_map_result() throw() {} + + std::map success; + InvalidRequestException ire; + + _Cassandra_describe_token_map_result__isset __isset; + + void __set_success(const std::map & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_token_map_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_token_map_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_token_map_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_token_map_presult__isset { + _Cassandra_describe_token_map_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_token_map_presult__isset; + +class Cassandra_describe_token_map_presult { + public: + + + virtual ~Cassandra_describe_token_map_presult() throw() {} + + std::map * success; + InvalidRequestException ire; + + _Cassandra_describe_token_map_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_partitioner_args { + public: + + Cassandra_describe_partitioner_args() { + } + + virtual ~Cassandra_describe_partitioner_args() throw() {} + + + bool operator == (const Cassandra_describe_partitioner_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_partitioner_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_partitioner_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_partitioner_pargs { + public: + + + virtual ~Cassandra_describe_partitioner_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_partitioner_result__isset { + _Cassandra_describe_partitioner_result__isset() : success(false) {} + bool success; +} _Cassandra_describe_partitioner_result__isset; + +class Cassandra_describe_partitioner_result { + public: + + Cassandra_describe_partitioner_result() : success("") { + } + + virtual ~Cassandra_describe_partitioner_result() throw() {} + + std::string success; + + _Cassandra_describe_partitioner_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + bool operator == (const Cassandra_describe_partitioner_result & rhs) const + { + if (!(success == rhs.success)) + return false; + return true; + } + bool operator != (const Cassandra_describe_partitioner_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_partitioner_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_partitioner_presult__isset { + _Cassandra_describe_partitioner_presult__isset() : success(false) {} + bool success; +} _Cassandra_describe_partitioner_presult__isset; + +class Cassandra_describe_partitioner_presult { + public: + + + virtual ~Cassandra_describe_partitioner_presult() throw() {} + + std::string* success; + + _Cassandra_describe_partitioner_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_snitch_args { + public: + + Cassandra_describe_snitch_args() { + } + + virtual ~Cassandra_describe_snitch_args() throw() {} + + + bool operator == (const Cassandra_describe_snitch_args & /* rhs */) const + { + return true; + } + bool operator != (const Cassandra_describe_snitch_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_snitch_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_snitch_pargs { + public: + + + virtual ~Cassandra_describe_snitch_pargs() throw() {} + + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_snitch_result__isset { + _Cassandra_describe_snitch_result__isset() : success(false) {} + bool success; +} _Cassandra_describe_snitch_result__isset; + +class Cassandra_describe_snitch_result { + public: + + Cassandra_describe_snitch_result() : success("") { + } + + virtual ~Cassandra_describe_snitch_result() throw() {} + + std::string success; + + _Cassandra_describe_snitch_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + bool operator == (const Cassandra_describe_snitch_result & rhs) const + { + if (!(success == rhs.success)) + return false; + return true; + } + bool operator != (const Cassandra_describe_snitch_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_snitch_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_snitch_presult__isset { + _Cassandra_describe_snitch_presult__isset() : success(false) {} + bool success; +} _Cassandra_describe_snitch_presult__isset; + +class Cassandra_describe_snitch_presult { + public: + + + virtual ~Cassandra_describe_snitch_presult() throw() {} + + std::string* success; + + _Cassandra_describe_snitch_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_keyspace_args { + public: + + Cassandra_describe_keyspace_args() : keyspace("") { + } + + virtual ~Cassandra_describe_keyspace_args() throw() {} + + std::string keyspace; + + void __set_keyspace(const std::string& val) { + keyspace = val; + } + + bool operator == (const Cassandra_describe_keyspace_args & rhs) const + { + if (!(keyspace == rhs.keyspace)) + return false; + return true; + } + bool operator != (const Cassandra_describe_keyspace_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_keyspace_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_keyspace_pargs { + public: + + + virtual ~Cassandra_describe_keyspace_pargs() throw() {} + + const std::string* keyspace; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_keyspace_result__isset { + _Cassandra_describe_keyspace_result__isset() : success(false), nfe(false), ire(false) {} + bool success; + bool nfe; + bool ire; +} _Cassandra_describe_keyspace_result__isset; + +class Cassandra_describe_keyspace_result { + public: + + Cassandra_describe_keyspace_result() { + } + + virtual ~Cassandra_describe_keyspace_result() throw() {} + + KsDef success; + NotFoundException nfe; + InvalidRequestException ire; + + _Cassandra_describe_keyspace_result__isset __isset; + + void __set_success(const KsDef& val) { + success = val; + } + + void __set_nfe(const NotFoundException& val) { + nfe = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_keyspace_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(nfe == rhs.nfe)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_keyspace_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_keyspace_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_keyspace_presult__isset { + _Cassandra_describe_keyspace_presult__isset() : success(false), nfe(false), ire(false) {} + bool success; + bool nfe; + bool ire; +} _Cassandra_describe_keyspace_presult__isset; + +class Cassandra_describe_keyspace_presult { + public: + + + virtual ~Cassandra_describe_keyspace_presult() throw() {} + + KsDef* success; + NotFoundException nfe; + InvalidRequestException ire; + + _Cassandra_describe_keyspace_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_describe_splits_args { + public: + + Cassandra_describe_splits_args() : cfName(""), start_token(""), end_token(""), keys_per_split(0) { + } + + virtual ~Cassandra_describe_splits_args() throw() {} + + std::string cfName; + std::string start_token; + std::string end_token; + int32_t keys_per_split; + + void __set_cfName(const std::string& val) { + cfName = val; + } + + void __set_start_token(const std::string& val) { + start_token = val; + } + + void __set_end_token(const std::string& val) { + end_token = val; + } + + void __set_keys_per_split(const int32_t val) { + keys_per_split = val; + } + + bool operator == (const Cassandra_describe_splits_args & rhs) const + { + if (!(cfName == rhs.cfName)) + return false; + if (!(start_token == rhs.start_token)) + return false; + if (!(end_token == rhs.end_token)) + return false; + if (!(keys_per_split == rhs.keys_per_split)) + return false; + return true; + } + bool operator != (const Cassandra_describe_splits_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_splits_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_describe_splits_pargs { + public: + + + virtual ~Cassandra_describe_splits_pargs() throw() {} + + const std::string* cfName; + const std::string* start_token; + const std::string* end_token; + const int32_t* keys_per_split; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_splits_result__isset { + _Cassandra_describe_splits_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_splits_result__isset; + +class Cassandra_describe_splits_result { + public: + + Cassandra_describe_splits_result() { + } + + virtual ~Cassandra_describe_splits_result() throw() {} + + std::vector success; + InvalidRequestException ire; + + _Cassandra_describe_splits_result__isset __isset; + + void __set_success(const std::vector & val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_describe_splits_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_describe_splits_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_describe_splits_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_describe_splits_presult__isset { + _Cassandra_describe_splits_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_describe_splits_presult__isset; + +class Cassandra_describe_splits_presult { + public: + + + virtual ~Cassandra_describe_splits_presult() throw() {} + + std::vector * success; + InvalidRequestException ire; + + _Cassandra_describe_splits_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_add_column_family_args { + public: + + Cassandra_system_add_column_family_args() { + } + + virtual ~Cassandra_system_add_column_family_args() throw() {} + + CfDef cf_def; + + void __set_cf_def(const CfDef& val) { + cf_def = val; + } + + bool operator == (const Cassandra_system_add_column_family_args & rhs) const + { + if (!(cf_def == rhs.cf_def)) + return false; + return true; + } + bool operator != (const Cassandra_system_add_column_family_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_add_column_family_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_add_column_family_pargs { + public: + + + virtual ~Cassandra_system_add_column_family_pargs() throw() {} + + const CfDef* cf_def; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_add_column_family_result__isset { + _Cassandra_system_add_column_family_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_add_column_family_result__isset; + +class Cassandra_system_add_column_family_result { + public: + + Cassandra_system_add_column_family_result() : success("") { + } + + virtual ~Cassandra_system_add_column_family_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_add_column_family_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_add_column_family_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_add_column_family_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_add_column_family_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_add_column_family_presult__isset { + _Cassandra_system_add_column_family_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_add_column_family_presult__isset; + +class Cassandra_system_add_column_family_presult { + public: + + + virtual ~Cassandra_system_add_column_family_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_add_column_family_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_drop_column_family_args { + public: + + Cassandra_system_drop_column_family_args() : column_family("") { + } + + virtual ~Cassandra_system_drop_column_family_args() throw() {} + + std::string column_family; + + void __set_column_family(const std::string& val) { + column_family = val; + } + + bool operator == (const Cassandra_system_drop_column_family_args & rhs) const + { + if (!(column_family == rhs.column_family)) + return false; + return true; + } + bool operator != (const Cassandra_system_drop_column_family_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_drop_column_family_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_drop_column_family_pargs { + public: + + + virtual ~Cassandra_system_drop_column_family_pargs() throw() {} + + const std::string* column_family; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_drop_column_family_result__isset { + _Cassandra_system_drop_column_family_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_drop_column_family_result__isset; + +class Cassandra_system_drop_column_family_result { + public: + + Cassandra_system_drop_column_family_result() : success("") { + } + + virtual ~Cassandra_system_drop_column_family_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_drop_column_family_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_drop_column_family_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_drop_column_family_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_drop_column_family_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_drop_column_family_presult__isset { + _Cassandra_system_drop_column_family_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_drop_column_family_presult__isset; + +class Cassandra_system_drop_column_family_presult { + public: + + + virtual ~Cassandra_system_drop_column_family_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_drop_column_family_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_add_keyspace_args { + public: + + Cassandra_system_add_keyspace_args() { + } + + virtual ~Cassandra_system_add_keyspace_args() throw() {} + + KsDef ks_def; + + void __set_ks_def(const KsDef& val) { + ks_def = val; + } + + bool operator == (const Cassandra_system_add_keyspace_args & rhs) const + { + if (!(ks_def == rhs.ks_def)) + return false; + return true; + } + bool operator != (const Cassandra_system_add_keyspace_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_add_keyspace_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_add_keyspace_pargs { + public: + + + virtual ~Cassandra_system_add_keyspace_pargs() throw() {} + + const KsDef* ks_def; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_add_keyspace_result__isset { + _Cassandra_system_add_keyspace_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_add_keyspace_result__isset; + +class Cassandra_system_add_keyspace_result { + public: + + Cassandra_system_add_keyspace_result() : success("") { + } + + virtual ~Cassandra_system_add_keyspace_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_add_keyspace_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_add_keyspace_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_add_keyspace_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_add_keyspace_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_add_keyspace_presult__isset { + _Cassandra_system_add_keyspace_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_add_keyspace_presult__isset; + +class Cassandra_system_add_keyspace_presult { + public: + + + virtual ~Cassandra_system_add_keyspace_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_add_keyspace_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_drop_keyspace_args { + public: + + Cassandra_system_drop_keyspace_args() : keyspace("") { + } + + virtual ~Cassandra_system_drop_keyspace_args() throw() {} + + std::string keyspace; + + void __set_keyspace(const std::string& val) { + keyspace = val; + } + + bool operator == (const Cassandra_system_drop_keyspace_args & rhs) const + { + if (!(keyspace == rhs.keyspace)) + return false; + return true; + } + bool operator != (const Cassandra_system_drop_keyspace_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_drop_keyspace_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_drop_keyspace_pargs { + public: + + + virtual ~Cassandra_system_drop_keyspace_pargs() throw() {} + + const std::string* keyspace; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_drop_keyspace_result__isset { + _Cassandra_system_drop_keyspace_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_drop_keyspace_result__isset; + +class Cassandra_system_drop_keyspace_result { + public: + + Cassandra_system_drop_keyspace_result() : success("") { + } + + virtual ~Cassandra_system_drop_keyspace_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_drop_keyspace_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_drop_keyspace_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_drop_keyspace_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_drop_keyspace_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_drop_keyspace_presult__isset { + _Cassandra_system_drop_keyspace_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_drop_keyspace_presult__isset; + +class Cassandra_system_drop_keyspace_presult { + public: + + + virtual ~Cassandra_system_drop_keyspace_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_drop_keyspace_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_update_keyspace_args { + public: + + Cassandra_system_update_keyspace_args() { + } + + virtual ~Cassandra_system_update_keyspace_args() throw() {} + + KsDef ks_def; + + void __set_ks_def(const KsDef& val) { + ks_def = val; + } + + bool operator == (const Cassandra_system_update_keyspace_args & rhs) const + { + if (!(ks_def == rhs.ks_def)) + return false; + return true; + } + bool operator != (const Cassandra_system_update_keyspace_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_update_keyspace_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_update_keyspace_pargs { + public: + + + virtual ~Cassandra_system_update_keyspace_pargs() throw() {} + + const KsDef* ks_def; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_update_keyspace_result__isset { + _Cassandra_system_update_keyspace_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_update_keyspace_result__isset; + +class Cassandra_system_update_keyspace_result { + public: + + Cassandra_system_update_keyspace_result() : success("") { + } + + virtual ~Cassandra_system_update_keyspace_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_update_keyspace_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_update_keyspace_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_update_keyspace_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_update_keyspace_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_update_keyspace_presult__isset { + _Cassandra_system_update_keyspace_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_update_keyspace_presult__isset; + +class Cassandra_system_update_keyspace_presult { + public: + + + virtual ~Cassandra_system_update_keyspace_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_update_keyspace_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_system_update_column_family_args { + public: + + Cassandra_system_update_column_family_args() { + } + + virtual ~Cassandra_system_update_column_family_args() throw() {} + + CfDef cf_def; + + void __set_cf_def(const CfDef& val) { + cf_def = val; + } + + bool operator == (const Cassandra_system_update_column_family_args & rhs) const + { + if (!(cf_def == rhs.cf_def)) + return false; + return true; + } + bool operator != (const Cassandra_system_update_column_family_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_update_column_family_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_system_update_column_family_pargs { + public: + + + virtual ~Cassandra_system_update_column_family_pargs() throw() {} + + const CfDef* cf_def; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_update_column_family_result__isset { + _Cassandra_system_update_column_family_result__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_update_column_family_result__isset; + +class Cassandra_system_update_column_family_result { + public: + + Cassandra_system_update_column_family_result() : success("") { + } + + virtual ~Cassandra_system_update_column_family_result() throw() {} + + std::string success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_update_column_family_result__isset __isset; + + void __set_success(const std::string& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_system_update_column_family_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_system_update_column_family_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_system_update_column_family_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_system_update_column_family_presult__isset { + _Cassandra_system_update_column_family_presult__isset() : success(false), ire(false), sde(false) {} + bool success; + bool ire; + bool sde; +} _Cassandra_system_update_column_family_presult__isset; + +class Cassandra_system_update_column_family_presult { + public: + + + virtual ~Cassandra_system_update_column_family_presult() throw() {} + + std::string* success; + InvalidRequestException ire; + SchemaDisagreementException sde; + + _Cassandra_system_update_column_family_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_execute_cql_query_args { + public: + + Cassandra_execute_cql_query_args() : query(""), compression((Compression::type)0) { + } + + virtual ~Cassandra_execute_cql_query_args() throw() {} + + std::string query; + Compression::type compression; + + void __set_query(const std::string& val) { + query = val; + } + + void __set_compression(const Compression::type val) { + compression = val; + } + + bool operator == (const Cassandra_execute_cql_query_args & rhs) const + { + if (!(query == rhs.query)) + return false; + if (!(compression == rhs.compression)) + return false; + return true; + } + bool operator != (const Cassandra_execute_cql_query_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_execute_cql_query_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_execute_cql_query_pargs { + public: + + + virtual ~Cassandra_execute_cql_query_pargs() throw() {} + + const std::string* query; + const Compression::type* compression; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_execute_cql_query_result__isset { + _Cassandra_execute_cql_query_result__isset() : success(false), ire(false), ue(false), te(false), sde(false) {} + bool success; + bool ire; + bool ue; + bool te; + bool sde; +} _Cassandra_execute_cql_query_result__isset; + +class Cassandra_execute_cql_query_result { + public: + + Cassandra_execute_cql_query_result() { + } + + virtual ~Cassandra_execute_cql_query_result() throw() {} + + CqlResult success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + SchemaDisagreementException sde; + + _Cassandra_execute_cql_query_result__isset __isset; + + void __set_success(const CqlResult& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_execute_cql_query_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_execute_cql_query_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_execute_cql_query_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_execute_cql_query_presult__isset { + _Cassandra_execute_cql_query_presult__isset() : success(false), ire(false), ue(false), te(false), sde(false) {} + bool success; + bool ire; + bool ue; + bool te; + bool sde; +} _Cassandra_execute_cql_query_presult__isset; + +class Cassandra_execute_cql_query_presult { + public: + + + virtual ~Cassandra_execute_cql_query_presult() throw() {} + + CqlResult* success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + SchemaDisagreementException sde; + + _Cassandra_execute_cql_query_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_prepare_cql_query_args { + public: + + Cassandra_prepare_cql_query_args() : query(""), compression((Compression::type)0) { + } + + virtual ~Cassandra_prepare_cql_query_args() throw() {} + + std::string query; + Compression::type compression; + + void __set_query(const std::string& val) { + query = val; + } + + void __set_compression(const Compression::type val) { + compression = val; + } + + bool operator == (const Cassandra_prepare_cql_query_args & rhs) const + { + if (!(query == rhs.query)) + return false; + if (!(compression == rhs.compression)) + return false; + return true; + } + bool operator != (const Cassandra_prepare_cql_query_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_prepare_cql_query_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_prepare_cql_query_pargs { + public: + + + virtual ~Cassandra_prepare_cql_query_pargs() throw() {} + + const std::string* query; + const Compression::type* compression; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_prepare_cql_query_result__isset { + _Cassandra_prepare_cql_query_result__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_prepare_cql_query_result__isset; + +class Cassandra_prepare_cql_query_result { + public: + + Cassandra_prepare_cql_query_result() { + } + + virtual ~Cassandra_prepare_cql_query_result() throw() {} + + CqlPreparedResult success; + InvalidRequestException ire; + + _Cassandra_prepare_cql_query_result__isset __isset; + + void __set_success(const CqlPreparedResult& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_prepare_cql_query_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_prepare_cql_query_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_prepare_cql_query_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_prepare_cql_query_presult__isset { + _Cassandra_prepare_cql_query_presult__isset() : success(false), ire(false) {} + bool success; + bool ire; +} _Cassandra_prepare_cql_query_presult__isset; + +class Cassandra_prepare_cql_query_presult { + public: + + + virtual ~Cassandra_prepare_cql_query_presult() throw() {} + + CqlPreparedResult* success; + InvalidRequestException ire; + + _Cassandra_prepare_cql_query_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_execute_prepared_cql_query_args { + public: + + Cassandra_execute_prepared_cql_query_args() : itemId(0) { + } + + virtual ~Cassandra_execute_prepared_cql_query_args() throw() {} + + int32_t itemId; + std::vector values; + + void __set_itemId(const int32_t val) { + itemId = val; + } + + void __set_values(const std::vector & val) { + values = val; + } + + bool operator == (const Cassandra_execute_prepared_cql_query_args & rhs) const + { + if (!(itemId == rhs.itemId)) + return false; + if (!(values == rhs.values)) + return false; + return true; + } + bool operator != (const Cassandra_execute_prepared_cql_query_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_execute_prepared_cql_query_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_execute_prepared_cql_query_pargs { + public: + + + virtual ~Cassandra_execute_prepared_cql_query_pargs() throw() {} + + const int32_t* itemId; + const std::vector * values; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_execute_prepared_cql_query_result__isset { + _Cassandra_execute_prepared_cql_query_result__isset() : success(false), ire(false), ue(false), te(false), sde(false) {} + bool success; + bool ire; + bool ue; + bool te; + bool sde; +} _Cassandra_execute_prepared_cql_query_result__isset; + +class Cassandra_execute_prepared_cql_query_result { + public: + + Cassandra_execute_prepared_cql_query_result() { + } + + virtual ~Cassandra_execute_prepared_cql_query_result() throw() {} + + CqlResult success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + SchemaDisagreementException sde; + + _Cassandra_execute_prepared_cql_query_result__isset __isset; + + void __set_success(const CqlResult& val) { + success = val; + } + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + void __set_ue(const UnavailableException& val) { + ue = val; + } + + void __set_te(const TimedOutException& val) { + te = val; + } + + void __set_sde(const SchemaDisagreementException& val) { + sde = val; + } + + bool operator == (const Cassandra_execute_prepared_cql_query_result & rhs) const + { + if (!(success == rhs.success)) + return false; + if (!(ire == rhs.ire)) + return false; + if (!(ue == rhs.ue)) + return false; + if (!(te == rhs.te)) + return false; + if (!(sde == rhs.sde)) + return false; + return true; + } + bool operator != (const Cassandra_execute_prepared_cql_query_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_execute_prepared_cql_query_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_execute_prepared_cql_query_presult__isset { + _Cassandra_execute_prepared_cql_query_presult__isset() : success(false), ire(false), ue(false), te(false), sde(false) {} + bool success; + bool ire; + bool ue; + bool te; + bool sde; +} _Cassandra_execute_prepared_cql_query_presult__isset; + +class Cassandra_execute_prepared_cql_query_presult { + public: + + + virtual ~Cassandra_execute_prepared_cql_query_presult() throw() {} + + CqlResult* success; + InvalidRequestException ire; + UnavailableException ue; + TimedOutException te; + SchemaDisagreementException sde; + + _Cassandra_execute_prepared_cql_query_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + + +class Cassandra_set_cql_version_args { + public: + + Cassandra_set_cql_version_args() : version("") { + } + + virtual ~Cassandra_set_cql_version_args() throw() {} + + std::string version; + + void __set_version(const std::string& val) { + version = val; + } + + bool operator == (const Cassandra_set_cql_version_args & rhs) const + { + if (!(version == rhs.version)) + return false; + return true; + } + bool operator != (const Cassandra_set_cql_version_args &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_set_cql_version_args & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class Cassandra_set_cql_version_pargs { + public: + + + virtual ~Cassandra_set_cql_version_pargs() throw() {} + + const std::string* version; + + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_set_cql_version_result__isset { + _Cassandra_set_cql_version_result__isset() : ire(false) {} + bool ire; +} _Cassandra_set_cql_version_result__isset; + +class Cassandra_set_cql_version_result { + public: + + Cassandra_set_cql_version_result() { + } + + virtual ~Cassandra_set_cql_version_result() throw() {} + + InvalidRequestException ire; + + _Cassandra_set_cql_version_result__isset __isset; + + void __set_ire(const InvalidRequestException& val) { + ire = val; + } + + bool operator == (const Cassandra_set_cql_version_result & rhs) const + { + if (!(ire == rhs.ire)) + return false; + return true; + } + bool operator != (const Cassandra_set_cql_version_result &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Cassandra_set_cql_version_result & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Cassandra_set_cql_version_presult__isset { + _Cassandra_set_cql_version_presult__isset() : ire(false) {} + bool ire; +} _Cassandra_set_cql_version_presult__isset; + +class Cassandra_set_cql_version_presult { + public: + + + virtual ~Cassandra_set_cql_version_presult() throw() {} + + InvalidRequestException ire; + + _Cassandra_set_cql_version_presult__isset __isset; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + +}; + +class CassandraClient : virtual public CassandraIf { + public: + CassandraClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) : + piprot_(prot), + poprot_(prot) { + iprot_ = prot.get(); + oprot_ = prot.get(); + } + CassandraClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) : + piprot_(iprot), + poprot_(oprot) { + iprot_ = iprot.get(); + oprot_ = oprot.get(); + } + boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() { + return piprot_; + } + boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() { + return poprot_; + } + void login(const AuthenticationRequest& auth_request); + void send_login(const AuthenticationRequest& auth_request); + void recv_login(); + void set_keyspace(const std::string& keyspace); + void send_set_keyspace(const std::string& keyspace); + void recv_set_keyspace(); + void get(ColumnOrSuperColumn& _return, const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level); + void send_get(const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level); + void recv_get(ColumnOrSuperColumn& _return); + void get_slice(std::vector & _return, const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void send_get_slice(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void recv_get_slice(std::vector & _return); + int32_t get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void send_get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + int32_t recv_get_count(); + void multiget_slice(std::map > & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void send_multiget_slice(const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void recv_multiget_slice(std::map > & _return); + void multiget_count(std::map & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void send_multiget_count(const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level); + void recv_multiget_count(std::map & _return); + void get_range_slices(std::vector & _return, const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level); + void send_get_range_slices(const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level); + void recv_get_range_slices(std::vector & _return); + void get_paged_slice(std::vector & _return, const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level); + void send_get_paged_slice(const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level); + void recv_get_paged_slice(std::vector & _return); + void get_indexed_slices(std::vector & _return, const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level); + void send_get_indexed_slices(const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level); + void recv_get_indexed_slices(std::vector & _return); + void insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level); + void send_insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level); + void recv_insert(); + void add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level); + void send_add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level); + void recv_add(); + void remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level); + void send_remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level); + void recv_remove(); + void remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level); + void send_remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level); + void recv_remove_counter(); + void batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level); + void send_batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level); + void recv_batch_mutate(); + void truncate(const std::string& cfname); + void send_truncate(const std::string& cfname); + void recv_truncate(); + void describe_schema_versions(std::map > & _return); + void send_describe_schema_versions(); + void recv_describe_schema_versions(std::map > & _return); + void describe_keyspaces(std::vector & _return); + void send_describe_keyspaces(); + void recv_describe_keyspaces(std::vector & _return); + void describe_cluster_name(std::string& _return); + void send_describe_cluster_name(); + void recv_describe_cluster_name(std::string& _return); + void describe_version(std::string& _return); + void send_describe_version(); + void recv_describe_version(std::string& _return); + void describe_ring(std::vector & _return, const std::string& keyspace); + void send_describe_ring(const std::string& keyspace); + void recv_describe_ring(std::vector & _return); + void describe_token_map(std::map & _return); + void send_describe_token_map(); + void recv_describe_token_map(std::map & _return); + void describe_partitioner(std::string& _return); + void send_describe_partitioner(); + void recv_describe_partitioner(std::string& _return); + void describe_snitch(std::string& _return); + void send_describe_snitch(); + void recv_describe_snitch(std::string& _return); + void describe_keyspace(KsDef& _return, const std::string& keyspace); + void send_describe_keyspace(const std::string& keyspace); + void recv_describe_keyspace(KsDef& _return); + void describe_splits(std::vector & _return, const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split); + void send_describe_splits(const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split); + void recv_describe_splits(std::vector & _return); + void system_add_column_family(std::string& _return, const CfDef& cf_def); + void send_system_add_column_family(const CfDef& cf_def); + void recv_system_add_column_family(std::string& _return); + void system_drop_column_family(std::string& _return, const std::string& column_family); + void send_system_drop_column_family(const std::string& column_family); + void recv_system_drop_column_family(std::string& _return); + void system_add_keyspace(std::string& _return, const KsDef& ks_def); + void send_system_add_keyspace(const KsDef& ks_def); + void recv_system_add_keyspace(std::string& _return); + void system_drop_keyspace(std::string& _return, const std::string& keyspace); + void send_system_drop_keyspace(const std::string& keyspace); + void recv_system_drop_keyspace(std::string& _return); + void system_update_keyspace(std::string& _return, const KsDef& ks_def); + void send_system_update_keyspace(const KsDef& ks_def); + void recv_system_update_keyspace(std::string& _return); + void system_update_column_family(std::string& _return, const CfDef& cf_def); + void send_system_update_column_family(const CfDef& cf_def); + void recv_system_update_column_family(std::string& _return); + void execute_cql_query(CqlResult& _return, const std::string& query, const Compression::type compression); + void send_execute_cql_query(const std::string& query, const Compression::type compression); + void recv_execute_cql_query(CqlResult& _return); + void prepare_cql_query(CqlPreparedResult& _return, const std::string& query, const Compression::type compression); + void send_prepare_cql_query(const std::string& query, const Compression::type compression); + void recv_prepare_cql_query(CqlPreparedResult& _return); + void execute_prepared_cql_query(CqlResult& _return, const int32_t itemId, const std::vector & values); + void send_execute_prepared_cql_query(const int32_t itemId, const std::vector & values); + void recv_execute_prepared_cql_query(CqlResult& _return); + void set_cql_version(const std::string& version); + void send_set_cql_version(const std::string& version); + void recv_set_cql_version(); + protected: + boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_; + boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_; + ::apache::thrift::protocol::TProtocol* iprot_; + ::apache::thrift::protocol::TProtocol* oprot_; +}; + +class CassandraProcessor : public ::apache::thrift::TProcessor { + protected: + boost::shared_ptr iface_; + virtual bool process_fn(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid, void* callContext); + private: + std::map processMap_; + void process_login(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_set_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get_count(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_multiget_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_multiget_count(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get_range_slices(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get_paged_slice(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_get_indexed_slices(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_insert(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_add(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_remove(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_remove_counter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_batch_mutate(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_truncate(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_schema_versions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_keyspaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_cluster_name(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_version(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_ring(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_token_map(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_partitioner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_snitch(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_describe_splits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_add_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_drop_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_add_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_drop_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_update_keyspace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_system_update_column_family(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_execute_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_prepare_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_execute_prepared_cql_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + void process_set_cql_version(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); + public: + CassandraProcessor(boost::shared_ptr iface) : + iface_(iface) { + processMap_["login"] = &CassandraProcessor::process_login; + processMap_["set_keyspace"] = &CassandraProcessor::process_set_keyspace; + processMap_["get"] = &CassandraProcessor::process_get; + processMap_["get_slice"] = &CassandraProcessor::process_get_slice; + processMap_["get_count"] = &CassandraProcessor::process_get_count; + processMap_["multiget_slice"] = &CassandraProcessor::process_multiget_slice; + processMap_["multiget_count"] = &CassandraProcessor::process_multiget_count; + processMap_["get_range_slices"] = &CassandraProcessor::process_get_range_slices; + processMap_["get_paged_slice"] = &CassandraProcessor::process_get_paged_slice; + processMap_["get_indexed_slices"] = &CassandraProcessor::process_get_indexed_slices; + processMap_["insert"] = &CassandraProcessor::process_insert; + processMap_["add"] = &CassandraProcessor::process_add; + processMap_["remove"] = &CassandraProcessor::process_remove; + processMap_["remove_counter"] = &CassandraProcessor::process_remove_counter; + processMap_["batch_mutate"] = &CassandraProcessor::process_batch_mutate; + processMap_["truncate"] = &CassandraProcessor::process_truncate; + processMap_["describe_schema_versions"] = &CassandraProcessor::process_describe_schema_versions; + processMap_["describe_keyspaces"] = &CassandraProcessor::process_describe_keyspaces; + processMap_["describe_cluster_name"] = &CassandraProcessor::process_describe_cluster_name; + processMap_["describe_version"] = &CassandraProcessor::process_describe_version; + processMap_["describe_ring"] = &CassandraProcessor::process_describe_ring; + processMap_["describe_token_map"] = &CassandraProcessor::process_describe_token_map; + processMap_["describe_partitioner"] = &CassandraProcessor::process_describe_partitioner; + processMap_["describe_snitch"] = &CassandraProcessor::process_describe_snitch; + processMap_["describe_keyspace"] = &CassandraProcessor::process_describe_keyspace; + processMap_["describe_splits"] = &CassandraProcessor::process_describe_splits; + processMap_["system_add_column_family"] = &CassandraProcessor::process_system_add_column_family; + processMap_["system_drop_column_family"] = &CassandraProcessor::process_system_drop_column_family; + processMap_["system_add_keyspace"] = &CassandraProcessor::process_system_add_keyspace; + processMap_["system_drop_keyspace"] = &CassandraProcessor::process_system_drop_keyspace; + processMap_["system_update_keyspace"] = &CassandraProcessor::process_system_update_keyspace; + processMap_["system_update_column_family"] = &CassandraProcessor::process_system_update_column_family; + processMap_["execute_cql_query"] = &CassandraProcessor::process_execute_cql_query; + processMap_["prepare_cql_query"] = &CassandraProcessor::process_prepare_cql_query; + processMap_["execute_prepared_cql_query"] = &CassandraProcessor::process_execute_prepared_cql_query; + processMap_["set_cql_version"] = &CassandraProcessor::process_set_cql_version; + } + + virtual bool process(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot, void* callContext); + virtual ~CassandraProcessor() {} +}; + +class CassandraProcessorFactory : public ::apache::thrift::TProcessorFactory { + public: + CassandraProcessorFactory(const ::boost::shared_ptr< CassandraIfFactory >& handlerFactory) : + handlerFactory_(handlerFactory) {} + + ::boost::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo); + + protected: + ::boost::shared_ptr< CassandraIfFactory > handlerFactory_; +}; + +class CassandraMultiface : virtual public CassandraIf { + public: + CassandraMultiface(std::vector >& ifaces) : ifaces_(ifaces) { + } + virtual ~CassandraMultiface() {} + protected: + std::vector > ifaces_; + CassandraMultiface() {} + void add(boost::shared_ptr iface) { + ifaces_.push_back(iface); + } + public: + void login(const AuthenticationRequest& auth_request) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->login(auth_request); + } + } + + void set_keyspace(const std::string& keyspace) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->set_keyspace(keyspace); + } + } + + void get(ColumnOrSuperColumn& _return, const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->get(_return, key, column_path, consistency_level); + return; + } else { + ifaces_[i]->get(_return, key, column_path, consistency_level); + } + } + } + + void get_slice(std::vector & _return, const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->get_slice(_return, key, column_parent, predicate, consistency_level); + return; + } else { + ifaces_[i]->get_slice(_return, key, column_parent, predicate, consistency_level); + } + } + } + + int32_t get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + return ifaces_[i]->get_count(key, column_parent, predicate, consistency_level); + } else { + ifaces_[i]->get_count(key, column_parent, predicate, consistency_level); + } + } + return 0xDEADBEEF; //psergey: shut up the compiler + } + + void multiget_slice(std::map > & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->multiget_slice(_return, keys, column_parent, predicate, consistency_level); + return; + } else { + ifaces_[i]->multiget_slice(_return, keys, column_parent, predicate, consistency_level); + } + } + } + + void multiget_count(std::map & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->multiget_count(_return, keys, column_parent, predicate, consistency_level); + return; + } else { + ifaces_[i]->multiget_count(_return, keys, column_parent, predicate, consistency_level); + } + } + } + + void get_range_slices(std::vector & _return, const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->get_range_slices(_return, column_parent, predicate, range, consistency_level); + return; + } else { + ifaces_[i]->get_range_slices(_return, column_parent, predicate, range, consistency_level); + } + } + } + + void get_paged_slice(std::vector & _return, const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->get_paged_slice(_return, column_family, range, start_column, consistency_level); + return; + } else { + ifaces_[i]->get_paged_slice(_return, column_family, range, start_column, consistency_level); + } + } + } + + void get_indexed_slices(std::vector & _return, const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->get_indexed_slices(_return, column_parent, index_clause, column_predicate, consistency_level); + return; + } else { + ifaces_[i]->get_indexed_slices(_return, column_parent, index_clause, column_predicate, consistency_level); + } + } + } + + void insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->insert(key, column_parent, column, consistency_level); + } + } + + void add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->add(key, column_parent, column, consistency_level); + } + } + + void remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->remove(key, column_path, timestamp, consistency_level); + } + } + + void remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->remove_counter(key, path, consistency_level); + } + } + + void batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->batch_mutate(mutation_map, consistency_level); + } + } + + void truncate(const std::string& cfname) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->truncate(cfname); + } + } + + void describe_schema_versions(std::map > & _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_schema_versions(_return); + return; + } else { + ifaces_[i]->describe_schema_versions(_return); + } + } + } + + void describe_keyspaces(std::vector & _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_keyspaces(_return); + return; + } else { + ifaces_[i]->describe_keyspaces(_return); + } + } + } + + void describe_cluster_name(std::string& _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_cluster_name(_return); + return; + } else { + ifaces_[i]->describe_cluster_name(_return); + } + } + } + + void describe_version(std::string& _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_version(_return); + return; + } else { + ifaces_[i]->describe_version(_return); + } + } + } + + void describe_ring(std::vector & _return, const std::string& keyspace) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_ring(_return, keyspace); + return; + } else { + ifaces_[i]->describe_ring(_return, keyspace); + } + } + } + + void describe_token_map(std::map & _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_token_map(_return); + return; + } else { + ifaces_[i]->describe_token_map(_return); + } + } + } + + void describe_partitioner(std::string& _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_partitioner(_return); + return; + } else { + ifaces_[i]->describe_partitioner(_return); + } + } + } + + void describe_snitch(std::string& _return) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_snitch(_return); + return; + } else { + ifaces_[i]->describe_snitch(_return); + } + } + } + + void describe_keyspace(KsDef& _return, const std::string& keyspace) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_keyspace(_return, keyspace); + return; + } else { + ifaces_[i]->describe_keyspace(_return, keyspace); + } + } + } + + void describe_splits(std::vector & _return, const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->describe_splits(_return, cfName, start_token, end_token, keys_per_split); + return; + } else { + ifaces_[i]->describe_splits(_return, cfName, start_token, end_token, keys_per_split); + } + } + } + + void system_add_column_family(std::string& _return, const CfDef& cf_def) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_add_column_family(_return, cf_def); + return; + } else { + ifaces_[i]->system_add_column_family(_return, cf_def); + } + } + } + + void system_drop_column_family(std::string& _return, const std::string& column_family) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_drop_column_family(_return, column_family); + return; + } else { + ifaces_[i]->system_drop_column_family(_return, column_family); + } + } + } + + void system_add_keyspace(std::string& _return, const KsDef& ks_def) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_add_keyspace(_return, ks_def); + return; + } else { + ifaces_[i]->system_add_keyspace(_return, ks_def); + } + } + } + + void system_drop_keyspace(std::string& _return, const std::string& keyspace) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_drop_keyspace(_return, keyspace); + return; + } else { + ifaces_[i]->system_drop_keyspace(_return, keyspace); + } + } + } + + void system_update_keyspace(std::string& _return, const KsDef& ks_def) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_update_keyspace(_return, ks_def); + return; + } else { + ifaces_[i]->system_update_keyspace(_return, ks_def); + } + } + } + + void system_update_column_family(std::string& _return, const CfDef& cf_def) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->system_update_column_family(_return, cf_def); + return; + } else { + ifaces_[i]->system_update_column_family(_return, cf_def); + } + } + } + + void execute_cql_query(CqlResult& _return, const std::string& query, const Compression::type compression) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->execute_cql_query(_return, query, compression); + return; + } else { + ifaces_[i]->execute_cql_query(_return, query, compression); + } + } + } + + void prepare_cql_query(CqlPreparedResult& _return, const std::string& query, const Compression::type compression) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->prepare_cql_query(_return, query, compression); + return; + } else { + ifaces_[i]->prepare_cql_query(_return, query, compression); + } + } + } + + void execute_prepared_cql_query(CqlResult& _return, const int32_t itemId, const std::vector & values) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + if (i == sz - 1) { + ifaces_[i]->execute_prepared_cql_query(_return, itemId, values); + return; + } else { + ifaces_[i]->execute_prepared_cql_query(_return, itemId, values); + } + } + } + + void set_cql_version(const std::string& version) { + size_t sz = ifaces_.size(); + for (size_t i = 0; i < sz; ++i) { + ifaces_[i]->set_cql_version(version); + } + } + +}; + +}}} // namespace + +#endif diff --git a/storage/cassandra/gen-cpp/Cassandra_server.skeleton.cpp b/storage/cassandra/gen-cpp/Cassandra_server.skeleton.cpp new file mode 100644 index 00000000000..4d4e489ef4d --- /dev/null +++ b/storage/cassandra/gen-cpp/Cassandra_server.skeleton.cpp @@ -0,0 +1,219 @@ +// This autogenerated skeleton file illustrates how to build a server. +// You should copy it to another filename to avoid overwriting it. + +#include "Cassandra.h" +#include +#include +#include +#include + +using namespace ::apache::thrift; +using namespace ::apache::thrift::protocol; +using namespace ::apache::thrift::transport; +using namespace ::apache::thrift::server; + +using boost::shared_ptr; + +using namespace ::org::apache::cassandra; + +class CassandraHandler : virtual public CassandraIf { + public: + CassandraHandler() { + // Your initialization goes here + } + + void login(const AuthenticationRequest& auth_request) { + // Your implementation goes here + printf("login\n"); + } + + void set_keyspace(const std::string& keyspace) { + // Your implementation goes here + printf("set_keyspace\n"); + } + + void get(ColumnOrSuperColumn& _return, const std::string& key, const ColumnPath& column_path, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get\n"); + } + + void get_slice(std::vector & _return, const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get_slice\n"); + } + + int32_t get_count(const std::string& key, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get_count\n"); + } + + void multiget_slice(std::map > & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("multiget_slice\n"); + } + + void multiget_count(std::map & _return, const std::vector & keys, const ColumnParent& column_parent, const SlicePredicate& predicate, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("multiget_count\n"); + } + + void get_range_slices(std::vector & _return, const ColumnParent& column_parent, const SlicePredicate& predicate, const KeyRange& range, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get_range_slices\n"); + } + + void get_paged_slice(std::vector & _return, const std::string& column_family, const KeyRange& range, const std::string& start_column, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get_paged_slice\n"); + } + + void get_indexed_slices(std::vector & _return, const ColumnParent& column_parent, const IndexClause& index_clause, const SlicePredicate& column_predicate, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("get_indexed_slices\n"); + } + + void insert(const std::string& key, const ColumnParent& column_parent, const Column& column, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("insert\n"); + } + + void add(const std::string& key, const ColumnParent& column_parent, const CounterColumn& column, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("add\n"); + } + + void remove(const std::string& key, const ColumnPath& column_path, const int64_t timestamp, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("remove\n"); + } + + void remove_counter(const std::string& key, const ColumnPath& path, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("remove_counter\n"); + } + + void batch_mutate(const std::map > > & mutation_map, const ConsistencyLevel::type consistency_level) { + // Your implementation goes here + printf("batch_mutate\n"); + } + + void truncate(const std::string& cfname) { + // Your implementation goes here + printf("truncate\n"); + } + + void describe_schema_versions(std::map > & _return) { + // Your implementation goes here + printf("describe_schema_versions\n"); + } + + void describe_keyspaces(std::vector & _return) { + // Your implementation goes here + printf("describe_keyspaces\n"); + } + + void describe_cluster_name(std::string& _return) { + // Your implementation goes here + printf("describe_cluster_name\n"); + } + + void describe_version(std::string& _return) { + // Your implementation goes here + printf("describe_version\n"); + } + + void describe_ring(std::vector & _return, const std::string& keyspace) { + // Your implementation goes here + printf("describe_ring\n"); + } + + void describe_token_map(std::map & _return) { + // Your implementation goes here + printf("describe_token_map\n"); + } + + void describe_partitioner(std::string& _return) { + // Your implementation goes here + printf("describe_partitioner\n"); + } + + void describe_snitch(std::string& _return) { + // Your implementation goes here + printf("describe_snitch\n"); + } + + void describe_keyspace(KsDef& _return, const std::string& keyspace) { + // Your implementation goes here + printf("describe_keyspace\n"); + } + + void describe_splits(std::vector & _return, const std::string& cfName, const std::string& start_token, const std::string& end_token, const int32_t keys_per_split) { + // Your implementation goes here + printf("describe_splits\n"); + } + + void system_add_column_family(std::string& _return, const CfDef& cf_def) { + // Your implementation goes here + printf("system_add_column_family\n"); + } + + void system_drop_column_family(std::string& _return, const std::string& column_family) { + // Your implementation goes here + printf("system_drop_column_family\n"); + } + + void system_add_keyspace(std::string& _return, const KsDef& ks_def) { + // Your implementation goes here + printf("system_add_keyspace\n"); + } + + void system_drop_keyspace(std::string& _return, const std::string& keyspace) { + // Your implementation goes here + printf("system_drop_keyspace\n"); + } + + void system_update_keyspace(std::string& _return, const KsDef& ks_def) { + // Your implementation goes here + printf("system_update_keyspace\n"); + } + + void system_update_column_family(std::string& _return, const CfDef& cf_def) { + // Your implementation goes here + printf("system_update_column_family\n"); + } + + void execute_cql_query(CqlResult& _return, const std::string& query, const Compression::type compression) { + // Your implementation goes here + printf("execute_cql_query\n"); + } + + void prepare_cql_query(CqlPreparedResult& _return, const std::string& query, const Compression::type compression) { + // Your implementation goes here + printf("prepare_cql_query\n"); + } + + void execute_prepared_cql_query(CqlResult& _return, const int32_t itemId, const std::vector & values) { + // Your implementation goes here + printf("execute_prepared_cql_query\n"); + } + + void set_cql_version(const std::string& version) { + // Your implementation goes here + printf("set_cql_version\n"); + } + +}; + +int main(int argc, char **argv) { + int port = 9090; + shared_ptr handler(new CassandraHandler()); + shared_ptr processor(new CassandraProcessor(handler)); + shared_ptr serverTransport(new TServerSocket(port)); + shared_ptr transportFactory(new TBufferedTransportFactory()); + shared_ptr protocolFactory(new TBinaryProtocolFactory()); + + TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); + server.serve(); + return 0; +} + diff --git a/storage/cassandra/gen-cpp/cassandra_constants.cpp b/storage/cassandra/gen-cpp/cassandra_constants.cpp new file mode 100644 index 00000000000..621d39027ad --- /dev/null +++ b/storage/cassandra/gen-cpp/cassandra_constants.cpp @@ -0,0 +1,18 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "cassandra_constants.h" + +namespace org { namespace apache { namespace cassandra { + +const cassandraConstants g_cassandra_constants; + +cassandraConstants::cassandraConstants() { + cassandra_const_VERSION = "19.32.0"; +} + +}}} // namespace + diff --git a/storage/cassandra/gen-cpp/cassandra_constants.h b/storage/cassandra/gen-cpp/cassandra_constants.h new file mode 100644 index 00000000000..fa12a1676ae --- /dev/null +++ b/storage/cassandra/gen-cpp/cassandra_constants.h @@ -0,0 +1,26 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef cassandra_CONSTANTS_H +#define cassandra_CONSTANTS_H + +#include "cassandra_types.h" + +namespace org { namespace apache { namespace cassandra { + +class cassandraConstants { + public: + cassandraConstants(); + +// std::string VERSION; + char* cassandra_const_VERSION; +}; + +extern const cassandraConstants g_cassandra_constants; + +}}} // namespace + +#endif diff --git a/storage/cassandra/gen-cpp/cassandra_types.cpp b/storage/cassandra/gen-cpp/cassandra_types.cpp new file mode 100644 index 00000000000..4b51c21a320 --- /dev/null +++ b/storage/cassandra/gen-cpp/cassandra_types.cpp @@ -0,0 +1,3512 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "cassandra_types.h" + +namespace org { namespace apache { namespace cassandra { + +int _kConsistencyLevelValues[] = { + ConsistencyLevel::ONE, + ConsistencyLevel::QUORUM, + ConsistencyLevel::LOCAL_QUORUM, + ConsistencyLevel::EACH_QUORUM, + ConsistencyLevel::ALL, + ConsistencyLevel::ANY, + ConsistencyLevel::TWO, + ConsistencyLevel::THREE +}; +const char* _kConsistencyLevelNames[] = { + "ONE", + "QUORUM", + "LOCAL_QUORUM", + "EACH_QUORUM", + "ALL", + "ANY", + "TWO", + "THREE" +}; +const std::map _ConsistencyLevel_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(8, _kConsistencyLevelValues, _kConsistencyLevelNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); + +int _kIndexOperatorValues[] = { + IndexOperator::EQ, + IndexOperator::GTE, + IndexOperator::GT, + IndexOperator::LTE, + IndexOperator::LT +}; +const char* _kIndexOperatorNames[] = { + "EQ", + "GTE", + "GT", + "LTE", + "LT" +}; +const std::map _IndexOperator_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(5, _kIndexOperatorValues, _kIndexOperatorNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); + +int _kIndexTypeValues[] = { + IndexType::KEYS, + IndexType::CUSTOM +}; +const char* _kIndexTypeNames[] = { + "KEYS", + "CUSTOM" +}; +const std::map _IndexType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kIndexTypeValues, _kIndexTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); + +int _kCompressionValues[] = { + Compression::GZIP, + Compression::NONE +}; +const char* _kCompressionNames[] = { + "GZIP", + "NONE" +}; +const std::map _Compression_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kCompressionValues, _kCompressionNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); + +int _kCqlResultTypeValues[] = { + CqlResultType::ROWS, + CqlResultType::VOID, + CqlResultType::INT +}; +const char* _kCqlResultTypeNames[] = { + "ROWS", + "VOID", + "INT" +}; +const std::map _CqlResultType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(3, _kCqlResultTypeValues, _kCqlResultTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); + +const char* Column::ascii_fingerprint = "3EE0E1C5C844001B62F08125068292CC"; +const uint8_t Column::binary_fingerprint[16] = {0x3E,0xE0,0xE1,0xC5,0xC8,0x44,0x00,0x1B,0x62,0xF0,0x81,0x25,0x06,0x82,0x92,0xCC}; + +uint32_t Column::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->value); + this->__isset.value = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I64) { + xfer += iprot->readI64(this->timestamp); + this->__isset.timestamp = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->ttl); + this->__isset.ttl = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t Column::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Column"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->name); + xfer += oprot->writeFieldEnd(); + if (this->__isset.value) { + xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeBinary(this->value); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.timestamp) { + xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 3); + xfer += oprot->writeI64(this->timestamp); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.ttl) { + xfer += oprot->writeFieldBegin("ttl", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32(this->ttl); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* SuperColumn::ascii_fingerprint = "470EFC558004E98D92D604898305C04E"; +const uint8_t SuperColumn::binary_fingerprint[16] = {0x47,0x0E,0xFC,0x55,0x80,0x04,0xE9,0x8D,0x92,0xD6,0x04,0x89,0x83,0x05,0xC0,0x4E}; + +uint32_t SuperColumn::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + bool isset_columns = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->columns.clear(); + uint32_t _size0; + ::apache::thrift::protocol::TType _etype3; + iprot->readListBegin(_etype3, _size0); + this->columns.resize(_size0); + uint32_t _i4; + for (_i4 = 0; _i4 < _size0; ++_i4) + { + xfer += this->columns[_i4].read(iprot); + } + iprot->readListEnd(); + } + isset_columns = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_columns) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t SuperColumn::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("SuperColumn"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->columns.size())); + std::vector ::const_iterator _iter5; + for (_iter5 = this->columns.begin(); _iter5 != this->columns.end(); ++_iter5) + { + xfer += (*_iter5).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CounterColumn::ascii_fingerprint = "1CCCF6FC31CFD1D61BBBB1BAF3590620"; +const uint8_t CounterColumn::binary_fingerprint[16] = {0x1C,0xCC,0xF6,0xFC,0x31,0xCF,0xD1,0xD6,0x1B,0xBB,0xB1,0xBA,0xF3,0x59,0x06,0x20}; + +uint32_t CounterColumn::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + bool isset_value = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I64) { + xfer += iprot->readI64(this->value); + isset_value = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_value) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CounterColumn::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CounterColumn"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_I64, 2); + xfer += oprot->writeI64(this->value); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CounterSuperColumn::ascii_fingerprint = "CD4C8C4BF7753E46DE417CDE369343A4"; +const uint8_t CounterSuperColumn::binary_fingerprint[16] = {0xCD,0x4C,0x8C,0x4B,0xF7,0x75,0x3E,0x46,0xDE,0x41,0x7C,0xDE,0x36,0x93,0x43,0xA4}; + +uint32_t CounterSuperColumn::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + bool isset_columns = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->columns.clear(); + uint32_t _size6; + ::apache::thrift::protocol::TType _etype9; + iprot->readListBegin(_etype9, _size6); + this->columns.resize(_size6); + uint32_t _i10; + for (_i10 = 0; _i10 < _size6; ++_i10) + { + xfer += this->columns[_i10].read(iprot); + } + iprot->readListEnd(); + } + isset_columns = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_columns) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CounterSuperColumn::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CounterSuperColumn"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->columns.size())); + std::vector ::const_iterator _iter11; + for (_iter11 = this->columns.begin(); _iter11 != this->columns.end(); ++_iter11) + { + xfer += (*_iter11).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* ColumnOrSuperColumn::ascii_fingerprint = "2B34AC9E80F1DAA3A2A63B1AB1841E61"; +const uint8_t ColumnOrSuperColumn::binary_fingerprint[16] = {0x2B,0x34,0xAC,0x9E,0x80,0xF1,0xDA,0xA3,0xA2,0xA6,0x3B,0x1A,0xB1,0x84,0x1E,0x61}; + +uint32_t ColumnOrSuperColumn::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column.read(iprot); + this->__isset.column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->super_column.read(iprot); + this->__isset.super_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->counter_column.read(iprot); + this->__isset.counter_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->counter_super_column.read(iprot); + this->__isset.counter_super_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t ColumnOrSuperColumn::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("ColumnOrSuperColumn"); + if (this->__isset.column) { + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->column.write(oprot); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.super_column) { + xfer += oprot->writeFieldBegin("super_column", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->super_column.write(oprot); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.counter_column) { + xfer += oprot->writeFieldBegin("counter_column", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->counter_column.write(oprot); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.counter_super_column) { + xfer += oprot->writeFieldBegin("counter_super_column", ::apache::thrift::protocol::T_STRUCT, 4); + xfer += this->counter_super_column.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* NotFoundException::ascii_fingerprint = "99914B932BD37A50B983C5E7C90AE93B"; +const uint8_t NotFoundException::binary_fingerprint[16] = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + +uint32_t NotFoundException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t NotFoundException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("NotFoundException"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* InvalidRequestException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1"; +const uint8_t InvalidRequestException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + +uint32_t InvalidRequestException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_why = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->why); + isset_why = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_why) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t InvalidRequestException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("InvalidRequestException"); + xfer += oprot->writeFieldBegin("why", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->why); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* UnavailableException::ascii_fingerprint = "99914B932BD37A50B983C5E7C90AE93B"; +const uint8_t UnavailableException::binary_fingerprint[16] = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + +uint32_t UnavailableException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t UnavailableException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("UnavailableException"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* TimedOutException::ascii_fingerprint = "99914B932BD37A50B983C5E7C90AE93B"; +const uint8_t TimedOutException::binary_fingerprint[16] = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + +uint32_t TimedOutException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t TimedOutException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("TimedOutException"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* AuthenticationException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1"; +const uint8_t AuthenticationException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + +uint32_t AuthenticationException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_why = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->why); + isset_why = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_why) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t AuthenticationException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("AuthenticationException"); + xfer += oprot->writeFieldBegin("why", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->why); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* AuthorizationException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1"; +const uint8_t AuthorizationException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + +uint32_t AuthorizationException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_why = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->why); + isset_why = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_why) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t AuthorizationException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("AuthorizationException"); + xfer += oprot->writeFieldBegin("why", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->why); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* SchemaDisagreementException::ascii_fingerprint = "99914B932BD37A50B983C5E7C90AE93B"; +const uint8_t SchemaDisagreementException::binary_fingerprint[16] = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + +uint32_t SchemaDisagreementException::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t SchemaDisagreementException::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("SchemaDisagreementException"); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* ColumnParent::ascii_fingerprint = "0A13AE61181713A4100DFFB3EC293822"; +const uint8_t ColumnParent::binary_fingerprint[16] = {0x0A,0x13,0xAE,0x61,0x18,0x17,0x13,0xA4,0x10,0x0D,0xFF,0xB3,0xEC,0x29,0x38,0x22}; + +uint32_t ColumnParent::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_family = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->column_family); + isset_column_family = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->super_column); + this->__isset.super_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_family) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t ColumnParent::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("ColumnParent"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->column_family); + xfer += oprot->writeFieldEnd(); + if (this->__isset.super_column) { + xfer += oprot->writeFieldBegin("super_column", ::apache::thrift::protocol::T_STRING, 4); + xfer += oprot->writeBinary(this->super_column); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* ColumnPath::ascii_fingerprint = "606212895BCF63C757913CF35AEB3462"; +const uint8_t ColumnPath::binary_fingerprint[16] = {0x60,0x62,0x12,0x89,0x5B,0xCF,0x63,0xC7,0x57,0x91,0x3C,0xF3,0x5A,0xEB,0x34,0x62}; + +uint32_t ColumnPath::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_family = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->column_family); + isset_column_family = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->super_column); + this->__isset.super_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->column); + this->__isset.column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_family) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t ColumnPath::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("ColumnPath"); + xfer += oprot->writeFieldBegin("column_family", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->column_family); + xfer += oprot->writeFieldEnd(); + if (this->__isset.super_column) { + xfer += oprot->writeFieldBegin("super_column", ::apache::thrift::protocol::T_STRING, 4); + xfer += oprot->writeBinary(this->super_column); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.column) { + xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRING, 5); + xfer += oprot->writeBinary(this->column); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* SliceRange::ascii_fingerprint = "184D24C9A0B8D4415E234DB649CAE740"; +const uint8_t SliceRange::binary_fingerprint[16] = {0x18,0x4D,0x24,0xC9,0xA0,0xB8,0xD4,0x41,0x5E,0x23,0x4D,0xB6,0x49,0xCA,0xE7,0x40}; + +uint32_t SliceRange::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_start = false; + bool isset_finish = false; + bool isset_reversed = false; + bool isset_count = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->start); + isset_start = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->finish); + isset_finish = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_BOOL) { + xfer += iprot->readBool(this->reversed); + isset_reversed = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->count); + isset_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_start) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_finish) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_reversed) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_count) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t SliceRange::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("SliceRange"); + xfer += oprot->writeFieldBegin("start", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->start); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("finish", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeBinary(this->finish); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("reversed", ::apache::thrift::protocol::T_BOOL, 3); + xfer += oprot->writeBool(this->reversed); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("count", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32(this->count); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* SlicePredicate::ascii_fingerprint = "F59D1D81C17DFFAF09988BF1C9CE5E27"; +const uint8_t SlicePredicate::binary_fingerprint[16] = {0xF5,0x9D,0x1D,0x81,0xC1,0x7D,0xFF,0xAF,0x09,0x98,0x8B,0xF1,0xC9,0xCE,0x5E,0x27}; + +uint32_t SlicePredicate::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->column_names.clear(); + uint32_t _size12; + ::apache::thrift::protocol::TType _etype15; + iprot->readListBegin(_etype15, _size12); + this->column_names.resize(_size12); + uint32_t _i16; + for (_i16 = 0; _i16 < _size12; ++_i16) + { + xfer += iprot->readBinary(this->column_names[_i16]); + } + iprot->readListEnd(); + } + this->__isset.column_names = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->slice_range.read(iprot); + this->__isset.slice_range = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t SlicePredicate::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("SlicePredicate"); + if (this->__isset.column_names) { + xfer += oprot->writeFieldBegin("column_names", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->column_names.size())); + std::vector ::const_iterator _iter17; + for (_iter17 = this->column_names.begin(); _iter17 != this->column_names.end(); ++_iter17) + { + xfer += oprot->writeBinary((*_iter17)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.slice_range) { + xfer += oprot->writeFieldBegin("slice_range", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->slice_range.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* IndexExpression::ascii_fingerprint = "D9F4CFE2F293A8B1052FD3031DD2C847"; +const uint8_t IndexExpression::binary_fingerprint[16] = {0xD9,0xF4,0xCF,0xE2,0xF2,0x93,0xA8,0xB1,0x05,0x2F,0xD3,0x03,0x1D,0xD2,0xC8,0x47}; + +uint32_t IndexExpression::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_column_name = false; + bool isset_op = false; + bool isset_value = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->column_name); + isset_column_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast18; + xfer += iprot->readI32(ecast18); + this->op = (IndexOperator::type)ecast18; + isset_op = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->value); + isset_value = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_column_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_op) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_value) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t IndexExpression::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("IndexExpression"); + xfer += oprot->writeFieldBegin("column_name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->column_name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("op", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32((int32_t)this->op); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeBinary(this->value); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* IndexClause::ascii_fingerprint = "9B551B9AB86120B0EEA9005C77FD3C1F"; +const uint8_t IndexClause::binary_fingerprint[16] = {0x9B,0x55,0x1B,0x9A,0xB8,0x61,0x20,0xB0,0xEE,0xA9,0x00,0x5C,0x77,0xFD,0x3C,0x1F}; + +uint32_t IndexClause::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_expressions = false; + bool isset_start_key = false; + bool isset_count = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->expressions.clear(); + uint32_t _size19; + ::apache::thrift::protocol::TType _etype22; + iprot->readListBegin(_etype22, _size19); + this->expressions.resize(_size19); + uint32_t _i23; + for (_i23 = 0; _i23 < _size19; ++_i23) + { + xfer += this->expressions[_i23].read(iprot); + } + iprot->readListEnd(); + } + isset_expressions = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->start_key); + isset_start_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->count); + isset_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_expressions) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_start_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_count) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t IndexClause::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("IndexClause"); + xfer += oprot->writeFieldBegin("expressions", ::apache::thrift::protocol::T_LIST, 1); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->expressions.size())); + std::vector ::const_iterator _iter24; + for (_iter24 = this->expressions.begin(); _iter24 != this->expressions.end(); ++_iter24) + { + xfer += (*_iter24).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("start_key", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeBinary(this->start_key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("count", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32(this->count); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* KeyRange::ascii_fingerprint = "A6EC82FA0980B91C7C8EB013C61CA1B0"; +const uint8_t KeyRange::binary_fingerprint[16] = {0xA6,0xEC,0x82,0xFA,0x09,0x80,0xB9,0x1C,0x7C,0x8E,0xB0,0x13,0xC6,0x1C,0xA1,0xB0}; + +uint32_t KeyRange::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_count = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->start_key); + this->__isset.start_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->end_key); + this->__isset.end_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->start_token); + this->__isset.start_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->end_token); + this->__isset.end_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 6: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->row_filter.clear(); + uint32_t _size25; + ::apache::thrift::protocol::TType _etype28; + iprot->readListBegin(_etype28, _size25); + this->row_filter.resize(_size25); + uint32_t _i29; + for (_i29 = 0; _i29 < _size25; ++_i29) + { + xfer += this->row_filter[_i29].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.row_filter = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->count); + isset_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_count) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t KeyRange::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("KeyRange"); + if (this->__isset.start_key) { + xfer += oprot->writeFieldBegin("start_key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->start_key); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.end_key) { + xfer += oprot->writeFieldBegin("end_key", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeBinary(this->end_key); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.start_token) { + xfer += oprot->writeFieldBegin("start_token", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->start_token); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.end_token) { + xfer += oprot->writeFieldBegin("end_token", ::apache::thrift::protocol::T_STRING, 4); + xfer += oprot->writeString(this->end_token); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldBegin("count", ::apache::thrift::protocol::T_I32, 5); + xfer += oprot->writeI32(this->count); + xfer += oprot->writeFieldEnd(); + if (this->__isset.row_filter) { + xfer += oprot->writeFieldBegin("row_filter", ::apache::thrift::protocol::T_LIST, 6); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->row_filter.size())); + std::vector ::const_iterator _iter30; + for (_iter30 = this->row_filter.begin(); _iter30 != this->row_filter.end(); ++_iter30) + { + xfer += (*_iter30).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* KeySlice::ascii_fingerprint = "D1568675B0C135C909E3169B72A4DA3D"; +const uint8_t KeySlice::binary_fingerprint[16] = {0xD1,0x56,0x86,0x75,0xB0,0xC1,0x35,0xC9,0x09,0xE3,0x16,0x9B,0x72,0xA4,0xDA,0x3D}; + +uint32_t KeySlice::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_columns = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->columns.clear(); + uint32_t _size31; + ::apache::thrift::protocol::TType _etype34; + iprot->readListBegin(_etype34, _size31); + this->columns.resize(_size31); + uint32_t _i35; + for (_i35 = 0; _i35 < _size31; ++_i35) + { + xfer += this->columns[_i35].read(iprot); + } + iprot->readListEnd(); + } + isset_columns = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_columns) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t KeySlice::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("KeySlice"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->columns.size())); + std::vector ::const_iterator _iter36; + for (_iter36 = this->columns.begin(); _iter36 != this->columns.end(); ++_iter36) + { + xfer += (*_iter36).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* KeyCount::ascii_fingerprint = "EEBC915CE44901401D881E6091423036"; +const uint8_t KeyCount::binary_fingerprint[16] = {0xEE,0xBC,0x91,0x5C,0xE4,0x49,0x01,0x40,0x1D,0x88,0x1E,0x60,0x91,0x42,0x30,0x36}; + +uint32_t KeyCount::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_count = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->count); + isset_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_count) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t KeyCount::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("KeyCount"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("count", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32(this->count); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* Deletion::ascii_fingerprint = "40F33ECF1C932CA77C2414C4E6C60CBE"; +const uint8_t Deletion::binary_fingerprint[16] = {0x40,0xF3,0x3E,0xCF,0x1C,0x93,0x2C,0xA7,0x7C,0x24,0x14,0xC4,0xE6,0xC6,0x0C,0xBE}; + +uint32_t Deletion::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_I64) { + xfer += iprot->readI64(this->timestamp); + this->__isset.timestamp = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->super_column); + this->__isset.super_column = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->predicate.read(iprot); + this->__isset.predicate = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Deletion::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Deletion"); + if (this->__isset.timestamp) { + xfer += oprot->writeFieldBegin("timestamp", ::apache::thrift::protocol::T_I64, 1); + xfer += oprot->writeI64(this->timestamp); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.super_column) { + xfer += oprot->writeFieldBegin("super_column", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeBinary(this->super_column); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.predicate) { + xfer += oprot->writeFieldBegin("predicate", ::apache::thrift::protocol::T_STRUCT, 3); + xfer += this->predicate.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* Mutation::ascii_fingerprint = "E8B65DF3979C6868F80DF81F8E769E63"; +const uint8_t Mutation::binary_fingerprint[16] = {0xE8,0xB6,0x5D,0xF3,0x97,0x9C,0x68,0x68,0xF8,0x0D,0xF8,0x1F,0x8E,0x76,0x9E,0x63}; + +uint32_t Mutation::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->column_or_supercolumn.read(iprot); + this->__isset.column_or_supercolumn = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->deletion.read(iprot); + this->__isset.deletion = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Mutation::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("Mutation"); + if (this->__isset.column_or_supercolumn) { + xfer += oprot->writeFieldBegin("column_or_supercolumn", ::apache::thrift::protocol::T_STRUCT, 1); + xfer += this->column_or_supercolumn.write(oprot); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.deletion) { + xfer += oprot->writeFieldBegin("deletion", ::apache::thrift::protocol::T_STRUCT, 2); + xfer += this->deletion.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* EndpointDetails::ascii_fingerprint = "F4A50F0EC638C7F66026F9B6678FD89B"; +const uint8_t EndpointDetails::binary_fingerprint[16] = {0xF4,0xA5,0x0F,0x0E,0xC6,0x38,0xC7,0xF6,0x60,0x26,0xF9,0xB6,0x67,0x8F,0xD8,0x9B}; + +uint32_t EndpointDetails::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->host); + this->__isset.host = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->datacenter); + this->__isset.datacenter = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->rack); + this->__isset.rack = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t EndpointDetails::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("EndpointDetails"); + xfer += oprot->writeFieldBegin("host", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->host); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("datacenter", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->datacenter); + xfer += oprot->writeFieldEnd(); + if (this->__isset.rack) { + xfer += oprot->writeFieldBegin("rack", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->rack); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* TokenRange::ascii_fingerprint = "832268DC4CD6B17EE8881FC57EA04679"; +const uint8_t TokenRange::binary_fingerprint[16] = {0x83,0x22,0x68,0xDC,0x4C,0xD6,0xB1,0x7E,0xE8,0x88,0x1F,0xC5,0x7E,0xA0,0x46,0x79}; + +uint32_t TokenRange::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_start_token = false; + bool isset_end_token = false; + bool isset_endpoints = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->start_token); + isset_start_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->end_token); + isset_end_token = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->endpoints.clear(); + uint32_t _size37; + ::apache::thrift::protocol::TType _etype40; + iprot->readListBegin(_etype40, _size37); + this->endpoints.resize(_size37); + uint32_t _i41; + for (_i41 = 0; _i41 < _size37; ++_i41) + { + xfer += iprot->readString(this->endpoints[_i41]); + } + iprot->readListEnd(); + } + isset_endpoints = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->rpc_endpoints.clear(); + uint32_t _size42; + ::apache::thrift::protocol::TType _etype45; + iprot->readListBegin(_etype45, _size42); + this->rpc_endpoints.resize(_size42); + uint32_t _i46; + for (_i46 = 0; _i46 < _size42; ++_i46) + { + xfer += iprot->readString(this->rpc_endpoints[_i46]); + } + iprot->readListEnd(); + } + this->__isset.rpc_endpoints = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->endpoint_details.clear(); + uint32_t _size47; + ::apache::thrift::protocol::TType _etype50; + iprot->readListBegin(_etype50, _size47); + this->endpoint_details.resize(_size47); + uint32_t _i51; + for (_i51 = 0; _i51 < _size47; ++_i51) + { + xfer += this->endpoint_details[_i51].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.endpoint_details = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_start_token) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_end_token) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_endpoints) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t TokenRange::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("TokenRange"); + xfer += oprot->writeFieldBegin("start_token", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->start_token); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("end_token", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->end_token); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("endpoints", ::apache::thrift::protocol::T_LIST, 3); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->endpoints.size())); + std::vector ::const_iterator _iter52; + for (_iter52 = this->endpoints.begin(); _iter52 != this->endpoints.end(); ++_iter52) + { + xfer += oprot->writeString((*_iter52)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + if (this->__isset.rpc_endpoints) { + xfer += oprot->writeFieldBegin("rpc_endpoints", ::apache::thrift::protocol::T_LIST, 4); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->rpc_endpoints.size())); + std::vector ::const_iterator _iter53; + for (_iter53 = this->rpc_endpoints.begin(); _iter53 != this->rpc_endpoints.end(); ++_iter53) + { + xfer += oprot->writeString((*_iter53)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.endpoint_details) { + xfer += oprot->writeFieldBegin("endpoint_details", ::apache::thrift::protocol::T_LIST, 5); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->endpoint_details.size())); + std::vector ::const_iterator _iter54; + for (_iter54 = this->endpoint_details.begin(); _iter54 != this->endpoint_details.end(); ++_iter54) + { + xfer += (*_iter54).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* AuthenticationRequest::ascii_fingerprint = "5EA2D527ECA3BA20C77AFC023EE8C05F"; +const uint8_t AuthenticationRequest::binary_fingerprint[16] = {0x5E,0xA2,0xD5,0x27,0xEC,0xA3,0xBA,0x20,0xC7,0x7A,0xFC,0x02,0x3E,0xE8,0xC0,0x5F}; + +uint32_t AuthenticationRequest::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_credentials = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->credentials.clear(); + uint32_t _size55; + ::apache::thrift::protocol::TType _ktype56; + ::apache::thrift::protocol::TType _vtype57; + iprot->readMapBegin(_ktype56, _vtype57, _size55); + uint32_t _i59; + for (_i59 = 0; _i59 < _size55; ++_i59) + { + std::string _key60; + xfer += iprot->readString(_key60); + std::string& _val61 = this->credentials[_key60]; + xfer += iprot->readString(_val61); + } + iprot->readMapEnd(); + } + isset_credentials = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_credentials) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t AuthenticationRequest::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("AuthenticationRequest"); + xfer += oprot->writeFieldBegin("credentials", ::apache::thrift::protocol::T_MAP, 1); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->credentials.size())); + std::map ::const_iterator _iter62; + for (_iter62 = this->credentials.begin(); _iter62 != this->credentials.end(); ++_iter62) + { + xfer += oprot->writeString(_iter62->first); + xfer += oprot->writeString(_iter62->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* ColumnDef::ascii_fingerprint = "0D89CE83D7EDAD079AC3213ED1DCAA58"; +const uint8_t ColumnDef::binary_fingerprint[16] = {0x0D,0x89,0xCE,0x83,0xD7,0xED,0xAD,0x07,0x9A,0xC3,0x21,0x3E,0xD1,0xDC,0xAA,0x58}; + +uint32_t ColumnDef::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + bool isset_validation_class = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->validation_class); + isset_validation_class = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast63; + xfer += iprot->readI32(ecast63); + this->index_type = (IndexType::type)ecast63; + this->__isset.index_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->index_name); + this->__isset.index_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->index_options.clear(); + uint32_t _size64; + ::apache::thrift::protocol::TType _ktype65; + ::apache::thrift::protocol::TType _vtype66; + iprot->readMapBegin(_ktype65, _vtype66, _size64); + uint32_t _i68; + for (_i68 = 0; _i68 < _size64; ++_i68) + { + std::string _key69; + xfer += iprot->readString(_key69); + std::string& _val70 = this->index_options[_key69]; + xfer += iprot->readString(_val70); + } + iprot->readMapEnd(); + } + this->__isset.index_options = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_validation_class) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t ColumnDef::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("ColumnDef"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("validation_class", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->validation_class); + xfer += oprot->writeFieldEnd(); + if (this->__isset.index_type) { + xfer += oprot->writeFieldBegin("index_type", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32((int32_t)this->index_type); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.index_name) { + xfer += oprot->writeFieldBegin("index_name", ::apache::thrift::protocol::T_STRING, 4); + xfer += oprot->writeString(this->index_name); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.index_options) { + xfer += oprot->writeFieldBegin("index_options", ::apache::thrift::protocol::T_MAP, 5); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->index_options.size())); + std::map ::const_iterator _iter71; + for (_iter71 = this->index_options.begin(); _iter71 != this->index_options.end(); ++_iter71) + { + xfer += oprot->writeString(_iter71->first); + xfer += oprot->writeString(_iter71->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CfDef::ascii_fingerprint = "231A260521B5DD99EFBCCBDD8768CA7D"; +const uint8_t CfDef::binary_fingerprint[16] = {0x23,0x1A,0x26,0x05,0x21,0xB5,0xDD,0x99,0xEF,0xBC,0xCB,0xDD,0x87,0x68,0xCA,0x7D}; + +uint32_t CfDef::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_keyspace = false; + bool isset_name = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->keyspace); + isset_keyspace = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->column_type); + this->__isset.column_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->comparator_type); + this->__isset.comparator_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 6: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->subcomparator_type); + this->__isset.subcomparator_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 8: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->comment); + this->__isset.comment = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 12: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->read_repair_chance); + this->__isset.read_repair_chance = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 13: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->column_metadata.clear(); + uint32_t _size72; + ::apache::thrift::protocol::TType _etype75; + iprot->readListBegin(_etype75, _size72); + this->column_metadata.resize(_size72); + uint32_t _i76; + for (_i76 = 0; _i76 < _size72; ++_i76) + { + xfer += this->column_metadata[_i76].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.column_metadata = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 14: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->gc_grace_seconds); + this->__isset.gc_grace_seconds = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 15: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->default_validation_class); + this->__isset.default_validation_class = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 16: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->id); + this->__isset.id = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 17: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->min_compaction_threshold); + this->__isset.min_compaction_threshold = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 18: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->max_compaction_threshold); + this->__isset.max_compaction_threshold = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 24: + if (ftype == ::apache::thrift::protocol::T_BOOL) { + xfer += iprot->readBool(this->replicate_on_write); + this->__isset.replicate_on_write = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 26: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->key_validation_class); + this->__isset.key_validation_class = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 28: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key_alias); + this->__isset.key_alias = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 29: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->compaction_strategy); + this->__isset.compaction_strategy = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 30: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->compaction_strategy_options.clear(); + uint32_t _size77; + ::apache::thrift::protocol::TType _ktype78; + ::apache::thrift::protocol::TType _vtype79; + iprot->readMapBegin(_ktype78, _vtype79, _size77); + uint32_t _i81; + for (_i81 = 0; _i81 < _size77; ++_i81) + { + std::string _key82; + xfer += iprot->readString(_key82); + std::string& _val83 = this->compaction_strategy_options[_key82]; + xfer += iprot->readString(_val83); + } + iprot->readMapEnd(); + } + this->__isset.compaction_strategy_options = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 32: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->compression_options.clear(); + uint32_t _size84; + ::apache::thrift::protocol::TType _ktype85; + ::apache::thrift::protocol::TType _vtype86; + iprot->readMapBegin(_ktype85, _vtype86, _size84); + uint32_t _i88; + for (_i88 = 0; _i88 < _size84; ++_i88) + { + std::string _key89; + xfer += iprot->readString(_key89); + std::string& _val90 = this->compression_options[_key89]; + xfer += iprot->readString(_val90); + } + iprot->readMapEnd(); + } + this->__isset.compression_options = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 33: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->bloom_filter_fp_chance); + this->__isset.bloom_filter_fp_chance = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 34: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->caching); + this->__isset.caching = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 37: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->dclocal_read_repair_chance); + this->__isset.dclocal_read_repair_chance = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 9: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->row_cache_size); + this->__isset.row_cache_size = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 11: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->key_cache_size); + this->__isset.key_cache_size = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 19: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->row_cache_save_period_in_seconds); + this->__isset.row_cache_save_period_in_seconds = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 20: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->key_cache_save_period_in_seconds); + this->__isset.key_cache_save_period_in_seconds = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 21: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->memtable_flush_after_mins); + this->__isset.memtable_flush_after_mins = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 22: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->memtable_throughput_in_mb); + this->__isset.memtable_throughput_in_mb = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 23: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->memtable_operations_in_millions); + this->__isset.memtable_operations_in_millions = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 25: + if (ftype == ::apache::thrift::protocol::T_DOUBLE) { + xfer += iprot->readDouble(this->merge_shards_chance); + this->__isset.merge_shards_chance = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 27: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->row_cache_provider); + this->__isset.row_cache_provider = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 31: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->row_cache_keys_to_save); + this->__isset.row_cache_keys_to_save = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_keyspace) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CfDef::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CfDef"); + xfer += oprot->writeFieldBegin("keyspace", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->keyspace); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->name); + xfer += oprot->writeFieldEnd(); + if (this->__isset.column_type) { + xfer += oprot->writeFieldBegin("column_type", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->column_type); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.comparator_type) { + xfer += oprot->writeFieldBegin("comparator_type", ::apache::thrift::protocol::T_STRING, 5); + xfer += oprot->writeString(this->comparator_type); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.subcomparator_type) { + xfer += oprot->writeFieldBegin("subcomparator_type", ::apache::thrift::protocol::T_STRING, 6); + xfer += oprot->writeString(this->subcomparator_type); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.comment) { + xfer += oprot->writeFieldBegin("comment", ::apache::thrift::protocol::T_STRING, 8); + xfer += oprot->writeString(this->comment); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.row_cache_size) { + xfer += oprot->writeFieldBegin("row_cache_size", ::apache::thrift::protocol::T_DOUBLE, 9); + xfer += oprot->writeDouble(this->row_cache_size); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.key_cache_size) { + xfer += oprot->writeFieldBegin("key_cache_size", ::apache::thrift::protocol::T_DOUBLE, 11); + xfer += oprot->writeDouble(this->key_cache_size); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.read_repair_chance) { + xfer += oprot->writeFieldBegin("read_repair_chance", ::apache::thrift::protocol::T_DOUBLE, 12); + xfer += oprot->writeDouble(this->read_repair_chance); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.column_metadata) { + xfer += oprot->writeFieldBegin("column_metadata", ::apache::thrift::protocol::T_LIST, 13); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->column_metadata.size())); + std::vector ::const_iterator _iter91; + for (_iter91 = this->column_metadata.begin(); _iter91 != this->column_metadata.end(); ++_iter91) + { + xfer += (*_iter91).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.gc_grace_seconds) { + xfer += oprot->writeFieldBegin("gc_grace_seconds", ::apache::thrift::protocol::T_I32, 14); + xfer += oprot->writeI32(this->gc_grace_seconds); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.default_validation_class) { + xfer += oprot->writeFieldBegin("default_validation_class", ::apache::thrift::protocol::T_STRING, 15); + xfer += oprot->writeString(this->default_validation_class); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.id) { + xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I32, 16); + xfer += oprot->writeI32(this->id); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.min_compaction_threshold) { + xfer += oprot->writeFieldBegin("min_compaction_threshold", ::apache::thrift::protocol::T_I32, 17); + xfer += oprot->writeI32(this->min_compaction_threshold); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.max_compaction_threshold) { + xfer += oprot->writeFieldBegin("max_compaction_threshold", ::apache::thrift::protocol::T_I32, 18); + xfer += oprot->writeI32(this->max_compaction_threshold); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.row_cache_save_period_in_seconds) { + xfer += oprot->writeFieldBegin("row_cache_save_period_in_seconds", ::apache::thrift::protocol::T_I32, 19); + xfer += oprot->writeI32(this->row_cache_save_period_in_seconds); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.key_cache_save_period_in_seconds) { + xfer += oprot->writeFieldBegin("key_cache_save_period_in_seconds", ::apache::thrift::protocol::T_I32, 20); + xfer += oprot->writeI32(this->key_cache_save_period_in_seconds); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.memtable_flush_after_mins) { + xfer += oprot->writeFieldBegin("memtable_flush_after_mins", ::apache::thrift::protocol::T_I32, 21); + xfer += oprot->writeI32(this->memtable_flush_after_mins); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.memtable_throughput_in_mb) { + xfer += oprot->writeFieldBegin("memtable_throughput_in_mb", ::apache::thrift::protocol::T_I32, 22); + xfer += oprot->writeI32(this->memtable_throughput_in_mb); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.memtable_operations_in_millions) { + xfer += oprot->writeFieldBegin("memtable_operations_in_millions", ::apache::thrift::protocol::T_DOUBLE, 23); + xfer += oprot->writeDouble(this->memtable_operations_in_millions); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.replicate_on_write) { + xfer += oprot->writeFieldBegin("replicate_on_write", ::apache::thrift::protocol::T_BOOL, 24); + xfer += oprot->writeBool(this->replicate_on_write); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.merge_shards_chance) { + xfer += oprot->writeFieldBegin("merge_shards_chance", ::apache::thrift::protocol::T_DOUBLE, 25); + xfer += oprot->writeDouble(this->merge_shards_chance); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.key_validation_class) { + xfer += oprot->writeFieldBegin("key_validation_class", ::apache::thrift::protocol::T_STRING, 26); + xfer += oprot->writeString(this->key_validation_class); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.row_cache_provider) { + xfer += oprot->writeFieldBegin("row_cache_provider", ::apache::thrift::protocol::T_STRING, 27); + xfer += oprot->writeString(this->row_cache_provider); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.key_alias) { + xfer += oprot->writeFieldBegin("key_alias", ::apache::thrift::protocol::T_STRING, 28); + xfer += oprot->writeBinary(this->key_alias); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.compaction_strategy) { + xfer += oprot->writeFieldBegin("compaction_strategy", ::apache::thrift::protocol::T_STRING, 29); + xfer += oprot->writeString(this->compaction_strategy); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.compaction_strategy_options) { + xfer += oprot->writeFieldBegin("compaction_strategy_options", ::apache::thrift::protocol::T_MAP, 30); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->compaction_strategy_options.size())); + std::map ::const_iterator _iter92; + for (_iter92 = this->compaction_strategy_options.begin(); _iter92 != this->compaction_strategy_options.end(); ++_iter92) + { + xfer += oprot->writeString(_iter92->first); + xfer += oprot->writeString(_iter92->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.row_cache_keys_to_save) { + xfer += oprot->writeFieldBegin("row_cache_keys_to_save", ::apache::thrift::protocol::T_I32, 31); + xfer += oprot->writeI32(this->row_cache_keys_to_save); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.compression_options) { + xfer += oprot->writeFieldBegin("compression_options", ::apache::thrift::protocol::T_MAP, 32); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->compression_options.size())); + std::map ::const_iterator _iter93; + for (_iter93 = this->compression_options.begin(); _iter93 != this->compression_options.end(); ++_iter93) + { + xfer += oprot->writeString(_iter93->first); + xfer += oprot->writeString(_iter93->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.bloom_filter_fp_chance) { + xfer += oprot->writeFieldBegin("bloom_filter_fp_chance", ::apache::thrift::protocol::T_DOUBLE, 33); + xfer += oprot->writeDouble(this->bloom_filter_fp_chance); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.caching) { + xfer += oprot->writeFieldBegin("caching", ::apache::thrift::protocol::T_STRING, 34); + xfer += oprot->writeString(this->caching); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.dclocal_read_repair_chance) { + xfer += oprot->writeFieldBegin("dclocal_read_repair_chance", ::apache::thrift::protocol::T_DOUBLE, 37); + xfer += oprot->writeDouble(this->dclocal_read_repair_chance); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* KsDef::ascii_fingerprint = "0767851B6476EB3777A21E59E912E11A"; +const uint8_t KsDef::binary_fingerprint[16] = {0x07,0x67,0x85,0x1B,0x64,0x76,0xEB,0x37,0x77,0xA2,0x1E,0x59,0xE9,0x12,0xE1,0x1A}; + +uint32_t KsDef::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name = false; + bool isset_strategy_class = false; + bool isset_cf_defs = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->name); + isset_name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->strategy_class); + isset_strategy_class = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->strategy_options.clear(); + uint32_t _size94; + ::apache::thrift::protocol::TType _ktype95; + ::apache::thrift::protocol::TType _vtype96; + iprot->readMapBegin(_ktype95, _vtype96, _size94); + uint32_t _i98; + for (_i98 = 0; _i98 < _size94; ++_i98) + { + std::string _key99; + xfer += iprot->readString(_key99); + std::string& _val100 = this->strategy_options[_key99]; + xfer += iprot->readString(_val100); + } + iprot->readMapEnd(); + } + this->__isset.strategy_options = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->replication_factor); + this->__isset.replication_factor = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 5: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->cf_defs.clear(); + uint32_t _size101; + ::apache::thrift::protocol::TType _etype104; + iprot->readListBegin(_etype104, _size101); + this->cf_defs.resize(_size101); + uint32_t _i105; + for (_i105 = 0; _i105 < _size101; ++_i105) + { + xfer += this->cf_defs[_i105].read(iprot); + } + iprot->readListEnd(); + } + isset_cf_defs = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 6: + if (ftype == ::apache::thrift::protocol::T_BOOL) { + xfer += iprot->readBool(this->durable_writes); + this->__isset.durable_writes = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_strategy_class) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_cf_defs) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t KsDef::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("KsDef"); + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->name); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("strategy_class", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->strategy_class); + xfer += oprot->writeFieldEnd(); + if (this->__isset.strategy_options) { + xfer += oprot->writeFieldBegin("strategy_options", ::apache::thrift::protocol::T_MAP, 3); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->strategy_options.size())); + std::map ::const_iterator _iter106; + for (_iter106 = this->strategy_options.begin(); _iter106 != this->strategy_options.end(); ++_iter106) + { + xfer += oprot->writeString(_iter106->first); + xfer += oprot->writeString(_iter106->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.replication_factor) { + xfer += oprot->writeFieldBegin("replication_factor", ::apache::thrift::protocol::T_I32, 4); + xfer += oprot->writeI32(this->replication_factor); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldBegin("cf_defs", ::apache::thrift::protocol::T_LIST, 5); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->cf_defs.size())); + std::vector ::const_iterator _iter107; + for (_iter107 = this->cf_defs.begin(); _iter107 != this->cf_defs.end(); ++_iter107) + { + xfer += (*_iter107).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + if (this->__isset.durable_writes) { + xfer += oprot->writeFieldBegin("durable_writes", ::apache::thrift::protocol::T_BOOL, 6); + xfer += oprot->writeBool(this->durable_writes); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CqlRow::ascii_fingerprint = "470EFC558004E98D92D604898305C04E"; +const uint8_t CqlRow::binary_fingerprint[16] = {0x47,0x0E,0xFC,0x55,0x80,0x04,0xE9,0x8D,0x92,0xD6,0x04,0x89,0x83,0x05,0xC0,0x4E}; + +uint32_t CqlRow::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_key = false; + bool isset_columns = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readBinary(this->key); + isset_key = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->columns.clear(); + uint32_t _size108; + ::apache::thrift::protocol::TType _etype111; + iprot->readListBegin(_etype111, _size108); + this->columns.resize(_size108); + uint32_t _i112; + for (_i112 = 0; _i112 < _size108; ++_i112) + { + xfer += this->columns[_i112].read(iprot); + } + iprot->readListEnd(); + } + isset_columns = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_key) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_columns) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CqlRow::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CqlRow"); + xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeBinary(this->key); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->columns.size())); + std::vector ::const_iterator _iter113; + for (_iter113 = this->columns.begin(); _iter113 != this->columns.end(); ++_iter113) + { + xfer += (*_iter113).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CqlMetadata::ascii_fingerprint = "B7C5A4AA9652C744A48EBC1C12D531E7"; +const uint8_t CqlMetadata::binary_fingerprint[16] = {0xB7,0xC5,0xA4,0xAA,0x96,0x52,0xC7,0x44,0xA4,0x8E,0xBC,0x1C,0x12,0xD5,0x31,0xE7}; + +uint32_t CqlMetadata::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_name_types = false; + bool isset_value_types = false; + bool isset_default_name_type = false; + bool isset_default_value_type = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->name_types.clear(); + uint32_t _size114; + ::apache::thrift::protocol::TType _ktype115; + ::apache::thrift::protocol::TType _vtype116; + iprot->readMapBegin(_ktype115, _vtype116, _size114); + uint32_t _i118; + for (_i118 = 0; _i118 < _size114; ++_i118) + { + std::string _key119; + xfer += iprot->readBinary(_key119); + std::string& _val120 = this->name_types[_key119]; + xfer += iprot->readString(_val120); + } + iprot->readMapEnd(); + } + isset_name_types = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_MAP) { + { + this->value_types.clear(); + uint32_t _size121; + ::apache::thrift::protocol::TType _ktype122; + ::apache::thrift::protocol::TType _vtype123; + iprot->readMapBegin(_ktype122, _vtype123, _size121); + uint32_t _i125; + for (_i125 = 0; _i125 < _size121; ++_i125) + { + std::string _key126; + xfer += iprot->readBinary(_key126); + std::string& _val127 = this->value_types[_key126]; + xfer += iprot->readString(_val127); + } + iprot->readMapEnd(); + } + isset_value_types = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->default_name_type); + isset_default_name_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->default_value_type); + isset_default_value_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_name_types) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_value_types) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_default_name_type) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_default_value_type) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CqlMetadata::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CqlMetadata"); + xfer += oprot->writeFieldBegin("name_types", ::apache::thrift::protocol::T_MAP, 1); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->name_types.size())); + std::map ::const_iterator _iter128; + for (_iter128 = this->name_types.begin(); _iter128 != this->name_types.end(); ++_iter128) + { + xfer += oprot->writeBinary(_iter128->first); + xfer += oprot->writeString(_iter128->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("value_types", ::apache::thrift::protocol::T_MAP, 2); + { + xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast(this->value_types.size())); + std::map ::const_iterator _iter129; + for (_iter129 = this->value_types.begin(); _iter129 != this->value_types.end(); ++_iter129) + { + xfer += oprot->writeBinary(_iter129->first); + xfer += oprot->writeString(_iter129->second); + } + xfer += oprot->writeMapEnd(); + } + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("default_name_type", ::apache::thrift::protocol::T_STRING, 3); + xfer += oprot->writeString(this->default_name_type); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("default_value_type", ::apache::thrift::protocol::T_STRING, 4); + xfer += oprot->writeString(this->default_value_type); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CqlResult::ascii_fingerprint = "521B9CE5AF77539F7267F6952B609E81"; +const uint8_t CqlResult::binary_fingerprint[16] = {0x52,0x1B,0x9C,0xE5,0xAF,0x77,0x53,0x9F,0x72,0x67,0xF6,0x95,0x2B,0x60,0x9E,0x81}; + +uint32_t CqlResult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_type = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_I32) { + int32_t ecast130; + xfer += iprot->readI32(ecast130); + this->type = (CqlResultType::type)ecast130; + isset_type = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->rows.clear(); + uint32_t _size131; + ::apache::thrift::protocol::TType _etype134; + iprot->readListBegin(_etype134, _size131); + this->rows.resize(_size131); + uint32_t _i135; + for (_i135 = 0; _i135 < _size131; ++_i135) + { + xfer += this->rows[_i135].read(iprot); + } + iprot->readListEnd(); + } + this->__isset.rows = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->num); + this->__isset.num = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_STRUCT) { + xfer += this->schema.read(iprot); + this->__isset.schema = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_type) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CqlResult::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CqlResult"); + xfer += oprot->writeFieldBegin("type", ::apache::thrift::protocol::T_I32, 1); + xfer += oprot->writeI32((int32_t)this->type); + xfer += oprot->writeFieldEnd(); + if (this->__isset.rows) { + xfer += oprot->writeFieldBegin("rows", ::apache::thrift::protocol::T_LIST, 2); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast(this->rows.size())); + std::vector ::const_iterator _iter136; + for (_iter136 = this->rows.begin(); _iter136 != this->rows.end(); ++_iter136) + { + xfer += (*_iter136).write(oprot); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.num) { + xfer += oprot->writeFieldBegin("num", ::apache::thrift::protocol::T_I32, 3); + xfer += oprot->writeI32(this->num); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.schema) { + xfer += oprot->writeFieldBegin("schema", ::apache::thrift::protocol::T_STRUCT, 4); + xfer += this->schema.write(oprot); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +const char* CqlPreparedResult::ascii_fingerprint = "7E1663EC688DFDC28722BF36F9F64E6F"; +const uint8_t CqlPreparedResult::binary_fingerprint[16] = {0x7E,0x16,0x63,0xEC,0x68,0x8D,0xFD,0xC2,0x87,0x22,0xBF,0x36,0xF9,0xF6,0x4E,0x6F}; + +uint32_t CqlPreparedResult::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + bool isset_itemId = false; + bool isset_count = false; + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->itemId); + isset_itemId = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_I32) { + xfer += iprot->readI32(this->count); + isset_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 3: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->variable_types.clear(); + uint32_t _size137; + ::apache::thrift::protocol::TType _etype140; + iprot->readListBegin(_etype140, _size137); + this->variable_types.resize(_size137); + uint32_t _i141; + for (_i141 = 0; _i141 < _size137; ++_i141) + { + xfer += iprot->readString(this->variable_types[_i141]); + } + iprot->readListEnd(); + } + this->__isset.variable_types = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 4: + if (ftype == ::apache::thrift::protocol::T_LIST) { + { + this->variable_names.clear(); + uint32_t _size142; + ::apache::thrift::protocol::TType _etype145; + iprot->readListBegin(_etype145, _size142); + this->variable_names.resize(_size142); + uint32_t _i146; + for (_i146 = 0; _i146 < _size142; ++_i146) + { + xfer += iprot->readString(this->variable_names[_i146]); + } + iprot->readListEnd(); + } + this->__isset.variable_names = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + if (!isset_itemId) + throw TProtocolException(TProtocolException::INVALID_DATA); + if (!isset_count) + throw TProtocolException(TProtocolException::INVALID_DATA); + return xfer; +} + +uint32_t CqlPreparedResult::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + xfer += oprot->writeStructBegin("CqlPreparedResult"); + xfer += oprot->writeFieldBegin("itemId", ::apache::thrift::protocol::T_I32, 1); + xfer += oprot->writeI32(this->itemId); + xfer += oprot->writeFieldEnd(); + xfer += oprot->writeFieldBegin("count", ::apache::thrift::protocol::T_I32, 2); + xfer += oprot->writeI32(this->count); + xfer += oprot->writeFieldEnd(); + if (this->__isset.variable_types) { + xfer += oprot->writeFieldBegin("variable_types", ::apache::thrift::protocol::T_LIST, 3); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->variable_types.size())); + std::vector ::const_iterator _iter147; + for (_iter147 = this->variable_types.begin(); _iter147 != this->variable_types.end(); ++_iter147) + { + xfer += oprot->writeString((*_iter147)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.variable_names) { + xfer += oprot->writeFieldBegin("variable_names", ::apache::thrift::protocol::T_LIST, 4); + { + xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast(this->variable_names.size())); + std::vector ::const_iterator _iter148; + for (_iter148 = this->variable_names.begin(); _iter148 != this->variable_names.end(); ++_iter148) + { + xfer += oprot->writeString((*_iter148)); + } + xfer += oprot->writeListEnd(); + } + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + return xfer; +} + +}}} // namespace diff --git a/storage/cassandra/gen-cpp/cassandra_types.h b/storage/cassandra/gen-cpp/cassandra_types.h new file mode 100644 index 00000000000..d675198dcc8 --- /dev/null +++ b/storage/cassandra/gen-cpp/cassandra_types.h @@ -0,0 +1,2149 @@ +/** + * Autogenerated by Thrift Compiler (0.8.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef cassandra_TYPES_H +#define cassandra_TYPES_H + +#include +#include + +#include +#include +#include +#include + + + +namespace org { namespace apache { namespace cassandra { + +struct ConsistencyLevel { + enum type { + ONE = 1, + QUORUM = 2, + LOCAL_QUORUM = 3, + EACH_QUORUM = 4, + ALL = 5, + ANY = 6, + TWO = 7, + THREE = 8 + }; +}; + +extern const std::map _ConsistencyLevel_VALUES_TO_NAMES; + +struct IndexOperator { + enum type { + EQ = 0, + GTE = 1, + GT = 2, + LTE = 3, + LT = 4 + }; +}; + +extern const std::map _IndexOperator_VALUES_TO_NAMES; + +struct IndexType { + enum type { + KEYS = 0, + CUSTOM = 1 + }; +}; + +extern const std::map _IndexType_VALUES_TO_NAMES; + +struct Compression { + enum type { + GZIP = 1, + NONE = 2 + }; +}; + +extern const std::map _Compression_VALUES_TO_NAMES; + +struct CqlResultType { + enum type { + ROWS = 1, + VOID = 2, + INT = 3 + }; +}; + +extern const std::map _CqlResultType_VALUES_TO_NAMES; + +typedef struct _Column__isset { + _Column__isset() : value(false), timestamp(false), ttl(false) {} + bool value; + bool timestamp; + bool ttl; +} _Column__isset; + +class Column { + public: + + static const char* ascii_fingerprint; // = "3EE0E1C5C844001B62F08125068292CC"; + static const uint8_t binary_fingerprint[16]; // = {0x3E,0xE0,0xE1,0xC5,0xC8,0x44,0x00,0x1B,0x62,0xF0,0x81,0x25,0x06,0x82,0x92,0xCC}; + + Column() : name(""), value(""), timestamp(0), ttl(0) { + } + + virtual ~Column() throw() {} + + std::string name; + std::string value; + int64_t timestamp; + int32_t ttl; + + _Column__isset __isset; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_value(const std::string& val) { + value = val; + __isset.value = true; + } + + void __set_timestamp(const int64_t val) { + timestamp = val; + __isset.timestamp = true; + } + + void __set_ttl(const int32_t val) { + ttl = val; + __isset.ttl = true; + } + + bool operator == (const Column & rhs) const + { + if (!(name == rhs.name)) + return false; + if (__isset.value != rhs.__isset.value) + return false; + else if (__isset.value && !(value == rhs.value)) + return false; + if (__isset.timestamp != rhs.__isset.timestamp) + return false; + else if (__isset.timestamp && !(timestamp == rhs.timestamp)) + return false; + if (__isset.ttl != rhs.__isset.ttl) + return false; + else if (__isset.ttl && !(ttl == rhs.ttl)) + return false; + return true; + } + bool operator != (const Column &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Column & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class SuperColumn { + public: + + static const char* ascii_fingerprint; // = "470EFC558004E98D92D604898305C04E"; + static const uint8_t binary_fingerprint[16]; // = {0x47,0x0E,0xFC,0x55,0x80,0x04,0xE9,0x8D,0x92,0xD6,0x04,0x89,0x83,0x05,0xC0,0x4E}; + + SuperColumn() : name("") { + } + + virtual ~SuperColumn() throw() {} + + std::string name; + std::vector columns; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_columns(const std::vector & val) { + columns = val; + } + + bool operator == (const SuperColumn & rhs) const + { + if (!(name == rhs.name)) + return false; + if (!(columns == rhs.columns)) + return false; + return true; + } + bool operator != (const SuperColumn &rhs) const { + return !(*this == rhs); + } + + bool operator < (const SuperColumn & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class CounterColumn { + public: + + static const char* ascii_fingerprint; // = "1CCCF6FC31CFD1D61BBBB1BAF3590620"; + static const uint8_t binary_fingerprint[16]; // = {0x1C,0xCC,0xF6,0xFC,0x31,0xCF,0xD1,0xD6,0x1B,0xBB,0xB1,0xBA,0xF3,0x59,0x06,0x20}; + + CounterColumn() : name(""), value(0) { + } + + virtual ~CounterColumn() throw() {} + + std::string name; + int64_t value; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_value(const int64_t val) { + value = val; + } + + bool operator == (const CounterColumn & rhs) const + { + if (!(name == rhs.name)) + return false; + if (!(value == rhs.value)) + return false; + return true; + } + bool operator != (const CounterColumn &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CounterColumn & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class CounterSuperColumn { + public: + + static const char* ascii_fingerprint; // = "CD4C8C4BF7753E46DE417CDE369343A4"; + static const uint8_t binary_fingerprint[16]; // = {0xCD,0x4C,0x8C,0x4B,0xF7,0x75,0x3E,0x46,0xDE,0x41,0x7C,0xDE,0x36,0x93,0x43,0xA4}; + + CounterSuperColumn() : name("") { + } + + virtual ~CounterSuperColumn() throw() {} + + std::string name; + std::vector columns; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_columns(const std::vector & val) { + columns = val; + } + + bool operator == (const CounterSuperColumn & rhs) const + { + if (!(name == rhs.name)) + return false; + if (!(columns == rhs.columns)) + return false; + return true; + } + bool operator != (const CounterSuperColumn &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CounterSuperColumn & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _ColumnOrSuperColumn__isset { + _ColumnOrSuperColumn__isset() : column(false), super_column(false), counter_column(false), counter_super_column(false) {} + bool column; + bool super_column; + bool counter_column; + bool counter_super_column; +} _ColumnOrSuperColumn__isset; + +class ColumnOrSuperColumn { + public: + + static const char* ascii_fingerprint; // = "2B34AC9E80F1DAA3A2A63B1AB1841E61"; + static const uint8_t binary_fingerprint[16]; // = {0x2B,0x34,0xAC,0x9E,0x80,0xF1,0xDA,0xA3,0xA2,0xA6,0x3B,0x1A,0xB1,0x84,0x1E,0x61}; + + ColumnOrSuperColumn() { + } + + virtual ~ColumnOrSuperColumn() throw() {} + + Column column; + SuperColumn super_column; + CounterColumn counter_column; + CounterSuperColumn counter_super_column; + + _ColumnOrSuperColumn__isset __isset; + + void __set_column(const Column& val) { + column = val; + __isset.column = true; + } + + void __set_super_column(const SuperColumn& val) { + super_column = val; + __isset.super_column = true; + } + + void __set_counter_column(const CounterColumn& val) { + counter_column = val; + __isset.counter_column = true; + } + + void __set_counter_super_column(const CounterSuperColumn& val) { + counter_super_column = val; + __isset.counter_super_column = true; + } + + bool operator == (const ColumnOrSuperColumn & rhs) const + { + if (__isset.column != rhs.__isset.column) + return false; + else if (__isset.column && !(column == rhs.column)) + return false; + if (__isset.super_column != rhs.__isset.super_column) + return false; + else if (__isset.super_column && !(super_column == rhs.super_column)) + return false; + if (__isset.counter_column != rhs.__isset.counter_column) + return false; + else if (__isset.counter_column && !(counter_column == rhs.counter_column)) + return false; + if (__isset.counter_super_column != rhs.__isset.counter_super_column) + return false; + else if (__isset.counter_super_column && !(counter_super_column == rhs.counter_super_column)) + return false; + return true; + } + bool operator != (const ColumnOrSuperColumn &rhs) const { + return !(*this == rhs); + } + + bool operator < (const ColumnOrSuperColumn & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class NotFoundException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B"; + static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + + NotFoundException() { + } + + virtual ~NotFoundException() throw() {} + + + bool operator == (const NotFoundException & /* rhs */) const + { + return true; + } + bool operator != (const NotFoundException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const NotFoundException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class InvalidRequestException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1"; + static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + + InvalidRequestException() : why("") { + } + + virtual ~InvalidRequestException() throw() {} + + std::string why; + + void __set_why(const std::string& val) { + why = val; + } + + bool operator == (const InvalidRequestException & rhs) const + { + if (!(why == rhs.why)) + return false; + return true; + } + bool operator != (const InvalidRequestException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const InvalidRequestException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class UnavailableException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B"; + static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + + UnavailableException() { + } + + virtual ~UnavailableException() throw() {} + + + bool operator == (const UnavailableException & /* rhs */) const + { + return true; + } + bool operator != (const UnavailableException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const UnavailableException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class TimedOutException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B"; + static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + + TimedOutException() { + } + + virtual ~TimedOutException() throw() {} + + + bool operator == (const TimedOutException & /* rhs */) const + { + return true; + } + bool operator != (const TimedOutException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const TimedOutException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class AuthenticationException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1"; + static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + + AuthenticationException() : why("") { + } + + virtual ~AuthenticationException() throw() {} + + std::string why; + + void __set_why(const std::string& val) { + why = val; + } + + bool operator == (const AuthenticationException & rhs) const + { + if (!(why == rhs.why)) + return false; + return true; + } + bool operator != (const AuthenticationException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const AuthenticationException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class AuthorizationException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1"; + static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1}; + + AuthorizationException() : why("") { + } + + virtual ~AuthorizationException() throw() {} + + std::string why; + + void __set_why(const std::string& val) { + why = val; + } + + bool operator == (const AuthorizationException & rhs) const + { + if (!(why == rhs.why)) + return false; + return true; + } + bool operator != (const AuthorizationException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const AuthorizationException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class SchemaDisagreementException : public ::apache::thrift::TException { + public: + + static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B"; + static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + + SchemaDisagreementException() { + } + + virtual ~SchemaDisagreementException() throw() {} + + + bool operator == (const SchemaDisagreementException & /* rhs */) const + { + return true; + } + bool operator != (const SchemaDisagreementException &rhs) const { + return !(*this == rhs); + } + + bool operator < (const SchemaDisagreementException & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _ColumnParent__isset { + _ColumnParent__isset() : super_column(false) {} + bool super_column; +} _ColumnParent__isset; + +class ColumnParent { + public: + + static const char* ascii_fingerprint; // = "0A13AE61181713A4100DFFB3EC293822"; + static const uint8_t binary_fingerprint[16]; // = {0x0A,0x13,0xAE,0x61,0x18,0x17,0x13,0xA4,0x10,0x0D,0xFF,0xB3,0xEC,0x29,0x38,0x22}; + + ColumnParent() : column_family(""), super_column("") { + } + + virtual ~ColumnParent() throw() {} + + std::string column_family; + std::string super_column; + + _ColumnParent__isset __isset; + + void __set_column_family(const std::string& val) { + column_family = val; + } + + void __set_super_column(const std::string& val) { + super_column = val; + __isset.super_column = true; + } + + bool operator == (const ColumnParent & rhs) const + { + if (!(column_family == rhs.column_family)) + return false; + if (__isset.super_column != rhs.__isset.super_column) + return false; + else if (__isset.super_column && !(super_column == rhs.super_column)) + return false; + return true; + } + bool operator != (const ColumnParent &rhs) const { + return !(*this == rhs); + } + + bool operator < (const ColumnParent & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _ColumnPath__isset { + _ColumnPath__isset() : super_column(false), column(false) {} + bool super_column; + bool column; +} _ColumnPath__isset; + +class ColumnPath { + public: + + static const char* ascii_fingerprint; // = "606212895BCF63C757913CF35AEB3462"; + static const uint8_t binary_fingerprint[16]; // = {0x60,0x62,0x12,0x89,0x5B,0xCF,0x63,0xC7,0x57,0x91,0x3C,0xF3,0x5A,0xEB,0x34,0x62}; + + ColumnPath() : column_family(""), super_column(""), column("") { + } + + virtual ~ColumnPath() throw() {} + + std::string column_family; + std::string super_column; + std::string column; + + _ColumnPath__isset __isset; + + void __set_column_family(const std::string& val) { + column_family = val; + } + + void __set_super_column(const std::string& val) { + super_column = val; + __isset.super_column = true; + } + + void __set_column(const std::string& val) { + column = val; + __isset.column = true; + } + + bool operator == (const ColumnPath & rhs) const + { + if (!(column_family == rhs.column_family)) + return false; + if (__isset.super_column != rhs.__isset.super_column) + return false; + else if (__isset.super_column && !(super_column == rhs.super_column)) + return false; + if (__isset.column != rhs.__isset.column) + return false; + else if (__isset.column && !(column == rhs.column)) + return false; + return true; + } + bool operator != (const ColumnPath &rhs) const { + return !(*this == rhs); + } + + bool operator < (const ColumnPath & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class SliceRange { + public: + + static const char* ascii_fingerprint; // = "184D24C9A0B8D4415E234DB649CAE740"; + static const uint8_t binary_fingerprint[16]; // = {0x18,0x4D,0x24,0xC9,0xA0,0xB8,0xD4,0x41,0x5E,0x23,0x4D,0xB6,0x49,0xCA,0xE7,0x40}; + + SliceRange() : start(""), finish(""), reversed(false), count(100) { + } + + virtual ~SliceRange() throw() {} + + std::string start; + std::string finish; + bool reversed; + int32_t count; + + void __set_start(const std::string& val) { + start = val; + } + + void __set_finish(const std::string& val) { + finish = val; + } + + void __set_reversed(const bool val) { + reversed = val; + } + + void __set_count(const int32_t val) { + count = val; + } + + bool operator == (const SliceRange & rhs) const + { + if (!(start == rhs.start)) + return false; + if (!(finish == rhs.finish)) + return false; + if (!(reversed == rhs.reversed)) + return false; + if (!(count == rhs.count)) + return false; + return true; + } + bool operator != (const SliceRange &rhs) const { + return !(*this == rhs); + } + + bool operator < (const SliceRange & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _SlicePredicate__isset { + _SlicePredicate__isset() : column_names(false), slice_range(false) {} + bool column_names; + bool slice_range; +} _SlicePredicate__isset; + +class SlicePredicate { + public: + + static const char* ascii_fingerprint; // = "F59D1D81C17DFFAF09988BF1C9CE5E27"; + static const uint8_t binary_fingerprint[16]; // = {0xF5,0x9D,0x1D,0x81,0xC1,0x7D,0xFF,0xAF,0x09,0x98,0x8B,0xF1,0xC9,0xCE,0x5E,0x27}; + + SlicePredicate() { + } + + virtual ~SlicePredicate() throw() {} + + std::vector column_names; + SliceRange slice_range; + + _SlicePredicate__isset __isset; + + void __set_column_names(const std::vector & val) { + column_names = val; + __isset.column_names = true; + } + + void __set_slice_range(const SliceRange& val) { + slice_range = val; + __isset.slice_range = true; + } + + bool operator == (const SlicePredicate & rhs) const + { + if (__isset.column_names != rhs.__isset.column_names) + return false; + else if (__isset.column_names && !(column_names == rhs.column_names)) + return false; + if (__isset.slice_range != rhs.__isset.slice_range) + return false; + else if (__isset.slice_range && !(slice_range == rhs.slice_range)) + return false; + return true; + } + bool operator != (const SlicePredicate &rhs) const { + return !(*this == rhs); + } + + bool operator < (const SlicePredicate & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class IndexExpression { + public: + + static const char* ascii_fingerprint; // = "D9F4CFE2F293A8B1052FD3031DD2C847"; + static const uint8_t binary_fingerprint[16]; // = {0xD9,0xF4,0xCF,0xE2,0xF2,0x93,0xA8,0xB1,0x05,0x2F,0xD3,0x03,0x1D,0xD2,0xC8,0x47}; + + IndexExpression() : column_name(""), op((IndexOperator::type)0), value("") { + } + + virtual ~IndexExpression() throw() {} + + std::string column_name; + IndexOperator::type op; + std::string value; + + void __set_column_name(const std::string& val) { + column_name = val; + } + + void __set_op(const IndexOperator::type val) { + op = val; + } + + void __set_value(const std::string& val) { + value = val; + } + + bool operator == (const IndexExpression & rhs) const + { + if (!(column_name == rhs.column_name)) + return false; + if (!(op == rhs.op)) + return false; + if (!(value == rhs.value)) + return false; + return true; + } + bool operator != (const IndexExpression &rhs) const { + return !(*this == rhs); + } + + bool operator < (const IndexExpression & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class IndexClause { + public: + + static const char* ascii_fingerprint; // = "9B551B9AB86120B0EEA9005C77FD3C1F"; + static const uint8_t binary_fingerprint[16]; // = {0x9B,0x55,0x1B,0x9A,0xB8,0x61,0x20,0xB0,0xEE,0xA9,0x00,0x5C,0x77,0xFD,0x3C,0x1F}; + + IndexClause() : start_key(""), count(100) { + } + + virtual ~IndexClause() throw() {} + + std::vector expressions; + std::string start_key; + int32_t count; + + void __set_expressions(const std::vector & val) { + expressions = val; + } + + void __set_start_key(const std::string& val) { + start_key = val; + } + + void __set_count(const int32_t val) { + count = val; + } + + bool operator == (const IndexClause & rhs) const + { + if (!(expressions == rhs.expressions)) + return false; + if (!(start_key == rhs.start_key)) + return false; + if (!(count == rhs.count)) + return false; + return true; + } + bool operator != (const IndexClause &rhs) const { + return !(*this == rhs); + } + + bool operator < (const IndexClause & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _KeyRange__isset { + _KeyRange__isset() : start_key(false), end_key(false), start_token(false), end_token(false), row_filter(false) {} + bool start_key; + bool end_key; + bool start_token; + bool end_token; + bool row_filter; +} _KeyRange__isset; + +class KeyRange { + public: + + static const char* ascii_fingerprint; // = "A6EC82FA0980B91C7C8EB013C61CA1B0"; + static const uint8_t binary_fingerprint[16]; // = {0xA6,0xEC,0x82,0xFA,0x09,0x80,0xB9,0x1C,0x7C,0x8E,0xB0,0x13,0xC6,0x1C,0xA1,0xB0}; + + KeyRange() : start_key(""), end_key(""), start_token(""), end_token(""), count(100) { + } + + virtual ~KeyRange() throw() {} + + std::string start_key; + std::string end_key; + std::string start_token; + std::string end_token; + std::vector row_filter; + int32_t count; + + _KeyRange__isset __isset; + + void __set_start_key(const std::string& val) { + start_key = val; + __isset.start_key = true; + } + + void __set_end_key(const std::string& val) { + end_key = val; + __isset.end_key = true; + } + + void __set_start_token(const std::string& val) { + start_token = val; + __isset.start_token = true; + } + + void __set_end_token(const std::string& val) { + end_token = val; + __isset.end_token = true; + } + + void __set_row_filter(const std::vector & val) { + row_filter = val; + __isset.row_filter = true; + } + + void __set_count(const int32_t val) { + count = val; + } + + bool operator == (const KeyRange & rhs) const + { + if (__isset.start_key != rhs.__isset.start_key) + return false; + else if (__isset.start_key && !(start_key == rhs.start_key)) + return false; + if (__isset.end_key != rhs.__isset.end_key) + return false; + else if (__isset.end_key && !(end_key == rhs.end_key)) + return false; + if (__isset.start_token != rhs.__isset.start_token) + return false; + else if (__isset.start_token && !(start_token == rhs.start_token)) + return false; + if (__isset.end_token != rhs.__isset.end_token) + return false; + else if (__isset.end_token && !(end_token == rhs.end_token)) + return false; + if (__isset.row_filter != rhs.__isset.row_filter) + return false; + else if (__isset.row_filter && !(row_filter == rhs.row_filter)) + return false; + if (!(count == rhs.count)) + return false; + return true; + } + bool operator != (const KeyRange &rhs) const { + return !(*this == rhs); + } + + bool operator < (const KeyRange & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class KeySlice { + public: + + static const char* ascii_fingerprint; // = "D1568675B0C135C909E3169B72A4DA3D"; + static const uint8_t binary_fingerprint[16]; // = {0xD1,0x56,0x86,0x75,0xB0,0xC1,0x35,0xC9,0x09,0xE3,0x16,0x9B,0x72,0xA4,0xDA,0x3D}; + + KeySlice() : key("") { + } + + virtual ~KeySlice() throw() {} + + std::string key; + std::vector columns; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_columns(const std::vector & val) { + columns = val; + } + + bool operator == (const KeySlice & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(columns == rhs.columns)) + return false; + return true; + } + bool operator != (const KeySlice &rhs) const { + return !(*this == rhs); + } + + bool operator < (const KeySlice & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class KeyCount { + public: + + static const char* ascii_fingerprint; // = "EEBC915CE44901401D881E6091423036"; + static const uint8_t binary_fingerprint[16]; // = {0xEE,0xBC,0x91,0x5C,0xE4,0x49,0x01,0x40,0x1D,0x88,0x1E,0x60,0x91,0x42,0x30,0x36}; + + KeyCount() : key(""), count(0) { + } + + virtual ~KeyCount() throw() {} + + std::string key; + int32_t count; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_count(const int32_t val) { + count = val; + } + + bool operator == (const KeyCount & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(count == rhs.count)) + return false; + return true; + } + bool operator != (const KeyCount &rhs) const { + return !(*this == rhs); + } + + bool operator < (const KeyCount & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Deletion__isset { + _Deletion__isset() : timestamp(false), super_column(false), predicate(false) {} + bool timestamp; + bool super_column; + bool predicate; +} _Deletion__isset; + +class Deletion { + public: + + static const char* ascii_fingerprint; // = "40F33ECF1C932CA77C2414C4E6C60CBE"; + static const uint8_t binary_fingerprint[16]; // = {0x40,0xF3,0x3E,0xCF,0x1C,0x93,0x2C,0xA7,0x7C,0x24,0x14,0xC4,0xE6,0xC6,0x0C,0xBE}; + + Deletion() : timestamp(0), super_column("") { + } + + virtual ~Deletion() throw() {} + + int64_t timestamp; + std::string super_column; + SlicePredicate predicate; + + _Deletion__isset __isset; + + void __set_timestamp(const int64_t val) { + timestamp = val; + __isset.timestamp = true; + } + + void __set_super_column(const std::string& val) { + super_column = val; + __isset.super_column = true; + } + + void __set_predicate(const SlicePredicate& val) { + predicate = val; + __isset.predicate = true; + } + + bool operator == (const Deletion & rhs) const + { + if (__isset.timestamp != rhs.__isset.timestamp) + return false; + else if (__isset.timestamp && !(timestamp == rhs.timestamp)) + return false; + if (__isset.super_column != rhs.__isset.super_column) + return false; + else if (__isset.super_column && !(super_column == rhs.super_column)) + return false; + if (__isset.predicate != rhs.__isset.predicate) + return false; + else if (__isset.predicate && !(predicate == rhs.predicate)) + return false; + return true; + } + bool operator != (const Deletion &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Deletion & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _Mutation__isset { + _Mutation__isset() : column_or_supercolumn(false), deletion(false) {} + bool column_or_supercolumn; + bool deletion; +} _Mutation__isset; + +class Mutation { + public: + + static const char* ascii_fingerprint; // = "E8B65DF3979C6868F80DF81F8E769E63"; + static const uint8_t binary_fingerprint[16]; // = {0xE8,0xB6,0x5D,0xF3,0x97,0x9C,0x68,0x68,0xF8,0x0D,0xF8,0x1F,0x8E,0x76,0x9E,0x63}; + + Mutation() { + } + + virtual ~Mutation() throw() {} + + ColumnOrSuperColumn column_or_supercolumn; + Deletion deletion; + + _Mutation__isset __isset; + + void __set_column_or_supercolumn(const ColumnOrSuperColumn& val) { + column_or_supercolumn = val; + __isset.column_or_supercolumn = true; + } + + void __set_deletion(const Deletion& val) { + deletion = val; + __isset.deletion = true; + } + + bool operator == (const Mutation & rhs) const + { + if (__isset.column_or_supercolumn != rhs.__isset.column_or_supercolumn) + return false; + else if (__isset.column_or_supercolumn && !(column_or_supercolumn == rhs.column_or_supercolumn)) + return false; + if (__isset.deletion != rhs.__isset.deletion) + return false; + else if (__isset.deletion && !(deletion == rhs.deletion)) + return false; + return true; + } + bool operator != (const Mutation &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Mutation & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _EndpointDetails__isset { + _EndpointDetails__isset() : host(false), datacenter(false), rack(false) {} + bool host; + bool datacenter; + bool rack; +} _EndpointDetails__isset; + +class EndpointDetails { + public: + + static const char* ascii_fingerprint; // = "F4A50F0EC638C7F66026F9B6678FD89B"; + static const uint8_t binary_fingerprint[16]; // = {0xF4,0xA5,0x0F,0x0E,0xC6,0x38,0xC7,0xF6,0x60,0x26,0xF9,0xB6,0x67,0x8F,0xD8,0x9B}; + + EndpointDetails() : host(""), datacenter(""), rack("") { + } + + virtual ~EndpointDetails() throw() {} + + std::string host; + std::string datacenter; + std::string rack; + + _EndpointDetails__isset __isset; + + void __set_host(const std::string& val) { + host = val; + } + + void __set_datacenter(const std::string& val) { + datacenter = val; + } + + void __set_rack(const std::string& val) { + rack = val; + __isset.rack = true; + } + + bool operator == (const EndpointDetails & rhs) const + { + if (!(host == rhs.host)) + return false; + if (!(datacenter == rhs.datacenter)) + return false; + if (__isset.rack != rhs.__isset.rack) + return false; + else if (__isset.rack && !(rack == rhs.rack)) + return false; + return true; + } + bool operator != (const EndpointDetails &rhs) const { + return !(*this == rhs); + } + + bool operator < (const EndpointDetails & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _TokenRange__isset { + _TokenRange__isset() : rpc_endpoints(false), endpoint_details(false) {} + bool rpc_endpoints; + bool endpoint_details; +} _TokenRange__isset; + +class TokenRange { + public: + + static const char* ascii_fingerprint; // = "832268DC4CD6B17EE8881FC57EA04679"; + static const uint8_t binary_fingerprint[16]; // = {0x83,0x22,0x68,0xDC,0x4C,0xD6,0xB1,0x7E,0xE8,0x88,0x1F,0xC5,0x7E,0xA0,0x46,0x79}; + + TokenRange() : start_token(""), end_token("") { + } + + virtual ~TokenRange() throw() {} + + std::string start_token; + std::string end_token; + std::vector endpoints; + std::vector rpc_endpoints; + std::vector endpoint_details; + + _TokenRange__isset __isset; + + void __set_start_token(const std::string& val) { + start_token = val; + } + + void __set_end_token(const std::string& val) { + end_token = val; + } + + void __set_endpoints(const std::vector & val) { + endpoints = val; + } + + void __set_rpc_endpoints(const std::vector & val) { + rpc_endpoints = val; + __isset.rpc_endpoints = true; + } + + void __set_endpoint_details(const std::vector & val) { + endpoint_details = val; + __isset.endpoint_details = true; + } + + bool operator == (const TokenRange & rhs) const + { + if (!(start_token == rhs.start_token)) + return false; + if (!(end_token == rhs.end_token)) + return false; + if (!(endpoints == rhs.endpoints)) + return false; + if (__isset.rpc_endpoints != rhs.__isset.rpc_endpoints) + return false; + else if (__isset.rpc_endpoints && !(rpc_endpoints == rhs.rpc_endpoints)) + return false; + if (__isset.endpoint_details != rhs.__isset.endpoint_details) + return false; + else if (__isset.endpoint_details && !(endpoint_details == rhs.endpoint_details)) + return false; + return true; + } + bool operator != (const TokenRange &rhs) const { + return !(*this == rhs); + } + + bool operator < (const TokenRange & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class AuthenticationRequest { + public: + + static const char* ascii_fingerprint; // = "5EA2D527ECA3BA20C77AFC023EE8C05F"; + static const uint8_t binary_fingerprint[16]; // = {0x5E,0xA2,0xD5,0x27,0xEC,0xA3,0xBA,0x20,0xC7,0x7A,0xFC,0x02,0x3E,0xE8,0xC0,0x5F}; + + AuthenticationRequest() { + } + + virtual ~AuthenticationRequest() throw() {} + + std::map credentials; + + void __set_credentials(const std::map & val) { + credentials = val; + } + + bool operator == (const AuthenticationRequest & rhs) const + { + if (!(credentials == rhs.credentials)) + return false; + return true; + } + bool operator != (const AuthenticationRequest &rhs) const { + return !(*this == rhs); + } + + bool operator < (const AuthenticationRequest & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _ColumnDef__isset { + _ColumnDef__isset() : index_type(false), index_name(false), index_options(false) {} + bool index_type; + bool index_name; + bool index_options; +} _ColumnDef__isset; + +class ColumnDef { + public: + + static const char* ascii_fingerprint; // = "0D89CE83D7EDAD079AC3213ED1DCAA58"; + static const uint8_t binary_fingerprint[16]; // = {0x0D,0x89,0xCE,0x83,0xD7,0xED,0xAD,0x07,0x9A,0xC3,0x21,0x3E,0xD1,0xDC,0xAA,0x58}; + + ColumnDef() : name(""), validation_class(""), index_type((IndexType::type)0), index_name("") { + } + + virtual ~ColumnDef() throw() {} + + std::string name; + std::string validation_class; + IndexType::type index_type; + std::string index_name; + std::map index_options; + + _ColumnDef__isset __isset; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_validation_class(const std::string& val) { + validation_class = val; + } + + void __set_index_type(const IndexType::type val) { + index_type = val; + __isset.index_type = true; + } + + void __set_index_name(const std::string& val) { + index_name = val; + __isset.index_name = true; + } + + void __set_index_options(const std::map & val) { + index_options = val; + __isset.index_options = true; + } + + bool operator == (const ColumnDef & rhs) const + { + if (!(name == rhs.name)) + return false; + if (!(validation_class == rhs.validation_class)) + return false; + if (__isset.index_type != rhs.__isset.index_type) + return false; + else if (__isset.index_type && !(index_type == rhs.index_type)) + return false; + if (__isset.index_name != rhs.__isset.index_name) + return false; + else if (__isset.index_name && !(index_name == rhs.index_name)) + return false; + if (__isset.index_options != rhs.__isset.index_options) + return false; + else if (__isset.index_options && !(index_options == rhs.index_options)) + return false; + return true; + } + bool operator != (const ColumnDef &rhs) const { + return !(*this == rhs); + } + + bool operator < (const ColumnDef & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _CfDef__isset { + _CfDef__isset() : column_type(false), comparator_type(false), subcomparator_type(false), comment(false), read_repair_chance(false), column_metadata(false), gc_grace_seconds(false), default_validation_class(false), id(false), min_compaction_threshold(false), max_compaction_threshold(false), replicate_on_write(false), key_validation_class(false), key_alias(false), compaction_strategy(false), compaction_strategy_options(false), compression_options(false), bloom_filter_fp_chance(false), caching(false), dclocal_read_repair_chance(false), row_cache_size(false), key_cache_size(false), row_cache_save_period_in_seconds(false), key_cache_save_period_in_seconds(false), memtable_flush_after_mins(false), memtable_throughput_in_mb(false), memtable_operations_in_millions(false), merge_shards_chance(false), row_cache_provider(false), row_cache_keys_to_save(false) {} + bool column_type; + bool comparator_type; + bool subcomparator_type; + bool comment; + bool read_repair_chance; + bool column_metadata; + bool gc_grace_seconds; + bool default_validation_class; + bool id; + bool min_compaction_threshold; + bool max_compaction_threshold; + bool replicate_on_write; + bool key_validation_class; + bool key_alias; + bool compaction_strategy; + bool compaction_strategy_options; + bool compression_options; + bool bloom_filter_fp_chance; + bool caching; + bool dclocal_read_repair_chance; + bool row_cache_size; + bool key_cache_size; + bool row_cache_save_period_in_seconds; + bool key_cache_save_period_in_seconds; + bool memtable_flush_after_mins; + bool memtable_throughput_in_mb; + bool memtable_operations_in_millions; + bool merge_shards_chance; + bool row_cache_provider; + bool row_cache_keys_to_save; +} _CfDef__isset; + +class CfDef { + public: + + static const char* ascii_fingerprint; // = "231A260521B5DD99EFBCCBDD8768CA7D"; + static const uint8_t binary_fingerprint[16]; // = {0x23,0x1A,0x26,0x05,0x21,0xB5,0xDD,0x99,0xEF,0xBC,0xCB,0xDD,0x87,0x68,0xCA,0x7D}; + + CfDef() : keyspace(""), name(""), column_type("Standard"), comparator_type("BytesType"), subcomparator_type(""), comment(""), read_repair_chance(0), gc_grace_seconds(0), default_validation_class(""), id(0), min_compaction_threshold(0), max_compaction_threshold(0), replicate_on_write(0), key_validation_class(""), key_alias(""), compaction_strategy(""), bloom_filter_fp_chance(0), caching("keys_only"), dclocal_read_repair_chance(0), row_cache_size(0), key_cache_size(0), row_cache_save_period_in_seconds(0), key_cache_save_period_in_seconds(0), memtable_flush_after_mins(0), memtable_throughput_in_mb(0), memtable_operations_in_millions(0), merge_shards_chance(0), row_cache_provider(""), row_cache_keys_to_save(0) { + } + + virtual ~CfDef() throw() {} + + std::string keyspace; + std::string name; + std::string column_type; + std::string comparator_type; + std::string subcomparator_type; + std::string comment; + double read_repair_chance; + std::vector column_metadata; + int32_t gc_grace_seconds; + std::string default_validation_class; + int32_t id; + int32_t min_compaction_threshold; + int32_t max_compaction_threshold; + bool replicate_on_write; + std::string key_validation_class; + std::string key_alias; + std::string compaction_strategy; + std::map compaction_strategy_options; + std::map compression_options; + double bloom_filter_fp_chance; + std::string caching; + double dclocal_read_repair_chance; + double row_cache_size; + double key_cache_size; + int32_t row_cache_save_period_in_seconds; + int32_t key_cache_save_period_in_seconds; + int32_t memtable_flush_after_mins; + int32_t memtable_throughput_in_mb; + double memtable_operations_in_millions; + double merge_shards_chance; + std::string row_cache_provider; + int32_t row_cache_keys_to_save; + + _CfDef__isset __isset; + + void __set_keyspace(const std::string& val) { + keyspace = val; + } + + void __set_name(const std::string& val) { + name = val; + } + + void __set_column_type(const std::string& val) { + column_type = val; + __isset.column_type = true; + } + + void __set_comparator_type(const std::string& val) { + comparator_type = val; + __isset.comparator_type = true; + } + + void __set_subcomparator_type(const std::string& val) { + subcomparator_type = val; + __isset.subcomparator_type = true; + } + + void __set_comment(const std::string& val) { + comment = val; + __isset.comment = true; + } + + void __set_read_repair_chance(const double val) { + read_repair_chance = val; + __isset.read_repair_chance = true; + } + + void __set_column_metadata(const std::vector & val) { + column_metadata = val; + __isset.column_metadata = true; + } + + void __set_gc_grace_seconds(const int32_t val) { + gc_grace_seconds = val; + __isset.gc_grace_seconds = true; + } + + void __set_default_validation_class(const std::string& val) { + default_validation_class = val; + __isset.default_validation_class = true; + } + + void __set_id(const int32_t val) { + id = val; + __isset.id = true; + } + + void __set_min_compaction_threshold(const int32_t val) { + min_compaction_threshold = val; + __isset.min_compaction_threshold = true; + } + + void __set_max_compaction_threshold(const int32_t val) { + max_compaction_threshold = val; + __isset.max_compaction_threshold = true; + } + + void __set_replicate_on_write(const bool val) { + replicate_on_write = val; + __isset.replicate_on_write = true; + } + + void __set_key_validation_class(const std::string& val) { + key_validation_class = val; + __isset.key_validation_class = true; + } + + void __set_key_alias(const std::string& val) { + key_alias = val; + __isset.key_alias = true; + } + + void __set_compaction_strategy(const std::string& val) { + compaction_strategy = val; + __isset.compaction_strategy = true; + } + + void __set_compaction_strategy_options(const std::map & val) { + compaction_strategy_options = val; + __isset.compaction_strategy_options = true; + } + + void __set_compression_options(const std::map & val) { + compression_options = val; + __isset.compression_options = true; + } + + void __set_bloom_filter_fp_chance(const double val) { + bloom_filter_fp_chance = val; + __isset.bloom_filter_fp_chance = true; + } + + void __set_caching(const std::string& val) { + caching = val; + __isset.caching = true; + } + + void __set_dclocal_read_repair_chance(const double val) { + dclocal_read_repair_chance = val; + __isset.dclocal_read_repair_chance = true; + } + + void __set_row_cache_size(const double val) { + row_cache_size = val; + __isset.row_cache_size = true; + } + + void __set_key_cache_size(const double val) { + key_cache_size = val; + __isset.key_cache_size = true; + } + + void __set_row_cache_save_period_in_seconds(const int32_t val) { + row_cache_save_period_in_seconds = val; + __isset.row_cache_save_period_in_seconds = true; + } + + void __set_key_cache_save_period_in_seconds(const int32_t val) { + key_cache_save_period_in_seconds = val; + __isset.key_cache_save_period_in_seconds = true; + } + + void __set_memtable_flush_after_mins(const int32_t val) { + memtable_flush_after_mins = val; + __isset.memtable_flush_after_mins = true; + } + + void __set_memtable_throughput_in_mb(const int32_t val) { + memtable_throughput_in_mb = val; + __isset.memtable_throughput_in_mb = true; + } + + void __set_memtable_operations_in_millions(const double val) { + memtable_operations_in_millions = val; + __isset.memtable_operations_in_millions = true; + } + + void __set_merge_shards_chance(const double val) { + merge_shards_chance = val; + __isset.merge_shards_chance = true; + } + + void __set_row_cache_provider(const std::string& val) { + row_cache_provider = val; + __isset.row_cache_provider = true; + } + + void __set_row_cache_keys_to_save(const int32_t val) { + row_cache_keys_to_save = val; + __isset.row_cache_keys_to_save = true; + } + + bool operator == (const CfDef & rhs) const + { + if (!(keyspace == rhs.keyspace)) + return false; + if (!(name == rhs.name)) + return false; + if (__isset.column_type != rhs.__isset.column_type) + return false; + else if (__isset.column_type && !(column_type == rhs.column_type)) + return false; + if (__isset.comparator_type != rhs.__isset.comparator_type) + return false; + else if (__isset.comparator_type && !(comparator_type == rhs.comparator_type)) + return false; + if (__isset.subcomparator_type != rhs.__isset.subcomparator_type) + return false; + else if (__isset.subcomparator_type && !(subcomparator_type == rhs.subcomparator_type)) + return false; + if (__isset.comment != rhs.__isset.comment) + return false; + else if (__isset.comment && !(comment == rhs.comment)) + return false; + if (__isset.read_repair_chance != rhs.__isset.read_repair_chance) + return false; + else if (__isset.read_repair_chance && !(read_repair_chance == rhs.read_repair_chance)) + return false; + if (__isset.column_metadata != rhs.__isset.column_metadata) + return false; + else if (__isset.column_metadata && !(column_metadata == rhs.column_metadata)) + return false; + if (__isset.gc_grace_seconds != rhs.__isset.gc_grace_seconds) + return false; + else if (__isset.gc_grace_seconds && !(gc_grace_seconds == rhs.gc_grace_seconds)) + return false; + if (__isset.default_validation_class != rhs.__isset.default_validation_class) + return false; + else if (__isset.default_validation_class && !(default_validation_class == rhs.default_validation_class)) + return false; + if (__isset.id != rhs.__isset.id) + return false; + else if (__isset.id && !(id == rhs.id)) + return false; + if (__isset.min_compaction_threshold != rhs.__isset.min_compaction_threshold) + return false; + else if (__isset.min_compaction_threshold && !(min_compaction_threshold == rhs.min_compaction_threshold)) + return false; + if (__isset.max_compaction_threshold != rhs.__isset.max_compaction_threshold) + return false; + else if (__isset.max_compaction_threshold && !(max_compaction_threshold == rhs.max_compaction_threshold)) + return false; + if (__isset.replicate_on_write != rhs.__isset.replicate_on_write) + return false; + else if (__isset.replicate_on_write && !(replicate_on_write == rhs.replicate_on_write)) + return false; + if (__isset.key_validation_class != rhs.__isset.key_validation_class) + return false; + else if (__isset.key_validation_class && !(key_validation_class == rhs.key_validation_class)) + return false; + if (__isset.key_alias != rhs.__isset.key_alias) + return false; + else if (__isset.key_alias && !(key_alias == rhs.key_alias)) + return false; + if (__isset.compaction_strategy != rhs.__isset.compaction_strategy) + return false; + else if (__isset.compaction_strategy && !(compaction_strategy == rhs.compaction_strategy)) + return false; + if (__isset.compaction_strategy_options != rhs.__isset.compaction_strategy_options) + return false; + else if (__isset.compaction_strategy_options && !(compaction_strategy_options == rhs.compaction_strategy_options)) + return false; + if (__isset.compression_options != rhs.__isset.compression_options) + return false; + else if (__isset.compression_options && !(compression_options == rhs.compression_options)) + return false; + if (__isset.bloom_filter_fp_chance != rhs.__isset.bloom_filter_fp_chance) + return false; + else if (__isset.bloom_filter_fp_chance && !(bloom_filter_fp_chance == rhs.bloom_filter_fp_chance)) + return false; + if (__isset.caching != rhs.__isset.caching) + return false; + else if (__isset.caching && !(caching == rhs.caching)) + return false; + if (__isset.dclocal_read_repair_chance != rhs.__isset.dclocal_read_repair_chance) + return false; + else if (__isset.dclocal_read_repair_chance && !(dclocal_read_repair_chance == rhs.dclocal_read_repair_chance)) + return false; + if (__isset.row_cache_size != rhs.__isset.row_cache_size) + return false; + else if (__isset.row_cache_size && !(row_cache_size == rhs.row_cache_size)) + return false; + if (__isset.key_cache_size != rhs.__isset.key_cache_size) + return false; + else if (__isset.key_cache_size && !(key_cache_size == rhs.key_cache_size)) + return false; + if (__isset.row_cache_save_period_in_seconds != rhs.__isset.row_cache_save_period_in_seconds) + return false; + else if (__isset.row_cache_save_period_in_seconds && !(row_cache_save_period_in_seconds == rhs.row_cache_save_period_in_seconds)) + return false; + if (__isset.key_cache_save_period_in_seconds != rhs.__isset.key_cache_save_period_in_seconds) + return false; + else if (__isset.key_cache_save_period_in_seconds && !(key_cache_save_period_in_seconds == rhs.key_cache_save_period_in_seconds)) + return false; + if (__isset.memtable_flush_after_mins != rhs.__isset.memtable_flush_after_mins) + return false; + else if (__isset.memtable_flush_after_mins && !(memtable_flush_after_mins == rhs.memtable_flush_after_mins)) + return false; + if (__isset.memtable_throughput_in_mb != rhs.__isset.memtable_throughput_in_mb) + return false; + else if (__isset.memtable_throughput_in_mb && !(memtable_throughput_in_mb == rhs.memtable_throughput_in_mb)) + return false; + if (__isset.memtable_operations_in_millions != rhs.__isset.memtable_operations_in_millions) + return false; + else if (__isset.memtable_operations_in_millions && !(memtable_operations_in_millions == rhs.memtable_operations_in_millions)) + return false; + if (__isset.merge_shards_chance != rhs.__isset.merge_shards_chance) + return false; + else if (__isset.merge_shards_chance && !(merge_shards_chance == rhs.merge_shards_chance)) + return false; + if (__isset.row_cache_provider != rhs.__isset.row_cache_provider) + return false; + else if (__isset.row_cache_provider && !(row_cache_provider == rhs.row_cache_provider)) + return false; + if (__isset.row_cache_keys_to_save != rhs.__isset.row_cache_keys_to_save) + return false; + else if (__isset.row_cache_keys_to_save && !(row_cache_keys_to_save == rhs.row_cache_keys_to_save)) + return false; + return true; + } + bool operator != (const CfDef &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CfDef & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _KsDef__isset { + _KsDef__isset() : strategy_options(false), replication_factor(false), durable_writes(false) {} + bool strategy_options; + bool replication_factor; + bool durable_writes; +} _KsDef__isset; + +class KsDef { + public: + + static const char* ascii_fingerprint; // = "0767851B6476EB3777A21E59E912E11A"; + static const uint8_t binary_fingerprint[16]; // = {0x07,0x67,0x85,0x1B,0x64,0x76,0xEB,0x37,0x77,0xA2,0x1E,0x59,0xE9,0x12,0xE1,0x1A}; + + KsDef() : name(""), strategy_class(""), replication_factor(0), durable_writes(true) { + } + + virtual ~KsDef() throw() {} + + std::string name; + std::string strategy_class; + std::map strategy_options; + int32_t replication_factor; + std::vector cf_defs; + bool durable_writes; + + _KsDef__isset __isset; + + void __set_name(const std::string& val) { + name = val; + } + + void __set_strategy_class(const std::string& val) { + strategy_class = val; + } + + void __set_strategy_options(const std::map & val) { + strategy_options = val; + __isset.strategy_options = true; + } + + void __set_replication_factor(const int32_t val) { + replication_factor = val; + __isset.replication_factor = true; + } + + void __set_cf_defs(const std::vector & val) { + cf_defs = val; + } + + void __set_durable_writes(const bool val) { + durable_writes = val; + __isset.durable_writes = true; + } + + bool operator == (const KsDef & rhs) const + { + if (!(name == rhs.name)) + return false; + if (!(strategy_class == rhs.strategy_class)) + return false; + if (__isset.strategy_options != rhs.__isset.strategy_options) + return false; + else if (__isset.strategy_options && !(strategy_options == rhs.strategy_options)) + return false; + if (__isset.replication_factor != rhs.__isset.replication_factor) + return false; + else if (__isset.replication_factor && !(replication_factor == rhs.replication_factor)) + return false; + if (!(cf_defs == rhs.cf_defs)) + return false; + if (__isset.durable_writes != rhs.__isset.durable_writes) + return false; + else if (__isset.durable_writes && !(durable_writes == rhs.durable_writes)) + return false; + return true; + } + bool operator != (const KsDef &rhs) const { + return !(*this == rhs); + } + + bool operator < (const KsDef & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class CqlRow { + public: + + static const char* ascii_fingerprint; // = "470EFC558004E98D92D604898305C04E"; + static const uint8_t binary_fingerprint[16]; // = {0x47,0x0E,0xFC,0x55,0x80,0x04,0xE9,0x8D,0x92,0xD6,0x04,0x89,0x83,0x05,0xC0,0x4E}; + + CqlRow() : key("") { + } + + virtual ~CqlRow() throw() {} + + std::string key; + std::vector columns; + + void __set_key(const std::string& val) { + key = val; + } + + void __set_columns(const std::vector & val) { + columns = val; + } + + bool operator == (const CqlRow & rhs) const + { + if (!(key == rhs.key)) + return false; + if (!(columns == rhs.columns)) + return false; + return true; + } + bool operator != (const CqlRow &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CqlRow & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + + +class CqlMetadata { + public: + + static const char* ascii_fingerprint; // = "B7C5A4AA9652C744A48EBC1C12D531E7"; + static const uint8_t binary_fingerprint[16]; // = {0xB7,0xC5,0xA4,0xAA,0x96,0x52,0xC7,0x44,0xA4,0x8E,0xBC,0x1C,0x12,0xD5,0x31,0xE7}; + + CqlMetadata() : default_name_type(""), default_value_type("") { + } + + virtual ~CqlMetadata() throw() {} + + std::map name_types; + std::map value_types; + std::string default_name_type; + std::string default_value_type; + + void __set_name_types(const std::map & val) { + name_types = val; + } + + void __set_value_types(const std::map & val) { + value_types = val; + } + + void __set_default_name_type(const std::string& val) { + default_name_type = val; + } + + void __set_default_value_type(const std::string& val) { + default_value_type = val; + } + + bool operator == (const CqlMetadata & rhs) const + { + if (!(name_types == rhs.name_types)) + return false; + if (!(value_types == rhs.value_types)) + return false; + if (!(default_name_type == rhs.default_name_type)) + return false; + if (!(default_value_type == rhs.default_value_type)) + return false; + return true; + } + bool operator != (const CqlMetadata &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CqlMetadata & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _CqlResult__isset { + _CqlResult__isset() : rows(false), num(false), schema(false) {} + bool rows; + bool num; + bool schema; +} _CqlResult__isset; + +class CqlResult { + public: + + static const char* ascii_fingerprint; // = "521B9CE5AF77539F7267F6952B609E81"; + static const uint8_t binary_fingerprint[16]; // = {0x52,0x1B,0x9C,0xE5,0xAF,0x77,0x53,0x9F,0x72,0x67,0xF6,0x95,0x2B,0x60,0x9E,0x81}; + + CqlResult() : type((CqlResultType::type)0), num(0) { + } + + virtual ~CqlResult() throw() {} + + CqlResultType::type type; + std::vector rows; + int32_t num; + CqlMetadata schema; + + _CqlResult__isset __isset; + + void __set_type(const CqlResultType::type val) { + type = val; + } + + void __set_rows(const std::vector & val) { + rows = val; + __isset.rows = true; + } + + void __set_num(const int32_t val) { + num = val; + __isset.num = true; + } + + void __set_schema(const CqlMetadata& val) { + schema = val; + __isset.schema = true; + } + + bool operator == (const CqlResult & rhs) const + { + if (!(type == rhs.type)) + return false; + if (__isset.rows != rhs.__isset.rows) + return false; + else if (__isset.rows && !(rows == rhs.rows)) + return false; + if (__isset.num != rhs.__isset.num) + return false; + else if (__isset.num && !(num == rhs.num)) + return false; + if (__isset.schema != rhs.__isset.schema) + return false; + else if (__isset.schema && !(schema == rhs.schema)) + return false; + return true; + } + bool operator != (const CqlResult &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CqlResult & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +typedef struct _CqlPreparedResult__isset { + _CqlPreparedResult__isset() : variable_types(false), variable_names(false) {} + bool variable_types; + bool variable_names; +} _CqlPreparedResult__isset; + +class CqlPreparedResult { + public: + + static const char* ascii_fingerprint; // = "7E1663EC688DFDC28722BF36F9F64E6F"; + static const uint8_t binary_fingerprint[16]; // = {0x7E,0x16,0x63,0xEC,0x68,0x8D,0xFD,0xC2,0x87,0x22,0xBF,0x36,0xF9,0xF6,0x4E,0x6F}; + + CqlPreparedResult() : itemId(0), count(0) { + } + + virtual ~CqlPreparedResult() throw() {} + + int32_t itemId; + int32_t count; + std::vector variable_types; + std::vector variable_names; + + _CqlPreparedResult__isset __isset; + + void __set_itemId(const int32_t val) { + itemId = val; + } + + void __set_count(const int32_t val) { + count = val; + } + + void __set_variable_types(const std::vector & val) { + variable_types = val; + __isset.variable_types = true; + } + + void __set_variable_names(const std::vector & val) { + variable_names = val; + __isset.variable_names = true; + } + + bool operator == (const CqlPreparedResult & rhs) const + { + if (!(itemId == rhs.itemId)) + return false; + if (!(count == rhs.count)) + return false; + if (__isset.variable_types != rhs.__isset.variable_types) + return false; + else if (__isset.variable_types && !(variable_types == rhs.variable_types)) + return false; + if (__isset.variable_names != rhs.__isset.variable_names) + return false; + else if (__isset.variable_names && !(variable_names == rhs.variable_names)) + return false; + return true; + } + bool operator != (const CqlPreparedResult &rhs) const { + return !(*this == rhs); + } + + bool operator < (const CqlPreparedResult & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + +}; + +}}} // namespace + +#endif diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc new file mode 100644 index 00000000000..4dec67202bf --- /dev/null +++ b/storage/cassandra/ha_cassandra.cc @@ -0,0 +1,727 @@ +/* + MP AB copyrights +*/ + +#ifdef USE_PRAGMA_IMPLEMENTATION +#pragma implementation // gcc: Class implementation +#endif + +#include +#include "ha_cassandra.h" +#include "sql_class.h" + +static handler *cassandra_create_handler(handlerton *hton, + TABLE_SHARE *table, + MEM_ROOT *mem_root); + + +handlerton *cassandra_hton; + + +/* + Hash used to track the number of open tables; variable for example share + methods +*/ +static HASH cassandra_open_tables; + +/* The mutex used to init the hash; variable for example share methods */ +mysql_mutex_t cassandra_mutex; + + +/** + Structure for CREATE TABLE options (table options). + It needs to be called ha_table_option_struct. + + The option values can be specified in the CREATE TABLE at the end: + CREATE TABLE ( ... ) *here* +*/ + +struct ha_table_option_struct +{ + const char *host; + const char *keyspace; + const char *column_family; +}; + + +ha_create_table_option cassandra_table_option_list[]= +{ + /* + one option that takes an arbitrary string + */ + HA_TOPTION_STRING("thrift_host", host), + HA_TOPTION_STRING("keyspace", keyspace), + HA_TOPTION_STRING("column_family", column_family), + HA_TOPTION_END +}; + + +/** + @brief + Function we use in the creation of our hash to get key. +*/ + +static uchar* cassandra_get_key(CASSANDRA_SHARE *share, size_t *length, + my_bool not_used __attribute__((unused))) +{ + *length=share->table_name_length; + return (uchar*) share->table_name; +} + +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key ex_key_mutex_example, ex_key_mutex_CASSANDRA_SHARE_mutex; + +static PSI_mutex_info all_cassandra_mutexes[]= +{ + { &ex_key_mutex_example, "cassandra", PSI_FLAG_GLOBAL}, + { &ex_key_mutex_CASSANDRA_SHARE_mutex, "CASSANDRA_SHARE::mutex", 0} +}; + +static void init_cassandra_psi_keys() +{ + const char* category= "cassandra"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_cassandra_mutexes); + PSI_server->register_mutex(category, all_cassandra_mutexes, count); +} +#endif + +static int cassandra_init_func(void *p) +{ + DBUG_ENTER("cassandra_init_func"); + +#ifdef HAVE_PSI_INTERFACE + init_cassandra_psi_keys(); +#endif + + cassandra_hton= (handlerton *)p; + mysql_mutex_init(ex_key_mutex_example, &cassandra_mutex, MY_MUTEX_INIT_FAST); + (void) my_hash_init(&cassandra_open_tables,system_charset_info,32,0,0, + (my_hash_get_key) cassandra_get_key,0,0); + + cassandra_hton->state= SHOW_OPTION_YES; + cassandra_hton->create= cassandra_create_handler; + cassandra_hton->flags= HTON_CAN_RECREATE; + cassandra_hton->table_options= cassandra_table_option_list; + //cassandra_hton->field_options= example_field_option_list; + cassandra_hton->field_options= NULL; + + DBUG_RETURN(0); +} + + +static int cassandra_done_func(void *p) +{ + int error= 0; + DBUG_ENTER("cassandra_done_func"); + if (cassandra_open_tables.records) + error= 1; + my_hash_free(&cassandra_open_tables); + mysql_mutex_destroy(&cassandra_mutex); + DBUG_RETURN(error); +} + + +/** + @brief + Example of simple lock controls. The "share" it creates is a + structure we will pass to each cassandra handler. Do you have to have + one of these? Well, you have pieces that are used for locking, and + they are needed to function. +*/ + +static CASSANDRA_SHARE *get_share(const char *table_name, TABLE *table) +{ + CASSANDRA_SHARE *share; + uint length; + char *tmp_name; + + mysql_mutex_lock(&cassandra_mutex); + length=(uint) strlen(table_name); + + if (!(share=(CASSANDRA_SHARE*) my_hash_search(&cassandra_open_tables, + (uchar*) table_name, + length))) + { + if (!(share=(CASSANDRA_SHARE *) + my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), + &share, sizeof(*share), + &tmp_name, length+1, + NullS))) + { + mysql_mutex_unlock(&cassandra_mutex); + return NULL; + } + + share->use_count=0; + share->table_name_length=length; + share->table_name=tmp_name; + strmov(share->table_name,table_name); + if (my_hash_insert(&cassandra_open_tables, (uchar*) share)) + goto error; + thr_lock_init(&share->lock); + mysql_mutex_init(ex_key_mutex_CASSANDRA_SHARE_mutex, + &share->mutex, MY_MUTEX_INIT_FAST); + } + share->use_count++; + mysql_mutex_unlock(&cassandra_mutex); + + return share; + +error: + mysql_mutex_destroy(&share->mutex); + my_free(share); + + return NULL; +} + + +/** + @brief + Free lock controls. We call this whenever we close a table. If the table had + the last reference to the share, then we free memory associated with it. +*/ + +static int free_share(CASSANDRA_SHARE *share) +{ + mysql_mutex_lock(&cassandra_mutex); + if (!--share->use_count) + { + my_hash_delete(&cassandra_open_tables, (uchar*) share); + thr_lock_delete(&share->lock); + mysql_mutex_destroy(&share->mutex); + my_free(share); + } + mysql_mutex_unlock(&cassandra_mutex); + + return 0; +} + + +static handler* cassandra_create_handler(handlerton *hton, + TABLE_SHARE *table, + MEM_ROOT *mem_root) +{ + return new (mem_root) ha_cassandra(hton, table); +} + + +ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) + :handler(hton, table_arg), + se(NULL), names_and_vals(NULL) +{} + + +static const char *ha_cassandra_exts[] = { + NullS +}; + +const char **ha_cassandra::bas_ext() const +{ + return ha_cassandra_exts; +} + + +int ha_cassandra::open(const char *name, int mode, uint test_if_locked) +{ + DBUG_ENTER("ha_cassandra::open"); + + if (!(share = get_share(name, table))) + DBUG_RETURN(1); + thr_lock_data_init(&share->lock,&lock,NULL); + + ha_table_option_struct *options= table->s->option_struct; + fprintf(stderr, "ha_cass: open thrift_host=%s keyspace=%s column_family=%s\n", + options->host, options->keyspace, options->column_family); + + DBUG_ASSERT(!se); + if (!options->host || !options->keyspace || !options->column_family) + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + se= get_cassandra_se(); + se->set_column_family(options->column_family); + if (se->connect(options->host, options->keyspace)) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); + DBUG_RETURN(HA_ERR_NO_CONNECTION); + } + + DBUG_RETURN(0); +} + + +int ha_cassandra::close(void) +{ + DBUG_ENTER("ha_cassandra::close"); + delete se; + se= NULL; + if (names_and_vals) + { + my_free(names_and_vals); + names_and_vals= NULL; + } + DBUG_RETURN(free_share(share)); +} + + +/** + @brief + create() is called to create a database. The variable name will have the name + of the table. + + @details + When create() is called you do not need to worry about + opening the table. Also, the .frm file will have already been + created so adjusting create_info is not necessary. You can overwrite + the .frm file at this point if you wish to change the table + definition, but there are no methods currently provided for doing + so. + + Called from handle.cc by ha_create_table(). + + @see + ha_create_table() in handle.cc +*/ + +int ha_cassandra::create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) +{ + ha_table_option_struct *options= table_arg->s->option_struct; + DBUG_ENTER("ha_cassandra::create"); + DBUG_ASSERT(options); + //psergey-todo: This is called for CREATE TABLE... check options here. + +/* + if (table_arg->s->fields != 2) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "The table must have two fields"); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } +*/ + + Field **pfield= table_arg->s->field; + if (strcmp((*pfield)->field_name, "rowkey")) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'"); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } + + if (table_arg->s->keys != 1 || table_arg->s->primary_key !=0 || + table_arg->key_info[0].key_parts != 1 || + table_arg->key_info[0].key_part[0].fieldnr != 1) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Table must have one PRIMARY KEY(rowkey)"); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } + +/* + pfield++; + if (strcmp((*pfield)->field_name, "data")) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Second column must be named 'data'"); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } +*/ + + + +#ifndef DBUG_OFF +/* + DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ + "boolparam: %u", + (options->strparam ? options->strparam : ""), + options->ullparam, options->enumparam, options->boolparam)); + + psergey-todo: check table definition! + for (Field **field= table_arg->s->field; *field; field++) + { + ha_field_option_struct *field_options= (*field)->option_struct; + DBUG_ASSERT(field_options); + DBUG_PRINT("info", ("field: %s complex: '%-.64s'", + (*field)->field_name, + (field_options->complex_param_to_parse_it_in_engine ? + field_options->complex_param_to_parse_it_in_engine : + ""))); + } +*/ +#endif + DBUG_ASSERT(!se); + if (!options->host || !options->keyspace || !options->column_family) + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + se= get_cassandra_se(); + se->set_column_family(options->column_family); + if (se->connect(options->host, options->keyspace)) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); + DBUG_RETURN(HA_ERR_NO_CONNECTION); + } + + /* + TODO: what about mapping the primary key? It has a 'type', too... + see CfDef::key_validation_class ? see also CfDef::key_alias? + */ + se->first_ddl_column(); + char *col_name; + int col_name_len; + char *col_type; + int col_type_len; + while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, + &col_type_len)) + { + /* Mapping for the 1st field is already known */ + for (Field **field= table_arg->s->field + 1; *field; field++) + { + if (!strcmp((*field)->field_name, col_name)) + { + //map_field_to_type(field, col_type); + } + } + } + + DBUG_RETURN(0); +} + +/* + Mapping needs to + - copy value from MySQL record to Thrift buffer + - copy value from Thrift bufer to MySQL record.. + +*/ + +const char * const validator_bigint="org.apache.cassandra.db.marshal.LongType"; +const char * const validator_int="org.apache.cassandra.db.marshal.Int32Type"; +const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType"; + +const char * const validator_float= "org.apache.cassandra.db.marshal.FloatType"; +const char * const validator_double= "org.apache.cassandra.db.marshal.DoubleType"; + +void map_field_to_type(Field *field, const char *validator_name) +{ + switch(field->type()) { + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + if (!strcmp(validator_name, validator_bigint)) + { + //setup bigint validator + } + break; + case MYSQL_TYPE_FLOAT: + if (!strcmp(validator_name, validator_float)) + break; + case MYSQL_TYPE_DOUBLE: + if (!strcmp(validator_name, validator_double)) + break; + default: + DBUG_ASSERT(0); + } +} + + +void store_key_image_to_rec(Field *field, uchar *ptr, uint len); + +int ha_cassandra::index_read_map(uchar *buf, const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + int rc; + DBUG_ENTER("ha_cassandra::index_read_map"); + + if (find_flag != HA_READ_KEY_EXACT) + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + + // todo: decode the search key. + uint key_len= calculate_key_len(table, active_index, key, keypart_map); + store_key_image_to_rec(table->field[0], (uchar*)key, key_len); + + char buff[256]; + String tmp(buff,sizeof(buff), &my_charset_bin); + tmp.length(0); + String *str; + str= table->field[0]->val_str(&tmp); + + bool found; + if (se->get_slice((char*)str->ptr(), str->length(), get_names_and_vals(), &found)) + rc= HA_ERR_INTERNAL_ERROR; + else + { + if (found) + { + //NameAndValue *nv= get_names_and_vals(); + // TODO: walk through the (name, value) pairs and return values. + } + else + rc= HA_ERR_KEY_NOT_FOUND; + } +#ifdef NEW_CODE + + se->get_slice(); + + for each column + { + find column; + } +#endif + + DBUG_RETURN(rc); +} + + +int ha_cassandra::write_row(uchar *buf) +{ + my_bitmap_map *old_map; + char buff[512]; + NameAndValue *tuple; + NameAndValue *nv; + DBUG_ENTER("ha_cassandra::write_row"); + + /* Temporary malloc-happy code just to get INSERTs to work */ + nv= tuple= get_names_and_vals(); + old_map= dbug_tmp_use_all_columns(table, table->read_set); + + for (Field **field= table->field; *field; field++, nv++) + { + String tmp(buff,sizeof(buff), &my_charset_bin); + tmp.length(0); + String *str; + str= (*field)->val_str(&tmp); + nv->name= (char*)(*field)->field_name; + nv->value_len= str->length(); + nv->value= (char*)my_malloc(nv->value_len, MYF(0)); + memcpy(nv->value, str->ptr(), nv->value_len); + } + nv->name= NULL; + dbug_tmp_restore_column_map(table->read_set, old_map); + + //invoke! + bool res= se->insert(tuple); + + for (nv= tuple; nv->name; nv++) + { + my_free(nv->value); + } + + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); +} + + +NameAndValue *ha_cassandra::get_names_and_vals() +{ + if (names_and_vals) + return names_and_vals; + else + { + size_t size= sizeof(NameAndValue) * (table->s->fields + 1); + names_and_vals= (NameAndValue*)my_malloc(size ,0); + memset(names_and_vals, 0, size); + return names_and_vals; + } +} + + +///////////////////////////////////////////////////////////////////////////// +// Dummy implementations start +///////////////////////////////////////////////////////////////////////////// + + +int ha_cassandra::index_next(uchar *buf) +{ + int rc; + DBUG_ENTER("ha_cassandra::index_next"); + rc= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(rc); +} + + +int ha_cassandra::index_prev(uchar *buf) +{ + int rc; + DBUG_ENTER("ha_cassandra::index_prev"); + rc= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(rc); +} + + +int ha_cassandra::index_first(uchar *buf) +{ + int rc; + DBUG_ENTER("ha_cassandra::index_first"); + rc= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(rc); +} + +int ha_cassandra::index_last(uchar *buf) +{ + int rc; + DBUG_ENTER("ha_cassandra::index_last"); + rc= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(rc); +} + +int ha_cassandra::rnd_init(bool scan) +{ + DBUG_ENTER("ha_cassandra::rnd_init"); + DBUG_RETURN(0); +} + +int ha_cassandra::rnd_end() +{ + DBUG_ENTER("ha_cassandra::rnd_end"); + DBUG_RETURN(0); +} + + +int ha_cassandra::rnd_next(uchar *buf) +{ + int rc; + DBUG_ENTER("ha_cassandra::rnd_next"); + rc= HA_ERR_END_OF_FILE; + DBUG_RETURN(rc); +} + +void ha_cassandra::position(const uchar *record) +{ + DBUG_ENTER("ha_cassandra::position"); + DBUG_VOID_RETURN; +} + +int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) +{ + int rc; + DBUG_ENTER("ha_cassandra::rnd_pos"); + rc= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(rc); +} + +ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, + key_range *max_key) +{ + DBUG_ENTER("ha_cassandra::records_in_range"); + DBUG_RETURN(10); // low number to force index usage +} + + +int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) +{ + + DBUG_ENTER("ha_cassandra::update_row"); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} + + +int ha_cassandra::info(uint flag) +{ + DBUG_ENTER("ha_cassandra::info"); + DBUG_RETURN(0); +} + + +int ha_cassandra::extra(enum ha_extra_function operation) +{ + DBUG_ENTER("ha_cassandra::extra"); + DBUG_RETURN(0); +} + + +THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, + THR_LOCK_DATA **to, + enum thr_lock_type lock_type) +{ + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + lock.type=lock_type; + *to++= &lock; + return to; +} + + +int ha_cassandra::external_lock(THD *thd, int lock_type) +{ + DBUG_ENTER("ha_cassandra::external_lock"); + DBUG_RETURN(0); +} + +int ha_cassandra::delete_table(const char *name) +{ + DBUG_ENTER("ha_cassandra::delete_table"); + /* This is not implemented but we want someone to be able that it works. */ + DBUG_RETURN(0); +} + + +int ha_cassandra::delete_row(const uchar *buf) +{ + DBUG_ENTER("ha_cassandra::delete_row"); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} + + +int ha_cassandra::delete_all_rows() +{ + DBUG_ENTER("ha_cassandra::delete_all_rows"); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} + + +/** + check_if_incompatible_data() called if ALTER TABLE can't detect otherwise + if new and old definition are compatible + + @details If there are no other explicit signs like changed number of + fields this function will be called by compare_tables() + (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm + file. + +*/ + +bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes) +{ + //ha_table_option_struct *param_old, *param_new; + DBUG_ENTER("ha_cassandra::check_if_incompatible_data"); + + DBUG_RETURN(COMPATIBLE_DATA_YES); +} + + +///////////////////////////////////////////////////////////////////////////// +// Dummy implementations end +///////////////////////////////////////////////////////////////////////////// + + +static struct st_mysql_sys_var* cassandra_system_variables[]= { +// MYSQL_SYSVAR(enum_var), +// MYSQL_SYSVAR(ulong_var), + NULL +}; + + +struct st_mysql_storage_engine cassandra_storage_engine= +{ MYSQL_HANDLERTON_INTERFACE_VERSION }; + +static struct st_mysql_show_var func_status[]= +{ +// {"example_func_example", (char *)show_func_example, SHOW_FUNC}, + {0,0,SHOW_UNDEF} +}; + +maria_declare_plugin(cassandra) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &cassandra_storage_engine, + "CASSANDRA", + "Monty Program Ab", + "Cassandra storage engine", + PLUGIN_LICENSE_GPL, + cassandra_init_func, /* Plugin Init */ + cassandra_done_func, /* Plugin Deinit */ + 0x0001, /* version number (0.1) */ + func_status, /* status variables */ + cassandra_system_variables, /* system variables */ + "0.1", /* string version */ + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */ +} +maria_declare_plugin_end; diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h new file mode 100644 index 00000000000..fc10dfb247c --- /dev/null +++ b/storage/cassandra/ha_cassandra.h @@ -0,0 +1,218 @@ +/* + MP AB copyrights +*/ +#ifdef USE_PRAGMA_INTERFACE +#pragma interface /* gcc class implementation */ +#endif + + +#include "my_global.h" /* ulonglong */ +#include "thr_lock.h" /* THR_LOCK, THR_LOCK_DATA */ +#include "handler.h" /* handler */ +#include "my_base.h" /* ha_rows */ + +#include "cassandra_se.h" + +/** @brief + CASSANDRA_SHARE is a structure that will be shared among all open handlers. + This example implements the minimum of what you will probably need. +*/ +typedef struct st_cassandra_share { + char *table_name; + uint table_name_length,use_count; + mysql_mutex_t mutex; + THR_LOCK lock; +} CASSANDRA_SHARE; + + +/** @brief + Class definition for the storage engine +*/ +class ha_cassandra: public handler +{ + THR_LOCK_DATA lock; ///< MySQL lock + CASSANDRA_SHARE *share; ///< Shared lock info + + Cassandra_se_interface *se; + + /* pre-allocated array of #fields elements */ + NameAndValue *names_and_vals; + NameAndValue *get_names_and_vals(); +public: + ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); + ~ha_cassandra() + { + delete se; + } + + /** @brief + The name that will be used for display purposes. + */ + const char *table_type() const { return "CASSANDRA"; } + + /** @brief + The name of the index type that will be used for display. + Don't implement this method unless you really have indexes. + */ + const char *index_type(uint inx) { return "HASH"; } + + /** @brief + The file extensions. + */ + const char **bas_ext() const; + + /** @brief + This is a list of flags that indicate what functionality the storage engine + implements. The current table flags are documented in handler.h + */ + ulonglong table_flags() const + { + /* + We are saying that this engine is just statement capable to have + an engine that can only handle statement-based logging. This is + used in testing. + */ + return HA_BINLOG_STMT_CAPABLE; + } + + /** @brief + This is a bitmap of flags that indicates how the storage engine + implements indexes. The current index flags are documented in + handler.h. If you do not implement indexes, just return zero here. + + @details + part is the key part to check. First key part is 0. + If all_parts is set, MySQL wants to know the flags for the combined + index, up to and including 'part'. + */ + ulong index_flags(uint inx, uint part, bool all_parts) const + { + return 0; + } + + /** @brief + unireg.cc will call max_supported_record_length(), max_supported_keys(), + max_supported_key_parts(), uint max_supported_key_length() + to make sure that the storage engine can handle the data it is about to + send. Return *real* limits of your storage engine here; MySQL will do + min(your_limits, MySQL_limits) automatically. + */ + uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } + + /* Support only one Primary Key, for now */ + uint max_supported_keys() const { return 1; } + uint max_supported_key_parts() const { return 1; } + + /** @brief + unireg.cc will call this to make sure that the storage engine can handle + the data it is about to send. Return *real* limits of your storage engine + here; MySQL will do min(your_limits, MySQL_limits) automatically. + + @details + There is no need to implement ..._key_... methods if your engine doesn't + support indexes. + */ + uint max_supported_key_length() const { return 16*1024; /* just to return something*/ } + + /* At the moment, we're ok with default handler::index_init() implementation. */ + int index_read_map(uchar * buf, const uchar * key, + key_part_map keypart_map, + enum ha_rkey_function find_flag); + + /** @brief + Called in test_quick_select to determine if indexes should be used. + */ + virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } + + /** @brief + This method will never be called if you do not implement indexes. + */ + virtual double read_time(uint, uint, ha_rows rows) + { return (double) rows / 20.0+1; } + + /* + Everything below are methods that we implement in ha_example.cc. + + Most of these methods are not obligatory, skip them and + MySQL will treat them as not implemented + */ + /** @brief + We implement this in ha_example.cc; it's a required method. + */ + int open(const char *name, int mode, uint test_if_locked); // required + + /** @brief + We implement this in ha_example.cc; it's a required method. + */ + int close(void); // required + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int write_row(uchar *buf); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int update_row(const uchar *old_data, uchar *new_data); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int delete_row(const uchar *buf); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int index_next(uchar *buf); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int index_prev(uchar *buf); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int index_first(uchar *buf); + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ + int index_last(uchar *buf); + + /** @brief + Unlike index_init(), rnd_init() can be called two consecutive times + without rnd_end() in between (it only makes sense if scan=1). In this + case, the second call should prepare for the new table scan (e.g if + rnd_init() allocates the cursor, the second call should position the + cursor to the start of the table; no need to deallocate and allocate + it again. This is a required method. + */ + int rnd_init(bool scan); //required + int rnd_end(); + int rnd_next(uchar *buf); ///< required + int rnd_pos(uchar *buf, uchar *pos); ///< required + void position(const uchar *record); ///< required + int info(uint); ///< required + int extra(enum ha_extra_function operation); + int external_lock(THD *thd, int lock_type); ///< required + int delete_all_rows(void); + ha_rows records_in_range(uint inx, key_range *min_key, + key_range *max_key); + int delete_table(const char *from); + int create(const char *name, TABLE *form, + HA_CREATE_INFO *create_info); ///< required + bool check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes); + + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, + enum thr_lock_type lock_type); ///< required +}; -- cgit v1.2.1 From 0d840d4d2370cde9e581ac9bc522d103d95badab Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 18 Aug 2012 16:28:35 +0400 Subject: MDEV-431: Cassandra storage engine - Introduce type converters (so far rather trivial) - switch INSERT to using batch_mutate() --- mysql-test/t/cassandra.test | 2 +- storage/cassandra/cassandra_se.cc | 189 ++++++++++++++-------- storage/cassandra/cassandra_se.h | 8 +- storage/cassandra/ha_cassandra.cc | 333 +++++++++++++++++++++++++++++--------- storage/cassandra/ha_cassandra.h | 7 + 5 files changed, 390 insertions(+), 149 deletions(-) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 34a6909af38..6acb5f769ab 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -49,7 +49,7 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar); ############################################################################ # Now, create a table for real and insert data -create table t1 (rowkey char(36) primary key, column1 char(60)) engine=cassandra +create table t1 (rowkey char(36) primary key, data1 varchar(60)) engine=cassandra thrift_host='localhost' keyspace='mariadbtest' column_family='cf1'; insert into t1 values ('key0', 'data1'); diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 1bc799d09c6..e3d731815f9 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -43,53 +43,56 @@ class Cassandra_se_impl: public Cassandra_se_interface std::string column_family; std::string keyspace; - /* DDL checks */ + /* DDL data */ KsDef ks_def; /* KeySpace we're using (TODO: put this in table->share) */ CfDef cf_def; /* Column family we're using (TODO: put in table->share)*/ std::vector::iterator column_ddl_it; /* The list that was returned by the last key lookup */ - std::vector col_supercol_vec; + std::vector column_data_vec; + std::vector::iterator column_data_it; + + /* Insert preparation */ + typedef std::map > ColumnFamilyToMutation; + typedef std::map KeyToCfMutationMap; + + KeyToCfMutationMap batch_mutation; /* Prepare operation here */ + std::string key_to_insert; + int64_t insert_timestamp; + std::vector* insert_list; public: - Cassandra_se_impl() : cass(NULL) {} virtual ~Cassandra_se_impl(){ delete cass; } + /* Connection and DDL checks */ bool connect(const char *host, const char *keyspace); + void set_column_family(const char *cfname) { column_family.assign(cfname); } - virtual void set_column_family(const char *cfname) - { - column_family.assign(cfname); - } - - virtual bool insert(NameAndValue *fields); - virtual bool get_slice(char *key, size_t key_len, NameAndValue *row, bool *found); - - - /* Functions to enumerate ColumnFamily's DDL data */ bool setup_ddl_checks(); void first_ddl_column(); bool next_ddl_column(char **name, int *name_len, char **value, int *value_len); + + /* Writes */ + void start_prepare_insert(const char *key, int key_len); + void add_insert_column(const char *name, const char *value, int value_len); + bool do_insert(); + + /* Reads */ + bool get_slice(char *key, size_t key_len, bool *found); + bool get_next_read_column(char **name, char **value, int *value_len); + }; +///////////////////////////////////////////////////////////////////////////// +// Connection and setup +///////////////////////////////////////////////////////////////////////////// Cassandra_se_interface *get_cassandra_se() { return new Cassandra_se_impl; } -#define CASS_TRY(x) try { \ - x; \ - }catch(TTransportException te){ \ - print_error("%s [%d]", te.what(), te.getType()); \ - }catch(InvalidRequestException ire){ \ - print_error("%s [%s]", ire.what(), ire.why.c_str()); \ - }catch(NotFoundException nfe){ \ - print_error("%s", nfe.what()); \ - } catch(...) { \ - print_error("Unknown Exception"); \ - } bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) { @@ -121,10 +124,9 @@ bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) print_error("Unknown Exception"); } - // For now: cur_consistency_level= ConsistencyLevel::ONE; - if (setup_ddl_checks()) + if (!res && setup_ddl_checks()) res= true; return res; } @@ -176,13 +178,20 @@ bool Cassandra_se_impl::next_ddl_column(char **name, int *name_len, return false; } +///////////////////////////////////////////////////////////////////////////// +// Data writes +///////////////////////////////////////////////////////////////////////////// -bool Cassandra_se_impl::insert(NameAndValue *fields) +void Cassandra_se_impl::start_prepare_insert(const char *key, int key_len) { - ColumnParent cparent; - cparent.column_family= column_family; - - Column c; + key_to_insert.assign(key, key_len); + batch_mutation.clear(); + batch_mutation[key_to_insert]= ColumnFamilyToMutation(); + ColumnFamilyToMutation& cf_mut= batch_mutation[key_to_insert]; + + cf_mut[column_family]= std::vector(); + insert_list= &cf_mut[column_family]; + struct timeval td; gettimeofday(&td, NULL); int64_t ms = td.tv_sec; @@ -190,37 +199,57 @@ bool Cassandra_se_impl::insert(NameAndValue *fields) int64_t usec = td.tv_usec; usec = usec / 1000; ms += usec; - c.timestamp = ms; - c.__isset.timestamp = true; + insert_timestamp= ms; +} + + +void Cassandra_se_impl::add_insert_column(const char *name, const char *value, + int value_len) +{ + Mutation mut; + mut.__isset.column_or_supercolumn= true; + mut.column_or_supercolumn.__isset.column= true; + + Column& col=mut.column_or_supercolumn.column; + col.name.assign(name); + col.value.assign(value, value_len); + col.timestamp= insert_timestamp; + col.__isset.value= true; + col.__isset.timestamp= true; + insert_list->push_back(mut); +} - std::string key; - key.assign(fields->value, fields->value_len); - fields++; - bool res= false; +bool Cassandra_se_impl::do_insert() +{ + bool res= true; try { - /* TODO: switch to batch_mutate(). Or, even to CQL? */ - - // TODO: what should INSERT table (co1, col2) VALUES ('foo', 'bar') mean? - // in SQL, it sets all columns.. what should it mean here? can we have - // it to work only for specified columns? (if yes, what do for - // VALUES()?) - c.__isset.value= true; - for(;fields->name; fields++) - { - c.name.assign(fields->name); - c.value.assign(fields->value, fields->value_len); - cass->insert(key, cparent, c, ConsistencyLevel::ONE); - } + + cass->batch_mutate(batch_mutation, cur_consistency_level); + res= false; - } catch (...) { - res= true; + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); } + return res; } -bool Cassandra_se_impl::get_slice(char *key, size_t key_len, NameAndValue *row, bool *found) +///////////////////////////////////////////////////////////////////////////// +// Reading data +///////////////////////////////////////////////////////////////////////////// + +/* + Make one key lookup. If the record is found, the result is stored locally and + the caller should iterate over it. +*/ + +bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) { ColumnParent cparent; cparent.column_family= column_family; @@ -235,37 +264,57 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, NameAndValue *row, slice_pred.__set_slice_range(sr); try { - std::vector &res= col_supercol_vec; - cass->get_slice(res, rowkey_str, cparent, slice_pred, ConsistencyLevel::ONE); - *found= true; + cass->get_slice(column_data_vec, rowkey_str, cparent, slice_pred, + ConsistencyLevel::ONE); - std::vector::iterator it; - if (res.size() == 0) + if (column_data_vec.size() == 0) { - /* + /* No columns found. Cassandra doesn't allow records without any column => this means the seach key doesn't exist */ *found= false; return false; } - for (it= res.begin(); it < res.end(); it++) - { - ColumnOrSuperColumn cs= *it; - if (!cs.__isset.column) - return true; - row->name= (char*)cs.column.name.c_str(); - row->value= (char*)cs.column.value.c_str(); - row->value_len= cs.column.value.length(); - row++; - } - row->name= NULL; + *found= true; + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); return true; } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); return true; } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); return true; } + + column_data_it= column_data_vec.begin(); + return false; +} + + +bool Cassandra_se_impl::get_next_read_column(char **name, char **value, + int *value_len) +{ + while (1) + { + if (column_data_it == column_data_vec.end()) + return true; + + if (((*column_data_it).__isset.column)) + break; /* Ok it's a real column. Should be always the case. */ + + column_data_it++; + } + + ColumnOrSuperColumn& cs= *column_data_it; + *name= (char*)cs.column.name.c_str(); + *value= (char*)cs.column.value.c_str(); + *value_len= cs.column.value.length(); + + column_data_it++; return false; } + + diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 1ab14c39602..dea4f0f51ea 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -43,10 +43,14 @@ public: int *value_len)=0; /* Writes */ - virtual bool insert(NameAndValue *fields)=0; + virtual void start_prepare_insert(const char *key, int key_len)=0; + virtual void add_insert_column(const char *name, const char *value, + int value_len)=0; + virtual bool do_insert()=0; /* Reads */ - virtual bool get_slice(char *key, size_t key_len, NameAndValue *row, bool *found)=0 ; + virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ; + virtual bool get_next_read_column(char **name, char **value, int *value_len)=0; /* Passing error messages up to ha_cassandra */ char err_buffer[512]; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 4dec67202bf..757c0fd5e10 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -212,7 +212,8 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), names_and_vals(NULL) + se(NULL), names_and_vals(NULL), + field_converters(NULL) {} @@ -249,6 +250,12 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(HA_ERR_NO_CONNECTION); } + if (setup_field_converters(table->field, table->s->fields)) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "setup_field_converters"); + DBUG_RETURN(HA_ERR_NO_CONNECTION); + } + DBUG_RETURN(0); } @@ -317,16 +324,6 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, DBUG_RETURN(HA_WRONG_CREATE_OPTION); } -/* - pfield++; - if (strcmp((*pfield)->field_name, "data")) - { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Second column must be named 'data'"); - DBUG_RETURN(HA_WRONG_CREATE_OPTION); - } -*/ - - #ifndef DBUG_OFF /* @@ -358,29 +355,12 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); DBUG_RETURN(HA_ERR_NO_CONNECTION); } - - /* - TODO: what about mapping the primary key? It has a 'type', too... - see CfDef::key_validation_class ? see also CfDef::key_alias? - */ - se->first_ddl_column(); - char *col_name; - int col_name_len; - char *col_type; - int col_type_len; - while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, - &col_type_len)) + + if (setup_field_converters(table_arg->s->field, table_arg->s->fields)) { - /* Mapping for the 1st field is already known */ - for (Field **field= table_arg->s->field + 1; *field; field++) - { - if (!strcmp((*field)->field_name, col_name)) - { - //map_field_to_type(field, col_type); - } - } + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "setup_field_converters"); + DBUG_RETURN(HA_ERR_NO_CONNECTION); } - DBUG_RETURN(0); } @@ -391,37 +371,224 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, */ -const char * const validator_bigint="org.apache.cassandra.db.marshal.LongType"; -const char * const validator_int="org.apache.cassandra.db.marshal.Int32Type"; +/* Converter base */ +class ColumnDataConverter +{ +public: + Field *field; + + /* This will save Cassandra's data in the Field */ + virtual void cassandra_to_mariadb(const char *cass_data, + int cass_data_len)=0; + + /* + This will get data from the Field pointer, store Cassandra's form + in internal buffer, and return pointer/size. + */ + virtual void mariadb_to_cassandra(char **cass_data, int *cass_data_len)=0; + virtual ~ColumnDataConverter() {}; +}; + + +class DoubleDataConverter : public ColumnDataConverter +{ + double buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + DBUG_ASSERT(cass_data_len == sizeof(double)); + double *pdata= (double*) cass_data; + field->store(*pdata); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + buf= field->val_real(); + *cass_data= (char*)&buf; + *cass_data_len=sizeof(double); + } + ~DoubleDataConverter(){} +}; + + +class FloatDataConverter : public ColumnDataConverter +{ + float buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + DBUG_ASSERT(cass_data_len == sizeof(float)); + float *pdata= (float*) cass_data; + field->store(*pdata); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + buf= field->val_real(); + *cass_data= (char*)&buf; + *cass_data_len=sizeof(float); + } + ~FloatDataConverter(){} +}; + + +class BigintDataConverter : public ColumnDataConverter +{ + longlong buf; +public: + void flip(const char *from, char* to) + { + to[0]= from[7]; + to[1]= from[6]; + to[2]= from[5]; + to[3]= from[4]; + to[4]= from[3]; + to[5]= from[2]; + to[6]= from[1]; + to[7]= from[0]; + } + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + longlong tmp; + DBUG_ASSERT(cass_data_len == sizeof(longlong)); + flip(cass_data, (char*)&tmp); + field->store(tmp); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + longlong tmp= field->val_int(); + flip((const char*)&tmp, (char*)&buf); + *cass_data= (char*)&buf; + *cass_data_len=sizeof(longlong); + } + ~BigintDataConverter(){} +}; + + +class StringCopyConverter : public ColumnDataConverter +{ + String buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + field->store(cass_data, cass_data_len,field->charset()); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + String *pstr= field->val_str(&buf); + *cass_data= (char*)pstr->c_ptr(); + *cass_data_len= pstr->length(); + } + ~StringCopyConverter(){} +}; + + +const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType"; +const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type"; const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType"; -const char * const validator_float= "org.apache.cassandra.db.marshal.FloatType"; -const char * const validator_double= "org.apache.cassandra.db.marshal.DoubleType"; +const char * const validator_float= "org.apache.cassandra.db.marshal.FloatType"; +const char * const validator_double= "org.apache.cassandra.db.marshal.DoubleType"; + +const char * const validator_blob= "org.apache.cassandra.db.marshal.BytesType"; +const char * const validator_ascii= "org.apache.cassandra.db.marshal.AsciiType"; +const char * const validator_text= "org.apache.cassandra.db.marshal.UTF8Type"; + -void map_field_to_type(Field *field, const char *validator_name) +ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { + ColumnDataConverter *res= NULL; + switch(field->type()) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: if (!strcmp(validator_name, validator_bigint)) - { - //setup bigint validator - } + res= new BigintDataConverter; break; case MYSQL_TYPE_FLOAT: if (!strcmp(validator_name, validator_float)) + res= new FloatDataConverter; break; case MYSQL_TYPE_DOUBLE: if (!strcmp(validator_name, validator_double)) + res= new DoubleDataConverter; break; - default: - DBUG_ASSERT(0); + + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_VARCHAR: + if (!strcmp(validator_name, validator_blob) || + !strcmp(validator_name, validator_ascii) || + !strcmp(validator_name, validator_text)) + { + res= new StringCopyConverter; + } + break; + default:; } + return res; } +bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) +{ + char *col_name; + int col_name_len; + char *col_type; + int col_type_len; + + DBUG_ASSERT(!field_converters); + size_t memsize= sizeof(ColumnDataConverter*) * n_fields; + if (!(field_converters= (ColumnDataConverter**)my_malloc(memsize, MYF(0)))) + return true; + bzero(field_converters, memsize); + n_field_converters= n_fields; + + /* + TODO: what about mapping the primary key? It has a 'type', too... + see CfDef::key_validation_class ? see also CfDef::key_alias? + */ + + se->first_ddl_column(); + uint n_mapped= 0; + while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, + &col_type_len)) + { + /* Mapping for the 1st field is already known */ + for (Field **field= field_arg + 1; *field; field++) + { + if (!strcmp((*field)->field_name, col_name)) + { + n_mapped++; + ColumnDataConverter **conv= field_converters + (*field)->field_index; + if (!(*conv= map_field_to_validator(*field, col_type))) + return true; + (*conv)->field= *field; + } + } + } + + if (n_mapped != n_fields - 1) + return true; + + return false; +} + + +void ha_cassandra::free_field_converters() +{ + if (field_converters) + { + for (uint i=0; i < n_field_converters; i++) + delete field_converters[i]; + my_free(field_converters); + field_converters= NULL; + } +} + void store_key_image_to_rec(Field *field, uchar *ptr, uint len); int ha_cassandra::index_read_map(uchar *buf, const uchar *key, @@ -445,27 +612,42 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, str= table->field[0]->val_str(&tmp); bool found; - if (se->get_slice((char*)str->ptr(), str->length(), get_names_and_vals(), &found)) + if (se->get_slice((char*)str->ptr(), str->length(), &found)) rc= HA_ERR_INTERNAL_ERROR; + + /* TODO: what if we're not reading all columns?? */ + if (!found) + { + rc= HA_ERR_KEY_NOT_FOUND; + } else { - if (found) + char *cass_name; + char *cass_value; + int cass_value_len; + Field **field; + + /* Start with all fields being NULL */ + for (field= table->field + 1; *field; field++) + (*field)->set_null(); + + while (!se->get_next_read_column(&cass_name, &cass_value, &cass_value_len)) { - //NameAndValue *nv= get_names_and_vals(); - // TODO: walk through the (name, value) pairs and return values. + // map to our column. todo: use hash or something.. + int idx=1; + for (field= table->field + 1; *field; field++) + { + idx++; + if (!strcmp((*field)->field_name, cass_name)) + { + int fieldnr= (*field)->field_index; + (*field)->set_notnull(); + field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len); + break; + } + } } - else - rc= HA_ERR_KEY_NOT_FOUND; } -#ifdef NEW_CODE - - se->get_slice(); - - for each column - { - find column; - } -#endif DBUG_RETURN(rc); } @@ -475,36 +657,35 @@ int ha_cassandra::write_row(uchar *buf) { my_bitmap_map *old_map; char buff[512]; - NameAndValue *tuple; - NameAndValue *nv; DBUG_ENTER("ha_cassandra::write_row"); - /* Temporary malloc-happy code just to get INSERTs to work */ - nv= tuple= get_names_and_vals(); old_map= dbug_tmp_use_all_columns(table, table->read_set); - - for (Field **field= table->field; *field; field++, nv++) + + /* Convert the key (todo: unify with the rest of the processing) */ { + Field *pk_col= table->field[0]; String tmp(buff,sizeof(buff), &my_charset_bin); - tmp.length(0); String *str; - str= (*field)->val_str(&tmp); - nv->name= (char*)(*field)->field_name; - nv->value_len= str->length(); - nv->value= (char*)my_malloc(nv->value_len, MYF(0)); - memcpy(nv->value, str->ptr(), nv->value_len); + tmp.length(0); + str= pk_col->val_str(&tmp); + + se->start_prepare_insert(str->ptr(), str->length()); } - nv->name= NULL; - dbug_tmp_restore_column_map(table->read_set, old_map); - - //invoke! - bool res= se->insert(tuple); - for (nv= tuple; nv->name; nv++) + /* Convert other fields */ + for (uint i= 1; i < table->s->fields; i++) { - my_free(nv->value); + char *cass_data; + int cass_data_len; + field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len); + se->add_insert_column(field_converters[i]->field->field_name, + cass_data, cass_data_len); } + dbug_tmp_restore_column_map(table->read_set, old_map); + + bool res= se->do_insert(); + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index fc10dfb247c..595b840d360 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -24,6 +24,7 @@ typedef struct st_cassandra_share { THR_LOCK lock; } CASSANDRA_SHARE; +class ColumnDataConverter; /** @brief Class definition for the storage engine @@ -38,6 +39,12 @@ class ha_cassandra: public handler /* pre-allocated array of #fields elements */ NameAndValue *names_and_vals; NameAndValue *get_names_and_vals(); + + + ColumnDataConverter **field_converters; + uint n_field_converters; + bool setup_field_converters(Field **field, uint n_fields); + void free_field_converters(); public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() -- cgit v1.2.1 From ab281741220a1bcb7ec9107bdb4f4b8ea4760e32 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 18 Aug 2012 21:21:50 +0400 Subject: MDEV-431: Cassandra storage engine - Got range reads to work (except for unpacking of the rowkey value) --- mysql-test/r/cassandra.result | 11 +++- mysql-test/t/cassandra.test | 15 +++-- storage/cassandra/cassandra_se.cc | 84 +++++++++++++++++++++++- storage/cassandra/cassandra_se.h | 25 +++---- storage/cassandra/ha_cassandra.cc | 133 ++++++++++++++++++++++---------------- storage/cassandra/ha_cassandra.h | 8 +-- 6 files changed, 187 insertions(+), 89 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 6dbf08651d8..651adf40c7b 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -14,7 +14,12 @@ ERROR HY000: Unable to connect to foreign data source: Default TException. [Keys create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; ERROR HY000: Can't create table 'test.t1' (errno: 140) -create table t1 (rowkey char(36) primary key, column1 char(60)) engine=cassandra -thrift_host='localhost' keyspace='mariadbtest' column_family='cf1'; -insert into t1 values ('key0', 'data1'); +create table t1 (rowkey char(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +select * from t1; +rowkey data1 data2 + data1-value 123456 + data1-value2 34543 drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 6acb5f769ab..e316e23d626 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -36,12 +36,12 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra ./cqlsh --cql3 -CREATE KEYSPACE mariadbtest +CREATE KEYSPACE mariadbtest2 WITH strategy_class = 'org.apache.cassandra.locator.SimpleStrategy' AND strategy_options:replication_factor='1'; -USE mariadbtest; -create columnfamily cf1 ( pk varchar primary key, data1 varchar); +USE mariadbtest2; +create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); --enable_parsing ############################################################################ @@ -49,11 +49,12 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar); ############################################################################ # Now, create a table for real and insert data -create table t1 (rowkey char(36) primary key, data1 varchar(60)) engine=cassandra - thrift_host='localhost' keyspace='mariadbtest' column_family='cf1'; - -insert into t1 values ('key0', 'data1'); +create table t1 (rowkey char(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra + thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +select * from t1; drop table t1; ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index e3d731815f9..f8891a43351 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -60,7 +60,12 @@ class Cassandra_se_impl: public Cassandra_se_interface std::string key_to_insert; int64_t insert_timestamp; std::vector* insert_list; + + /* Resultset we're reading */ + std::vector key_slice_vec; + std::vector::iterator key_slice_it; + SlicePredicate slice_pred; public: Cassandra_se_impl() : cass(NULL) {} virtual ~Cassandra_se_impl(){ delete cass; } @@ -78,10 +83,18 @@ public: void add_insert_column(const char *name, const char *value, int value_len); bool do_insert(); - /* Reads */ + /* Reads, point lookups */ bool get_slice(char *key, size_t key_len, bool *found); bool get_next_read_column(char **name, char **value, int *value_len); + /* Reads, multi-row scans */ + bool get_range_slices(); + void finish_reading_range_slices(); + bool get_next_range_slice_row(); + + /* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */ + void clear_read_columns(); + void add_read_column(const char *name); }; @@ -265,7 +278,7 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) try { cass->get_slice(column_data_vec, rowkey_str, cparent, slice_pred, - ConsistencyLevel::ONE); + cur_consistency_level); if (column_data_vec.size() == 0) { @@ -318,3 +331,70 @@ bool Cassandra_se_impl::get_next_read_column(char **name, char **value, } +bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as parameters +{ + bool res= true; + + ColumnParent cparent; + cparent.column_family= column_family; + + /* SlicePredicate can be used to limit columns we will retrieve */ + // Try passing nothing... + + KeyRange key_range; // Try passing nothing, too. + key_range.__isset.start_key=true; + key_range.__isset.end_key=true; + key_range.start_key.assign("", 0); + key_range.end_key.assign("", 0); + + try { + + cass->get_range_slices(key_slice_vec, + cparent, slice_pred, key_range, + cur_consistency_level); + res= false; + + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); + } + + key_slice_it= key_slice_vec.begin(); + return res; +} + + +bool Cassandra_se_impl::get_next_range_slice_row() +{ + if (key_slice_it == key_slice_vec.end()) + return true; + + column_data_vec= key_slice_it->columns; + column_data_it= column_data_vec.begin(); + key_slice_it++; + return false; +} + + +void Cassandra_se_impl::finish_reading_range_slices() +{ + key_slice_vec.clear(); +} + + +void Cassandra_se_impl::clear_read_columns() +{ + slice_pred.column_names.clear(); +} + + +void Cassandra_se_impl::add_read_column(const char *name_arg) +{ + std::string name(name_arg); + slice_pred.__isset.column_names= true; + slice_pred.column_names.push_back(name); +} + diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index dea4f0f51ea..d35a6e6a003 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -7,22 +7,6 @@ */ -/* - Storage for (name,value) pairs. name==NULL means 'non-object'. - - This should be used for - - shipping data from sql to cassandra for INSERTs - - shipping data from cassandra to SQL for record reads. - -*/ -class NameAndValue -{ -public: - char *name; - char *value; - size_t value_len; -}; - /* Interface to one cassandra column family, i.e. one 'table' */ @@ -52,6 +36,15 @@ public: virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ; virtual bool get_next_read_column(char **name, char **value, int *value_len)=0; + /* Reads, multi-row scans */ + virtual bool get_range_slices()=0; + virtual void finish_reading_range_slices()=0; + virtual bool get_next_range_slice_row()=0; + + /* read_set setup */ + virtual void clear_read_columns()=0; + virtual void add_read_column(const char *name)=0; + /* Passing error messages up to ha_cassandra */ char err_buffer[512]; const char *error_str() { return err_buffer; } diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 757c0fd5e10..02eddcaf5cd 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -212,8 +212,7 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), names_and_vals(NULL), - field_converters(NULL) + se(NULL), field_converters(NULL) {} @@ -265,11 +264,7 @@ int ha_cassandra::close(void) DBUG_ENTER("ha_cassandra::close"); delete se; se= NULL; - if (names_and_vals) - { - my_free(names_and_vals); - names_and_vals= NULL; - } + free_field_converters(); DBUG_RETURN(free_share(share)); } @@ -589,6 +584,7 @@ void ha_cassandra::free_field_converters() } } + void store_key_image_to_rec(Field *field, uchar *ptr, uint len); int ha_cassandra::index_read_map(uchar *buf, const uchar *key, @@ -622,34 +618,49 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, } else { - char *cass_name; - char *cass_value; - int cass_value_len; - Field **field; + read_cassandra_columns(); + } - /* Start with all fields being NULL */ - for (field= table->field + 1; *field; field++) - (*field)->set_null(); + DBUG_RETURN(rc); +} - while (!se->get_next_read_column(&cass_name, &cass_value, &cass_value_len)) + +void ha_cassandra::read_cassandra_columns() +{ + char *cass_name; + char *cass_value; + int cass_value_len; + Field **field; + + /* + cassandra_to_mariadb() calls will use field->store(...) methods, which + require that the column is in the table->write_set + */ + my_bitmap_map *old_map; + old_map= dbug_tmp_use_all_columns(table, table->write_set); + + /* Start with all fields being NULL */ + for (field= table->field + 1; *field; field++) + (*field)->set_null(); + + while (!se->get_next_read_column(&cass_name, &cass_value, &cass_value_len)) + { + // map to our column. todo: use hash or something.. + int idx=1; + for (field= table->field + 1; *field; field++) { - // map to our column. todo: use hash or something.. - int idx=1; - for (field= table->field + 1; *field; field++) + idx++; + if (!strcmp((*field)->field_name, cass_name)) { - idx++; - if (!strcmp((*field)->field_name, cass_name)) - { - int fieldnr= (*field)->field_index; - (*field)->set_notnull(); - field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len); - break; - } + int fieldnr= (*field)->field_index; + (*field)->set_notnull(); + field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len); + break; } } } - DBUG_RETURN(rc); + dbug_tmp_restore_column_map(table->write_set, old_map); } @@ -690,19 +701,50 @@ int ha_cassandra::write_row(uchar *buf) } -NameAndValue *ha_cassandra::get_names_and_vals() +int ha_cassandra::rnd_init(bool scan) +{ + bool bres; + DBUG_ENTER("ha_cassandra::rnd_init"); + if (!scan) + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + + se->clear_read_columns(); + for (uint i= 1; i < table->s->fields; i++) + se->add_read_column(table->field[i]->field_name); + + bres= se->get_range_slices(); + + DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); +} + + +int ha_cassandra::rnd_end() +{ + DBUG_ENTER("ha_cassandra::rnd_end"); + + se->finish_reading_range_slices(); + DBUG_RETURN(0); +} + + +int ha_cassandra::rnd_next(uchar *buf) { - if (names_and_vals) - return names_and_vals; + int rc; + DBUG_ENTER("ha_cassandra::rnd_next"); + + // Unpack and return the next record. + if (se->get_next_range_slice_row()) + { + rc= HA_ERR_END_OF_FILE; + } else { - size_t size= sizeof(NameAndValue) * (table->s->fields + 1); - names_and_vals= (NameAndValue*)my_malloc(size ,0); - memset(names_and_vals, 0, size); - return names_and_vals; + read_cassandra_columns(); + rc= 0; } -} + DBUG_RETURN(rc); +} ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start @@ -743,27 +785,6 @@ int ha_cassandra::index_last(uchar *buf) DBUG_RETURN(rc); } -int ha_cassandra::rnd_init(bool scan) -{ - DBUG_ENTER("ha_cassandra::rnd_init"); - DBUG_RETURN(0); -} - -int ha_cassandra::rnd_end() -{ - DBUG_ENTER("ha_cassandra::rnd_end"); - DBUG_RETURN(0); -} - - -int ha_cassandra::rnd_next(uchar *buf) -{ - int rc; - DBUG_ENTER("ha_cassandra::rnd_next"); - rc= HA_ERR_END_OF_FILE; - DBUG_RETURN(rc); -} - void ha_cassandra::position(const uchar *record) { DBUG_ENTER("ha_cassandra::position"); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 595b840d360..30958e4e17c 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -36,19 +36,17 @@ class ha_cassandra: public handler Cassandra_se_interface *se; - /* pre-allocated array of #fields elements */ - NameAndValue *names_and_vals; - NameAndValue *get_names_and_vals(); - - ColumnDataConverter **field_converters; uint n_field_converters; bool setup_field_converters(Field **field, uint n_fields); void free_field_converters(); + + void read_cassandra_columns(); public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() { + free_field_converters(); delete se; } -- cgit v1.2.1 From 9cdf5eeec91b60fbdffdc7d7a675f47bdb39ff50 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 18 Aug 2012 21:29:31 +0400 Subject: MDEV-431: Cassandra storage engine - Support "DELETE FROM cassandra_table" --- mysql-test/r/cassandra.result | 3 +++ mysql-test/t/cassandra.test | 5 +++++ storage/cassandra/cassandra_se.cc | 22 ++++++++++++++++++++++ storage/cassandra/cassandra_se.h | 3 ++- storage/cassandra/ha_cassandra.cc | 19 ++++++++++++------- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 651adf40c7b..4e45685a8c2 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -22,4 +22,7 @@ select * from t1; rowkey data1 data2 data1-value 123456 data1-value2 34543 +delete from t1; +select * from t1; +rowkey data1 data2 drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index e316e23d626..80271e48d3e 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -55,6 +55,11 @@ create table t1 (rowkey char(36) primary key, data1 varchar(60), data2 bigint) e insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey11', 'data1-value2', 34543); select * from t1; + +# Check if deletion works +delete from t1; +select * from t1; + drop table t1; ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index f8891a43351..c47787d97f4 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -95,6 +95,8 @@ public: /* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */ void clear_read_columns(); void add_read_column(const char *name); + + bool truncate(); }; @@ -398,3 +400,23 @@ void Cassandra_se_impl::add_read_column(const char *name_arg) slice_pred.column_names.push_back(name); } + +bool Cassandra_se_impl::truncate() +{ + bool res= true; + try { + + cass->truncate(column_family); + res= false; + + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); + } + + return res; +} + diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index d35a6e6a003..44b6ac05ca8 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -44,7 +44,8 @@ public: /* read_set setup */ virtual void clear_read_columns()=0; virtual void add_read_column(const char *name)=0; - + + virtual bool truncate()=0; /* Passing error messages up to ha_cassandra */ char err_buffer[512]; const char *error_str() { return err_buffer; } diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 02eddcaf5cd..21131944bb3 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -746,6 +746,18 @@ int ha_cassandra::rnd_next(uchar *buf) DBUG_RETURN(rc); } + +int ha_cassandra::delete_all_rows() +{ + bool bres; + DBUG_ENTER("ha_cassandra::delete_all_rows"); + + bres= se->truncate(); + + DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); +} + + ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start ///////////////////////////////////////////////////////////////////////////// @@ -861,13 +873,6 @@ int ha_cassandra::delete_row(const uchar *buf) } -int ha_cassandra::delete_all_rows() -{ - DBUG_ENTER("ha_cassandra::delete_all_rows"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} - - /** check_if_incompatible_data() called if ALTER TABLE can't detect otherwise if new and old definition are compatible -- cgit v1.2.1 From d36259703b8ffa37ed47ed9dec7f393c8283c4c5 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 19 Aug 2012 12:50:53 +0400 Subject: MDEV-431: Cassandra storage engine - Descriptive error messages - Unpack PK column on range scans --- mysql-test/r/cassandra.result | 19 +++++-- mysql-test/t/cassandra.test | 10 +++- storage/cassandra/cassandra_se.cc | 34 ++++++++++-- storage/cassandra/cassandra_se.h | 2 + storage/cassandra/ha_cassandra.cc | 108 ++++++++++++++++++++++++++++++-------- storage/cassandra/ha_cassandra.h | 5 +- 6 files changed, 147 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 4e45685a8c2..b77dcc40c14 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -13,15 +13,26 @@ thrift_host='localhost' keyspace='no_such_keyspace' column_family='colfam'; ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace no_such_keyspace does not exist] create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; -ERROR HY000: Can't create table 'test.t1' (errno: 140) -create table t1 (rowkey char(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s +create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +select * from t1; +rowkey data1 data2 insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); select * from t1; rowkey data1 data2 - data1-value 123456 - data1-value2 34543 +rowkey12 data1-value3 454 +rowkey10 data1-value 123456 +rowkey11 data1-value2 34543 +explain +select * from t1 where rowkey='rowkey11'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 38 const 1 +select * from t1 where rowkey='rowkey11'; +rowkey data1 data2 +rowkey11 data1-value2 34543 delete from t1; select * from t1; rowkey data1 data2 diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 80271e48d3e..0f0a1544af5 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -25,7 +25,7 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace' column_family='colfam'; # No column family specified ---error ER_CANT_CREATE_TABLE +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; @@ -49,13 +49,19 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); ############################################################################ # Now, create a table for real and insert data -create table t1 (rowkey char(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +select * from t1; insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); select * from t1; +explain +select * from t1 where rowkey='rowkey11'; +select * from t1 where rowkey='rowkey11'; + # Check if deletion works delete from t1; select * from t1; diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index c47787d97f4..82b6dcbb93b 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -64,6 +64,8 @@ class Cassandra_se_impl: public Cassandra_se_interface /* Resultset we're reading */ std::vector key_slice_vec; std::vector::iterator key_slice_it; + + std::string rowkey; /* key of the record we're returning now */ SlicePredicate slice_pred; public: @@ -77,6 +79,7 @@ public: bool setup_ddl_checks(); void first_ddl_column(); bool next_ddl_column(char **name, int *name_len, char **value, int *value_len); + void get_rowkey_type(char **name, char **type); /* Writes */ void start_prepare_insert(const char *key, int key_len); @@ -86,6 +89,7 @@ public: /* Reads, point lookups */ bool get_slice(char *key, size_t key_len, bool *found); bool get_next_read_column(char **name, char **value, int *value_len); + void get_read_rowkey(char **value, int *value_len); /* Reads, multi-row scans */ bool get_range_slices(); @@ -193,6 +197,21 @@ bool Cassandra_se_impl::next_ddl_column(char **name, int *name_len, return false; } + +void Cassandra_se_impl::get_rowkey_type(char **name, char **type) +{ + if (cf_def.__isset.key_validation_class) + *type= (char*)cf_def.key_validation_class.c_str(); + else + *type= NULL; + + if (cf_def.__isset.key_alias) + *name= (char*)cf_def.key_alias.c_str(); + else + *name= NULL; +} + + ///////////////////////////////////////////////////////////////////////////// // Data writes ///////////////////////////////////////////////////////////////////////////// @@ -269,8 +288,7 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) ColumnParent cparent; cparent.column_family= column_family; - std::string rowkey_str; - rowkey_str.assign(key, key_len); + rowkey.assign(key, key_len); SlicePredicate slice_pred; SliceRange sr; @@ -279,7 +297,7 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) slice_pred.__set_slice_range(sr); try { - cass->get_slice(column_data_vec, rowkey_str, cparent, slice_pred, + cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, cur_consistency_level); if (column_data_vec.size() == 0) @@ -333,6 +351,15 @@ bool Cassandra_se_impl::get_next_read_column(char **name, char **value, } +/* Return the rowkey for the record that was read */ + +void Cassandra_se_impl::get_read_rowkey(char **value, int *value_len) +{ + *value= (char*)rowkey.c_str(); + *value_len= rowkey.length(); +} + + bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as parameters { bool res= true; @@ -375,6 +402,7 @@ bool Cassandra_se_impl::get_next_range_slice_row() return true; column_data_vec= key_slice_it->columns; + rowkey= key_slice_it->key; column_data_it= column_data_vec.begin(); key_slice_it++; return false; diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 44b6ac05ca8..6e3380e7f50 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -25,6 +25,7 @@ public: virtual void first_ddl_column()=0; virtual bool next_ddl_column(char **name, int *name_len, char **value, int *value_len)=0; + virtual void get_rowkey_type(char **name, char **type)=0; /* Writes */ virtual void start_prepare_insert(const char *key, int key_len)=0; @@ -35,6 +36,7 @@ public: /* Reads */ virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ; virtual bool get_next_read_column(char **name, char **value, int *value_len)=0; + virtual void get_read_rowkey(char **value, int *value_len)=0; /* Reads, multi-row scans */ virtual bool get_range_slices()=0; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 21131944bb3..8d7c4051c01 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -212,7 +212,7 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), field_converters(NULL) + se(NULL), field_converters(NULL),rowkey_converter(NULL) {} @@ -251,7 +251,6 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) if (setup_field_converters(table->field, table->s->fields)) { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "setup_field_converters"); DBUG_RETURN(HA_ERR_NO_CONNECTION); } @@ -341,8 +340,12 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, */ #endif DBUG_ASSERT(!se); - if (!options->host || !options->keyspace || !options->column_family) + if (!options->host || !options->keyspace || !options->column_family) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + "thrift_host, keyspace, and column_family table options must be specified"); DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } se= get_cassandra_se(); se->set_column_family(options->column_family); if (se->connect(options->host, options->keyspace)) @@ -515,6 +518,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: + //case MYSQL_TYPE_STRING: <-- todo: should we allow end-padded 'CHAR(N)'? if (!strcmp(validator_name, validator_blob) || !strcmp(validator_name, validator_ascii) || !strcmp(validator_name, validator_text)) @@ -560,7 +564,12 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) n_mapped++; ColumnDataConverter **conv= field_converters + (*field)->field_index; if (!(*conv= map_field_to_validator(*field, col_type))) + { + se->print_error("Failed to map column %s to datatype %s", + (*field)->field_name, col_type); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); return true; + } (*conv)->field= *field; } } @@ -568,6 +577,28 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) if (n_mapped != n_fields - 1) return true; + + /* + Setup type conversion for row_key. It may also have a name, but we ignore + it currently + */ + se->get_rowkey_type(&col_name, &col_type); + if (col_type != NULL) + { + if (!(rowkey_converter= map_field_to_validator(*field_arg, col_type))) + { + se->print_error("Failed to map PRIMARY KEY to datatype %s", col_type); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + return true; + } + rowkey_converter->field= *field_arg; + } + else + { + se->print_error("Cassandra's rowkey has no defined datatype (todo: support this)"); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + return true; + } return false; } @@ -575,6 +606,9 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) void ha_cassandra::free_field_converters() { + delete rowkey_converter; + rowkey_converter= NULL; + if (field_converters) { for (uint i=0; i < n_field_converters; i++) @@ -588,8 +622,8 @@ void ha_cassandra::free_field_converters() void store_key_image_to_rec(Field *field, uchar *ptr, uint len); int ha_cassandra::index_read_map(uchar *buf, const uchar *key, - key_part_map keypart_map, - enum ha_rkey_function find_flag) + key_part_map keypart_map, + enum ha_rkey_function find_flag) { int rc; DBUG_ENTER("ha_cassandra::index_read_map"); @@ -597,19 +631,26 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, if (find_flag != HA_READ_KEY_EXACT) DBUG_RETURN(HA_ERR_WRONG_COMMAND); - // todo: decode the search key. uint key_len= calculate_key_len(table, active_index, key, keypart_map); store_key_image_to_rec(table->field[0], (uchar*)key, key_len); - +#if 0 char buff[256]; String tmp(buff,sizeof(buff), &my_charset_bin); tmp.length(0); String *str; str= table->field[0]->val_str(&tmp); - +#endif + + char *cass_key; + int cass_key_len; + rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + bool found; - if (se->get_slice((char*)str->ptr(), str->length(), &found)) + if (se->get_slice(cass_key, cass_key_len, &found)) + { + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); rc= HA_ERR_INTERNAL_ERROR; + } /* TODO: what if we're not reading all columns?? */ if (!found) @@ -618,14 +659,14 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, } else { - read_cassandra_columns(); + read_cassandra_columns(false); } DBUG_RETURN(rc); } -void ha_cassandra::read_cassandra_columns() +void ha_cassandra::read_cassandra_columns(bool unpack_pk) { char *cass_name; char *cass_value; @@ -659,6 +700,15 @@ void ha_cassandra::read_cassandra_columns() } } } + + if (unpack_pk) + { + /* Unpack rowkey to primary key */ + field= table->field; + (*field)->set_notnull(); + se->get_read_rowkey(&cass_value, &cass_value_len); + rowkey_converter->cassandra_to_mariadb(cass_value, cass_value_len); + } dbug_tmp_restore_column_map(table->write_set, old_map); } @@ -667,12 +717,13 @@ void ha_cassandra::read_cassandra_columns() int ha_cassandra::write_row(uchar *buf) { my_bitmap_map *old_map; - char buff[512]; +// char buff[512]; DBUG_ENTER("ha_cassandra::write_row"); old_map= dbug_tmp_use_all_columns(table, table->read_set); /* Convert the key (todo: unify with the rest of the processing) */ +#if 0 { Field *pk_col= table->field[0]; String tmp(buff,sizeof(buff), &my_charset_bin); @@ -682,6 +733,11 @@ int ha_cassandra::write_row(uchar *buf) se->start_prepare_insert(str->ptr(), str->length()); } +#endif + char *cass_key; + int cass_key_len; + rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + se->start_prepare_insert(cass_key, cass_key_len); /* Convert other fields */ for (uint i= 1; i < table->s->fields; i++) @@ -697,6 +753,9 @@ int ha_cassandra::write_row(uchar *buf) bool res= se->do_insert(); + if (res) + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } @@ -713,6 +772,8 @@ int ha_cassandra::rnd_init(bool scan) se->add_read_column(table->field[i]->field_name); bres= se->get_range_slices(); + if (bres) + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); } @@ -739,7 +800,7 @@ int ha_cassandra::rnd_next(uchar *buf) } else { - read_cassandra_columns(); + read_cassandra_columns(true); rc= 0; } @@ -753,11 +814,22 @@ int ha_cassandra::delete_all_rows() DBUG_ENTER("ha_cassandra::delete_all_rows"); bres= se->truncate(); + + if (bres) + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); } +int ha_cassandra::delete_row(const uchar *buf) +{ + DBUG_ENTER("ha_cassandra::delete_row"); + // todo: delete the row we've just read. + DBUG_RETURN(HA_ERR_WRONG_COMMAND); +} + + ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start ///////////////////////////////////////////////////////////////////////////// @@ -815,7 +887,8 @@ ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, key_range *max_key) { DBUG_ENTER("ha_cassandra::records_in_range"); - DBUG_RETURN(10); // low number to force index usage + //DBUG_RETURN(10); // low number to force index usage + DBUG_RETURN(HA_POS_ERROR); } @@ -866,13 +939,6 @@ int ha_cassandra::delete_table(const char *name) } -int ha_cassandra::delete_row(const uchar *buf) -{ - DBUG_ENTER("ha_cassandra::delete_row"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); -} - - /** check_if_incompatible_data() called if ALTER TABLE can't detect otherwise if new and old definition are compatible diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 30958e4e17c..7a163363ab6 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -38,10 +38,13 @@ class ha_cassandra: public handler ColumnDataConverter **field_converters; uint n_field_converters; + + ColumnDataConverter *rowkey_converter; + bool setup_field_converters(Field **field, uint n_fields); void free_field_converters(); - void read_cassandra_columns(); + void read_cassandra_columns(bool unpack_pk); public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() -- cgit v1.2.1 From 62c1c3f0c50a3727fa634e2b965fd78e376aab5e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 19 Aug 2012 13:21:23 +0400 Subject: MDEV-431: Cassandra storage engine - Partial support for DELETE ... WHERE. --- mysql-test/r/cassandra.result | 9 ++++++++ mysql-test/t/cassandra.test | 22 ++++++++++++++++-- storage/cassandra/cassandra_se.cc | 47 ++++++++++++++++++++++++++++++++------- storage/cassandra/cassandra_se.h | 2 ++ storage/cassandra/ha_cassandra.cc | 12 +++++++--- 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index b77dcc40c14..b39a29b22eb 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -14,8 +14,11 @@ ERROR HY000: Unable to connect to foreign data source: Default TException. [Keys create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s +# Now, create a table for real and insert data create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +# Just in case there were left-overs from previous: +delete from t1; select * from t1; rowkey data1 data2 insert into t1 values ('rowkey10', 'data1-value', 123456); @@ -33,6 +36,12 @@ id select_type table type possible_keys key key_len ref rows Extra select * from t1 where rowkey='rowkey11'; rowkey data1 data2 rowkey11 data1-value2 34543 +delete from t1 where rowkey='rowkey11'; +select * from t1; +rowkey data1 data2 +rowkey12 data1-value3 454 +rowkey10 data1-value 123456 +rowkey11 NULL NULL delete from t1; select * from t1; rowkey data1 data2 diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 0f0a1544af5..7c00e20651a 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -48,9 +48,12 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); ## Cassandra initialization ends ############################################################################ -# Now, create a table for real and insert data +--echo # Now, create a table for real and insert data create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; + +--echo # Just in case there were left-overs from previous: +delete from t1; select * from t1; insert into t1 values ('rowkey10', 'data1-value', 123456); @@ -62,7 +65,22 @@ explain select * from t1 where rowkey='rowkey11'; select * from t1 where rowkey='rowkey11'; -# Check if deletion works +# Deletion functions weirdly: it sets all columns to NULL +# but when If I do this in cassandra-cli: +# +# del cf1[ascii('rowkey10')] +# +# Subsequent 'list cf1' command also gives +# +# RowKey: rowkey10 +# +# without any columns. +# +# CQL seems to simply ignore all "incomplete" records. + +delete from t1 where rowkey='rowkey11'; +select * from t1; + delete from t1; select * from t1; diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 82b6dcbb93b..7d7d6bf9eee 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -101,6 +101,10 @@ public: void add_read_column(const char *name); bool truncate(); + bool remove_row(); + + /* Non-inherited utility functions: */ + int64_t get_i64_timestamp(); }; @@ -215,6 +219,18 @@ void Cassandra_se_impl::get_rowkey_type(char **name, char **type) ///////////////////////////////////////////////////////////////////////////// // Data writes ///////////////////////////////////////////////////////////////////////////// +int64_t Cassandra_se_impl::get_i64_timestamp() +{ + struct timeval td; + gettimeofday(&td, NULL); + int64_t ms = td.tv_sec; + ms = ms * 1000; + int64_t usec = td.tv_usec; + usec = usec / 1000; + ms += usec; + + return ms; +} void Cassandra_se_impl::start_prepare_insert(const char *key, int key_len) { @@ -226,14 +242,7 @@ void Cassandra_se_impl::start_prepare_insert(const char *key, int key_len) cf_mut[column_family]= std::vector(); insert_list= &cf_mut[column_family]; - struct timeval td; - gettimeofday(&td, NULL); - int64_t ms = td.tv_sec; - ms = ms * 1000; - int64_t usec = td.tv_usec; - usec = usec / 1000; - ms += usec; - insert_timestamp= ms; + insert_timestamp= get_i64_timestamp(); } @@ -448,3 +457,25 @@ bool Cassandra_se_impl::truncate() return res; } +bool Cassandra_se_impl::remove_row() +{ + bool res= true; + + ColumnPath column_path; + column_path.column_family= column_family; + + try { + + cass->remove(rowkey, column_path, get_i64_timestamp(), cur_consistency_level); + res= false; + + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); + } + + return res; +} diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 6e3380e7f50..bbd4c8dd883 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -48,6 +48,8 @@ public: virtual void add_read_column(const char *name)=0; virtual bool truncate()=0; + virtual bool remove_row()=0; + /* Passing error messages up to ha_cassandra */ char err_buffer[512]; const char *error_str() { return err_buffer; } diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 8d7c4051c01..c6cb624156b 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -625,7 +625,7 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { - int rc; + int rc= 0; DBUG_ENTER("ha_cassandra::index_read_map"); if (find_flag != HA_READ_KEY_EXACT) @@ -824,9 +824,15 @@ int ha_cassandra::delete_all_rows() int ha_cassandra::delete_row(const uchar *buf) { + bool bres; DBUG_ENTER("ha_cassandra::delete_row"); - // todo: delete the row we've just read. - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + + bres= se->remove_row(); + + if (bres) + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + + DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); } -- cgit v1.2.1 From 38bc66fb1a0eff9d96ecbc205e95e720ffbc46d7 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 19 Aug 2012 14:54:58 +0400 Subject: position() and rnd_pos() implementations. --- storage/cassandra/ha_cassandra.cc | 105 +++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index c6cb624156b..5e950eb4b96 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -254,6 +254,8 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(HA_ERR_NO_CONNECTION); } + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + DBUG_RETURN(0); } @@ -310,6 +312,12 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, DBUG_RETURN(HA_WRONG_CREATE_OPTION); } + if (!((*pfield)->flags & NOT_NULL_FLAG)) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL"); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } + if (table_arg->s->keys != 1 || table_arg->s->primary_key !=0 || table_arg->key_info[0].key_parts != 1 || table_arg->key_info[0].key_part[0].fieldnr != 1) @@ -633,13 +641,6 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, uint key_len= calculate_key_len(table, active_index, key, keypart_map); store_key_image_to_rec(table->field[0], (uchar*)key, key_len); -#if 0 - char buff[256]; - String tmp(buff,sizeof(buff), &my_charset_bin); - tmp.length(0); - String *str; - str= table->field[0]->val_str(&tmp); -#endif char *cass_key; int cass_key_len; @@ -717,23 +718,11 @@ void ha_cassandra::read_cassandra_columns(bool unpack_pk) int ha_cassandra::write_row(uchar *buf) { my_bitmap_map *old_map; -// char buff[512]; DBUG_ENTER("ha_cassandra::write_row"); old_map= dbug_tmp_use_all_columns(table, table->read_set); - /* Convert the key (todo: unify with the rest of the processing) */ -#if 0 - { - Field *pk_col= table->field[0]; - String tmp(buff,sizeof(buff), &my_charset_bin); - String *str; - tmp.length(0); - str= pk_col->val_str(&tmp); - - se->start_prepare_insert(str->ptr(), str->length()); - } -#endif + /* Convert the key */ char *cass_key; int cass_key_len; rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); @@ -836,6 +825,57 @@ int ha_cassandra::delete_row(const uchar *buf) } +int ha_cassandra::info(uint flag) +{ + DBUG_ENTER("ha_cassandra::info"); + + if (!table) + return 1; + + if (flag & HA_STATUS_VARIABLE) + { + stats.records= 1000; + //TODO: any other stats? + } + if (flag & HA_STATUS_CONST) + { + ref_length= table->field[0]->key_length(); + } + + DBUG_RETURN(0); +} + + +void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, + uint key_length, bool with_zerofill); + + +void ha_cassandra::position(const uchar *record) +{ + DBUG_ENTER("ha_cassandra::position"); + + /* Copy the primary key to rowid */ + key_copy(ref, (uchar*)record, &table->key_info[0], + table->field[0]->key_length(), true); + + DBUG_VOID_RETURN; +} + + +int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) +{ + int rc; + DBUG_ENTER("ha_cassandra::rnd_pos"); + + int save_active_index= active_index; + rc= index_read_map(buf, pos, key_part_map(1), HA_READ_KEY_EXACT); + + active_index= save_active_index; + + DBUG_RETURN(rc); +} + + ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start ///////////////////////////////////////////////////////////////////////////// @@ -875,19 +915,6 @@ int ha_cassandra::index_last(uchar *buf) DBUG_RETURN(rc); } -void ha_cassandra::position(const uchar *record) -{ - DBUG_ENTER("ha_cassandra::position"); - DBUG_VOID_RETURN; -} - -int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) -{ - int rc; - DBUG_ENTER("ha_cassandra::rnd_pos"); - rc= HA_ERR_WRONG_COMMAND; - DBUG_RETURN(rc); -} ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, key_range *max_key) @@ -906,13 +933,6 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) } -int ha_cassandra::info(uint flag) -{ - DBUG_ENTER("ha_cassandra::info"); - DBUG_RETURN(0); -} - - int ha_cassandra::extra(enum ha_extra_function operation) { DBUG_ENTER("ha_cassandra::extra"); @@ -940,7 +960,10 @@ int ha_cassandra::external_lock(THD *thd, int lock_type) int ha_cassandra::delete_table(const char *name) { DBUG_ENTER("ha_cassandra::delete_table"); - /* This is not implemented but we want someone to be able that it works. */ + /* + Cassandra table is just a view. Dropping it doesn't affect the underlying + column family. + */ DBUG_RETURN(0); } -- cgit v1.2.1 From 81817412aa526628cb3f02f5075c03f034a69424 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 20 Aug 2012 12:08:29 +0400 Subject: Read records in batches when doing full table scan. --- storage/cassandra/cassandra_se.cc | 52 +++++++++++++++++++++++++++++++-------- storage/cassandra/cassandra_se.h | 6 +++-- storage/cassandra/ha_cassandra.cc | 20 ++++++++++----- storage/cassandra/ha_cassandra.h | 2 ++ 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 7d7d6bf9eee..bd5056bcda4 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -68,6 +68,7 @@ class Cassandra_se_impl: public Cassandra_se_interface std::string rowkey; /* key of the record we're returning now */ SlicePredicate slice_pred; + bool get_slices_returned_less; public: Cassandra_se_impl() : cass(NULL) {} virtual ~Cassandra_se_impl(){ delete cass; } @@ -92,9 +93,9 @@ public: void get_read_rowkey(char **value, int *value_len); /* Reads, multi-row scans */ - bool get_range_slices(); + bool get_range_slices(bool last_key_as_start_key); void finish_reading_range_slices(); - bool get_next_range_slice_row(); + bool get_next_range_slice_row(bool *eof); /* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */ void clear_read_columns(); @@ -369,7 +370,7 @@ void Cassandra_se_impl::get_read_rowkey(char **value, int *value_len) } -bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as parameters +bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) { bool res= true; @@ -380,11 +381,16 @@ bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as para // Try passing nothing... KeyRange key_range; // Try passing nothing, too. - key_range.__isset.start_key=true; - key_range.__isset.end_key=true; - key_range.start_key.assign("", 0); - key_range.end_key.assign("", 0); + key_range.__isset.start_key= true; + key_range.__isset.end_key= true; + + if (last_key_as_start_key) + key_range.start_key= rowkey; + else + key_range.start_key.assign("", 0); + key_range.end_key.assign("", 0); + key_range.count= read_batch_size; try { cass->get_range_slices(key_slice_vec, @@ -392,6 +398,11 @@ bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as para cur_consistency_level); res= false; + if (key_slice_vec.size() < (uint)read_batch_size) + get_slices_returned_less= true; + else + get_slices_returned_less= false; + } catch (InvalidRequestException ire) { print_error("%s [%s]", ire.what(), ire.why.c_str()); } catch (UnavailableException ue) { @@ -405,11 +416,32 @@ bool Cassandra_se_impl::get_range_slices() //todo: start_range/end_range as para } -bool Cassandra_se_impl::get_next_range_slice_row() +/* Switch to next row. This may produce an error */ +bool Cassandra_se_impl::get_next_range_slice_row(bool *eof) { if (key_slice_it == key_slice_vec.end()) - return true; - + { + if (get_slices_returned_less) + { + *eof= true; + return false; + } + + /* + We have read through all columns in this batch. Try getting the next + batch. + */ + if (get_range_slices(true)) + return true; + + if (key_slice_vec.empty()) + { + *eof= true; + return false; + } + } + + *eof= false; column_data_vec= key_slice_it->columns; rowkey= key_slice_it->key; column_data_it= column_data_vec.begin(); diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index bbd4c8dd883..e65e495e91c 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -39,9 +39,11 @@ public: virtual void get_read_rowkey(char **value, int *value_len)=0; /* Reads, multi-row scans */ - virtual bool get_range_slices()=0; + int read_batch_size; + + virtual bool get_range_slices(bool last_key_as_start_key)=0; virtual void finish_reading_range_slices()=0; - virtual bool get_next_range_slice_row()=0; + virtual bool get_next_range_slice_row(bool *eof)=0; /* read_set setup */ virtual void clear_read_columns()=0; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 5e950eb4b96..0f196ed2a99 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -212,7 +212,8 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), field_converters(NULL),rowkey_converter(NULL) + se(NULL), field_converters(NULL), rowkey_converter(NULL), + rnd_batch_size(10*1000) {} @@ -760,7 +761,8 @@ int ha_cassandra::rnd_init(bool scan) for (uint i= 1; i < table->s->fields; i++) se->add_read_column(table->field[i]->field_name); - bres= se->get_range_slices(); + se->read_batch_size= rnd_batch_size; + bres= se->get_range_slices(false); if (bres) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); @@ -780,17 +782,23 @@ int ha_cassandra::rnd_end() int ha_cassandra::rnd_next(uchar *buf) { int rc; + bool reached_eof; DBUG_ENTER("ha_cassandra::rnd_next"); // Unpack and return the next record. - if (se->get_next_range_slice_row()) + if (se->get_next_range_slice_row(&reached_eof)) { - rc= HA_ERR_END_OF_FILE; + rc= HA_ERR_INTERNAL_ERROR; } else { - read_cassandra_columns(true); - rc= 0; + if (reached_eof) + rc= HA_ERR_END_OF_FILE; + else + { + read_cassandra_columns(true); + rc= 0; + } } DBUG_RETURN(rc); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 7a163363ab6..d5327e20934 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -45,6 +45,8 @@ class ha_cassandra: public handler void free_field_converters(); void read_cassandra_columns(bool unpack_pk); + + ha_rows rnd_batch_size; public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() -- cgit v1.2.1 From 06ea60d221761af9f9dee5345b783ba75c3cb6c1 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 21 Aug 2012 18:38:27 +0400 Subject: Make ha_cassandra work with filesort(). --- mysql-test/r/cassandra.result | 13 +++++++++++++ mysql-test/t/cassandra.test | 10 ++++++++++ storage/cassandra/ha_cassandra.cc | 5 ++++- storage/cassandra/ha_cassandra.h | 14 ++++++++++---- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index b39a29b22eb..b6b7429ee0a 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -45,4 +45,17 @@ rowkey11 NULL NULL delete from t1; select * from t1; rowkey data1 data2 +# +# A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ, +# also check ::rnd_pos() +# +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); +select * from t1 order by data2; +rowkey data1 data2 +rowkey12 data1-value3 454 +rowkey11 data1-value2 34543 +rowkey10 data1-value 123456 +delete from t1; drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 7c00e20651a..b4727709f8e 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -84,6 +84,16 @@ select * from t1; delete from t1; select * from t1; +--echo # +--echo # A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ, +--echo # also check ::rnd_pos() +--echo # +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); +select * from t1 order by data2; + +delete from t1; drop table t1; ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 0f196ed2a99..7455420870c 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -755,7 +755,10 @@ int ha_cassandra::rnd_init(bool scan) bool bres; DBUG_ENTER("ha_cassandra::rnd_init"); if (!scan) - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + { + /* Prepare for rnd_pos() calls. We don't need to anything. */ + DBUG_RETURN(0); + } se->clear_read_columns(); for (uint i= 1; i < table->s->fields; i++) diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index d5327e20934..cca70814b1b 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -78,11 +78,17 @@ public: ulonglong table_flags() const { /* - We are saying that this engine is just statement capable to have - an engine that can only handle statement-based logging. This is - used in testing. + HA_BINLOG_STMT_CAPABLE + We are saying that this engine is just statement capable to have + an engine that can only handle statement-based logging. This is + used in testing. + HA_REC_NOT_IN_SEQ + If we don't set it, filesort crashes, because it assumes rowids are + 1..8 byte numbers */ - return HA_BINLOG_STMT_CAPABLE; + return HA_BINLOG_STMT_CAPABLE | + HA_REC_NOT_IN_SEQ; + } /** @brief -- cgit v1.2.1 From 38d4e02559ad33ae7c4e9258528d78a09e5e330b Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 23 Aug 2012 16:15:28 +0400 Subject: # MDEV-476: Cassandra: Server crashes in calculate_key_len on DELETE with ORDER BY - Fix typo in ha_cassandra::rnd_pos(). - in ::index_read_map(), do not assume that pk column is part of table->read_set. --- mysql-test/r/cassandra.result | 8 ++++++++ mysql-test/t/cassandra.test | 13 +++++++++++++ storage/cassandra/ha_cassandra.cc | 7 +++++++ 3 files changed, 28 insertions(+) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index b6b7429ee0a..8d200e783bc 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -59,3 +59,11 @@ rowkey11 data1-value2 34543 rowkey10 data1-value 123456 delete from t1; drop table t1; +# +# MDEV-476: Cassandra: Server crashes in calculate_key_len on DELETE with ORDER BY +# +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1 ORDER BY a LIMIT 1; +DROP TABLE t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index b4727709f8e..5630d4da666 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -43,6 +43,8 @@ CREATE KEYSPACE mariadbtest2 USE mariadbtest2; create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); +create columnfamily cf2 (rowkey bigint primary key, a bigint); + --enable_parsing ############################################################################ ## Cassandra initialization ends @@ -96,6 +98,17 @@ select * from t1 order by data2; delete from t1; drop table t1; +--echo # +--echo # MDEV-476: Cassandra: Server crashes in calculate_key_len on DELETE with ORDER BY +--echo # +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; + +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1 ORDER BY a LIMIT 1; + +DROP TABLE t1; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 7455420870c..d1006a6e816 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -645,8 +645,14 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, char *cass_key; int cass_key_len; + my_bitmap_map *old_map; + + old_map= dbug_tmp_use_all_columns(table, table->read_set); + rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + dbug_tmp_restore_column_map(table->read_set, old_map); + bool found; if (se->get_slice(cass_key, cass_key_len, &found)) { @@ -879,6 +885,7 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) DBUG_ENTER("ha_cassandra::rnd_pos"); int save_active_index= active_index; + active_index= 0; /* The primary key */ rc= index_read_map(buf, pos, key_part_map(1), HA_READ_KEY_EXACT); active_index= save_active_index; -- cgit v1.2.1 From 38a3df4a2c887b406a8adb2d55e2adb5b80a2748 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 23 Aug 2012 21:16:01 +0400 Subject: - Enable mapping of CHAR(n) - preparations for support of bulk INSERT. --- storage/cassandra/ha_cassandra.cc | 14 +++++++++++++- storage/cassandra/ha_cassandra.h | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index d1006a6e816..29159828a97 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -527,7 +527,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: - //case MYSQL_TYPE_STRING: <-- todo: should we allow end-padded 'CHAR(N)'? + case MYSQL_TYPE_STRING: // these are space padded strings. if (!strcmp(validator_name, validator_blob) || !strcmp(validator_name, validator_ascii) || !strcmp(validator_name, validator_text)) @@ -893,7 +893,19 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) DBUG_RETURN(rc); } +#if 0 +void ha_cassandra::start_bulk_insert(ha_rows rows) +{ + /* Do nothing? */ +} + +int ha_cassandra::end_bulk_insert() +{ + // TODO! + return 0; +} +#endif ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start ///////////////////////////////////////////////////////////////////////////// diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index cca70814b1b..469440a0049 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -145,7 +145,10 @@ public: */ virtual double read_time(uint, uint, ha_rows rows) { return (double) rows / 20.0+1; } - +#if 0 + virtual void start_bulk_insert(ha_rows rows); + virtual int end_bulk_insert(); +#endif /* Everything below are methods that we implement in ha_example.cc. -- cgit v1.2.1 From fdab0300c1e11511df4bae3072eb642fdc222ff8 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 26 Aug 2012 16:06:39 +0400 Subject: Cassandra storage engine: bulk INSERT support - bulk inserts themselves - control variable and counters. --- mysql-test/r/cassandra.result | 25 ++++++++++ mysql-test/t/cassandra.test | 18 ++++++++ storage/cassandra/cassandra_se.cc | 19 ++++++-- storage/cassandra/cassandra_se.h | 13 +++++- storage/cassandra/ha_cassandra.cc | 96 ++++++++++++++++++++++++++++++++------- storage/cassandra/ha_cassandra.h | 9 +++- 6 files changed, 156 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 8d200e783bc..3b78bd5466a 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -67,3 +67,28 @@ thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; INSERT INTO t1 VALUES (1,1),(2,2); DELETE FROM t1 ORDER BY a LIMIT 1; DROP TABLE t1; +# +# Batched INSERT +# +show variables like 'cassandra_insert_batch_size'; +Variable_name Value +cassandra_insert_batch_size 100 +show status like 'cassandra_row_insert%'; +Variable_name Value +Cassandra_row_inserts 8 +Cassandra_row_insert_batches 7 +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1 ORDER BY a LIMIT 1; +DROP TABLE t1; +show status like 'cassandra_row_insert%'; +Variable_name Value +Cassandra_row_inserts 10 +Cassandra_row_insert_batches 8 +# FLUSH STATUS doesn't work for our variables, just like with InnoDB. +flush status; +show status like 'cassandra_row_insert%'; +Variable_name Value +Cassandra_row_inserts 10 +Cassandra_row_insert_batches 8 diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 5630d4da666..195f365a372 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -109,6 +109,24 @@ DELETE FROM t1 ORDER BY a LIMIT 1; DROP TABLE t1; +--echo # +--echo # Batched INSERT +--echo # +show variables like 'cassandra_insert_batch_size'; +show status like 'cassandra_row_insert%'; +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; + +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1 ORDER BY a LIMIT 1; + +DROP TABLE t1; +show status like 'cassandra_row_insert%'; + +--echo # FLUSH STATUS doesn't work for our variables, just like with InnoDB. +flush status; +show status like 'cassandra_row_insert%'; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index bd5056bcda4..75ce33cb981 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -57,7 +57,6 @@ class Cassandra_se_impl: public Cassandra_se_interface typedef std::map KeyToCfMutationMap; KeyToCfMutationMap batch_mutation; /* Prepare operation here */ - std::string key_to_insert; int64_t insert_timestamp; std::vector* insert_list; @@ -83,7 +82,8 @@ public: void get_rowkey_type(char **name, char **type); /* Writes */ - void start_prepare_insert(const char *key, int key_len); + void clear_insert_buffer(); + void start_row_insert(const char *key, int key_len); void add_insert_column(const char *name, const char *value, int value_len); bool do_insert(); @@ -233,10 +233,17 @@ int64_t Cassandra_se_impl::get_i64_timestamp() return ms; } -void Cassandra_se_impl::start_prepare_insert(const char *key, int key_len) + +void Cassandra_se_impl::clear_insert_buffer() { - key_to_insert.assign(key, key_len); batch_mutation.clear(); +} + + +void Cassandra_se_impl::start_row_insert(const char *key, int key_len) +{ + std::string key_to_insert; + key_to_insert.assign(key, key_len); batch_mutation[key_to_insert]= ColumnFamilyToMutation(); ColumnFamilyToMutation& cf_mut= batch_mutation[key_to_insert]; @@ -270,6 +277,10 @@ bool Cassandra_se_impl::do_insert() try { cass->batch_mutate(batch_mutation, cur_consistency_level); + + cassandra_counters.row_inserts+= batch_mutation.size(); + cassandra_counters.row_insert_batches++; + res= false; } catch (InvalidRequestException ire) { diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index e65e495e91c..78bf1016fea 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -28,7 +28,8 @@ public: virtual void get_rowkey_type(char **name, char **type)=0; /* Writes */ - virtual void start_prepare_insert(const char *key, int key_len)=0; + virtual void clear_insert_buffer()=0; + virtual void start_row_insert(const char *key, int key_len)=0; virtual void add_insert_column(const char *name, const char *value, int value_len)=0; virtual bool do_insert()=0; @@ -58,4 +59,14 @@ public: void print_error(const char *format, ...); }; +/* A structure with global counters */ +class Cassandra_status_vars +{ +public: + ulong row_inserts; + ulong row_insert_batches; +}; +extern Cassandra_status_vars cassandra_counters; + + Cassandra_se_interface *get_cassandra_se(); diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 29159828a97..70d389d4992 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -56,6 +56,23 @@ ha_create_table_option cassandra_table_option_list[]= }; +static MYSQL_THDVAR_ULONG(insert_batch_size, PLUGIN_VAR_RQCMDARG, + "Number of rows in an INSERT batch", + NULL, NULL, /*default*/ 100, /*min*/ 1, /*max*/ 1024*1024*1024, 0); + + +static struct st_mysql_sys_var* cassandra_system_variables[]= { + MYSQL_SYSVAR(insert_batch_size), +// MYSQL_SYSVAR(enum_var), +// MYSQL_SYSVAR(ulong_var), + NULL +}; + + +Cassandra_status_vars cassandra_counters; +Cassandra_status_vars cassandra_counters_copy; + + /** @brief Function we use in the creation of our hash to get key. @@ -727,13 +744,16 @@ int ha_cassandra::write_row(uchar *buf) my_bitmap_map *old_map; DBUG_ENTER("ha_cassandra::write_row"); + if (!doing_insert_batch) + se->clear_insert_buffer(); + old_map= dbug_tmp_use_all_columns(table, table->read_set); /* Convert the key */ char *cass_key; int cass_key_len; rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); - se->start_prepare_insert(cass_key, cass_key_len); + se->start_row_insert(cass_key, cass_key_len); /* Convert other fields */ for (uint i= 1; i < table->s->fields; i++) @@ -747,7 +767,20 @@ int ha_cassandra::write_row(uchar *buf) dbug_tmp_restore_column_map(table->read_set, old_map); - bool res= se->do_insert(); + bool res; + + if (doing_insert_batch) + { + res= 0; + if (++insert_rows_batched >= /*insert_batch_size*/ + THDVAR(table->in_use, insert_batch_size)) + { + res= se->do_insert(); + insert_rows_batched= 0; + } + } + else + res= se->do_insert(); if (res) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); @@ -756,6 +789,28 @@ int ha_cassandra::write_row(uchar *buf) } +void ha_cassandra::start_bulk_insert(ha_rows rows) +{ + doing_insert_batch= true; + insert_rows_batched= 0; + + se->clear_insert_buffer(); +} + + +int ha_cassandra::end_bulk_insert() +{ + DBUG_ENTER("ha_cassandra::end_bulk_insert"); + + /* Flush out the insert buffer */ + doing_insert_batch= false; + bool bres= se->do_insert(); + se->clear_insert_buffer(); + + DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); +} + + int ha_cassandra::rnd_init(bool scan) { bool bres; @@ -893,19 +948,14 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) DBUG_RETURN(rc); } -#if 0 -void ha_cassandra::start_bulk_insert(ha_rows rows) -{ - /* Do nothing? */ -} - -int ha_cassandra::end_bulk_insert() +int ha_cassandra::reset() { - // TODO! + doing_insert_batch= false; return 0; } -#endif + + ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start ///////////////////////////////////////////////////////////////////////////// @@ -1023,20 +1073,32 @@ bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, // Dummy implementations end ///////////////////////////////////////////////////////////////////////////// - -static struct st_mysql_sys_var* cassandra_system_variables[]= { -// MYSQL_SYSVAR(enum_var), -// MYSQL_SYSVAR(ulong_var), - NULL +static SHOW_VAR cassandra_status_variables[]= { + {"row_inserts", + (char*) &cassandra_counters.row_inserts, SHOW_LONG}, + {"row_insert_batches", + (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, + {NullS, NullS, SHOW_LONG} }; +static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) +{ + //innodb_export_status(); + cassandra_counters_copy= cassandra_counters; + + var->type= SHOW_ARRAY; + var->value= (char *) &cassandra_status_variables; + return 0; +} + + struct st_mysql_storage_engine cassandra_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; static struct st_mysql_show_var func_status[]= { -// {"example_func_example", (char *)show_func_example, SHOW_FUNC}, + {"Cassandra", (char *)show_cassandra_vars, SHOW_FUNC}, {0,0,SHOW_UNDEF} }; diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 469440a0049..c8042cfb14a 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -47,6 +47,9 @@ class ha_cassandra: public handler void read_cassandra_columns(bool unpack_pk); ha_rows rnd_batch_size; + + bool doing_insert_batch; + ha_rows insert_rows_batched; public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() @@ -145,10 +148,12 @@ public: */ virtual double read_time(uint, uint, ha_rows rows) { return (double) rows / 20.0+1; } -#if 0 + virtual void start_bulk_insert(ha_rows rows); virtual int end_bulk_insert(); -#endif + + virtual int reset(); + /* Everything below are methods that we implement in ha_example.cc. -- cgit v1.2.1 From 8eb16159e19b38e67728fca7c7f316f921a2c7e0 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 27 Aug 2012 08:44:58 +0400 Subject: Cassandra storage engine: BKA support - We use HA_MRR_NO_ASSOC ("optimizer_switch=join_cache_hashed") mode - Not able to use BKA's buffers yet. - There is a variable to control batch size - There are status counters. - Nedeed to make some fixes in BKA code (to be checked with Igor) --- mysql-test/r/cassandra.result | 64 +++++++++++++++ mysql-test/t/cassandra.test | 35 +++++++++ sql/sql_join_cache.cc | 5 +- storage/cassandra/cassandra_se.cc | 82 ++++++++++++++++++- storage/cassandra/cassandra_se.h | 14 +++- storage/cassandra/ha_cassandra.cc | 161 +++++++++++++++++++++++++++++++++++--- storage/cassandra/ha_cassandra.h | 18 +++++ 7 files changed, 365 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 3b78bd5466a..096e501ceae 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -79,6 +79,7 @@ Cassandra_row_inserts 8 Cassandra_row_insert_batches 7 CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +delete from t1; INSERT INTO t1 VALUES (1,1),(2,2); DELETE FROM t1 ORDER BY a LIMIT 1; DROP TABLE t1; @@ -92,3 +93,66 @@ show status like 'cassandra_row_insert%'; Variable_name Value Cassandra_row_inserts 10 Cassandra_row_insert_batches 8 +# +# Batched Key Access +# +# Control variable (we are not yet able to make use of MRR's buffer) +show variables like 'cassandra_multi%'; +Variable_name Value +cassandra_multiget_batch_size 100 +# MRR-related status variables: +show status like 'cassandra_multi%'; +Variable_name Value +Cassandra_multiget_reads 0 +Cassandra_multiget_keys_scanned 0 +Cassandra_multiget_rows_read 0 +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +delete from t1; +INSERT INTO t1 VALUES (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9); +set @tmp_jcl=@@join_cache_level; +set join_cache_level=8; +explain select * from t1 A, t1 B where B.rowkey=A.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE A ALL NULL NULL NULL NULL 1000 Using where +1 SIMPLE B eq_ref PRIMARY PRIMARY 8 test.A.a 1 Using join buffer (flat, BKAH join); multiget_slice +select * from t1 A, t1 B where B.rowkey=A.a; +rowkey a rowkey a +0 0 0 0 +1 1 1 1 +2 2 2 2 +3 3 3 3 +4 4 4 4 +5 5 5 5 +6 6 6 6 +7 7 7 7 +8 8 8 8 +9 9 9 9 +show status like 'cassandra_multi%'; +Variable_name Value +Cassandra_multiget_reads 1 +Cassandra_multiget_keys_scanned 10 +Cassandra_multiget_rows_read 10 +insert into t1 values(1, 8); +insert into t1 values(3, 8); +insert into t1 values(5, 8); +insert into t1 values(7, 8); +select * from t1 A, t1 B where B.rowkey=A.a; +rowkey a rowkey a +0 0 0 0 +2 2 2 2 +4 4 4 4 +6 6 6 6 +1 8 8 8 +7 8 8 8 +8 8 8 8 +5 8 8 8 +3 8 8 8 +9 9 9 9 +show status like 'cassandra_multi%'; +Variable_name Value +Cassandra_multiget_reads 2 +Cassandra_multiget_keys_scanned 16 +Cassandra_multiget_rows_read 16 +delete from t1; +drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 195f365a372..2d76a4aeb71 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -117,6 +117,7 @@ show status like 'cassandra_row_insert%'; CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +delete from t1; INSERT INTO t1 VALUES (1,1),(2,2); DELETE FROM t1 ORDER BY a LIMIT 1; @@ -127,6 +128,40 @@ show status like 'cassandra_row_insert%'; flush status; show status like 'cassandra_row_insert%'; +--echo # +--echo # Batched Key Access +--echo # + +--echo # Control variable (we are not yet able to make use of MRR's buffer) +show variables like 'cassandra_multi%'; + +--echo # MRR-related status variables: +show status like 'cassandra_multi%'; + +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +delete from t1; +INSERT INTO t1 VALUES (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9); + +set @tmp_jcl=@@join_cache_level; +set join_cache_level=8; +explain select * from t1 A, t1 B where B.rowkey=A.a; + +select * from t1 A, t1 B where B.rowkey=A.a; +show status like 'cassandra_multi%'; + +# The following INSERTs are really UPDATEs +insert into t1 values(1, 8); +insert into t1 values(3, 8); +insert into t1 values(5, 8); +insert into t1 values(7, 8); + +select * from t1 A, t1 B where B.rowkey=A.a; +show status like 'cassandra_multi%'; + + +delete from t1; +drop table t1; ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index f953cf4df57..d785366ae69 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -3876,8 +3876,11 @@ int JOIN_TAB_SCAN_MRR::next() If a record in in an incremental cache contains no fields then the association for the last record in cache will be equal to cache->end_pos */ + /* + psergey: this makes no sense where HA_MRR_NO_ASSOC is used. DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) && (uchar *) (*ptr) <= cache->end_pos); + */ if (join_tab->table->vfield) update_virtual_fields(join->thd, join_tab->table); } @@ -4543,7 +4546,7 @@ bool JOIN_CACHE_BKAH::prepare_look_for_matches(bool skip_last) { last_matching_rec_ref_ptr= next_matching_rec_ref_ptr= 0; if (no_association && - (curr_matching_chain= get_matching_chain_by_join_key())) + !(curr_matching_chain= get_matching_chain_by_join_key())) //psergey: added '!' return 1; last_matching_rec_ref_ptr= get_next_rec_ref(curr_matching_chain); return 0; diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 75ce33cb981..27ff83f7c0d 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -100,7 +100,18 @@ public: /* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */ void clear_read_columns(); void add_read_column(const char *name); - + + /* Reads, MRR scans */ + void new_lookup_keys(); + int add_lookup_key(const char *key, size_t key_len); + bool multiget_slice(); + + std::vector mrr_keys; /* TODO: can we use allocator to put them onto MRR buffer? */ + std::map > mrr_result; + std::map >::iterator mrr_result_it; + + bool get_next_multiget_row(); + bool truncate(); bool remove_row(); @@ -522,3 +533,72 @@ bool Cassandra_se_impl::remove_row() return res; } + +///////////////////////////////////////////////////////////////////////////// +// MRR reads +///////////////////////////////////////////////////////////////////////////// + +void Cassandra_se_impl::new_lookup_keys() +{ + mrr_keys.clear(); +} + + +int Cassandra_se_impl::add_lookup_key(const char *key, size_t key_len) +{ + mrr_keys.push_back(std::string(key, key_len)); + return mrr_keys.size(); +} + + +bool Cassandra_se_impl::multiget_slice() +{ + ColumnParent cparent; + cparent.column_family= column_family; + + SlicePredicate slice_pred; + SliceRange sr; + sr.start = ""; + sr.finish = ""; + slice_pred.__set_slice_range(sr); + + bool res= true; + + try { + + cassandra_counters.multiget_reads++; + cassandra_counters.multiget_keys_scanned += mrr_keys.size(); + + cass->multiget_slice(mrr_result, mrr_keys, cparent, slice_pred, + cur_consistency_level); + + cassandra_counters.multiget_rows_read += mrr_result.size(); + + res= false; + mrr_result_it= mrr_result.begin(); + + } catch (InvalidRequestException ire) { + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + print_error("TimedOutException: %s", te.what()); + } + + return res; +} + + +bool Cassandra_se_impl::get_next_multiget_row() +{ + if (mrr_result_it == mrr_result.end()) + return true; /* EOF */ + + column_data_vec= mrr_result_it->second; + rowkey= mrr_result_it->first; + + column_data_it= column_data_vec.begin(); + mrr_result_it++; + return false; +} + diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 78bf1016fea..d2ece4d9441 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -41,11 +41,16 @@ public: /* Reads, multi-row scans */ int read_batch_size; - virtual bool get_range_slices(bool last_key_as_start_key)=0; virtual void finish_reading_range_slices()=0; virtual bool get_next_range_slice_row(bool *eof)=0; + /* Reads, MRR scans */ + virtual void new_lookup_keys()=0; + virtual int add_lookup_key(const char *key, size_t key_len)=0; + virtual bool multiget_slice()=0; + virtual bool get_next_multiget_row()=0; + /* read_set setup */ virtual void clear_read_columns()=0; virtual void add_read_column(const char *name)=0; @@ -59,13 +64,20 @@ public: void print_error(const char *format, ...); }; + /* A structure with global counters */ class Cassandra_status_vars { public: ulong row_inserts; ulong row_insert_batches; + + ulong multiget_reads; + ulong multiget_keys_scanned; + ulong multiget_rows_read; }; + + extern Cassandra_status_vars cassandra_counters; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 70d389d4992..9e94c848988 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -60,15 +60,35 @@ static MYSQL_THDVAR_ULONG(insert_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in an INSERT batch", NULL, NULL, /*default*/ 100, /*min*/ 1, /*max*/ 1024*1024*1024, 0); +static MYSQL_THDVAR_ULONG(multiget_batch_size, PLUGIN_VAR_RQCMDARG, + "Number of rows in a multiget(MRR) batch", + NULL, NULL, /*default*/ 100, /*min*/ 1, /*max*/ 1024*1024*1024, 0); static struct st_mysql_sys_var* cassandra_system_variables[]= { MYSQL_SYSVAR(insert_batch_size), + MYSQL_SYSVAR(multiget_batch_size), // MYSQL_SYSVAR(enum_var), // MYSQL_SYSVAR(ulong_var), NULL }; +static SHOW_VAR cassandra_status_variables[]= { + {"row_inserts", + (char*) &cassandra_counters.row_inserts, SHOW_LONG}, + {"row_insert_batches", + (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, + + {"multiget_reads", + (char*) &cassandra_counters.multiget_reads, SHOW_LONG}, + {"multiget_keys_scanned", + (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, + {"multiget_rows_read", + (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, + {NullS, NullS, SHOW_LONG} +}; + + Cassandra_status_vars cassandra_counters; Cassandra_status_vars cassandra_counters_copy; @@ -772,8 +792,7 @@ int ha_cassandra::write_row(uchar *buf) if (doing_insert_batch) { res= 0; - if (++insert_rows_batched >= /*insert_batch_size*/ - THDVAR(table->in_use, insert_batch_size)) + if (++insert_rows_batched >= THDVAR(table->in_use, insert_batch_size)) { res= se->do_insert(); insert_rows_batched= 0; @@ -955,6 +974,135 @@ int ha_cassandra::reset() return 0; } +///////////////////////////////////////////////////////////////////////////// +// MRR implementation +///////////////////////////////////////////////////////////////////////////// + + +/* + - The key can be only primary key + - allow equality-ranges only. + - anything else? +*/ +ha_rows ha_cassandra::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, + void *seq_init_param, + uint n_ranges, uint *bufsz, + uint *flags, COST_VECT *cost) +{ + /* No support for const ranges so far */ + return HA_POS_ERROR; +} + + +ha_rows ha_cassandra::multi_range_read_info(uint keyno, uint n_ranges, uint keys, + uint key_parts, uint *bufsz, + uint *flags, COST_VECT *cost) +{ + /* Can only be equality lookups on the primary key... */ + // TODO anything else? + *flags &= ~HA_MRR_USE_DEFAULT_IMPL; + *flags |= HA_MRR_NO_ASSOCIATION; + + return 10; +} + + +int ha_cassandra::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, + uint n_ranges, uint mode, HANDLER_BUFFER *buf) +{ + int res; + mrr_iter= seq->init(seq_init_param, n_ranges, mode); + mrr_funcs= *seq; + res= mrr_start_read(); + return (res? HA_ERR_INTERNAL_ERROR: 0); +} + + +bool ha_cassandra::mrr_start_read() +{ + uint key_len; + + my_bitmap_map *old_map; + old_map= dbug_tmp_use_all_columns(table, table->read_set); + + se->new_lookup_keys(); + + while (!(source_exhausted= mrr_funcs.next(mrr_iter, &mrr_cur_range))) + { + char *cass_key; + int cass_key_len; + + DBUG_ASSERT(mrr_cur_range.range_flag & EQ_RANGE); + + uchar *key= (uchar*)mrr_cur_range.start_key.key; + key_len= mrr_cur_range.start_key.length; + //key_len= calculate_key_len(table, active_index, key, keypart_map); // NEED THIS?? + store_key_image_to_rec(table->field[0], (uchar*)key, key_len); + + rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + + // Primitive buffer control + if (se->add_lookup_key(cass_key, cass_key_len) > + THDVAR(table->in_use, multiget_batch_size)) + break; + } + + dbug_tmp_restore_column_map(table->read_set, old_map); + + return se->multiget_slice(); +} + + +int ha_cassandra::multi_range_read_next(range_id_t *range_info) +{ + int res; + while(1) + { + if (!se->get_next_multiget_row()) + { + read_cassandra_columns(true); + res= 0; + break; + } + else + { + if (source_exhausted) + { + res= HA_ERR_END_OF_FILE; + break; + } + else + { + if (mrr_start_read()) + { + res= HA_ERR_INTERNAL_ERROR; + break; + } + } + } + /* + We get here if we've refilled the buffer and done another read. Try + reading from results again + */ + } + return res; +} + + +int ha_cassandra::multi_range_read_explain_info(uint mrr_mode, char *str, size_t size) +{ + const char *mrr_str= "multiget_slice"; + + if (!(mrr_mode & HA_MRR_USE_DEFAULT_IMPL)) + { + uint mrr_str_len= strlen(mrr_str); + uint copy_len= min(mrr_str_len, size); + memcpy(str, mrr_str, size); + return copy_len; + } + return 0; +} + ///////////////////////////////////////////////////////////////////////////// // Dummy implementations start @@ -1073,15 +1221,6 @@ bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, // Dummy implementations end ///////////////////////////////////////////////////////////////////////////// -static SHOW_VAR cassandra_status_variables[]= { - {"row_inserts", - (char*) &cassandra_counters.row_inserts, SHOW_LONG}, - {"row_insert_batches", - (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, - {NullS, NullS, SHOW_LONG} -}; - - static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) { //innodb_export_status(); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index c8042cfb14a..66e79f4ee70 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -154,6 +154,24 @@ public: virtual int reset(); + + int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, + uint n_ranges, uint mode, HANDLER_BUFFER *buf); + int multi_range_read_next(range_id_t *range_info); + ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, + void *seq_init_param, + uint n_ranges, uint *bufsz, + uint *flags, COST_VECT *cost); + ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, + uint key_parts, uint *bufsz, + uint *flags, COST_VECT *cost); + int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size); + +private: + bool source_exhausted; + bool mrr_start_read(); +public: + /* Everything below are methods that we implement in ha_example.cc. -- cgit v1.2.1 From 869826d770e844608e5871a40610f676b8e0754b Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 28 Aug 2012 12:53:33 +0400 Subject: MDEV-480: TRUNCATE TABLE on a Cassandra table does not remove rows - Remove HTON_CAN_RECREATE flag, re-create won't delete rows in cassandra. --- mysql-test/r/cassandra.result | 10 ++++++++++ mysql-test/t/cassandra.test | 12 +++++++++++- storage/cassandra/ha_cassandra.cc | 7 ++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 096e501ceae..bb41e9a010b 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -156,3 +156,13 @@ Cassandra_multiget_keys_scanned 16 Cassandra_multiget_rows_read 16 delete from t1; drop table t1; +# +# MDEV-480: TRUNCATE TABLE on a Cassandra table does not remove rows +# +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +INSERT INTO t1 VALUES (0,0),(1,1),(2,2); +truncate table t1; +select * from t1; +rowkey a +drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 2d76a4aeb71..26e1cf85839 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -159,9 +159,19 @@ insert into t1 values(7, 8); select * from t1 A, t1 B where B.rowkey=A.a; show status like 'cassandra_multi%'; - delete from t1; drop table t1; + +--echo # +--echo # MDEV-480: TRUNCATE TABLE on a Cassandra table does not remove rows +--echo # +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +INSERT INTO t1 VALUES (0,0),(1,1),(2,2); +truncate table t1; +select * from t1; +drop table t1; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 9e94c848988..5b1a411be6a 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -142,7 +142,12 @@ static int cassandra_init_func(void *p) cassandra_hton->state= SHOW_OPTION_YES; cassandra_hton->create= cassandra_create_handler; - cassandra_hton->flags= HTON_CAN_RECREATE; + /* + Don't specify HTON_CAN_RECREATE in flags. re-create is used by TRUNCATE + TABLE to create an *empty* table from scratch. Cassandra table won't be + emptied if re-created. + */ + cassandra_hton->flags= 0; cassandra_hton->table_options= cassandra_table_option_list; //cassandra_hton->field_options= example_field_option_list; cassandra_hton->field_options= NULL; -- cgit v1.2.1 From c943dfd8b2374b9c910ad08b1d08011fdd94257f Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 28 Aug 2012 20:22:45 +0400 Subject: MDEV-494, part #1: phantom row for big full-scan selects - Full table scan internally uses LIMIT n, and re-starts the scan from the last seen rowkey value. rowkey ranges are inclusive, so we will see the same rowkey again. We should ignore it. --- mysql-test/r/cassandra.result | 17 +++++++++++++++++ mysql-test/t/cassandra.test | 17 +++++++++++++++++ storage/cassandra/cassandra_se.cc | 25 +++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index bb41e9a010b..608eef2e629 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -166,3 +166,20 @@ truncate table t1; select * from t1; rowkey a drop table t1; +# +# MDEV-494, part #1: phantom row for big full-scan selects +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +insert into t1 select A.a + 10 * B.a + 100*C.a, 12345 from t0 A, t0 B, t0 C; +select count(*) from t1; +count(*) +1000 +select count(*) from t1 where a=12345; +count(*) +1000 +delete from t1; +drop table t1; +drop table t0; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 26e1cf85839..9d395ae3474 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -172,6 +172,23 @@ truncate table t1; select * from t1; drop table t1; +--echo # +--echo # MDEV-494, part #1: phantom row for big full-scan selects +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; + +insert into t1 select A.a + 10 * B.a + 100*C.a, 12345 from t0 A, t0 B, t0 C; + +select count(*) from t1; +select count(*) from t1 where a=12345; + +delete from t1; +drop table t1; +drop table t0; ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 27ff83f7c0d..d74f6c9444a 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -93,6 +93,10 @@ public: void get_read_rowkey(char **value, int *value_len); /* Reads, multi-row scans */ +private: + bool have_rowkey_to_skip; + std::string rowkey_to_skip; +public: bool get_range_slices(bool last_key_as_start_key); void finish_reading_range_slices(); bool get_next_range_slice_row(bool *eof); @@ -106,15 +110,17 @@ public: int add_lookup_key(const char *key, size_t key_len); bool multiget_slice(); +private: std::vector mrr_keys; /* TODO: can we use allocator to put them onto MRR buffer? */ std::map > mrr_result; std::map >::iterator mrr_result_it; - +public: bool get_next_multiget_row(); bool truncate(); bool remove_row(); +private: /* Non-inherited utility functions: */ int64_t get_i64_timestamp(); }; @@ -407,9 +413,17 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) key_range.__isset.end_key= true; if (last_key_as_start_key) + { key_range.start_key= rowkey; + + have_rowkey_to_skip= true; + rowkey_to_skip= rowkey; + } else + { + have_rowkey_to_skip= false; key_range.start_key.assign("", 0); + } key_range.end_key.assign("", 0); key_range.count= read_batch_size; @@ -441,6 +455,7 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) /* Switch to next row. This may produce an error */ bool Cassandra_se_impl::get_next_range_slice_row(bool *eof) { +restart: if (key_slice_it == key_slice_vec.end()) { if (get_slices_returned_less) @@ -462,7 +477,13 @@ bool Cassandra_se_impl::get_next_range_slice_row(bool *eof) return false; } } - + + if (have_rowkey_to_skip && !rowkey_to_skip.compare(key_slice_it->key)) + { + key_slice_it++; + goto restart; + } + *eof= false; column_data_vec= key_slice_it->columns; rowkey= key_slice_it->key; -- cgit v1.2.1 From c34b24ff88ccf6c5645b7c6bb469a08ca78af019 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 29 Aug 2012 07:39:22 +0400 Subject: Cassandra storage engine: add @@rnd_batch_size variable. --- mysql-test/t/cassandra.test | 1 + storage/cassandra/ha_cassandra.cc | 10 +++++++--- storage/cassandra/ha_cassandra.h | 2 -- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 9d395ae3474..bfefb987572 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -194,6 +194,7 @@ drop table t0; ############################################################################ --disable_parsing drop columnfamily cf1; +drop columnfamily cf2; --enable_parsing ############################################################################ ## Cassandra cleanup ends diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 5b1a411be6a..2c4b4371005 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -64,9 +64,14 @@ static MYSQL_THDVAR_ULONG(multiget_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in a multiget(MRR) batch", NULL, NULL, /*default*/ 100, /*min*/ 1, /*max*/ 1024*1024*1024, 0); +static MYSQL_THDVAR_ULONG(rnd_batch_size, PLUGIN_VAR_RQCMDARG, + "Number of rows in an rnd_read (full scan) batch", + NULL, NULL, /*default*/ 10*1000, /*min*/ 1, /*max*/ 1024*1024*1024, 0); + static struct st_mysql_sys_var* cassandra_system_variables[]= { MYSQL_SYSVAR(insert_batch_size), MYSQL_SYSVAR(multiget_batch_size), + MYSQL_SYSVAR(rnd_batch_size), // MYSQL_SYSVAR(enum_var), // MYSQL_SYSVAR(ulong_var), NULL @@ -254,8 +259,7 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), field_converters(NULL), rowkey_converter(NULL), - rnd_batch_size(10*1000) + se(NULL), field_converters(NULL), rowkey_converter(NULL) {} @@ -849,7 +853,7 @@ int ha_cassandra::rnd_init(bool scan) for (uint i= 1; i < table->s->fields; i++) se->add_read_column(table->field[i]->field_name); - se->read_batch_size= rnd_batch_size; + se->read_batch_size= THDVAR(table->in_use, rnd_batch_size); bres= se->get_range_slices(false); if (bres) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 66e79f4ee70..d5b542aae06 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -46,8 +46,6 @@ class ha_cassandra: public handler void read_cassandra_columns(bool unpack_pk); - ha_rows rnd_batch_size; - bool doing_insert_batch; ha_rows insert_rows_batched; public: -- cgit v1.2.1 From 22e71e4cc19b3c12f0c5721d6845ba7c28b25060 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 29 Aug 2012 10:05:21 +0400 Subject: Cassandra SE - Add mapping for INT datatype - Primary key column should now be named like CQL's primary key, or 'rowkey' if CF has key_alias. --- mysql-test/r/cassandra.result | 40 ++++++++++++++------- mysql-test/t/cassandra.test | 40 ++++++++++++++++++--- storage/cassandra/ha_cassandra.cc | 76 +++++++++++++++++++++++++++++---------- 3 files changed, 120 insertions(+), 36 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 608eef2e629..a0447776582 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -1,10 +1,10 @@ drop table if exists t0, t1; create table t1 (a int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; -ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' +ERROR 42000: Incorrect column name 'First column must be NOT NULL' create table t1 (a int primary key, b int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; -ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' +ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace foo does not exist] create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='127.0.0.2' keyspace='foo' column_family='colfam'; ERROR HY000: Unable to connect to foreign data source: connect() failed: Connection refused [1] @@ -15,36 +15,36 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s # Now, create a table for real and insert data -create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; # Just in case there were left-overs from previous: delete from t1; select * from t1; -rowkey data1 data2 +pk data1 data2 insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey11', 'data1-value2', 34543); insert into t1 values ('rowkey12', 'data1-value3', 454); select * from t1; -rowkey data1 data2 +pk data1 data2 rowkey12 data1-value3 454 rowkey10 data1-value 123456 rowkey11 data1-value2 34543 explain -select * from t1 where rowkey='rowkey11'; +select * from t1 where pk='rowkey11'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 38 const 1 -select * from t1 where rowkey='rowkey11'; -rowkey data1 data2 +select * from t1 where pk='rowkey11'; +pk data1 data2 rowkey11 data1-value2 34543 -delete from t1 where rowkey='rowkey11'; +delete from t1 where pk='rowkey11'; select * from t1; -rowkey data1 data2 +pk data1 data2 rowkey12 data1-value3 454 rowkey10 data1-value 123456 rowkey11 NULL NULL delete from t1; select * from t1; -rowkey data1 data2 +pk data1 data2 # # A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ, # also check ::rnd_pos() @@ -53,7 +53,7 @@ insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey11', 'data1-value2', 34543); insert into t1 values ('rowkey12', 'data1-value3', 454); select * from t1 order by data2; -rowkey data1 data2 +pk data1 data2 rowkey12 data1-value3 454 rowkey11 data1-value2 34543 rowkey10 data1-value 123456 @@ -183,3 +183,19 @@ count(*) delete from t1; drop table t1; drop table t0; +# 32-bit INT type support +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, intcol INT) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3'; +insert into t1 values (10,10); +insert into t1 values (12,12); +delete from t1; +drop table t1; +# +# Try accessing column family w/o explicitly defined columns +# +CREATE TABLE t1 (my_primary_key varchar(10) PRIMARY KEY) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10'; +ERROR HY000: Internal error: 'target column family has no key_alias defined, PRIMARY KEY column must be named 'rowkey'' +CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10'; +DROP TABLE t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index bfefb987572..c35c15da8ca 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -12,7 +12,7 @@ drop table if exists t0, t1; create table t1 (a int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; ---error ER_WRONG_COLUMN_NAME +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE create table t1 (a int primary key, b int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; @@ -45,13 +45,22 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); create columnfamily cf2 (rowkey bigint primary key, a bigint); +create columnfamily cf3 (rowkey bigint primary key, intcol int); + +./cassandra-cli + +CREATE COLUMN FAMILY cf10 + WITH comparator = UTF8Type + AND key_validation_class=UTF8Type + AND default_validation_class = UTF8Type; + --enable_parsing ############################################################################ ## Cassandra initialization ends ############################################################################ --echo # Now, create a table for real and insert data -create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; --echo # Just in case there were left-overs from previous: @@ -64,8 +73,8 @@ insert into t1 values ('rowkey12', 'data1-value3', 454); select * from t1; explain -select * from t1 where rowkey='rowkey11'; -select * from t1 where rowkey='rowkey11'; +select * from t1 where pk='rowkey11'; +select * from t1 where pk='rowkey11'; # Deletion functions weirdly: it sets all columns to NULL # but when If I do this in cassandra-cli: @@ -80,7 +89,7 @@ select * from t1 where rowkey='rowkey11'; # # CQL seems to simply ignore all "incomplete" records. -delete from t1 where rowkey='rowkey11'; +delete from t1 where pk='rowkey11'; select * from t1; delete from t1; @@ -189,6 +198,27 @@ select count(*) from t1 where a=12345; delete from t1; drop table t1; drop table t0; + +--echo # 32-bit INT type support +CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, intcol INT) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3'; +insert into t1 values (10,10); +insert into t1 values (12,12); +delete from t1; +drop table t1; + +--echo # +--echo # Try accessing column family w/o explicitly defined columns +--echo # +--error ER_INTERNAL_ERROR +CREATE TABLE t1 (my_primary_key varchar(10) PRIMARY KEY) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10'; + +CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10'; + +DROP TABLE t1; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 2c4b4371005..1778622ae9f 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -342,23 +342,16 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, ha_table_option_struct *options= table_arg->s->option_struct; DBUG_ENTER("ha_cassandra::create"); DBUG_ASSERT(options); - //psergey-todo: This is called for CREATE TABLE... check options here. -/* - if (table_arg->s->fields != 2) - { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), "The table must have two fields"); - DBUG_RETURN(HA_WRONG_CREATE_OPTION); - } -*/ Field **pfield= table_arg->s->field; +/* if (strcmp((*pfield)->field_name, "rowkey")) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'"); DBUG_RETURN(HA_WRONG_CREATE_OPTION); } - +*/ if (!((*pfield)->flags & NOT_NULL_FLAG)) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL"); @@ -369,11 +362,11 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, table_arg->key_info[0].key_parts != 1 || table_arg->key_info[0].key_part[0].fieldnr != 1) { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Table must have one PRIMARY KEY(rowkey)"); + my_error(ER_WRONG_COLUMN_NAME, MYF(0), + "Table must have PRIMARY KEY defined over the first column"); DBUG_RETURN(HA_WRONG_CREATE_OPTION); } - #ifndef DBUG_OFF /* DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ @@ -519,6 +512,36 @@ public: }; +class Int32DataConverter : public ColumnDataConverter +{ + int32_t buf; +public: + void flip(const char *from, char* to) + { + to[0]= from[3]; + to[1]= from[2]; + to[2]= from[1]; + to[3]= from[0]; + } + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + int32_t tmp; + DBUG_ASSERT(cass_data_len == sizeof(int32_t)); + flip(cass_data, (char*)&tmp); + field->store(tmp); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + int32_t tmp= field->val_int(); + flip((const char*)&tmp, (char*)&buf); + *cass_data= (char*)&buf; + *cass_data_len=sizeof(int32_t); + } + ~Int32DataConverter(){} +}; + + class StringCopyConverter : public ColumnDataConverter { String buf; @@ -557,15 +580,16 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ switch(field->type()) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: if (!strcmp(validator_name, validator_bigint)) res= new BigintDataConverter; break; + case MYSQL_TYPE_FLOAT: if (!strcmp(validator_name, validator_float)) res= new FloatDataConverter; break; + case MYSQL_TYPE_DOUBLE: if (!strcmp(validator_name, validator_double)) res= new DoubleDataConverter; @@ -581,6 +605,12 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ res= new StringCopyConverter; } break; + + case MYSQL_TYPE_LONG: + if (!strcmp(validator_name, validator_int)) + res= new Int32DataConverter; + break; + default:; } return res; @@ -601,11 +631,6 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) bzero(field_converters, memsize); n_field_converters= n_fields; - /* - TODO: what about mapping the primary key? It has a 'type', too... - see CfDef::key_validation_class ? see also CfDef::key_alias? - */ - se->first_ddl_column(); uint n_mapped= 0; while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, @@ -634,10 +659,23 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) return true; /* - Setup type conversion for row_key. It may also have a name, but we ignore - it currently + Setup type conversion for row_key. */ se->get_rowkey_type(&col_name, &col_type); + if (col_name && strcmp(col_name, (*field_arg)->field_name)) + { + se->print_error("PRIMARY KEY column must match Cassandra's name '%s'", col_name); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + return true; + } + if (!col_name && strcmp("rowkey", (*field_arg)->field_name)) + { + se->print_error("target column family has no key_alias defined, " + "PRIMARY KEY column must be named 'rowkey'"); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + return true; + } + if (col_type != NULL) { if (!(rowkey_converter= map_field_to_validator(*field_arg, col_type))) -- cgit v1.2.1 From fd53cbbff61bcfb882c11f3dab3a020262736ce4 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 29 Aug 2012 11:05:46 +0400 Subject: Cassandra SE: Timestamp data type support. --- mysql-test/r/cassandra.result | 12 ++++++ mysql-test/t/cassandra.test | 14 +++++++ storage/cassandra/ha_cassandra.cc | 81 ++++++++++++++++++++++++++++----------- 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index a0447776582..e7f34860444 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -199,3 +199,15 @@ ERROR HY000: Internal error: 'target column family has no key_alias defined, PRI CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10'; DROP TABLE t1; +# +# Timestamp datatype support +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +delete from t2; +insert into t2 values (1, '2012-08-29 01:23:45'); +select * from t2; +rowkey datecol +1 2012-08-29 01:23:45 +delete from t2; +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index c35c15da8ca..052afdad89e 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -47,6 +47,8 @@ create columnfamily cf2 (rowkey bigint primary key, a bigint); create columnfamily cf3 (rowkey bigint primary key, intcol int); +create columnfamily cf4 (rowkey bigint primary key, datecol timestamp); + ./cassandra-cli CREATE COLUMN FAMILY cf10 @@ -219,6 +221,18 @@ CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA DROP TABLE t1; +--echo # +--echo # Timestamp datatype support +--echo # +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; + +delete from t2; +insert into t2 values (1, '2012-08-29 01:23:45'); +select * from t2; +delete from t2; + +drop table t2; ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 1778622ae9f..519190ad5d2 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -477,64 +477,64 @@ public: ~FloatDataConverter(){} }; +static void flip64(const char *from, char* to) +{ + to[0]= from[7]; + to[1]= from[6]; + to[2]= from[5]; + to[3]= from[4]; + to[4]= from[3]; + to[5]= from[2]; + to[6]= from[1]; + to[7]= from[0]; +} class BigintDataConverter : public ColumnDataConverter { longlong buf; public: - void flip(const char *from, char* to) - { - to[0]= from[7]; - to[1]= from[6]; - to[2]= from[5]; - to[3]= from[4]; - to[4]= from[3]; - to[5]= from[2]; - to[6]= from[1]; - to[7]= from[0]; - } void cassandra_to_mariadb(const char *cass_data, int cass_data_len) { longlong tmp; DBUG_ASSERT(cass_data_len == sizeof(longlong)); - flip(cass_data, (char*)&tmp); + flip64(cass_data, (char*)&tmp); field->store(tmp); } void mariadb_to_cassandra(char **cass_data, int *cass_data_len) { longlong tmp= field->val_int(); - flip((const char*)&tmp, (char*)&buf); + flip64((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; *cass_data_len=sizeof(longlong); } ~BigintDataConverter(){} }; +static void flip32(const char *from, char* to) +{ + to[0]= from[3]; + to[1]= from[2]; + to[2]= from[1]; + to[3]= from[0]; +} class Int32DataConverter : public ColumnDataConverter { int32_t buf; public: - void flip(const char *from, char* to) - { - to[0]= from[3]; - to[1]= from[2]; - to[2]= from[1]; - to[3]= from[0]; - } void cassandra_to_mariadb(const char *cass_data, int cass_data_len) { int32_t tmp; DBUG_ASSERT(cass_data_len == sizeof(int32_t)); - flip(cass_data, (char*)&tmp); + flip32(cass_data, (char*)&tmp); field->store(tmp); } void mariadb_to_cassandra(char **cass_data, int *cass_data_len) { int32_t tmp= field->val_int(); - flip((const char*)&tmp, (char*)&buf); + flip32((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; *cass_data_len=sizeof(int32_t); } @@ -561,6 +561,34 @@ public: }; +class TimestampDataConverter : public ColumnDataConverter +{ + int64_t buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + int64_t tmp; + DBUG_ASSERT(cass_data_len==8); + flip64(cass_data, (char*)&tmp); + ((Field_timestamp*)field)->store_TIME(tmp / 1000, tmp % 1000); + } + + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + my_time_t ts_time; + ulong ts_millis; + int64_t tmp; + ts_time= ((Field_timestamp*)field)->get_timestamp(&ts_millis); + + tmp= ts_time * 1000 + ts_millis; + flip64((const char*)&tmp, (char*)&buf); + + *cass_data= (char*)&buf; + *cass_data_len= 8; + } + ~TimestampDataConverter(){} +}; + const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType"; const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type"; const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType"; @@ -572,6 +600,7 @@ const char * const validator_blob= "org.apache.cassandra.db.marshal.BytesType const char * const validator_ascii= "org.apache.cassandra.db.marshal.AsciiType"; const char * const validator_text= "org.apache.cassandra.db.marshal.UTF8Type"; +const char * const validator_timestamp="org.apache.cassandra.db.marshal.DateType"; ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { @@ -581,7 +610,8 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONGLONG: - if (!strcmp(validator_name, validator_bigint)) + if (!strcmp(validator_name, validator_bigint) || + 0/*!strcmp(validator_name, validator_timestamp)*/) res= new BigintDataConverter; break; @@ -594,6 +624,11 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ if (!strcmp(validator_name, validator_double)) res= new DoubleDataConverter; break; + + case MYSQL_TYPE_TIMESTAMP: + if (!strcmp(validator_name, validator_timestamp)) + res= new TimestampDataConverter; + break; case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: -- cgit v1.2.1 From 6a827daf61cd1a999e9191d6815c9ade4c0a3f78 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 29 Aug 2012 11:14:04 +0400 Subject: Fix for the previous cset: Field::store_TIME() accepts microseconds fraction, not millisecond. --- storage/cassandra/ha_cassandra.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 519190ad5d2..fcaf4bd0fc1 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -567,20 +567,27 @@ class TimestampDataConverter : public ColumnDataConverter public: void cassandra_to_mariadb(const char *cass_data, int cass_data_len) { + /* Cassandra data is milliseconds-since-epoch in network byte order */ int64_t tmp; DBUG_ASSERT(cass_data_len==8); flip64(cass_data, (char*)&tmp); - ((Field_timestamp*)field)->store_TIME(tmp / 1000, tmp % 1000); + /* + store_TIME's arguments: + - seconds since epoch + - microsecond fraction of a second. + */ + ((Field_timestamp*)field)->store_TIME(tmp / 1000, (tmp % 1000)*1000); } - + void mariadb_to_cassandra(char **cass_data, int *cass_data_len) { my_time_t ts_time; - ulong ts_millis; + ulong ts_microsec; int64_t tmp; - ts_time= ((Field_timestamp*)field)->get_timestamp(&ts_millis); - - tmp= ts_time * 1000 + ts_millis; + ts_time= ((Field_timestamp*)field)->get_timestamp(&ts_microsec); + + /* Cassandra needs milliseconds-since-epoch */ + tmp= ts_time * 1000 + ts_microsec/1000; flip64((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; -- cgit v1.2.1 From 29e9406a82a00e6ec81a65e0254d9527ba25ba20 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 29 Aug 2012 20:27:11 +0400 Subject: Cassandra SE: fix batched insert to flush its buffers after insert operation. --- mysql-test/r/cassandra.result | 15 +++++++++++++ mysql-test/t/cassandra.test | 44 +++++++++++++++++++++++++++++++++++++++ storage/cassandra/cassandra_se.cc | 11 ++++++++++ 3 files changed, 70 insertions(+) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index e7f34860444..8f4b261b5ae 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -210,4 +210,19 @@ select * from t2; rowkey datecol 1 2012-08-29 01:23:45 delete from t2; +# +# (no MDEV#) Check that insert counters work correctly +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +set cassandra_insert_batch_size=10; +insert into t2 select A.a+10*B.a, now() from t0 A, t0 B; +inserts insert_batches +100 10 +set cassandra_insert_batch_size=1; +insert into t2 select A.a+10*B.a+100, now() from t0 A, t0 B; +inserts insert_batches +100 100 +delete from t2; drop table t2; +drop table t0; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 052afdad89e..9abe9448c45 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -232,7 +232,51 @@ insert into t2 values (1, '2012-08-29 01:23:45'); select * from t2; delete from t2; +--echo # +--echo # (no MDEV#) Check that insert counters work correctly +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +let $start_inserts=`select variable_value from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_inserts'`; +let $start_insert_batches=`select variable_value from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_insert_batches'`; + +set cassandra_insert_batch_size=10; +insert into t2 select A.a+10*B.a, now() from t0 A, t0 B; + +--disable_query_log +eval select + (select variable_value - $start_inserts from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_inserts') + AS 'inserts', + (select variable_value - $start_insert_batches from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_insert_batches') + AS 'insert_batches'; +--enable_query_log + +let $start_inserts=`select variable_value from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_inserts'`; +let $start_insert_batches=`select variable_value from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_insert_batches'`; + +set cassandra_insert_batch_size=1; +insert into t2 select A.a+10*B.a+100, now() from t0 A, t0 B; + +--disable_query_log +eval select + (select variable_value - $start_inserts from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_inserts') + AS 'inserts', + (select variable_value - $start_insert_batches from information_schema.SESSION_STATUS + where variable_name ='Cassandra_row_insert_batches') + AS 'insert_batches'; +--enable_query_log + +delete from t2; drop table t2; +drop table t0; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index d74f6c9444a..670c13c2e91 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -291,6 +291,15 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value, bool Cassandra_se_impl::do_insert() { bool res= true; + + /* + zero-size mutations are allowed by Cassandra's batch_mutate but lets not + do them (we may attempt to do it if there is a bulk insert that stores + exactly @@cassandra_insert_batch_size*n elements. + */ + if (batch_mutation.empty()) + return false; + try { cass->batch_mutate(batch_mutation, cur_consistency_level); @@ -298,6 +307,7 @@ bool Cassandra_se_impl::do_insert() cassandra_counters.row_inserts+= batch_mutation.size(); cassandra_counters.row_insert_batches++; + clear_insert_buffer(); res= false; } catch (InvalidRequestException ire) { @@ -623,3 +633,4 @@ bool Cassandra_se_impl::get_next_multiget_row() return false; } + -- cgit v1.2.1 From 6cce520472989216ac57349f1ad6d4b2afe03c91 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 31 Aug 2012 10:49:36 +0400 Subject: Cassandra SE - add support for Cassandra's UUID datatype. We map it to CHAR(36). --- mysql-test/r/cassandra.result | 34 +++++++++ mysql-test/t/cassandra.test | 49 +++++++++++++ storage/cassandra/cassandra_se.cc | 3 +- storage/cassandra/ha_cassandra.cc | 150 ++++++++++++++++++++++++++++++++++---- storage/cassandra/ha_cassandra.h | 3 + 5 files changed, 222 insertions(+), 17 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 8f4b261b5ae..a340ae75f62 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -226,3 +226,37 @@ inserts insert_batches delete from t2; drop table t2; drop table t0; +# +# UUID datatype support +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; +insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09'); +insert into t2 values(2,'not-an-uuid'); +ERROR 22003: Out of range value for column 'uuidcol' at row 1 +insert into t2 values(3,'9b5658dc-f32f-11e1=94cd-f46d046e9f09'); +ERROR 22003: Out of range value for column 'uuidcol' at row 1 +insert into t2 values(4,'9b5658dc-fzzf-11e1-94cd-f46d046e9f09'); +ERROR 22003: Out of range value for column 'uuidcol' at row 1 +insert into t2 values +(5,'9b5658dc-f11f-11e1-94cd-f46d046e9f09'), +(6,'9b5658dc-f11f011e1-94cd-f46d046e9f09'); +ERROR 22003: Out of range value for column 'uuidcol' at row 2 +select * from t2; +rowkey uuidcol +1 9b5658dc-f32f-11e1-94cd-f46d046e9f09 +5 9b5658dc-f11f-11e1-94cd-f46d046e9f09 +delete from t2; +drop table t2; +CREATE TABLE t2 (rowkey char(36) PRIMARY KEY, col1 int) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf6'; +delete from t2; +insert into t2 values('9b5658dc-f32f-11e1-94cd-f46d046e9f09', 1234); +insert into t2 values('not-an-uuid', 563); +ERROR 22003: Out of range value for column 'rowkey' at row 1 +select * from t2; +rowkey col1 +9b5658dc-f32f-11e1-94cd-f46d046e9f09 1234 +delete from t2; +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 9abe9448c45..365cb5f8230 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -49,6 +49,10 @@ create columnfamily cf3 (rowkey bigint primary key, intcol int); create columnfamily cf4 (rowkey bigint primary key, datecol timestamp); +create columnfamily cf5 (rowkey bigint primary key, uuidcol uuid); + +create columnfamily cf6 (rowkey uuid primary key, col1 int); + ./cassandra-cli CREATE COLUMN FAMILY cf10 @@ -277,12 +281,57 @@ delete from t2; drop table t2; drop table t0; +--echo # +--echo # UUID datatype support +--echo # +#create columnfamily cf5 (rowkey bigint primary key, uuidcol uuid); +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; + +insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09'); + +--error ER_WARN_DATA_OUT_OF_RANGE +insert into t2 values(2,'not-an-uuid'); + +--error ER_WARN_DATA_OUT_OF_RANGE +insert into t2 values(3,'9b5658dc-f32f-11e1=94cd-f46d046e9f09'); + +--error ER_WARN_DATA_OUT_OF_RANGE +insert into t2 values(4,'9b5658dc-fzzf-11e1-94cd-f46d046e9f09'); + +--error ER_WARN_DATA_OUT_OF_RANGE +insert into t2 values + (5,'9b5658dc-f11f-11e1-94cd-f46d046e9f09'), + (6,'9b5658dc-f11f011e1-94cd-f46d046e9f09'); + +select * from t2; + +delete from t2; +drop table t2; + +# create columnfamily cf6 (rowkey uuid primary key, col1 int); +CREATE TABLE t2 (rowkey char(36) PRIMARY KEY, col1 int) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf6'; +delete from t2; + +insert into t2 values('9b5658dc-f32f-11e1-94cd-f46d046e9f09', 1234); + +--error ER_WARN_DATA_OUT_OF_RANGE +insert into t2 values('not-an-uuid', 563); + +select * from t2; +delete from t2; +drop table t2; + ############################################################################ ## Cassandra cleanup ############################################################################ --disable_parsing drop columnfamily cf1; drop columnfamily cf2; +drop columnfamily cf3; +drop columnfamily cf4; --enable_parsing ############################################################################ ## Cassandra cleanup ends diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 670c13c2e91..692bfb595da 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -416,9 +416,8 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) cparent.column_family= column_family; /* SlicePredicate can be used to limit columns we will retrieve */ - // Try passing nothing... - KeyRange key_range; // Try passing nothing, too. + KeyRange key_range; key_range.__isset.start_key= true; key_range.__isset.end_key= true; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index fcaf4bd0fc1..3be416e99cc 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -302,6 +302,7 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) } info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + insert_lineno= 0; DBUG_RETURN(0); } @@ -407,6 +408,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "setup_field_converters"); DBUG_RETURN(HA_ERR_NO_CONNECTION); } + insert_lineno= 0; DBUG_RETURN(0); } @@ -430,8 +432,13 @@ public: /* This will get data from the Field pointer, store Cassandra's form in internal buffer, and return pointer/size. + + @return + false - OK + true - Failed to convert value (completely, there is no value to insert + at all). */ - virtual void mariadb_to_cassandra(char **cass_data, int *cass_data_len)=0; + virtual bool mariadb_to_cassandra(char **cass_data, int *cass_data_len)=0; virtual ~ColumnDataConverter() {}; }; @@ -447,11 +454,12 @@ public: field->store(*pdata); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { buf= field->val_real(); *cass_data= (char*)&buf; *cass_data_len=sizeof(double); + return false; } ~DoubleDataConverter(){} }; @@ -468,11 +476,12 @@ public: field->store(*pdata); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { buf= field->val_real(); *cass_data= (char*)&buf; *cass_data_len=sizeof(float); + return false; } ~FloatDataConverter(){} }; @@ -501,12 +510,13 @@ public: field->store(tmp); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { longlong tmp= field->val_int(); flip64((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; *cass_data_len=sizeof(longlong); + return false; } ~BigintDataConverter(){} }; @@ -531,12 +541,13 @@ public: field->store(tmp); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { int32_t tmp= field->val_int(); flip32((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; *cass_data_len=sizeof(int32_t); + return false; } ~Int32DataConverter(){} }; @@ -551,11 +562,12 @@ public: field->store(cass_data, cass_data_len,field->charset()); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { String *pstr= field->val_str(&buf); *cass_data= (char*)pstr->c_ptr(); *cass_data_len= pstr->length(); + return false; } ~StringCopyConverter(){} }; @@ -579,7 +591,7 @@ public: ((Field_timestamp*)field)->store_TIME(tmp / 1000, (tmp % 1000)*1000); } - void mariadb_to_cassandra(char **cass_data, int *cass_data_len) + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { my_time_t ts_time; ulong ts_microsec; @@ -592,10 +604,85 @@ public: *cass_data= (char*)&buf; *cass_data_len= 8; + return false; } ~TimestampDataConverter(){} }; + + +static int convert_hex_digit(const char c) +{ + int num; + if (c >= '0' && c <= '9') + num= c - '0'; + else if (c >= 'A' && c <= 'F') + num= c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + num= c - 'a' + 10; + else + return -1; /* Couldn't convert */ + return num; +} + + +const char map2number[]="0123456789abcdef"; + +class UuidDataConverter : public ColumnDataConverter +{ + char buf[16]; /* Binary UUID representation */ + String str_buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + DBUG_ASSERT(cass_data_len==16); + char str[37]; + char *ptr= str; + /* UUID arrives as 16-byte number in network byte order */ + for (uint i=0; i < 16; i++) + { + *(ptr++)= map2number[(cass_data[i] >> 4) & 0xF]; + *(ptr++)= map2number[cass_data[i] & 0xF]; + if (i == 3 || i == 5 || i == 7 || i == 9) + *(ptr++)= '-'; + } + *ptr= 0; + field->store(str, 36,field->charset()); + } + + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + String *uuid_str= field->val_str(&str_buf); + char *pstr= (char*)uuid_str->c_ptr(); + + if (uuid_str->length() != 36) + return true; + + int lower, upper; + for (uint i=0; i < 16; i++) + { + if ((upper= convert_hex_digit(pstr[0])) == -1 || + (lower= convert_hex_digit(pstr[1])) == -1) + { + return true; + } + buf[i]= lower | (upper << 4); + pstr += 2; + if (i == 3 || i == 5 || i == 7 || i == 9) + { + if (pstr[0] != '-') + return true; + pstr++; + } + } + + *cass_data= buf; + *cass_data_len= 16; + return false; + } + ~UuidDataConverter(){} +}; + const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType"; const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type"; const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType"; @@ -609,6 +696,8 @@ const char * const validator_text= "org.apache.cassandra.db.marshal.UTF8Type" const char * const validator_timestamp="org.apache.cassandra.db.marshal.DateType"; +const char * const validator_uuid= "org.apache.cassandra.db.marshal.UUIDType"; + ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { ColumnDataConverter *res= NULL; @@ -617,8 +706,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONGLONG: - if (!strcmp(validator_name, validator_bigint) || - 0/*!strcmp(validator_name, validator_timestamp)*/) + if (!strcmp(validator_name, validator_bigint)) res= new BigintDataConverter; break; @@ -637,9 +725,18 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ res= new TimestampDataConverter; break; - case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: // these are space padded CHAR(n) strings. + if (!strcmp(validator_name, validator_uuid) && + field->real_type() == MYSQL_TYPE_STRING && + field->field_length == 36) + { + // UUID maps to CHAR(36), its text representation + res= new UuidDataConverter; + break; + } + /* fall through: */ case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_STRING: // these are space padded strings. + case MYSQL_TYPE_VAR_STRING: if (!strcmp(validator_name, validator_blob) || !strcmp(validator_name, validator_ascii) || !strcmp(validator_name, validator_text)) @@ -698,7 +795,11 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) } if (n_mapped != n_fields - 1) + { + se->print_error("Some of SQL fields were not mapped to Cassandra's fields"); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); return true; + } /* Setup type conversion for row_key. @@ -775,7 +876,11 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, old_map= dbug_tmp_use_all_columns(table, table->read_set); - rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + if (rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len)) + { + /* We get here when making lookups like uuid_column='not-an-uuid' */ + DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); + } dbug_tmp_restore_column_map(table->read_set, old_map); @@ -858,10 +963,18 @@ int ha_cassandra::write_row(uchar *buf) old_map= dbug_tmp_use_all_columns(table, table->read_set); + insert_lineno++; + /* Convert the key */ char *cass_key; int cass_key_len; - rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); + if (rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + rowkey_converter->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } se->start_row_insert(cass_key, cass_key_len); /* Convert other fields */ @@ -869,7 +982,13 @@ int ha_cassandra::write_row(uchar *buf) { char *cass_data; int cass_data_len; - field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len); + if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + field_converters[i]->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } se->add_insert_column(field_converters[i]->field->field_name, cass_data, cass_data_len); } @@ -892,7 +1011,7 @@ int ha_cassandra::write_row(uchar *buf) if (res) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } @@ -1060,6 +1179,7 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) int ha_cassandra::reset() { doing_insert_batch= false; + insert_lineno= 0; return 0; } diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index d5b542aae06..948bd8a6687 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -48,6 +48,9 @@ class ha_cassandra: public handler bool doing_insert_batch; ha_rows insert_rows_batched; + + /* Used to produce 'wrong column %s at row %lu' warnings */ + ha_rows insert_lineno; public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() -- cgit v1.2.1 From 12ab6a4f3cae9a3100eecba616824a3c040672fc Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 31 Aug 2012 11:03:59 +0400 Subject: MDEV-498: Cassandra: Inserting a timestamp does not work on a 32-bit system - Make an attempt at fixing. --- mysql-test/r/cassandra.result | 6 ++++++ mysql-test/t/cassandra.test | 5 +++++ storage/cassandra/ha_cassandra.cc | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index a340ae75f62..36d562f3348 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -210,6 +210,12 @@ select * from t2; rowkey datecol 1 2012-08-29 01:23:45 delete from t2; +# MDEV-498: Cassandra: Inserting a timestamp does not work on a 32-bit system +INSERT INTO t2 VALUES (10,'2012-12-12 12:12:12'); +SELECT * FROM t2; +rowkey datecol +10 2012-12-12 12:12:12 +delete from t2; # # (no MDEV#) Check that insert counters work correctly # diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 365cb5f8230..b7762085029 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -236,6 +236,11 @@ insert into t2 values (1, '2012-08-29 01:23:45'); select * from t2; delete from t2; +--echo # MDEV-498: Cassandra: Inserting a timestamp does not work on a 32-bit system +INSERT INTO t2 VALUES (10,'2012-12-12 12:12:12'); +SELECT * FROM t2; +delete from t2; + --echo # --echo # (no MDEV#) Check that insert counters work correctly --echo # diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 3be416e99cc..f5ca8a4494d 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -599,7 +599,7 @@ public: ts_time= ((Field_timestamp*)field)->get_timestamp(&ts_microsec); /* Cassandra needs milliseconds-since-epoch */ - tmp= ts_time * 1000 + ts_microsec/1000; + tmp= ((int64_t)ts_time) * 1000 + ts_microsec/1000; flip64((const char*)&tmp, (char*)&buf); *cass_data= (char*)&buf; -- cgit v1.2.1 From 4986de84ad0a7b70e8cd4788564d13ad6f03e016 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 7 Sep 2012 15:32:43 +0400 Subject: Cassandra SE: added support for boolean type. --- mysql-test/r/cassandra.result | 10 ++++++++++ mysql-test/t/cassandra.test | 15 +++++++++++++++ storage/cassandra/ha_cassandra.cc | 31 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 36d562f3348..401bc75cc80 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -266,3 +266,13 @@ rowkey col1 9b5658dc-f32f-11e1-94cd-f46d046e9f09 1234 delete from t2; drop table t2; +CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol varchar(12)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; +insert into t2 values (0, 0); +insert into t2 values (1, 1); +select * from t2; +rowkey boolcol +0 0 +1 1 +delete from t2; +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index b7762085029..6738cee4c77 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -53,6 +53,8 @@ create columnfamily cf5 (rowkey bigint primary key, uuidcol uuid); create columnfamily cf6 (rowkey uuid primary key, col1 int); +create columnfamily cf7 (rowkey int primary key, boolcol boolean); + ./cassandra-cli CREATE COLUMN FAMILY cf10 @@ -329,6 +331,16 @@ select * from t2; delete from t2; drop table t2; + +# create columnfamily cf7 (rowkey int primary key, boolcol boolean); +CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol varchar(12)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; +insert into t2 values (0, 0); +insert into t2 values (1, 1); +select * from t2; +delete from t2; +drop table t2; + ############################################################################ ## Cassandra cleanup ############################################################################ @@ -337,6 +349,9 @@ drop columnfamily cf1; drop columnfamily cf2; drop columnfamily cf3; drop columnfamily cf4; +drop columnfamily cf5; +drop columnfamily cf6; +drop columnfamily cf7; --enable_parsing ############################################################################ ## Cassandra cleanup ends diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index f5ca8a4494d..7ef563114fd 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -529,6 +529,28 @@ static void flip32(const char *from, char* to) to[3]= from[0]; } + +class TinyintDataConverter : public ColumnDataConverter +{ + char buf; +public: + void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + { + DBUG_ASSERT(cass_data_len == 1); + field->store(cass_data[0]); + } + + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) + { + buf= field->val_int()? 1 : 0; /* TODO: error handling? */ + *cass_data= (char*)&buf; + *cass_data_len= 1; + return false; + } + ~TinyintDataConverter(){} +}; + + class Int32DataConverter : public ColumnDataConverter { int32_t buf; @@ -683,6 +705,7 @@ public: ~UuidDataConverter(){} }; + const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType"; const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type"; const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType"; @@ -698,12 +721,20 @@ const char * const validator_timestamp="org.apache.cassandra.db.marshal.DateType const char * const validator_uuid= "org.apache.cassandra.db.marshal.UUIDType"; +const char * const validator_boolean= "org.apache.cassandra.db.marshal.BooleanType"; + ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { ColumnDataConverter *res= NULL; switch(field->type()) { case MYSQL_TYPE_TINY: + if (!strcmp(validator_name, validator_boolean)) + { + res= new TinyintDataConverter; + break; + } + /* fall through: */ case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONGLONG: if (!strcmp(validator_name, validator_bigint)) -- cgit v1.2.1 From 82e74d4cc1b59ed5901e2e06ead6df972b1b815d Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 10 Sep 2012 12:50:58 +0400 Subject: Cassandra SE - Make cassandra.test drop and re-crate the test keyspace. --- mysql-test/t/cassandra.test | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 6738cee4c77..44d42512fbc 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -30,11 +30,20 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; ############################################################################ -## Cassandra initialization: +## Cassandra initialization ############################################################################ ---disable_parsing -./cqlsh --cql3 +# Step 1: remove the keyspace that could be left over from the previous test +--remove_files_wildcard $MYSQLTEST_VARDIR cassandra_test_cleanup.cql +--write_file $MYSQLTEST_VARDIR/cassandra_test_cleanup.cql +drop keyspace mariadbtest2; +EOF +--error 0,1,2 +--system cqlsh -3 -f $MYSQLTEST_VARDIR/cassandra_test_cleanup.cql + +# Step 2: create new keyspace and test column families +--remove_files_wildcard $MYSQLTEST_VARDIR cassandra_test_init.cql +--write_file $MYSQLTEST_VARDIR/cassandra_test_init.cql CREATE KEYSPACE mariadbtest2 WITH strategy_class = 'org.apache.cassandra.locator.SimpleStrategy' @@ -55,14 +64,27 @@ create columnfamily cf6 (rowkey uuid primary key, col1 int); create columnfamily cf7 (rowkey int primary key, boolcol boolean); -./cassandra-cli +create columnfamily cf8 (rowkey int primary key, countercol counter); + +EOF +--error 0,1,2 +--system cqlsh -3 -f $MYSQLTEST_VARDIR/cassandra_test_init.cql + +# Step 3: Cassandra's CQL doesn't allow certain kinds of queries. Run them in +# CLI +--remove_files_wildcard $MYSQLTEST_VARDIR cassandra_test_init.cli +--write_file $MYSQLTEST_VARDIR/cassandra_test_init.cli +use mariadbtest2; CREATE COLUMN FAMILY cf10 WITH comparator = UTF8Type AND key_validation_class=UTF8Type AND default_validation_class = UTF8Type; +EOF + +--error 0,1,2 +--system cassandra-cli -f $MYSQLTEST_VARDIR/cassandra_test_init.cli ---enable_parsing ############################################################################ ## Cassandra initialization ends ############################################################################ -- cgit v1.2.1 From a3f33268ec00740596527951ef9b7906a77a0835 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 10 Sep 2012 14:40:07 +0400 Subject: Cassandra SE: add support for reading counter type values --- mysql-test/t/cassandra.test | 13 +++++++++++-- storage/cassandra/cassandra_se.cc | 24 ++++++++++++++++++++---- storage/cassandra/ha_cassandra.cc | 22 +++++++++++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 44d42512fbc..4d2d390fdb5 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -64,7 +64,9 @@ create columnfamily cf6 (rowkey uuid primary key, col1 int); create columnfamily cf7 (rowkey int primary key, boolcol boolean); -create columnfamily cf8 (rowkey int primary key, countercol counter); +create columnfamily cf8 (rowkey varchar primary key, countercol counter); +update cf8 set countercol=countercol+1 where rowkey='cnt1'; +update cf8 set countercol=countercol+100 where rowkey='cnt2'; EOF --error 0,1,2 @@ -355,7 +357,7 @@ drop table t2; # create columnfamily cf7 (rowkey int primary key, boolcol boolean); -CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol varchar(12)) ENGINE=CASSANDRA +CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol bool) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; insert into t2 values (0, 0); insert into t2 values (1, 1); @@ -363,6 +365,13 @@ select * from t2; delete from t2; drop table t2; + +# Counter type +# create columnfamily cf8 (rowkey int primary key, countercol counter); +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf8'; +select * from t2; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 692bfb595da..6eba141cf58 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -378,21 +378,37 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) bool Cassandra_se_impl::get_next_read_column(char **name, char **value, int *value_len) { + bool use_counter=false; while (1) { if (column_data_it == column_data_vec.end()) return true; - if (((*column_data_it).__isset.column)) + if ((*column_data_it).__isset.column) break; /* Ok it's a real column. Should be always the case. */ + if ((*column_data_it).__isset.counter_column) + { + use_counter= true; + break; + } + column_data_it++; } ColumnOrSuperColumn& cs= *column_data_it; - *name= (char*)cs.column.name.c_str(); - *value= (char*)cs.column.value.c_str(); - *value_len= cs.column.value.length(); + if (use_counter) + { + *name= (char*)cs.counter_column.name.c_str(); + *value= (char*)&cs.counter_column.value; + *value_len= sizeof(cs.counter_column.value); + } + else + { + *name= (char*)cs.column.name.c_str(); + *value= (char*)cs.column.value.c_str(); + *value_len= cs.column.value.length(); + } column_data_it++; return false; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 7ef563114fd..f1a5916ffc6 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -501,23 +501,31 @@ static void flip64(const char *from, char* to) class BigintDataConverter : public ColumnDataConverter { longlong buf; + bool flip; /* is false when reading counter columns */ public: void cassandra_to_mariadb(const char *cass_data, int cass_data_len) { longlong tmp; DBUG_ASSERT(cass_data_len == sizeof(longlong)); - flip64(cass_data, (char*)&tmp); + if (flip) + flip64(cass_data, (char*)&tmp); + else + memcpy(&tmp, cass_data, sizeof(longlong)); field->store(tmp); } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { longlong tmp= field->val_int(); - flip64((const char*)&tmp, (char*)&buf); + if (flip) + flip64((const char*)&tmp, (char*)&buf); + else + memcpy(&buf, &tmp, sizeof(longlong)); *cass_data= (char*)&buf; *cass_data_len=sizeof(longlong); return false; } + BigintDataConverter(bool flip_arg) : flip(flip_arg) {} ~BigintDataConverter(){} }; @@ -723,6 +731,7 @@ const char * const validator_uuid= "org.apache.cassandra.db.marshal.UUIDType"; const char * const validator_boolean= "org.apache.cassandra.db.marshal.BooleanType"; + ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { ColumnDataConverter *res= NULL; @@ -737,10 +746,13 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ /* fall through: */ case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONGLONG: - if (!strcmp(validator_name, validator_bigint)) - res= new BigintDataConverter; + { + bool is_counter= false; + if (!strcmp(validator_name, validator_bigint) || + (is_counter= !strcmp(validator_name, validator_counter))) + res= new BigintDataConverter(!is_counter); break; - + } case MYSQL_TYPE_FLOAT: if (!strcmp(validator_name, validator_float)) res= new FloatDataConverter; -- cgit v1.2.1 From e4bffe61784f82fb9b8df43075481d0d7468d200 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 12 Sep 2012 07:36:23 +0400 Subject: Update test results after last cset --- mysql-test/r/cassandra.result | 9 ++++++++- mysql-test/t/cassandra.test | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 401bc75cc80..25722aeacb3 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -266,7 +266,7 @@ rowkey col1 9b5658dc-f32f-11e1-94cd-f46d046e9f09 1234 delete from t2; drop table t2; -CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol varchar(12)) ENGINE=CASSANDRA +CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol bool) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; insert into t2 values (0, 0); insert into t2 values (1, 1); @@ -276,3 +276,10 @@ rowkey boolcol 1 1 delete from t2; drop table t2; +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf8'; +select * from t2; +rowkey countercol +cnt1 1 +cnt2 100 +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 4d2d390fdb5..0389363fdda 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -371,6 +371,7 @@ drop table t2; CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf8'; select * from t2; +drop table t2; ############################################################################ ## Cassandra cleanup -- cgit v1.2.1 From 16fec32ecc2492cf8c2d56f0f03d6bfb2a1b7f2b Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 12 Sep 2012 20:52:23 +0400 Subject: Cassandra SE: small optimization: StringCopyConverter::mariadb_to_cassandra doesn't need to make NULL-terminated strings. --- storage/cassandra/ha_cassandra.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index f1a5916ffc6..af34750d031 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -595,7 +595,7 @@ public: bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { String *pstr= field->val_str(&buf); - *cass_data= (char*)pstr->c_ptr(); + *cass_data= (char*)pstr->ptr(); *cass_data_len= pstr->length(); return false; } -- cgit v1.2.1 From d6f2d692c129412a72549085d5cfe83a1edae1b5 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 14 Sep 2012 08:44:34 +0400 Subject: Cassandra SE - Catch all kinds of exceptions when calling Thrift code. --- storage/cassandra/cassandra_se.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 6eba141cf58..dbaa00f8d1e 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -160,9 +160,8 @@ bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) print_error("%s [%s]", ire.what(), ire.why.c_str()); }catch(NotFoundException nfe){ print_error("%s", nfe.what()); - } - catch(...) { - print_error("Unknown Exception"); + }catch (...) { + print_error("Unknown exception"); } cur_consistency_level= ConsistencyLevel::ONE; @@ -192,7 +191,10 @@ bool Cassandra_se_impl::setup_ddl_checks() print_error("%s [%s]", ire.what(), ire.why.c_str()); } catch (NotFoundException nfe) { print_error("keyspace not found: %s", nfe.what()); + } catch (...) { + print_error("Unknown exception"); } + return true; } @@ -316,6 +318,8 @@ bool Cassandra_se_impl::do_insert() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + } catch (...) { + print_error("Unknown exception"); } return res; @@ -368,6 +372,9 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); return true; + } catch (...) { + print_error("Unknown exception"); + return true; } column_data_it= column_data_vec.begin(); @@ -470,6 +477,8 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + } catch (...) { + print_error("Unknown exception"); } key_slice_it= key_slice_vec.begin(); @@ -552,6 +561,8 @@ bool Cassandra_se_impl::truncate() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + } catch (...) { + print_error("Unknown exception"); } return res; @@ -575,6 +586,8 @@ bool Cassandra_se_impl::remove_row() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + } catch (...) { + print_error("Unknown exception"); } return res; @@ -629,6 +642,8 @@ bool Cassandra_se_impl::multiget_slice() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + } catch (...) { + print_error("Unknown exception"); } return res; -- cgit v1.2.1 From c7b41e5d466863cf2f7ef2599e9d2cd6d0cd8e57 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 14 Sep 2012 09:03:25 +0400 Subject: Cassandra SE - Also provide handling for generic Thrift exceptions. These are not listed in the 'throws' clause of API definition but still can happen. --- storage/cassandra/cassandra_se.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index dbaa00f8d1e..044e727e1c8 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -160,6 +160,8 @@ bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) print_error("%s [%s]", ire.what(), ire.why.c_str()); }catch(NotFoundException nfe){ print_error("%s", nfe.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); }catch (...) { print_error("Unknown exception"); } @@ -191,6 +193,8 @@ bool Cassandra_se_impl::setup_ddl_checks() print_error("%s [%s]", ire.what(), ire.why.c_str()); } catch (NotFoundException nfe) { print_error("keyspace not found: %s", nfe.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } @@ -318,6 +322,8 @@ bool Cassandra_se_impl::do_insert() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } @@ -372,6 +378,8 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); return true; + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); return true; @@ -477,6 +485,8 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } @@ -561,6 +571,8 @@ bool Cassandra_se_impl::truncate() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } @@ -586,6 +598,8 @@ bool Cassandra_se_impl::remove_row() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } @@ -642,6 +656,8 @@ bool Cassandra_se_impl::multiget_slice() print_error("UnavailableException: %s", ue.what()); } catch (TimedOutException te) { print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + print_error("Thrift exception: %s", e.what()); } catch (...) { print_error("Unknown exception"); } -- cgit v1.2.1 From c3de7c977adc6a7810c8f83dfb4614acc82a67c6 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 14 Sep 2012 09:25:42 +0400 Subject: MDEV-530: Cassandra SE: Locking is incorrect - Use more permissive locking. --- storage/cassandra/ha_cassandra.cc | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index af34750d031..b6983be498a 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1420,14 +1420,41 @@ int ha_cassandra::extra(enum ha_extra_function operation) } +/* The following function was copied from ha_blackhole::store_lock: */ THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, - THR_LOCK_DATA **to, - enum thr_lock_type lock_type) + THR_LOCK_DATA **to, + enum thr_lock_type lock_type) { + DBUG_ENTER("ha_cassandra::store_lock"); if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) - lock.type=lock_type; + { + /* + Here is where we get into the guts of a row level lock. + If TL_UNLOCK is set + If we are not doing a LOCK TABLE or DISCARD/IMPORT + TABLESPACE, then allow multiple writers + */ + + if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && + lock_type <= TL_WRITE) && !thd_in_lock_tables(thd) + && !thd_tablespace_op(thd)) + lock_type = TL_WRITE_ALLOW_WRITE; + + /* + In queries of type INSERT INTO t1 SELECT ... FROM t2 ... + MySQL would use the lock TL_READ_NO_INSERT on t2, and that + would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts + to t2. Convert the lock to a normal read lock to allow + concurrent inserts to t2. + */ + + if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd)) + lock_type = TL_READ; + + lock.type= lock_type; + } *to++= &lock; - return to; + DBUG_RETURN(to); } -- cgit v1.2.1 From eb63b07ace114f58984055610fe4a76accca9480 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 16 Sep 2012 12:22:21 +0400 Subject: Cassandra SE: - added option thrift_port which allows to specify which port to connect to - not adding username/password - it turns out, there are no authentication schemes in stock cassandra distribution. --- storage/cassandra/cassandra_se.cc | 7 ++++--- storage/cassandra/cassandra_se.h | 3 ++- storage/cassandra/ha_cassandra.cc | 16 +++++++++------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 044e727e1c8..c6415e6a4aa 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -73,7 +73,7 @@ public: virtual ~Cassandra_se_impl(){ delete cass; } /* Connection and DDL checks */ - bool connect(const char *host, const char *keyspace); + bool connect(const char *host, int port, const char *keyspace); void set_column_family(const char *cfname) { column_family.assign(cfname); } bool setup_ddl_checks(); @@ -135,7 +135,7 @@ Cassandra_se_interface *get_cassandra_se() } -bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) +bool Cassandra_se_impl::connect(const char *host, int port, const char *keyspace_arg) { bool res= true; @@ -143,7 +143,7 @@ bool Cassandra_se_impl::connect(const char *host, const char *keyspace_arg) try { boost::shared_ptr socket = - boost::shared_ptr(new TSocket(host, 9160)); + boost::shared_ptr(new TSocket(host, port)); boost::shared_ptr tr = boost::shared_ptr(new TFramedTransport (socket)); boost::shared_ptr p = @@ -680,3 +680,4 @@ bool Cassandra_se_impl::get_next_multiget_row() } + diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index d2ece4d9441..598267308af 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -17,7 +17,7 @@ public: virtual ~Cassandra_se_interface(){}; /* Init */ - virtual bool connect(const char *host, const char *port)=0; + virtual bool connect(const char *host, int port, const char *keyspace)=0; virtual void set_column_family(const char *cfname) = 0; /* Check underlying DDL */ @@ -82,3 +82,4 @@ extern Cassandra_status_vars cassandra_counters; Cassandra_se_interface *get_cassandra_se(); + diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index b6983be498a..c2570ad7a3a 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -38,7 +38,8 @@ mysql_mutex_t cassandra_mutex; struct ha_table_option_struct { - const char *host; + const char *thrift_host; + int thrift_port; const char *keyspace; const char *column_family; }; @@ -49,7 +50,8 @@ ha_create_table_option cassandra_table_option_list[]= /* one option that takes an arbitrary string */ - HA_TOPTION_STRING("thrift_host", host), + HA_TOPTION_STRING("thrift_host", thrift_host), + HA_TOPTION_NUMBER("thrift_port", thrift_port, 9160, 1, 65535, 0), HA_TOPTION_STRING("keyspace", keyspace), HA_TOPTION_STRING("column_family", column_family), HA_TOPTION_END @@ -283,14 +285,14 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) ha_table_option_struct *options= table->s->option_struct; fprintf(stderr, "ha_cass: open thrift_host=%s keyspace=%s column_family=%s\n", - options->host, options->keyspace, options->column_family); + options->thrift_host, options->keyspace, options->column_family); DBUG_ASSERT(!se); - if (!options->host || !options->keyspace || !options->column_family) + if (!options->thrift_host || !options->keyspace || !options->column_family) DBUG_RETURN(HA_WRONG_CREATE_OPTION); se= get_cassandra_se(); se->set_column_family(options->column_family); - if (se->connect(options->host, options->keyspace)) + if (se->connect(options->thrift_host, options->thrift_port, options->keyspace)) { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); DBUG_RETURN(HA_ERR_NO_CONNECTION); @@ -389,7 +391,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, */ #endif DBUG_ASSERT(!se); - if (!options->host || !options->keyspace || !options->column_family) + if (!options->thrift_host || !options->keyspace || !options->column_family) { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "thrift_host, keyspace, and column_family table options must be specified"); @@ -397,7 +399,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, } se= get_cassandra_se(); se->set_column_family(options->column_family); - if (se->connect(options->host, options->keyspace)) + if (se->connect(options->thrift_host, options->thrift_port, options->keyspace)) { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); DBUG_RETURN(HA_ERR_NO_CONNECTION); -- cgit v1.2.1 From 004e024775ed5c68dcc721f36aedda7f59a2197e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 20 Sep 2012 14:22:36 +0400 Subject: Cassandra SE: - Added @@cassandra_thrift_host global variable. --- mysql-test/r/cassandra.result | 25 +++++++- mysql-test/t/cassandra.test | 21 ++++++- storage/cassandra/ha_cassandra.cc | 124 ++++++++++++++++++++++++++++++-------- storage/cassandra/ha_cassandra.h | 19 +++++- 4 files changed, 159 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 25722aeacb3..15a68421d9e 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -13,7 +13,7 @@ thrift_host='localhost' keyspace='no_such_keyspace' column_family='colfam'; ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace no_such_keyspace does not exist] create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra thrift_host='localhost' keyspace='no_such_keyspace'; -ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s +ERROR HY000: Unable to connect to foreign data source: keyspace and column_family table options must be specified # Now, create a table for real and insert data create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; @@ -266,6 +266,9 @@ rowkey col1 9b5658dc-f32f-11e1-94cd-f46d046e9f09 1234 delete from t2; drop table t2; +# +# boolean datatype support +# CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol bool) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; insert into t2 values (0, 0); @@ -276,6 +279,9 @@ rowkey boolcol 1 1 delete from t2; drop table t2; +# +# Counter datatype support (read-only) +# CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf8'; select * from t2; @@ -283,3 +289,20 @@ rowkey countercol cnt1 1 cnt2 100 drop table t2; +# +# Check that @@cassandra_default_thrift_host works +# +show variables like 'cassandra_default_thrift_host'; +Variable_name Value +cassandra_default_thrift_host +set cassandra_default_thrift_host='localhost'; +ERROR HY000: Variable 'cassandra_default_thrift_host' is a GLOBAL variable and should be set with SET GLOBAL +set global cassandra_default_thrift_host='localhost'; +# Try creating a table without specifying thrift_host: +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA +keyspace='mariadbtest2' column_family = 'cf8'; +select * from t2; +rowkey countercol +cnt1 1 +cnt2 100 +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 0389363fdda..f76fbc6e129 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -356,6 +356,9 @@ delete from t2; drop table t2; +--echo # +--echo # boolean datatype support +--echo # # create columnfamily cf7 (rowkey int primary key, boolcol boolean); CREATE TABLE t2 (rowkey int PRIMARY KEY, boolcol bool) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; @@ -366,13 +369,29 @@ delete from t2; drop table t2; -# Counter type +--echo # +--echo # Counter datatype support (read-only) +--echo # # create columnfamily cf8 (rowkey int primary key, countercol counter); CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf8'; select * from t2; drop table t2; +--echo # +--echo # Check that @@cassandra_default_thrift_host works +--echo # +show variables like 'cassandra_default_thrift_host'; +--error ER_GLOBAL_VARIABLE +set cassandra_default_thrift_host='localhost'; +set global cassandra_default_thrift_host='localhost'; + +--echo # Try creating a table without specifying thrift_host: +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSANDRA + keyspace='mariadbtest2' column_family = 'cf8'; +select * from t2; +drop table t2; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index c2570ad7a3a..59f754287a0 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1,6 +1,18 @@ /* - MP AB copyrights -*/ + Copyright (c) 2012, Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation @@ -70,12 +82,54 @@ static MYSQL_THDVAR_ULONG(rnd_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in an rnd_read (full scan) batch", NULL, NULL, /*default*/ 10*1000, /*min*/ 1, /*max*/ 1024*1024*1024, 0); +mysql_mutex_t cassandra_default_host_lock; +static char* cassandra_default_thrift_host = NULL; +static char cassandra_default_host_buf[256]=""; + +static void +cassandra_default_thrift_host_update(THD *thd, + struct st_mysql_sys_var* var, + void* var_ptr, /*!< out: where the + formal string goes */ + const void* save) /*!< in: immediate result + from check function */ +{ + const char *new_host= *((char**)save); + const size_t max_len= sizeof(cassandra_default_host_buf); + + mysql_mutex_lock(&cassandra_default_host_lock); + + if (new_host) + { + strncpy(cassandra_default_host_buf, new_host, max_len); + cassandra_default_host_buf[max_len]= 0; + cassandra_default_thrift_host= cassandra_default_host_buf; + } + else + { + cassandra_default_host_buf[0]= 0; + cassandra_default_thrift_host= NULL; + } + + *((const char**)var_ptr)= cassandra_default_thrift_host; + + mysql_mutex_unlock(&cassandra_default_host_lock); +} + + +static MYSQL_SYSVAR_STR(default_thrift_host, cassandra_default_thrift_host, + PLUGIN_VAR_RQCMDARG, + "Default host for Cassandra thrift connections", + /*check*/NULL, + cassandra_default_thrift_host_update, + /*default*/NULL); + static struct st_mysql_sys_var* cassandra_system_variables[]= { MYSQL_SYSVAR(insert_batch_size), MYSQL_SYSVAR(multiget_batch_size), MYSQL_SYSVAR(rnd_batch_size), -// MYSQL_SYSVAR(enum_var), -// MYSQL_SYSVAR(ulong_var), + + MYSQL_SYSVAR(default_thrift_host), NULL }; @@ -158,6 +212,9 @@ static int cassandra_init_func(void *p) cassandra_hton->table_options= cassandra_table_option_list; //cassandra_hton->field_options= example_field_option_list; cassandra_hton->field_options= NULL; + + mysql_mutex_init(0 /* no instrumentation */, + &cassandra_default_host_lock, MY_MUTEX_INIT_FAST); DBUG_RETURN(0); } @@ -171,6 +228,7 @@ static int cassandra_done_func(void *p) error= 1; my_hash_free(&cassandra_open_tables); mysql_mutex_destroy(&cassandra_mutex); + mysql_mutex_destroy(&cassandra_default_host_lock); DBUG_RETURN(error); } @@ -277,22 +335,23 @@ const char **ha_cassandra::bas_ext() const int ha_cassandra::open(const char *name, int mode, uint test_if_locked) { + ha_table_option_struct *options= table->s->option_struct; + int res; DBUG_ENTER("ha_cassandra::open"); if (!(share = get_share(name, table))) DBUG_RETURN(1); thr_lock_data_init(&share->lock,&lock,NULL); - ha_table_option_struct *options= table->s->option_struct; - fprintf(stderr, "ha_cass: open thrift_host=%s keyspace=%s column_family=%s\n", - options->thrift_host, options->keyspace, options->column_family); - DBUG_ASSERT(!se); - if (!options->thrift_host || !options->keyspace || !options->column_family) - DBUG_RETURN(HA_WRONG_CREATE_OPTION); + if ((res= check_table_options(options))) + DBUG_RETURN(res); + se= get_cassandra_se(); se->set_column_family(options->column_family); - if (se->connect(options->thrift_host, options->thrift_port, options->keyspace)) + const char *thrift_host= options->thrift_host? options->thrift_host: + cassandra_default_thrift_host; + if (se->connect(thrift_host, options->thrift_port, options->keyspace)) { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); DBUG_RETURN(HA_ERR_NO_CONNECTION); @@ -320,6 +379,27 @@ int ha_cassandra::close(void) } +int ha_cassandra::check_table_options(ha_table_option_struct *options) +{ + if (!options->thrift_host && (!cassandra_default_thrift_host || + !cassandra_default_thrift_host[0])) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + "thrift_host table option must be specified, or " + "@@cassandra_default_thrift_host must be set"); + return HA_WRONG_CREATE_OPTION; + } + + if (!options->keyspace || !options->column_family) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + "keyspace and column_family table options must be specified"); + return HA_WRONG_CREATE_OPTION; + } + return 0; +} + + /** @brief create() is called to create a database. The variable name will have the name @@ -343,18 +423,11 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { ha_table_option_struct *options= table_arg->s->option_struct; + int res; DBUG_ENTER("ha_cassandra::create"); DBUG_ASSERT(options); - Field **pfield= table_arg->s->field; -/* - if (strcmp((*pfield)->field_name, "rowkey")) - { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'"); - DBUG_RETURN(HA_WRONG_CREATE_OPTION); - } -*/ if (!((*pfield)->flags & NOT_NULL_FLAG)) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL"); @@ -391,15 +464,14 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, */ #endif DBUG_ASSERT(!se); - if (!options->thrift_host || !options->keyspace || !options->column_family) - { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), - "thrift_host, keyspace, and column_family table options must be specified"); - DBUG_RETURN(HA_WRONG_CREATE_OPTION); - } + if ((res= check_table_options(options))) + DBUG_RETURN(res); + se= get_cassandra_se(); se->set_column_family(options->column_family); - if (se->connect(options->thrift_host, options->thrift_port, options->keyspace)) + const char *thrift_host= options->thrift_host? options->thrift_host: + cassandra_default_thrift_host; + if (se->connect(thrift_host, options->thrift_port, options->keyspace)) { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); DBUG_RETURN(HA_ERR_NO_CONNECTION); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 948bd8a6687..9b11b055af3 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -1,6 +1,18 @@ /* - MP AB copyrights -*/ + Copyright (c) 2012, Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -26,6 +38,8 @@ typedef struct st_cassandra_share { class ColumnDataConverter; +struct ha_table_option_struct; + /** @brief Class definition for the storage engine */ @@ -45,6 +59,7 @@ class ha_cassandra: public handler void free_field_converters(); void read_cassandra_columns(bool unpack_pk); + int check_table_options(struct ha_table_option_struct* options); bool doing_insert_batch; ha_rows insert_rows_batched; -- cgit v1.2.1 From c59faf95ae31b9ba61ba14ed53ddd92695eb05c8 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 22 Sep 2012 23:30:29 +0400 Subject: Cassandra SE: make consistency settings user-settable. --- mysql-test/r/cassandra.result | 20 ++++++++++++++++++++ mysql-test/t/cassandra.test | 21 +++++++++++++++++++++ storage/cassandra/cassandra_se.cc | 33 ++++++++++++++++++++++++--------- storage/cassandra/cassandra_se.h | 16 ++++++++++++++++ storage/cassandra/ha_cassandra.cc | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 15a68421d9e..32e1789983c 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -295,6 +295,7 @@ drop table t2; show variables like 'cassandra_default_thrift_host'; Variable_name Value cassandra_default_thrift_host +set @tmp=@@cassandra_default_thrift_host; set cassandra_default_thrift_host='localhost'; ERROR HY000: Variable 'cassandra_default_thrift_host' is a GLOBAL variable and should be set with SET GLOBAL set global cassandra_default_thrift_host='localhost'; @@ -306,3 +307,22 @@ rowkey countercol cnt1 1 cnt2 100 drop table t2; +set global cassandra_default_thrift_host=@tmp; +# +# Consistency settings +# +show variables like 'cassandra_%consistency'; +Variable_name Value +cassandra_read_consistency ONE +cassandra_write_consistency ONE +set @tmp=@@cassandra_write_consistency; +# Unfortunately, there is no easy way to check if setting have the effect.. +set cassandra_write_consistency='ONE'; +set cassandra_write_consistency='QUORUM'; +set cassandra_write_consistency='LOCAL_QUORUM'; +set cassandra_write_consistency='EACH_QUORUM'; +set cassandra_write_consistency='ALL'; +set cassandra_write_consistency='ANY'; +set cassandra_write_consistency='TWO'; +set cassandra_write_consistency='THREE'; +set cassandra_write_consistency=@tmp; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index f76fbc6e129..8a2da608c22 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -382,6 +382,7 @@ drop table t2; --echo # Check that @@cassandra_default_thrift_host works --echo # show variables like 'cassandra_default_thrift_host'; +set @tmp=@@cassandra_default_thrift_host; --error ER_GLOBAL_VARIABLE set cassandra_default_thrift_host='localhost'; set global cassandra_default_thrift_host='localhost'; @@ -392,6 +393,26 @@ CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, countercol bigint) ENGINE=CASSA select * from t2; drop table t2; +set global cassandra_default_thrift_host=@tmp; + +--echo # +--echo # Consistency settings +--echo # +show variables like 'cassandra_%consistency'; +set @tmp=@@cassandra_write_consistency; + +--echo # Unfortunately, there is no easy way to check if setting have the effect.. +set cassandra_write_consistency='ONE'; +set cassandra_write_consistency='QUORUM'; +set cassandra_write_consistency='LOCAL_QUORUM'; +set cassandra_write_consistency='EACH_QUORUM'; +set cassandra_write_consistency='ALL'; +set cassandra_write_consistency='ANY'; +set cassandra_write_consistency='TWO'; +set cassandra_write_consistency='THREE'; + +set cassandra_write_consistency=@tmp; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index c6415e6a4aa..3be81c5e6bf 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -23,6 +23,7 @@ using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using namespace org::apache::cassandra; + void Cassandra_se_interface::print_error(const char *format, ...) { va_list ap; @@ -38,10 +39,13 @@ void Cassandra_se_interface::print_error(const char *format, ...) class Cassandra_se_impl: public Cassandra_se_interface { CassandraClient *cass; /* Connection to cassandra */ - ConsistencyLevel::type cur_consistency_level; std::string column_family; std::string keyspace; + + ConsistencyLevel::type write_consistency; + ConsistencyLevel::type read_consistency; + /* DDL data */ KsDef ks_def; /* KeySpace we're using (TODO: put this in table->share) */ @@ -69,7 +73,9 @@ class Cassandra_se_impl: public Cassandra_se_interface SlicePredicate slice_pred; bool get_slices_returned_less; public: - Cassandra_se_impl() : cass(NULL) {} + Cassandra_se_impl() : cass(NULL), + write_consistency(ConsistencyLevel::ONE), + read_consistency(ConsistencyLevel::ONE) {} virtual ~Cassandra_se_impl(){ delete cass; } /* Connection and DDL checks */ @@ -81,6 +87,9 @@ public: bool next_ddl_column(char **name, int *name_len, char **value, int *value_len); void get_rowkey_type(char **name, char **type); + /* Settings */ + void set_consistency_levels(ulong read_cons_level, ulong write_cons_level); + /* Writes */ void clear_insert_buffer(); void start_row_insert(const char *key, int key_len); @@ -166,14 +175,20 @@ bool Cassandra_se_impl::connect(const char *host, int port, const char *keyspace print_error("Unknown exception"); } - cur_consistency_level= ConsistencyLevel::ONE; - if (!res && setup_ddl_checks()) res= true; return res; } +void Cassandra_se_impl::set_consistency_levels(ulong read_cons_level, + ulong write_cons_level) +{ + write_cons_level= (ConsistencyLevel::type)(write_cons_level + 1); + read_cons_level= (ConsistencyLevel::type)(read_cons_level + 1); +} + + bool Cassandra_se_impl::setup_ddl_checks() { try { @@ -308,7 +323,7 @@ bool Cassandra_se_impl::do_insert() try { - cass->batch_mutate(batch_mutation, cur_consistency_level); + cass->batch_mutate(batch_mutation, write_consistency); cassandra_counters.row_inserts+= batch_mutation.size(); cassandra_counters.row_insert_batches++; @@ -356,7 +371,7 @@ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) try { cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, - cur_consistency_level); + read_consistency); if (column_data_vec.size() == 0) { @@ -471,7 +486,7 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) cass->get_range_slices(key_slice_vec, cparent, slice_pred, key_range, - cur_consistency_level); + read_consistency); res= false; if (key_slice_vec.size() < (uint)read_batch_size) @@ -589,7 +604,7 @@ bool Cassandra_se_impl::remove_row() try { - cass->remove(rowkey, column_path, get_i64_timestamp(), cur_consistency_level); + cass->remove(rowkey, column_path, get_i64_timestamp(), write_consistency); res= false; } catch (InvalidRequestException ire) { @@ -643,7 +658,7 @@ bool Cassandra_se_impl::multiget_slice() cassandra_counters.multiget_keys_scanned += mrr_keys.size(); cass->multiget_slice(mrr_result, mrr_keys, cparent, slice_pred, - cur_consistency_level); + read_consistency); cassandra_counters.multiget_rows_read += mrr_result.size(); diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 598267308af..33ef677d276 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -7,6 +7,19 @@ */ +/* We need to define this here so that ha_cassandra.cc also has access to it */ +typedef enum +{ + ONE = 1-1, + QUORUM = 2-1, + LOCAL_QUORUM = 3-1, + EACH_QUORUM = 4-1, + ALL = 5-1, + ANY = 6-1, + TWO = 7-1, + THREE = 8-1, +} enum_cassandra_consistency_level; + /* Interface to one cassandra column family, i.e. one 'table' */ @@ -19,6 +32,9 @@ public: /* Init */ virtual bool connect(const char *host, int port, const char *keyspace)=0; virtual void set_column_family(const char *cfname) = 0; + + /* Settings */ + virtual void set_consistency_levels(ulong read_cons_level, ulong write_cons_level)=0; /* Check underlying DDL */ virtual bool setup_ddl_checks()=0; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 59f754287a0..3643da97287 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -82,6 +82,35 @@ static MYSQL_THDVAR_ULONG(rnd_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in an rnd_read (full scan) batch", NULL, NULL, /*default*/ 10*1000, /*min*/ 1, /*max*/ 1024*1024*1024, 0); +/* These match values in enum_cassandra_consistency_level */ +const char *cassandra_consistency_level[] = +{ + "ONE", + "QUORUM", + "LOCAL_QUORUM", + "EACH_QUORUM", + "ALL", + "ANY", + "TWO", + "THREE", + NullS +}; + +TYPELIB cassandra_consistency_level_typelib= { + array_elements(cassandra_consistency_level) - 1, "", + cassandra_consistency_level, NULL +}; + + +static MYSQL_THDVAR_ENUM(write_consistency, PLUGIN_VAR_RQCMDARG, + "Cassandra consistency level to use for write operations", NULL, NULL, + ONE, &cassandra_consistency_level_typelib); + +static MYSQL_THDVAR_ENUM(read_consistency, PLUGIN_VAR_RQCMDARG, + "Cassandra consistency level to use for read operations", NULL, NULL, + ONE, &cassandra_consistency_level_typelib); + + mysql_mutex_t cassandra_default_host_lock; static char* cassandra_default_thrift_host = NULL; static char cassandra_default_host_buf[256]=""; @@ -130,6 +159,8 @@ static struct st_mysql_sys_var* cassandra_system_variables[]= { MYSQL_SYSVAR(rnd_batch_size), MYSQL_SYSVAR(default_thrift_host), + MYSQL_SYSVAR(write_consistency), + MYSQL_SYSVAR(read_consistency), NULL }; @@ -1297,6 +1328,11 @@ int ha_cassandra::reset() { doing_insert_batch= false; insert_lineno= 0; + if (se) + { + se->set_consistency_levels(THDVAR(table->in_use, read_consistency), + THDVAR(table->in_use, write_consistency)); + } return 0; } -- cgit v1.2.1 From bce2e6683a19f7d32c4540b5850f370db6bb4e36 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 24 Sep 2012 19:15:12 +0400 Subject: Cassandra SE - Add support for Cassandra's 'varint' datatype, mappable to VARBINARY. --- mysql-test/r/cassandra.result | 17 +++++++ mysql-test/t/cassandra.test | 24 +++++++++ storage/cassandra/ha_cassandra.cc | 102 ++++++++++++++++++++++++++++---------- storage/cassandra/ha_cassandra.h | 4 +- 4 files changed, 121 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 32e1789983c..3ca4091ed29 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -326,3 +326,20 @@ set cassandra_write_consistency='ANY'; set cassandra_write_consistency='TWO'; set cassandra_write_consistency='THREE'; set cassandra_write_consistency=@tmp; +# +# varint datatype support +# +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(32)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; +select rowkey, hex(varint_col) from t2; +rowkey hex(varint_col) +val-01 01 +val-0x123456 123456 +val-0x12345678 12345678 +drop table t2; +# now, let's check what happens when MariaDB's column is not wide enough: +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(2)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; +select rowkey, hex(varint_col) from t2; +ERROR HY000: Internal error: 'Unable to convert value of field `varint_col` from cassandra's data format. Source has 4 bytes, data: 12345678' +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 8a2da608c22..5ff6018214e 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -68,6 +68,11 @@ create columnfamily cf8 (rowkey varchar primary key, countercol counter); update cf8 set countercol=countercol+1 where rowkey='cnt1'; update cf8 set countercol=countercol+100 where rowkey='cnt2'; +create columnfamily cf9 (rowkey varchar primary key, varint_col varint); +insert into cf9 (rowkey, varint_col) values ('val-01', 1); +insert into cf9 (rowkey, varint_col) values ('val-0x123456', 1193046); +insert into cf9 (rowkey, varint_col) values ('val-0x12345678', 305419896); + EOF --error 0,1,2 --system cqlsh -3 -f $MYSQLTEST_VARDIR/cassandra_test_init.cql @@ -413,6 +418,25 @@ set cassandra_write_consistency='THREE'; set cassandra_write_consistency=@tmp; +--echo # +--echo # varint datatype support +--echo # +# create columnfamily cf9 (rowkey varchar primary key, varint_col varint); +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(32)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; +--sorted_result +select rowkey, hex(varint_col) from t2; +drop table t2; + +--echo # now, let's check what happens when MariaDB's column is not wide enough: +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(2)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; +--sorted_result +--error ER_INTERNAL_ERROR +select rowkey, hex(varint_col) from t2; +drop table t2; + + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 3643da97287..6a82f811eb4 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -531,7 +531,7 @@ public: Field *field; /* This will save Cassandra's data in the Field */ - virtual void cassandra_to_mariadb(const char *cass_data, + virtual int cassandra_to_mariadb(const char *cass_data, int cass_data_len)=0; /* @@ -552,11 +552,12 @@ class DoubleDataConverter : public ColumnDataConverter { double buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { DBUG_ASSERT(cass_data_len == sizeof(double)); double *pdata= (double*) cass_data; field->store(*pdata); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -574,11 +575,12 @@ class FloatDataConverter : public ColumnDataConverter { float buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { DBUG_ASSERT(cass_data_len == sizeof(float)); float *pdata= (float*) cass_data; field->store(*pdata); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -608,7 +610,7 @@ class BigintDataConverter : public ColumnDataConverter longlong buf; bool flip; /* is false when reading counter columns */ public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { longlong tmp; DBUG_ASSERT(cass_data_len == sizeof(longlong)); @@ -617,6 +619,7 @@ public: else memcpy(&tmp, cass_data, sizeof(longlong)); field->store(tmp); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -647,10 +650,11 @@ class TinyintDataConverter : public ColumnDataConverter { char buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { DBUG_ASSERT(cass_data_len == 1); field->store(cass_data[0]); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -668,12 +672,13 @@ class Int32DataConverter : public ColumnDataConverter { int32_t buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { int32_t tmp; DBUG_ASSERT(cass_data_len == sizeof(int32_t)); flip32(cass_data, (char*)&tmp); field->store(tmp); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -691,10 +696,14 @@ public: class StringCopyConverter : public ColumnDataConverter { String buf; + size_t max_length; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { + if ((size_t)cass_data_len > max_length) + return 1; field->store(cass_data, cass_data_len,field->charset()); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -704,6 +713,7 @@ public: *cass_data_len= pstr->length(); return false; } + StringCopyConverter(size_t max_length_arg) : max_length(max_length_arg) {} ~StringCopyConverter(){} }; @@ -712,7 +722,7 @@ class TimestampDataConverter : public ColumnDataConverter { int64_t buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { /* Cassandra data is milliseconds-since-epoch in network byte order */ int64_t tmp; @@ -724,6 +734,7 @@ public: - microsecond fraction of a second. */ ((Field_timestamp*)field)->store_TIME(tmp / 1000, (tmp % 1000)*1000); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -768,7 +779,7 @@ class UuidDataConverter : public ColumnDataConverter char buf[16]; /* Binary UUID representation */ String str_buf; public: - void cassandra_to_mariadb(const char *cass_data, int cass_data_len) + int cassandra_to_mariadb(const char *cass_data, int cass_data_len) { DBUG_ASSERT(cass_data_len==16); char str[37]; @@ -783,6 +794,7 @@ public: } *ptr= 0; field->store(str, 36,field->charset()); + return 0; } bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) @@ -836,6 +848,11 @@ const char * const validator_uuid= "org.apache.cassandra.db.marshal.UUIDType"; const char * const validator_boolean= "org.apache.cassandra.db.marshal.BooleanType"; +/* + VARINTs are stored as little-endian big numbers. +*/ +const char * const validator_varint= "org.apache.cassandra.db.marshal.IntegerType"; + ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { @@ -885,14 +902,20 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ /* fall through: */ case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: + { + bool is_varint; if (!strcmp(validator_name, validator_blob) || !strcmp(validator_name, validator_ascii) || - !strcmp(validator_name, validator_text)) + !strcmp(validator_name, validator_text) || + (is_varint= !strcmp(validator_name, validator_varint))) { - res= new StringCopyConverter; + size_t max_size= (size_t)-1; + if (is_varint) + max_size= field->field_length; + res= new StringCopyConverter(max_size); } break; - + } case MYSQL_TYPE_LONG: if (!strcmp(validator_name, validator_int)) res= new Int32DataConverter; @@ -1041,24 +1064,43 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, /* TODO: what if we're not reading all columns?? */ if (!found) - { rc= HA_ERR_KEY_NOT_FOUND; - } else + rc= read_cassandra_columns(false); + + DBUG_RETURN(rc); +} + + +void ha_cassandra::print_conversion_error(const char *field_name, + char *cass_value, + int cass_value_len) +{ + char buf[32]; + char *p= cass_value; + size_t i= 0; + for (; (i < (int)sizeof(buf)-1) && (p < cass_value + cass_value_len); p++) { - read_cassandra_columns(false); + buf[i++]= map2number[(*p >> 4) & 0xF]; + buf[i++]= map2number[*p & 0xF]; } + buf[i]=0; - DBUG_RETURN(rc); + se->print_error("Unable to convert value for field `%s` from Cassandra's data" + " format. Source data is %d bytes, 0x%s%s", + field_name, cass_value_len, buf, + (i == sizeof(buf) - 1)? "..." : ""); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); } -void ha_cassandra::read_cassandra_columns(bool unpack_pk) +int ha_cassandra::read_cassandra_columns(bool unpack_pk) { char *cass_name; char *cass_value; int cass_value_len; Field **field; + int res= 0; /* cassandra_to_mariadb() calls will use field->store(...) methods, which @@ -1082,7 +1124,14 @@ void ha_cassandra::read_cassandra_columns(bool unpack_pk) { int fieldnr= (*field)->field_index; (*field)->set_notnull(); - field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len); + if (field_converters[fieldnr]->cassandra_to_mariadb(cass_value, + cass_value_len)) + { + print_conversion_error((*field)->field_name, cass_value, + cass_value_len); + res=1; + goto err; + } break; } } @@ -1094,10 +1143,17 @@ void ha_cassandra::read_cassandra_columns(bool unpack_pk) field= table->field; (*field)->set_notnull(); se->get_read_rowkey(&cass_value, &cass_value_len); - rowkey_converter->cassandra_to_mariadb(cass_value, cass_value_len); + if (rowkey_converter->cassandra_to_mariadb(cass_value, cass_value_len)) + { + print_conversion_error((*field)->field_name, cass_value, cass_value_len); + res=1; + goto err; + } } +err: dbug_tmp_restore_column_map(table->write_set, old_map); + return res; } @@ -1234,10 +1290,7 @@ int ha_cassandra::rnd_next(uchar *buf) if (reached_eof) rc= HA_ERR_END_OF_FILE; else - { - read_cassandra_columns(true); - rc= 0; - } + rc= read_cassandra_columns(true); } DBUG_RETURN(rc); @@ -1422,8 +1475,7 @@ int ha_cassandra::multi_range_read_next(range_id_t *range_info) { if (!se->get_next_multiget_row()) { - read_cassandra_columns(true); - res= 0; + res= read_cassandra_columns(true); break; } else diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 9b11b055af3..52fd46fa5ef 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -58,7 +58,7 @@ class ha_cassandra: public handler bool setup_field_converters(Field **field, uint n_fields); void free_field_converters(); - void read_cassandra_columns(bool unpack_pk); + int read_cassandra_columns(bool unpack_pk); int check_table_options(struct ha_table_option_struct* options); bool doing_insert_batch; @@ -66,6 +66,8 @@ class ha_cassandra: public handler /* Used to produce 'wrong column %s at row %lu' warnings */ ha_rows insert_lineno; + void print_conversion_error(const char *field_name, + char *cass_value, int cass_value_len); public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() -- cgit v1.2.1 From 366638718c0f5ca328f023f1fea4cc4731595953 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 24 Sep 2012 20:58:26 +0400 Subject: Cassandra SE: varint datatype support: - allow only VARBINARY(n), all other types can get meaningless data after conversions - more comments --- mysql-test/r/cassandra.result | 2 +- storage/cassandra/ha_cassandra.cc | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 3ca4091ed29..89e39a99c44 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -341,5 +341,5 @@ drop table t2; CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(2)) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; select rowkey, hex(varint_col) from t2; -ERROR HY000: Internal error: 'Unable to convert value of field `varint_col` from cassandra's data format. Source has 4 bytes, data: 12345678' +ERROR HY000: Internal error: 'Unable to convert value for field `varint_col` from Cassandra's data format. Source data is 4 bytes, 0x12345678' drop table t2; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 6a82f811eb4..6dc774266e4 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -848,9 +848,7 @@ const char * const validator_uuid= "org.apache.cassandra.db.marshal.UUIDType"; const char * const validator_boolean= "org.apache.cassandra.db.marshal.BooleanType"; -/* - VARINTs are stored as little-endian big numbers. -*/ +/* VARINTs are stored as big-endian big numbers. */ const char * const validator_varint= "org.apache.cassandra.db.marshal.IntegerType"; @@ -900,19 +898,32 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ break; } /* fall through: */ - case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_VARCHAR: { - bool is_varint; + /* + Cassandra's "varint" type is a binary-encoded arbitary-length + big-endian number. + - It can be mapped to VARBINARY(N), with sufficiently big N. + - If the value does not fit into N bytes, it is an error. We should not + truncate it, because that is just as good as returning garbage. + - varint should not be mapped to BINARY(N), because BINARY(N) values + are zero-padded, which will work as multiplying the value by + 2^k for some value of k. + */ + if (field->type() == MYSQL_TYPE_VARCHAR && + field->binary() && + !strcmp(validator_name, validator_varint)) + { + res= new StringCopyConverter(field->field_length); + break; + } + if (!strcmp(validator_name, validator_blob) || !strcmp(validator_name, validator_ascii) || - !strcmp(validator_name, validator_text) || - (is_varint= !strcmp(validator_name, validator_varint))) + !strcmp(validator_name, validator_text)) { - size_t max_size= (size_t)-1; - if (is_varint) - max_size= field->field_length; - res= new StringCopyConverter(max_size); + res= new StringCopyConverter((size_t)-1); } break; } -- cgit v1.2.1 From 73dfd5782bf2ec845dc5490de22d9ef8ea9f7326 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 25 Sep 2012 16:20:19 +0400 Subject: Cassandra SE: more datatypes support - Support mapping Cassandra's timestamp to INT64 - Support mapping Cassadnra's decimal to VARBINARY. --- mysql-test/r/cassandra.result | 26 ++++++++++++++++++++++++++ mysql-test/t/cassandra.test | 27 +++++++++++++++++++++++++++ storage/cassandra/ha_cassandra.cc | 5 ++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 89e39a99c44..a2bb6129928 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -343,3 +343,29 @@ thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf9'; select rowkey, hex(varint_col) from t2; ERROR HY000: Internal error: 'Unable to convert value for field `varint_col` from Cassandra's data format. Source data is 4 bytes, 0x12345678' drop table t2; +# +# Decimal datatype support +# +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; +select rowkey, hex(decimal_col) from t2; +rowkey hex(decimal_col) +val_1.5 000000010F +val_0.5 0000000105 +val_1234 0000000004D2 +drop table t2; +# +# Mapping TIMESTAMP -> int64 +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +insert into t2 values (1, '2012-08-29 01:23:45'); +INSERT INTO t2 VALUES (10,'2012-08-29 01:23:46'); +drop table t2; +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +select * from t2; +rowkey datecol +1 1346189025000 +10 1346189026000 +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 5ff6018214e..9a0c4976254 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -73,6 +73,11 @@ insert into cf9 (rowkey, varint_col) values ('val-01', 1); insert into cf9 (rowkey, varint_col) values ('val-0x123456', 1193046); insert into cf9 (rowkey, varint_col) values ('val-0x12345678', 305419896); +create columnfamily cf11 (rowkey varchar primary key, decimal_col decimal); +insert into cf11 (rowkey, decimal_col) values ('val_0.5', 0.5); +insert into cf11 (rowkey, decimal_col) values ('val_1.5', 1.5); +insert into cf11 (rowkey, decimal_col) values ('val_1234', 1234); + EOF --error 0,1,2 --system cqlsh -3 -f $MYSQLTEST_VARDIR/cassandra_test_init.cql @@ -436,6 +441,28 @@ CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, varint_col varbinary(2)) ENGINE select rowkey, hex(varint_col) from t2; drop table t2; +--echo # +--echo # Decimal datatype support +--echo # +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; +select rowkey, hex(decimal_col) from t2; +drop table t2; + +--echo # +--echo # Mapping TIMESTAMP -> int64 +--echo # +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +insert into t2 values (1, '2012-08-29 01:23:45'); +INSERT INTO t2 VALUES (10,'2012-08-29 01:23:46'); +drop table t2; + +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +select * from t2; + +drop table t2; ############################################################################ ## Cassandra cleanup diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 6dc774266e4..18a4a8c2728 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -850,6 +850,7 @@ const char * const validator_boolean= "org.apache.cassandra.db.marshal.BooleanTy /* VARINTs are stored as big-endian big numbers. */ const char * const validator_varint= "org.apache.cassandra.db.marshal.IntegerType"; +const char * const validator_decimal= "org.apache.cassandra.db.marshal.DecimalType"; ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) @@ -869,6 +870,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ { bool is_counter= false; if (!strcmp(validator_name, validator_bigint) || + !strcmp(validator_name, validator_timestamp) || (is_counter= !strcmp(validator_name, validator_counter))) res= new BigintDataConverter(!is_counter); break; @@ -913,7 +915,8 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ */ if (field->type() == MYSQL_TYPE_VARCHAR && field->binary() && - !strcmp(validator_name, validator_varint)) + (!strcmp(validator_name, validator_varint) || + !strcmp(validator_name, validator_decimal))) { res= new StringCopyConverter(field->field_length); break; -- cgit v1.2.1 From 344c0ea4232a4954a6eb83195bb78cace03bd4c4 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 26 Sep 2012 14:13:03 +0400 Subject: Cassandra SE: Add capability to retry failed API calls - Add capability to retry calls that have failed with UnavailableException or [Cassandra's] TimedOutException. - We don't retry for Thrift errors yet, although could easily do, now. --- storage/cassandra/cassandra_se.cc | 338 +++++++++++++++++++------------------- storage/cassandra/cassandra_se.h | 3 + storage/cassandra/ha_cassandra.cc | 12 +- 3 files changed, 187 insertions(+), 166 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 3be81c5e6bf..7a825a9fc00 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -45,6 +45,9 @@ class Cassandra_se_impl: public Cassandra_se_interface ConsistencyLevel::type write_consistency; ConsistencyLevel::type read_consistency; + + /* How many times to retry an operation before giving up */ + int thrift_call_retries_to_do; /* DDL data */ @@ -72,10 +75,12 @@ class Cassandra_se_impl: public Cassandra_se_interface SlicePredicate slice_pred; bool get_slices_returned_less; + bool get_slice_found_rows; public: Cassandra_se_impl() : cass(NULL), write_consistency(ConsistencyLevel::ONE), - read_consistency(ConsistencyLevel::ONE) {} + read_consistency(ConsistencyLevel::ONE), + thrift_call_retries_to_do(0) {} virtual ~Cassandra_se_impl(){ delete cass; } /* Connection and DDL checks */ @@ -94,6 +99,7 @@ public: void clear_insert_buffer(); void start_row_insert(const char *key, int key_len); void add_insert_column(const char *name, const char *value, int value_len); + bool do_insert(); /* Reads, point lookups */ @@ -105,6 +111,8 @@ public: private: bool have_rowkey_to_skip; std::string rowkey_to_skip; + + bool get_range_slices_param_last_key_as_start_key; public: bool get_range_slices(bool last_key_as_start_key); void finish_reading_range_slices(); @@ -119,19 +127,30 @@ public: int add_lookup_key(const char *key, size_t key_len); bool multiget_slice(); -private: - std::vector mrr_keys; /* TODO: can we use allocator to put them onto MRR buffer? */ - std::map > mrr_result; - std::map >::iterator mrr_result_it; -public: bool get_next_multiget_row(); bool truncate(); + bool remove_row(); private: + bool retryable_truncate(); + bool retryable_do_insert(); + bool retryable_remove_row(); + bool retryable_setup_ddl_checks(); + bool retryable_multiget_slice(); + bool retryable_get_range_slices(); + bool retryable_get_slice(); + + std::vector mrr_keys; /* can we use allocator to put these into MRR buffer? */ + std::map > mrr_result; + std::map >::iterator mrr_result_it; + /* Non-inherited utility functions: */ int64_t get_i64_timestamp(); + + typedef bool (Cassandra_se_impl::*retryable_func_t)(); + bool try_operation(retryable_func_t func); }; @@ -189,34 +208,36 @@ void Cassandra_se_impl::set_consistency_levels(ulong read_cons_level, } -bool Cassandra_se_impl::setup_ddl_checks() +bool Cassandra_se_impl::retryable_setup_ddl_checks() { try { - cass->describe_keyspace(ks_def, keyspace); - std::vector::iterator it; - for (it= ks_def.cf_defs.begin(); it < ks_def.cf_defs.end(); it++) - { - cf_def= *it; - if (!cf_def.name.compare(column_family)) - return false; - } - - print_error("describe_keyspace() didn't return our column family"); - - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); + cass->describe_keyspace(ks_def, keyspace); + } catch (NotFoundException nfe) { - print_error("keyspace not found: %s", nfe.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); + print_error("keyspace `%s` not found: %s", keyspace.c_str(), nfe.what()); + return true; + } + + std::vector::iterator it; + for (it= ks_def.cf_defs.begin(); it < ks_def.cf_defs.end(); it++) + { + cf_def= *it; + if (!cf_def.name.compare(column_family)) + return false; } + print_error("Column family %s not found in keyspace %s", + column_family.c_str(), + keyspace.c_str()); return true; } +bool Cassandra_se_impl::setup_ddl_checks() +{ + return try_operation(&Cassandra_se_impl::retryable_setup_ddl_checks); +} + void Cassandra_se_impl::first_ddl_column() { @@ -309,41 +330,29 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value, } +bool Cassandra_se_impl::retryable_do_insert() +{ + cass->batch_mutate(batch_mutation, write_consistency); + + cassandra_counters.row_inserts+= batch_mutation.size(); + cassandra_counters.row_insert_batches++; + + clear_insert_buffer(); + return 0; +} + + bool Cassandra_se_impl::do_insert() { - bool res= true; - /* - zero-size mutations are allowed by Cassandra's batch_mutate but lets not + zero-size mutations are allowed by Cassandra's batch_mutate but lets not do them (we may attempt to do it if there is a bulk insert that stores exactly @@cassandra_insert_batch_size*n elements. */ if (batch_mutation.empty()) return false; - - try { - - cass->batch_mutate(batch_mutation, write_consistency); - - cassandra_counters.row_inserts+= batch_mutation.size(); - cassandra_counters.row_insert_batches++; - - clear_insert_buffer(); - res= false; - - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - } - - return res; + + return try_operation(&Cassandra_se_impl::retryable_do_insert); } @@ -357,48 +366,40 @@ bool Cassandra_se_impl::do_insert() */ bool Cassandra_se_impl::get_slice(char *key, size_t key_len, bool *found) +{ + bool res; + rowkey.assign(key, key_len); + + if (!(res= try_operation(&Cassandra_se_impl::retryable_get_slice))) + *found= get_slice_found_rows; + return res; +} + + +bool Cassandra_se_impl::retryable_get_slice() { ColumnParent cparent; cparent.column_family= column_family; - rowkey.assign(key, key_len); - SlicePredicate slice_pred; SliceRange sr; sr.start = ""; sr.finish = ""; slice_pred.__set_slice_range(sr); - try { - cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, - read_consistency); + cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, + read_consistency); - if (column_data_vec.size() == 0) - { - /* - No columns found. Cassandra doesn't allow records without any column => - this means the seach key doesn't exist - */ - *found= false; - return false; - } - *found= true; - - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - return true; - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - return true; - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - return true; - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - return true; + if (column_data_vec.size() == 0) + { + /* + No columns found. Cassandra doesn't allow records without any column => + this means the seach key doesn't exist + */ + get_slice_found_rows= false; + return false; } + get_slice_found_rows= true; column_data_it= column_data_vec.begin(); return false; @@ -456,7 +457,15 @@ void Cassandra_se_impl::get_read_rowkey(char **value, int *value_len) bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) { - bool res= true; + get_range_slices_param_last_key_as_start_key= last_key_as_start_key; + + return try_operation(&Cassandra_se_impl::retryable_get_range_slices); +} + + +bool Cassandra_se_impl::retryable_get_range_slices() +{ + bool last_key_as_start_key= get_range_slices_param_last_key_as_start_key; ColumnParent cparent; cparent.column_family= column_family; @@ -482,32 +491,17 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) key_range.end_key.assign("", 0); key_range.count= read_batch_size; - try { - - cass->get_range_slices(key_slice_vec, - cparent, slice_pred, key_range, - read_consistency); - res= false; - if (key_slice_vec.size() < (uint)read_batch_size) - get_slices_returned_less= true; - else - get_slices_returned_less= false; + cass->get_range_slices(key_slice_vec, cparent, slice_pred, key_range, + read_consistency); - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - } + if (key_slice_vec.size() < (uint)read_batch_size) + get_slices_returned_less= true; + else + get_slices_returned_less= false; key_slice_it= key_slice_vec.begin(); - return res; + return false; } @@ -574,50 +568,78 @@ void Cassandra_se_impl::add_read_column(const char *name_arg) bool Cassandra_se_impl::truncate() { - bool res= true; - try { - - cass->truncate(column_family); - res= false; + return try_operation(&Cassandra_se_impl::retryable_truncate); +} - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - } - return res; +bool Cassandra_se_impl::retryable_truncate() +{ + cass->truncate(column_family); + return 0; } + bool Cassandra_se_impl::remove_row() { - bool res= true; + return try_operation(&Cassandra_se_impl::retryable_remove_row); +} + +bool Cassandra_se_impl::retryable_remove_row() +{ ColumnPath column_path; column_path.column_family= column_family; + cass->remove(rowkey, column_path, get_i64_timestamp(), write_consistency); + return 0; +} - try { - - cass->remove(rowkey, column_path, get_i64_timestamp(), write_consistency); - res= false; +/* + This function will try a Cassandra operation, and handle errors. - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - } +*/ +bool Cassandra_se_impl::try_operation(retryable_func_t func_to_call) +{ + bool res; + int n_retries= thrift_call_retries_to_do; + + do + { + res= true; + + try { + + if ((res= (this->*func_to_call)())) + { + /* + The function call was made successfully (without timeouts, etc), + but something inside it returned 'true'. + This is supposedly a failure (or "not found" or other negative + result). We need to return this to the caller. + */ + n_retries= 0; + } + + } catch (InvalidRequestException ire) { + n_retries= 0; /* there is no point in retrying this operation */ + print_error("%s [%s]", ire.what(), ire.why.c_str()); + } catch (UnavailableException ue) { + cassandra_counters.unavailable_exceptions++; + if (!--n_retries) + print_error("UnavailableException: %s", ue.what()); + } catch (TimedOutException te) { + cassandra_counters.timeout_exceptions++; + if (!--n_retries) + print_error("TimedOutException: %s", te.what()); + }catch(TException e){ + /* todo: we may use retry for certain kinds of Thrift errors */ + n_retries= 0; + print_error("Thrift exception: %s", e.what()); + } catch (...) { + n_retries= 0; /* Don't retry */ + print_error("Unknown exception"); + } + + } while (res && n_retries > 0); return res; } @@ -638,8 +660,13 @@ int Cassandra_se_impl::add_lookup_key(const char *key, size_t key_len) return mrr_keys.size(); } - bool Cassandra_se_impl::multiget_slice() +{ + return try_operation(&Cassandra_se_impl::retryable_multiget_slice); +} + + +bool Cassandra_se_impl::retryable_multiget_slice() { ColumnParent cparent; cparent.column_family= column_family; @@ -650,34 +677,15 @@ bool Cassandra_se_impl::multiget_slice() sr.finish = ""; slice_pred.__set_slice_range(sr); - bool res= true; - - try { - - cassandra_counters.multiget_reads++; - cassandra_counters.multiget_keys_scanned += mrr_keys.size(); - - cass->multiget_slice(mrr_result, mrr_keys, cparent, slice_pred, - read_consistency); - - cassandra_counters.multiget_rows_read += mrr_result.size(); - - res= false; - mrr_result_it= mrr_result.begin(); + cassandra_counters.multiget_reads++; + cassandra_counters.multiget_keys_scanned += mrr_keys.size(); + cass->multiget_slice(mrr_result, mrr_keys, cparent, slice_pred, + read_consistency); - } catch (InvalidRequestException ire) { - print_error("%s [%s]", ire.what(), ire.why.c_str()); - } catch (UnavailableException ue) { - print_error("UnavailableException: %s", ue.what()); - } catch (TimedOutException te) { - print_error("TimedOutException: %s", te.what()); - }catch(TException e){ - print_error("Thrift exception: %s", e.what()); - } catch (...) { - print_error("Unknown exception"); - } + cassandra_counters.multiget_rows_read += mrr_result.size(); + mrr_result_it= mrr_result.begin(); - return res; + return false; } diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 33ef677d276..c6de779f8bc 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -91,6 +91,9 @@ public: ulong multiget_reads; ulong multiget_keys_scanned; ulong multiget_rows_read; + + ulong timeout_exceptions; + ulong unavailable_exceptions; }; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 18a4a8c2728..187df2a2dd8 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -82,6 +82,11 @@ static MYSQL_THDVAR_ULONG(rnd_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in an rnd_read (full scan) batch", NULL, NULL, /*default*/ 10*1000, /*min*/ 1, /*max*/ 1024*1024*1024, 0); +static MYSQL_THDVAR_ULONG(failure_retries, PLUGIN_VAR_RQCMDARG, + "Number of times to retry Cassandra calls that failed due to timeouts or " + "network communication problems. The default, 0, means not to retry.", + NULL, NULL, /*default*/ 0, /*min*/ 0, /*max*/ 1024*1024*1024, 0); + /* These match values in enum_cassandra_consistency_level */ const char *cassandra_consistency_level[] = { @@ -161,6 +166,7 @@ static struct st_mysql_sys_var* cassandra_system_variables[]= { MYSQL_SYSVAR(default_thrift_host), MYSQL_SYSVAR(write_consistency), MYSQL_SYSVAR(read_consistency), + MYSQL_SYSVAR(failure_retries), NULL }; @@ -177,6 +183,11 @@ static SHOW_VAR cassandra_status_variables[]= { (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, {"multiget_rows_read", (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, + + {"timeout_exceptions", + (char*) &cassandra_counters.timeout_exceptions, SHOW_LONG}, + {"unavailable_exceptions", + (char*) &cassandra_counters.unavailable_exceptions, SHOW_LONG}, {NullS, NullS, SHOW_LONG} }; @@ -1678,7 +1689,6 @@ bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) { - //innodb_export_status(); cassandra_counters_copy= cassandra_counters; var->type= SHOW_ARRAY; -- cgit v1.2.1 From 0362968be82c391db9d19230090f4a7d95092018 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 26 Sep 2012 14:57:45 +0400 Subject: Cassandra SE: - Add a test for ALTER TABLE --- mysql-test/t/cassandra.test | 26 ++++++++++++++++++++++++++ storage/cassandra/cassandra_se.cc | 4 ++-- storage/cassandra/ha_cassandra.cc | 3 +-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 9a0c4976254..c564a63fd2d 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -78,6 +78,8 @@ insert into cf11 (rowkey, decimal_col) values ('val_0.5', 0.5); insert into cf11 (rowkey, decimal_col) values ('val_1.5', 1.5); insert into cf11 (rowkey, decimal_col) values ('val_1234', 1234); +create columnfamily cf12 (rowkey varchar primary key, decimal_col decimal); + EOF --error 0,1,2 --system cqlsh -3 -f $MYSQLTEST_VARDIR/cassandra_test_init.cql @@ -464,6 +466,30 @@ select * from t2; drop table t2; +--echo # +--echo # Check whether changing parameters with ALTER TABLE works. +--echo # +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; + +--error ER_INTERNAL_ERROR +alter table t2 column_family='cf9'; + +drop table t2; + +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; + +let $c1= `select variable_value from information_schema.global_status + where variable_name like 'cassandra_row_inserts'`; +alter table t2 column_family='cf12'; +let $c2= `select variable_value from information_schema.global_status + where variable_name like 'cassandra_row_inserts'`; + +--disable_query_log +eval select ($c2 - $c1) as 'Writes made during ALTER TABLE'; +--enable_query_log + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 7a825a9fc00..e46d02f48d9 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -594,8 +594,8 @@ bool Cassandra_se_impl::retryable_remove_row() } /* - This function will try a Cassandra operation, and handle errors. - + Try calling a function, catching possible Cassandra errors, and re-trying + for "transient" errors. */ bool Cassandra_se_impl::try_operation(retryable_func_t func_to_call) { diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 187df2a2dd8..df4b54cc4f7 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1676,9 +1676,8 @@ int ha_cassandra::delete_table(const char *name) bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes) { - //ha_table_option_struct *param_old, *param_new; DBUG_ENTER("ha_cassandra::check_if_incompatible_data"); - + /* Checked, we intend to have this empty for Cassandra SE. */ DBUG_RETURN(COMPATIBLE_DATA_YES); } -- cgit v1.2.1 From c69a8fa6164c112b496c92000be5525dd46da7f8 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 26 Sep 2012 19:02:12 +0400 Subject: - Update testcases - Better error messages. --- mysql-test/r/cassandra.result | 12 ++++++++++++ mysql-test/t/cassandra.test | 6 ++++-- storage/cassandra/ha_cassandra.cc | 15 ++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index a2bb6129928..6497eab6dd2 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -369,3 +369,15 @@ rowkey datecol 1 1346189025000 10 1346189026000 drop table t2; +# +# Check whether changing parameters with ALTER TABLE works. +# +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; +drop table t2; +CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; +alter table t2 column_family='cf12'; +Writes made during ALTER TABLE +0 +drop table t2; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index c564a63fd2d..3f5933e8b66 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -472,8 +472,8 @@ drop table t2; CREATE TABLE t2 (rowkey varchar(32) PRIMARY KEY, decimal_col varbinary(32)) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf11'; ---error ER_INTERNAL_ERROR -alter table t2 column_family='cf9'; +#--error ER_INTERNAL_ERROR +#alter table t2 column_family='cf9'; drop table t2; @@ -490,6 +490,8 @@ let $c2= `select variable_value from information_schema.global_status eval select ($c2 - $c1) as 'Writes made during ALTER TABLE'; --enable_query_log +drop table t2; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index df4b54cc4f7..f9aa8cd40a8 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -992,7 +992,20 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) if (n_mapped != n_fields - 1) { - se->print_error("Some of SQL fields were not mapped to Cassandra's fields"); + Field *first_unmapped= NULL; + /* Find the first field */ + for (uint i= 1; i < n_fields;i++) + { + if (!field_converters[i]) + { + first_unmapped= field_arg[i]; + break; + } + } + DBUG_ASSERT(first_unmapped); + + se->print_error("Field `%s` could not be mapped to any field in Cassandra", + first_unmapped->field_name); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); return true; } -- cgit v1.2.1 From 2d88c4befb93c5d02f91aa01c33824d86d056188 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 27 Sep 2012 11:59:14 +0400 Subject: Cassandra SE - Support UPDATE statements - Follow what CQL does: don't show deleted rows (they show up as rows without any columns in reads) --- mysql-test/r/cassandra.result | 28 ++++++++++++- mysql-test/t/cassandra.test | 19 +++++++++ storage/cassandra/cassandra_se.cc | 46 +++++++++++++++++++- storage/cassandra/cassandra_se.h | 10 +++++ storage/cassandra/ha_cassandra.cc | 88 ++++++++++++++++++++++++++++++++++++++- storage/cassandra/ha_cassandra.h | 1 + 6 files changed, 188 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 6497eab6dd2..07720bb5b23 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -41,7 +41,6 @@ select * from t1; pk data1 data2 rowkey12 data1-value3 454 rowkey10 data1-value 123456 -rowkey11 NULL NULL delete from t1; select * from t1; pk data1 data2 @@ -381,3 +380,30 @@ alter table t2 column_family='cf12'; Writes made during ALTER TABLE 0 drop table t2; +# +# UPDATE command support +# +create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra +thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); +select * from t1; +pk data1 data2 +rowkey12 data1-value3 454 +rowkey10 data1-value 123456 +rowkey11 data1-value2 34543 +update t1 set data1='updated-1' where pk='rowkey11'; +select * from t1; +pk data1 data2 +rowkey12 data1-value3 454 +rowkey10 data1-value 123456 +rowkey11 updated-1 34543 +update t1 set pk='new-rowkey12' where pk='rowkey12'; +select * from t1; +pk data1 data2 +rowkey10 data1-value 123456 +new-rowkey12 data1-value3 454 +rowkey11 updated-1 34543 +delete from t1; +drop table t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 3f5933e8b66..7e5b327580c 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -492,6 +492,25 @@ eval select ($c2 - $c1) as 'Writes made during ALTER TABLE'; drop table t2; +--echo # +--echo # UPDATE command support +--echo # +create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra + thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; + +insert into t1 values ('rowkey10', 'data1-value', 123456); +insert into t1 values ('rowkey11', 'data1-value2', 34543); +insert into t1 values ('rowkey12', 'data1-value3', 454); +select * from t1; + +update t1 set data1='updated-1' where pk='rowkey11'; +select * from t1; +update t1 set pk='new-rowkey12' where pk='rowkey12'; +select * from t1; + +delete from t1; +drop table t1; + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index e46d02f48d9..2239323bd20 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -99,6 +99,8 @@ public: void clear_insert_buffer(); void start_row_insert(const char *key, int key_len); void add_insert_column(const char *name, const char *value, int value_len); + void add_row_deletion(const char *key, int key_len, + Column_name_enumerator *col_names); bool do_insert(); @@ -313,6 +315,42 @@ void Cassandra_se_impl::start_row_insert(const char *key, int key_len) } +void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, + Column_name_enumerator *col_names) +{ + std::string key_to_delete; + key_to_delete.assign(key, key_len); + + batch_mutation[key_to_delete]= ColumnFamilyToMutation(); + ColumnFamilyToMutation& cf_mut= batch_mutation[key_to_delete]; + + cf_mut[column_family]= std::vector(); + std::vector &mutation_list= cf_mut[column_family]; + + Mutation mut; + mut.__isset.deletion= true; + mut.deletion.__isset.timestamp= true; + mut.deletion.timestamp= get_i64_timestamp(); + mut.deletion.__isset.predicate= true; + + /* + Attempting to delete columns with SliceRange causes exception with message + "Deletion does not yet support SliceRange predicates". + + Delete all columns individually. + */ + SlicePredicate slice_pred; + slice_pred.__isset.column_names= true; + const char *col_name; + while ((col_name= col_names->get_next_name())) + slice_pred.column_names.push_back(std::string(col_name)); + + mut.deletion.predicate= slice_pred; + + mutation_list.push_back(mut); +} + + void Cassandra_se_impl::add_insert_column(const char *name, const char *value, int value_len) { @@ -531,7 +569,13 @@ restart: } } - if (have_rowkey_to_skip && !rowkey_to_skip.compare(key_slice_it->key)) + /* + (1) - skip the last row that we have read in the previous batch. + (2) - Rows that were deleted show up as rows without any columns. Skip + them, like CQL does. + */ + if ((have_rowkey_to_skip && !rowkey_to_skip.compare(key_slice_it->key)) || // (1) + key_slice_it->columns.size() == 0) // (2) { key_slice_it++; goto restart; diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index c6de779f8bc..069a3b238f9 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -20,6 +20,14 @@ typedef enum THREE = 8-1, } enum_cassandra_consistency_level; + +class Column_name_enumerator +{ +public: + virtual const char* get_next_name()=0; + virtual ~Column_name_enumerator(){} +}; + /* Interface to one cassandra column family, i.e. one 'table' */ @@ -45,6 +53,8 @@ public: /* Writes */ virtual void clear_insert_buffer()=0; + virtual void add_row_deletion(const char *key, int key_len, + Column_name_enumerator *col_names)=0; virtual void start_row_insert(const char *key, int key_len)=0; virtual void add_insert_column(const char *name, const char *value, int value_len)=0; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index f9aa8cd40a8..7ec7f7aa4eb 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1605,11 +1605,95 @@ ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, } -int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) +class Column_name_enumerator_impl : public Column_name_enumerator { + ha_cassandra *obj; + uint idx; +public: + Column_name_enumerator_impl(ha_cassandra *obj_arg) : obj(obj_arg), idx(1) {} + const char* get_next_name() + { + if (idx == obj->table->s->fields) + return NULL; + else + return obj->table->field[idx++]->field_name; + } +}; + +int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) +{ + my_bitmap_map *old_map; DBUG_ENTER("ha_cassandra::update_row"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + /* Currently, it is guaranteed that new_data == table->record[0] */ + + /* For now, just rewrite the full record */ + se->clear_insert_buffer(); + + + old_map= dbug_tmp_use_all_columns(table, table->read_set); + + char *old_key; + int old_key_len; + se->get_read_rowkey(&old_key, &old_key_len); + + /* Get the key we're going to write */ + char *new_key; + int new_key_len; + if (rowkey_converter->mariadb_to_cassandra(&new_key, &new_key_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + rowkey_converter->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } + + /* + Compare it to the key we've read. For all types that Cassandra supports, + binary byte-wise comparison can be used + */ + bool new_primary_key; + if (new_key_len != old_key_len || memcmp(old_key, new_key, new_key_len)) + new_primary_key= true; + else + new_primary_key= false; + + + if (new_primary_key) + { + /* + Primary key value changed. This is essentially a DELETE + INSERT. + Add a DELETE operation into the batch + */ + Column_name_enumerator_impl name_enumerator(this); + se->add_row_deletion(old_key, old_key_len, &name_enumerator); + } + + se->start_row_insert(new_key, new_key_len); + + /* Convert other fields */ + for (uint i= 1; i < table->s->fields; i++) + { + char *cass_data; + int cass_data_len; + if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + field_converters[i]->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } + se->add_insert_column(field_converters[i]->field->field_name, + cass_data, cass_data_len); + } + dbug_tmp_restore_column_map(table->read_set, old_map); + + bool res= se->do_insert(); + + if (res) + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 52fd46fa5ef..f94dbc1c49d 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -45,6 +45,7 @@ struct ha_table_option_struct; */ class ha_cassandra: public handler { + friend class Column_name_enumerator_impl; THR_LOCK_DATA lock; ///< MySQL lock CASSANDRA_SHARE *share; ///< Shared lock info -- cgit v1.2.1 From 4db207d56da2f832d8bc6cc1d935a17efcbc1035 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 27 Sep 2012 16:08:28 +0400 Subject: Cassandra SE: lazy connections - Don't connect right away in ha_cassandra::open. If we do this, it becomes impossible to do SHOW CREATE TABLE when the server is not present. - Note: CREATE TABLE still requires that connection is present, as it needs to check whether the specified DDL can be used with Cassandra. We could delay that check also, but then one would not be able to find out about errors in table DDL until they do a SELECT. --- storage/cassandra/cassandra_se.cc | 2 +- storage/cassandra/cassandra_se.h | 2 +- storage/cassandra/ha_cassandra.cc | 104 +++++++++++++++++++++----------------- storage/cassandra/ha_cassandra.h | 4 +- 4 files changed, 62 insertions(+), 50 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 2239323bd20..7d48bbc30d6 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -159,7 +159,7 @@ private: ///////////////////////////////////////////////////////////////////////////// // Connection and setup ///////////////////////////////////////////////////////////////////////////// -Cassandra_se_interface *get_cassandra_se() +Cassandra_se_interface *create_cassandra_se() { return new Cassandra_se_impl; } diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 069a3b238f9..33c602d93a6 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -110,5 +110,5 @@ public: extern Cassandra_status_vars cassandra_counters; -Cassandra_se_interface *get_cassandra_se(); +Cassandra_se_interface *create_cassandra_se(); diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 7ec7f7aa4eb..c4069458c41 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -375,21 +375,16 @@ const char **ha_cassandra::bas_ext() const } -int ha_cassandra::open(const char *name, int mode, uint test_if_locked) +int ha_cassandra::connect_and_check_options(TABLE *table_arg) { - ha_table_option_struct *options= table->s->option_struct; + ha_table_option_struct *options= table_arg->s->option_struct; int res; - DBUG_ENTER("ha_cassandra::open"); + DBUG_ENTER("ha_cassandra::connect_and_check_options"); - if (!(share = get_share(name, table))) - DBUG_RETURN(1); - thr_lock_data_init(&share->lock,&lock,NULL); - - DBUG_ASSERT(!se); if ((res= check_table_options(options))) DBUG_RETURN(res); - se= get_cassandra_se(); + se= create_cassandra_se(); se->set_column_family(options->column_family); const char *thrift_host= options->thrift_host? options->thrift_host: cassandra_default_thrift_host; @@ -399,11 +394,36 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(HA_ERR_NO_CONNECTION); } - if (setup_field_converters(table->field, table->s->fields)) + if (setup_field_converters(table_arg->field, table_arg->s->fields)) { DBUG_RETURN(HA_ERR_NO_CONNECTION); } + DBUG_RETURN(0); +} + + +int ha_cassandra::open(const char *name, int mode, uint test_if_locked) +{ + DBUG_ENTER("ha_cassandra::open"); + + if (!(share = get_share(name, table))) + DBUG_RETURN(1); + thr_lock_data_init(&share->lock,&lock,NULL); + + DBUG_ASSERT(!se); + /* + Don't do the following on open: it prevents SHOW CREATE TABLE when the server + has gone away. + */ + /* + int res; + if ((res= connect_and_check_options(table))) + { + DBUG_RETURN(res); + } + */ + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); insert_lineno= 0; @@ -444,7 +464,7 @@ int ha_cassandra::check_table_options(ha_table_option_struct *options) /** @brief - create() is called to create a database. The variable name will have the name + create() is called to create a table. The variable name will have the name of the table. @details @@ -485,45 +505,10 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, DBUG_RETURN(HA_WRONG_CREATE_OPTION); } -#ifndef DBUG_OFF -/* - DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ - "boolparam: %u", - (options->strparam ? options->strparam : ""), - options->ullparam, options->enumparam, options->boolparam)); - - psergey-todo: check table definition! - for (Field **field= table_arg->s->field; *field; field++) - { - ha_field_option_struct *field_options= (*field)->option_struct; - DBUG_ASSERT(field_options); - DBUG_PRINT("info", ("field: %s complex: '%-.64s'", - (*field)->field_name, - (field_options->complex_param_to_parse_it_in_engine ? - field_options->complex_param_to_parse_it_in_engine : - ""))); - } -*/ -#endif DBUG_ASSERT(!se); - if ((res= check_table_options(options))) + if ((res= connect_and_check_options(table_arg))) DBUG_RETURN(res); - se= get_cassandra_se(); - se->set_column_family(options->column_family); - const char *thrift_host= options->thrift_host? options->thrift_host: - cassandra_default_thrift_host; - if (se->connect(thrift_host, options->thrift_port, options->keyspace)) - { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), se->error_str()); - DBUG_RETURN(HA_ERR_NO_CONNECTION); - } - - if (setup_field_converters(table_arg->s->field, table_arg->s->fields)) - { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "setup_field_converters"); - DBUG_RETURN(HA_ERR_NO_CONNECTION); - } insert_lineno= 0; DBUG_RETURN(0); } @@ -1064,6 +1049,14 @@ void ha_cassandra::free_field_converters() } +int ha_cassandra::index_init(uint idx, bool sorted) +{ + int ires; + if (!se && (ires= connect_and_check_options(table))) + return ires; + return 0; +} + void store_key_image_to_rec(Field *field, uchar *ptr, uint len); int ha_cassandra::index_read_map(uchar *buf, const uchar *key, @@ -1198,8 +1191,12 @@ err: int ha_cassandra::write_row(uchar *buf) { my_bitmap_map *old_map; + int ires; DBUG_ENTER("ha_cassandra::write_row"); + if (!se && (ires= connect_and_check_options(table))) + DBUG_RETURN(ires); + if (!doing_insert_batch) se->clear_insert_buffer(); @@ -1260,6 +1257,10 @@ int ha_cassandra::write_row(uchar *buf) void ha_cassandra::start_bulk_insert(ha_rows rows) { + int ires; + if (!se && (ires= connect_and_check_options(table))) + return; + doing_insert_batch= true; insert_rows_batched= 0; @@ -1283,7 +1284,12 @@ int ha_cassandra::end_bulk_insert() int ha_cassandra::rnd_init(bool scan) { bool bres; + int ires; DBUG_ENTER("ha_cassandra::rnd_init"); + + if (!se && (ires= connect_and_check_options(table))) + DBUG_RETURN(ires); + if (!scan) { /* Prepare for rnd_pos() calls. We don't need to anything. */ @@ -1338,8 +1344,12 @@ int ha_cassandra::rnd_next(uchar *buf) int ha_cassandra::delete_all_rows() { bool bres; + int ires; DBUG_ENTER("ha_cassandra::delete_all_rows"); + if (!se && (ires= connect_and_check_options(table))) + DBUG_RETURN(ires); + bres= se->truncate(); if (bres) diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index f94dbc1c49d..fb5236bf118 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -69,6 +69,7 @@ class ha_cassandra: public handler ha_rows insert_lineno; void print_conversion_error(const char *field_name, char *cass_value, int cass_value_len); + int connect_and_check_options(TABLE *table_arg); public: ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg); ~ha_cassandra() @@ -152,7 +153,8 @@ public: */ uint max_supported_key_length() const { return 16*1024; /* just to return something*/ } - /* At the moment, we're ok with default handler::index_init() implementation. */ + int index_init(uint idx, bool sorted); + int index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag); -- cgit v1.2.1 From 7327cd9717f0b98499f0f5b19c84e5e3e48241df Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Sep 2012 14:01:17 +0300 Subject: =?UTF-8?q?MDEV-377=20Name=20support=20for=20dynamic=20columns=20M?= =?UTF-8?q?DEV-127=20Optimization=20of=20memory=20allocation=20MDEV-483=20?= =?UTF-8?q?Make=20column=5Fcheck=20function=20which=20che=D1=81ks=20dynami?= =?UTF-8?q?c=20columns=20integrit=20JSON=20conversion=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ma_dyncol.h | 32 + include/my_sys.h | 6 + mysql-test/r/dyncol.result | 292 ++++- mysql-test/t/dyncol.test | 122 ++ mysys/ma_dyncol.c | 2714 ++++++++++++++++++++++++++++++++++---------- mysys/string.c | 102 ++ sql/item.h | 2 +- sql/item_cmpfunc.cc | 73 +- sql/item_cmpfunc.h | 8 + sql/item_create.cc | 14 +- sql/item_create.h | 1 + sql/item_strfunc.cc | 226 +++- sql/item_strfunc.h | 18 +- sql/lex.h | 2 + sql/sql_string.cc | 73 -- sql/sql_yacc.yy | 20 +- 16 files changed, 2961 insertions(+), 744 deletions(-) diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h index 6174328d62a..b4b9df7da19 100644 --- a/include/ma_dyncol.h +++ b/include/ma_dyncol.h @@ -102,6 +102,13 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str, uint *column_numbers, DYNAMIC_COLUMN_VALUE *values); +enum enum_dyncol_func_result +dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str, + uint column_count, + uchar *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool names); + enum enum_dyncol_func_result dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, DYNAMIC_COLUMN_VALUE *value); @@ -110,16 +117,30 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, uint add_column_count, uint *column_numbers, DYNAMIC_COLUMN_VALUE *values); +enum enum_dyncol_func_result +dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, + uint add_column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool string_keys); enum enum_dyncol_func_result dynamic_column_delete(DYNAMIC_COLUMN *org, uint column_nr); enum enum_dyncol_func_result dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr); +enum enum_dyncol_func_result +dynamic_column_exists_str(DYNAMIC_COLUMN *str, LEX_STRING *name); +enum enum_dyncol_func_result +dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_keys); /* List of not NULL columns */ enum enum_dyncol_func_result dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); +enum enum_dyncol_func_result +dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr); +enum enum_dyncol_func_result +dynamic_column_list_fmt(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array, my_bool string_keys); /* if the column do not exists it is NULL @@ -127,6 +148,17 @@ dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); enum enum_dyncol_func_result dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, DYNAMIC_COLUMN_VALUE *store_it_here); +enum enum_dyncol_func_result +dynamic_column_get_str(DYNAMIC_COLUMN *str, LEX_STRING *name, + DYNAMIC_COLUMN_VALUE *store_it_here); + +my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str); + +enum enum_dyncol_func_result +dynamic_column_check(DYNAMIC_COLUMN *str); + +enum enum_dyncol_func_result +dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); #define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A))) #define dynamic_column_column_free(V) dynstr_free(V) diff --git a/include/my_sys.h b/include/my_sys.h index a02c390fe4b..58a343bb789 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -793,12 +793,18 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append, size_t length); extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...); +extern my_bool dynstr_append_quoted(DYNAMIC_STRING *str, + const char *append, size_t len); extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str); extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size); extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n); extern void dynstr_free(DYNAMIC_STRING *str); extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length, size_t *alloc_length); +extern uint32 copy_and_convert_extended(char *to, uint32 to_length, + CHARSET_INFO *to_cs, + const char *from, uint32 from_length, + CHARSET_INFO *from_cs, uint *errors); #ifdef HAVE_MLOCK extern void *my_malloc_lock(size_t length,myf flags); extern void my_free_lock(void *ptr); diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index 13543223ad8..2e9a8462eee 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1088,7 +1088,7 @@ column_list(column_add(column_create(1, 1), 1, null)) select column_list(column_add(column_create(1, 1), 1, "")); column_list(column_add(column_create(1, 1), 1, "")) -1 +`1` select hex(column_add("", 1, 1)); hex(column_add("", 1, 1)) 00010001000002 @@ -1133,10 +1133,10 @@ column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4) # column list select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)); column_list(column_create(1, 1212 as integer, 2, 1212 as integer)) -1,2 +`1`,`2` select column_list(column_create(1, 1212 as integer)); column_list(column_create(1, 1212 as integer)) -1 +`1` select column_list(column_create(1, NULL as integer)); column_list(column_create(1, NULL as integer)) @@ -1218,35 +1218,35 @@ sum(column_get(str, 1 as int)) 11 select id, column_list(str) from t1 where id= 5; id column_list(str) -5 1,2,3,10 +5 `1`,`2`,`3`,`10` update t1 set str=column_delete(str, 3, 4, 2) where id= 5; select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1; id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int) -1 12 1,2 1 a NULL -2 12 1,2 2 a NULL -3 12 2,3 NULL c 100 -4 16 1,2,3 5 c 100 -5 15 1,10 6 NULL NULL -6 21 2,3,10 NULL c 100 +1 12 `1`,`2` 1 a NULL +2 12 `1`,`2` 2 a NULL +3 12 `2`,`3` NULL c 100 +4 16 `1`,`2`,`3` 5 c 100 +5 15 `1`,`10` 6 NULL NULL +6 21 `2`,`3`,`10` NULL c 100 update t1 set str=column_add(str, 4, 45 as char, 2, 'c') where id= 5; select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1 where id = 5; id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int) -5 26 1,2,4,10 6 c NULL +5 26 `1`,`2`,`4`,`10` 6 c NULL select id, length(str), column_list(str), column_exists(str, 4) from t1; id length(str) column_list(str) column_exists(str, 4) -1 12 1,2 0 -2 12 1,2 0 -3 12 2,3 0 -4 16 1,2,3 0 -5 26 1,2,4,10 1 -6 21 2,3,10 0 +1 12 `1`,`2` 0 +2 12 `1`,`2` 0 +3 12 `2`,`3` 0 +4 16 `1`,`2`,`3` 0 +5 26 `1`,`2`,`4`,`10` 1 +6 21 `2`,`3`,`10` 0 select sum(column_get(str, 1 as int)), column_list(str) from t1 group by 2; sum(column_get(str, 1 as int)) column_list(str) -3 1,2 -5 1,2,3 -6 1,2,4,10 -NULL 2,3 -NULL 2,3,10 +3 `1`,`2` +5 `1`,`2`,`3` +6 `1`,`2`,`4`,`10` +NULL `2`,`3` +NULL `2`,`3`,`10` select id, hex(str) from t1; id hex(str) 1 00020001000002000B020861 @@ -1282,11 +1282,11 @@ id 5 select id, column_list(str), length(str) from t1 where id=5; id column_list(str) length(str) -5 1,2,4,5,10 100048 +5 `1`,`2`,`4`,`5`,`10` 100048 update t1 set str=column_delete(str, 5) where id=5; select id, column_list(str), length(str) from t1 where id=5; id column_list(str) length(str) -5 1,2,4,10 34 +5 `1`,`2`,`4`,`10` 34 drop table t1; # # LP#778905: Assertion `value->year <= 9999' failed in @@ -1306,7 +1306,7 @@ INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' ); SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1; HEX(COLUMN_ADD(f1, 1, 'abc')) COLUMN_LIST(f1) NULL NULL -0002000100030200230861626308636465 2 +0002000100030200230861626308636465 `2` SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1; DROP TABLE t1; # @@ -1335,3 +1335,245 @@ hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal)) select hex(COLUMN_CREATE(0, 0.0 as decimal)); hex(COLUMN_CREATE(0, 0.0 as decimal)) 000100000004 +# +# test of symbolic names +# +# creation test (names) +set names utf8; +select hex(column_create("адын", 1212)); +hex(column_create("адын", 1212)) +040100080008000000D0B0D0B4D18BD0BD7809 +select hex(column_create("1212", 1212)); +hex(column_create("1212", 1212)) +040100040004000000313231327809 +select hex(column_create(1212, 2, "www", 3)); +hex(column_create(1212, 2, "www", 3)) +04020007000300000004030008777777313231320604 +select hex(column_create("1212", 2, "www", 3)); +hex(column_create("1212", 2, "www", 3)) +04020007000300000004030008777777313231320604 +select hex(column_create("1212", 2, 3, 3)); +hex(column_create("1212", 2, 3, 3)) +0402000500010000000401000833313231320604 +select hex(column_create("1212", 2, "адын", 1, 3, 3)); +hex(column_create("1212", 2, "адын", 1, 3, 3)) +0403000D000100000004010008080500103331323132D0B0D0B4D18BD0BD060402 +set names default; +# fetching column test (names) +set names utf8; +select column_get(column_create("адын", 1212), "адын" as int); +column_get(column_create("адын", 1212), "адын" as int) +1212 +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int) +1 +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int) +2 +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int) +3 +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int) +3 +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int) +NULL +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int); +column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int) +NULL +set names default; +# column existance test (names) +set names utf8; +select column_exists(column_create("адын", 1212), "адын"); +column_exists(column_create("адын", 1212), "адын") +1 +select column_exists(column_create("адын", 1212), "aады"); +column_exists(column_create("адын", 1212), "aады") +0 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын"); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын") +1 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212) +1 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3"); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3") +1 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3) +1 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4) +0 +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4"); +column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4") +0 +set names default; +# column changing test (names) +select hex(column_add(column_create(1, "AAA"), "b", "BBB")); +hex(column_add(column_create(1, "AAA"), "b", "BBB")) +0402000200010000030101002331620841414108424242 +select hex(column_add(column_create("1", "AAA"), "b", "BBB")); +hex(column_add(column_create("1", "AAA"), "b", "BBB")) +0402000200010000030101002331620841414108424242 +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char); +column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char) +AAA +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char); +column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char) +BBB +select hex(column_add(column_create("a", "AAA"), 1, "BBB")); +hex(column_add(column_create("a", "AAA"), 1, "BBB")) +0402000200010000030101002331610842424208414141 +select hex(column_add(column_create("a", "AAA"), "1", "BBB")); +hex(column_add(column_create("a", "AAA"), "1", "BBB")) +0402000200010000030101002331610842424208414141 +select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)); +hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)) +04020002000100000001010010616278097809 +select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)); +hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)) +040100010001000000617809 +select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)); +hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)) +0400000000 +select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)); +hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)) +040100010001000000617809 +select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)); +hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)) +040200020001000000010100086162167809 +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer); +column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer) +11 +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer); +column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer) +1212 +select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)); +hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)) +040200020001000000010100106162780916 +select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)); +hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)) +040200020001000000010100106162780916 +select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)); +hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)) +040200020001000000010100086162167809 +select hex(column_add(column_create("a", 1), "a", null)); +hex(column_add(column_create("a", 1), "a", null)) +0400000000 +select column_list(column_add(column_create("a", 1), "a", null)); +column_list(column_add(column_create("a", 1), "a", null)) + +select column_list(column_add(column_create("a", 1), "a", "")); +column_list(column_add(column_create("a", 1), "a", "")) +`a` +select hex(column_add("", "a", 1)); +hex(column_add("", "a", 1)) +0401000100010000006102 +# column delete (names) +select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")); +hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")) +040100010001000000627809 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")) +0402000200010000000101000861630206 +select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)); +hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)) +0403000300010000000101000801020010616263020406 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")) +0402000200010000000101000861620204 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")) +0403000300010000000101000801020010616263020406 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")) +0401000100010000006306 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")) +0401000100010000006102 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")) +0400000000 +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")); +hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")) +0400000000 +select hex(column_delete(column_create("a", 1), "a")); +hex(column_delete(column_create("a", 1), "a")) +0400000000 +select hex(column_delete("", "a")); +hex(column_delete("", "a")) + +# +# MDEV-458 DNAMES: Server crashes on using an unquoted string +# as a dynamic column name +# +select COLUMN_CREATE(color, "black"); +ERROR 42S22: Unknown column 'color' in 'field list' +# +# MDEV-489 Assertion `offset < 0x1f' failed in +# type_and_offset_store on COLUMN_ADD +# +CREATE TABLE t1 (f1 tinyblob); +INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30))); +UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' ); +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 +UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' ); +ERROR HY000: Encountered illegal format of dynamic column string +drop table t1; +# +# MDEV-490/MDEV-491 null as arguments +# +SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ); +COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ) +NULL +SELECT COLUMN_GET( NULL, 'col' as char ); +COLUMN_GET( NULL, 'col' as char ) +NULL +SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL); +COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL) +NULL +SELECT COLUMN_EXISTS( NULL, 'col'); +COLUMN_EXISTS( NULL, 'col') +NULL +SELECT COLUMN_CREATE( NULL, 'val' ); +COLUMN_CREATE( NULL, 'val' ) +NULL +SELECT COLUMN_ADD( NULL, 'val', 'col'); +COLUMN_ADD( NULL, 'val', 'col') +NULL +# +# MDEV-488: Assertion `column_name->length < 255' failed on a +# column name with length 255 (precisely) +# +SELECT hex(COLUMN_CREATE(REPEAT('a',255),1)); +hex(COLUMN_CREATE(REPEAT('a',255),1)) +040100FF00FF00000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102 +SELECT hex(COLUMN_CREATE(REPEAT('a',256),1)); +ERROR 22007: Illegal value used as argument of dynamic column function +# +# JSON conversion +# +select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)); +column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" +[{"int":-1212},{"date":"2011-04-05"},{"time":"00:45:49.000001"},{"uint":12334},{"double":"1.23444e+50"},{"string":"gdgd\\dhdjh\"dhdhd"},{"decimal":23.344},{"datetime":"2011-04-05 00:45:49.000001"}] +select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)); +column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)) +[{"1":-1212},{"2":12334},{"3":23.344},{"4":"1.23444e+50"},{"5":"gdgd\\dhdjh\"dhdhd"},{"6":"00:45:49.000001"},{"7":"2011-04-05 00:45:49.000001"},{"8":"2011-04-05"}] +# +# CHECK test +# +SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a')); +COLUMN_CHECK(COLUMN_CREATE(1,'a')) +1 +SELECT COLUMN_CHECK('abracadabra'); +COLUMN_CHECK('abracadabra') +0 +SELECT COLUMN_CHECK(''); +COLUMN_CHECK('') +1 +SELECT COLUMN_CHECK(NULL); +COLUMN_CHECK(NULL) +NULL diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 66e308540f4..143a833fe8d 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -550,3 +550,125 @@ select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))); select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))); select hex(COLUMN_CREATE(0, 0.0 as decimal)); + +--echo # +--echo # test of symbolic names +--echo # +--echo # creation test (names) +set names utf8; +select hex(column_create("адын", 1212)); +select hex(column_create("1212", 1212)); +select hex(column_create(1212, 2, "www", 3)); +select hex(column_create("1212", 2, "www", 3)); +select hex(column_create("1212", 2, 3, 3)); +select hex(column_create("1212", 2, "адын", 1, 3, 3)); +set names default; + +--echo # fetching column test (names) +set names utf8; +select column_get(column_create("адын", 1212), "адын" as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int); +select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int); +set names default; + +--echo # column existance test (names) +set names utf8; +select column_exists(column_create("адын", 1212), "адын"); +select column_exists(column_create("адын", 1212), "aады"); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын"); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3"); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4); +select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4"); +set names default; + +--echo # column changing test (names) +select hex(column_add(column_create(1, "AAA"), "b", "BBB")); +select hex(column_add(column_create("1", "AAA"), "b", "BBB")); +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char); +select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char); +select hex(column_add(column_create("a", "AAA"), 1, "BBB")); +select hex(column_add(column_create("a", "AAA"), "1", "BBB")); +select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)); +select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)); +select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)); +select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)); +select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)); +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer); +select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer); +select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)); +select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)); +select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)); +select hex(column_add(column_create("a", 1), "a", null)); +select column_list(column_add(column_create("a", 1), "a", null)); +select column_list(column_add(column_create("a", 1), "a", "")); +select hex(column_add("", "a", 1)); + +-- echo # column delete (names) +select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")); +select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")); +select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e")); +select hex(column_delete(column_create("a", 1), "a")); +select hex(column_delete("", "a")); + +--echo # +--echo # MDEV-458 DNAMES: Server crashes on using an unquoted string +--echo # as a dynamic column name +--echo # +--error ER_BAD_FIELD_ERROR +select COLUMN_CREATE(color, "black"); + +--echo # +--echo # MDEV-489 Assertion `offset < 0x1f' failed in +--echo # type_and_offset_store on COLUMN_ADD +--echo # +CREATE TABLE t1 (f1 tinyblob); + +INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30))); +UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' ); +--error ER_DYN_COL_WRONG_FORMAT +UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' ); +drop table t1; + +--echo # +--echo # MDEV-490/MDEV-491 null as arguments +--echo # +SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR ); +SELECT COLUMN_GET( NULL, 'col' as char ); +SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL); +SELECT COLUMN_EXISTS( NULL, 'col'); +SELECT COLUMN_CREATE( NULL, 'val' ); +SELECT COLUMN_ADD( NULL, 'val', 'col'); + +--echo # +--echo # MDEV-488: Assertion `column_name->length < 255' failed on a +--echo # column name with length 255 (precisely) +--echo # +SELECT hex(COLUMN_CREATE(REPEAT('a',255),1)); +--error ER_DYN_COL_DATA +SELECT hex(COLUMN_CREATE(REPEAT('a',256),1)); + +--echo # +--echo # JSON conversion +--echo # +select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)); +select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)); + +--echo # +--echo # CHECK test +--echo # +SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a')); +SELECT COLUMN_CHECK('abracadabra'); +SELECT COLUMN_CHECK(''); +SELECT COLUMN_CHECK(NULL); diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index c717f69c3e5..70ae4935528 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -29,7 +29,11 @@ #include "mysys_priv.h" #include #include +#include +uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, + const char *from, uint32 from_length, + CHARSET_INFO *from_cs, uint *errors); /* Flag byte bits @@ -37,19 +41,40 @@ */ /* mask to get above bits */ #define DYNCOL_FLG_OFFSET 3 +#define DYNCOL_FLG_NAMES 4 /* All known flags mask */ -#define DYNCOL_FLG_KNOWN 3 +#define DYNCOL_FLG_KNOWN 7 + +/* formats */ +#define DYNCOL_FMT_NUM 0 +#define DYNCOL_FMT_STR 1 /* dynamic column size reserve */ #define DYNCOL_SYZERESERVE 80 +#define DYNCOL_OFFSET_ERROR 0xffffffff + /* length of fixed string header 1 byte - flags, 2 bytes - columns counter */ #define FIXED_HEADER_SIZE 3 +/* + length of fixed string header with names + 1 byte - flags, 2 bytes - columns counter, 2 bytes - name pool size +*/ +#define FIXED_HEADER_SIZE_NM 5 #define COLUMN_NUMBER_SIZE 2 +/* 1 byte name length + 2 bytes offset from the name pool */ +#define COLUMN_NAMEPTR_SIZE 3 #define MAX_OFFSET_LENGTH 5 +my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str) +{ + if (str->length < 1) + return FALSE; + return test(str->str[0] & DYNCOL_FLG_NAMES); +} + static enum enum_dyncol_func_result dynamic_column_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value); @@ -62,6 +87,311 @@ dynamic_column_time_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here, static enum enum_dyncol_func_result dynamic_column_date_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here, uchar *data, size_t length); +static enum enum_dyncol_func_result +dynamic_column_get_internal(DYNAMIC_COLUMN *str, + DYNAMIC_COLUMN_VALUE *store_it_here, + uint num_key, LEX_STRING *str_key); +static enum enum_dyncol_func_result +dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, + LEX_STRING *str_key); +enum enum_dyncol_func_result +dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, + uint add_column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool string_keys); +static int plan_sort_num(const void *a, const void *b); +static int plan_sort_str(const void *a, const void *b); + +/* + Structure to hold information about dynamic columns record and + iterate through it. +*/ + +struct st_dyn_header +{ + uchar *header, *nmpool, *dtpool, *data_end; + size_t offset_size; + size_t entry_size; + size_t header_size; + size_t nmpool_size; + size_t data_size; + /* DYNCOL_FMT_NUM - numeric columns, DYNCOL_FMT_STR - column names */ + uint format; + uint column_count; + + uchar *entry, *data, *name; + size_t offset; + uint length; + enum enum_dynamic_column_type type; +}; + +typedef struct st_dyn_header DYN_HEADER; + +static inline my_bool read_fixed_header(DYN_HEADER *hdr, + DYNAMIC_COLUMN *str); +static void set_fixed_header(DYNAMIC_COLUMN *str, + uint offset_size, + uint column_count); +static my_bool type_and_offset_store(uchar *place, size_t offset_size, + DYNAMIC_COLUMN_TYPE type, + size_t offset); + +/* + Calculate entry size (E) and header size (H) by offset size (O) and column + count (C) and fixed part of entry size (F). +*/ + +#define calc_param(E,H,F,O,C) do { \ + (*(E))= (O) + F; \ + (*(H))= (*(E)) * (C); \ +}while(0); + + +/** + Name pool size functions, for numeric format it is 0 +*/ + +size_t name_size_num(void *keys __attribute__((unused)), + uint i __attribute__((unused))) +{ + return 0; +} + + +/** + Name pool size functions. +*/ +size_t name_size_str(void *keys, uint i) +{ + return ((LEX_STRING *) keys)[i].length; +} + + +/** + Comparator function for references on column numbers for qsort + (numeric format) +*/ + +static int column_sort_num(const void *a, const void *b) +{ + return **((uint **)a) - **((uint **)b); +} + + +/** + Comparator function for references on column numbers for qsort + (names format) +*/ + +static int column_sort_str(const void *a, const void *b) +{ + LEX_STRING *s1= *((LEX_STRING **)a); + LEX_STRING *s2= *((LEX_STRING **)b); + int rc= s1->length - s2->length; + if (rc == 0) + rc= memcmp((void *)s1->str, (void *)s2->str, (size_t) s1->length); + return rc; +} + + +/** + Check limit function (numeric format) +*/ + +static my_bool check_limit_num(const void *val) +{ + return **((uint **)val) > UINT_MAX16; +} + + +/** + Check limit function (names format) +*/ + +static my_bool check_limit_str(const void *val) +{ + return (*((LEX_STRING **)val))->length > 255; +} + + +/** + Write numeric format static header part. +*/ + +void set_fixed_header_num(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) +{ + set_fixed_header(str, hdr->offset_size, hdr->column_count); + hdr->header= (uchar *)str->str + FIXED_HEADER_SIZE; + hdr->nmpool= hdr->dtpool= hdr->header + hdr->header_size; +} + + +/** + Write names format static header part. +*/ + +void set_fixed_header_str(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) +{ + set_fixed_header(str, hdr->offset_size, hdr->column_count); + str->str[0]|= DYNCOL_FLG_NAMES; + int2store(str->str + 3, hdr->nmpool_size); + hdr->header= (uchar *)str->str + FIXED_HEADER_SIZE_NM; + hdr->nmpool= hdr->header + hdr->header_size; + hdr->dtpool= hdr->nmpool + hdr->nmpool_size; +} + + +/** + Write numeric format header entry + 2 bytes - column number + 1-4 bytes - data offset combined with type + + @param hdr descriptor of dynamic column record + @param column_key pointer to uint (column number) + @param value value which will be written (only type used) + @param offset offset of the data +*/ + +my_bool put_header_entry_num(DYN_HEADER *hdr, + void *column_key, + DYNAMIC_COLUMN_VALUE *value, + size_t offset) +{ + uint *column_number= (uint *)column_key; + int2store(hdr->entry, *column_number); + DBUG_ASSERT(hdr->nmpool_size == 0); + if (type_and_offset_store(hdr->entry, hdr->offset_size, + value->type, + offset)) + return TRUE; + hdr->entry= hdr->entry + hdr->entry_size; + return FALSE; +} + + +/** + Write names format header entry + 1 byte - name length + 2 bytes - name offset in the name pool + 1-4 bytes - data offset combined with type + + @param hdr descriptor of dynamic column record + @param column_key pointer to LEX_STRING (column name) + @param value value which will be written (only type used) + @param offset offset of the data +*/ + +my_bool put_header_entry_str(DYN_HEADER *hdr, + void *column_key, + DYNAMIC_COLUMN_VALUE *value, + size_t offset) +{ + LEX_STRING *column_name= (LEX_STRING *)column_key; + DBUG_ASSERT(column_name->length <= 255); + hdr->entry[0]= column_name->length; + DBUG_ASSERT(hdr->name - hdr->nmpool < (long) 0x10000L); + int2store(hdr->entry + 1, hdr->name - hdr->nmpool); + memcpy(hdr->name, column_name->str, column_name->length); + DBUG_ASSERT(hdr->nmpool_size != 0 || column_name->length == 0); + if (type_and_offset_store(hdr->entry + 1, hdr->offset_size, + value->type, + offset)) + return TRUE; + hdr->entry+= hdr->entry_size; + hdr->name+= column_name->length; + return FALSE; +} + + +/** + Format descriptor, contain constants and function references for + format processing +*/ + +struct st_service_funcs +{ + /* size of fixed header */ + uint fixed_hdr; + /* size of fixed part of header entry */ + uint fixed_hdr_entry; + + /*size of array element which stores keys */ + uint key_size_in_array; + + size_t (*name_size) + (void *, uint); + int (*column_sort) + (const void *a, const void *b); + my_bool (*check_limit) + (const void *val); + void (*set_fixed_hdr) + (DYNAMIC_COLUMN *str, DYN_HEADER *hdr); + my_bool (*put_header_entry)(DYN_HEADER *hdr, + void *column_key, + DYNAMIC_COLUMN_VALUE *value, + size_t offset); + int (*plan_sort)(const void *a, const void *b); +}; + + +/** + Actual our 2 format descriptors +*/ + +static struct st_service_funcs fmt_data[2]= +{ + { + FIXED_HEADER_SIZE, + COLUMN_NUMBER_SIZE, + sizeof(uint), + &name_size_num, + &column_sort_num, + &check_limit_num, + &set_fixed_header_num, + &put_header_entry_num, + &plan_sort_num + }, + { + FIXED_HEADER_SIZE_NM, + COLUMN_NAMEPTR_SIZE, + sizeof(LEX_STRING), + &name_size_str, + &column_sort_str, + &check_limit_str, + &set_fixed_header_str, + &put_header_entry_str, + &plan_sort_str + } +}; + + +/** + Read dynamic column record header and fill the descriptor + + @param hdr dynamic columns record descriptor to fill + @param str dynamic columns record + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +init_read_hdr(DYN_HEADER *hdr, DYNAMIC_COLUMN *str) +{ + if (read_fixed_header(hdr, str)) + return ER_DYNCOL_FORMAT; + hdr->header= (uchar*)str->str + fmt_data[hdr->format].fixed_hdr; + calc_param(&hdr->entry_size, &hdr->header_size, + fmt_data[hdr->format].fixed_hdr_entry, hdr->offset_size, + hdr->column_count); + hdr->nmpool= hdr->header + hdr->header_size; + hdr->dtpool= hdr->nmpool + hdr->nmpool_size; + hdr->data_size= str->length - fmt_data[hdr->format].fixed_hdr - + hdr->header_size - hdr->nmpool_size; + hdr->data_end= (uchar*)str->str + str->length; + return ER_DYNCOL_OK; +} + /** Initialize dynamic column string with (make it empty but correct format) @@ -82,11 +412,8 @@ static my_bool dynamic_column_init_str(DYNAMIC_COLUMN *str, size_t size) - First \0 is flags - other 2 \0 is number of fields */ - if (init_dynamic_string(str, NULL, - size + FIXED_HEADER_SIZE, DYNCOL_SYZERESERVE)) + if (init_dynamic_string(str, NULL, size, DYNCOL_SYZERESERVE)) return TRUE; - bzero(str->str, FIXED_HEADER_SIZE); - str->length= FIXED_HEADER_SIZE; return FALSE; } @@ -902,37 +1229,42 @@ static size_t dynamic_column_offset_bytes(size_t data_length) @param offset Offset to be written */ -static void type_and_offset_store(uchar *place, size_t offset_size, - DYNAMIC_COLUMN_TYPE type, - size_t offset) +static my_bool type_and_offset_store(uchar *place, size_t offset_size, + DYNAMIC_COLUMN_TYPE type, + size_t offset) { ulong val = (((ulong) offset) << 3) | (type - 1); DBUG_ASSERT(type != DYN_COL_NULL); DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */ /* Index entry starts with column number; Jump over it */ - place+= COLUMN_NUMBER_SIZE; + place+= COLUMN_NUMBER_SIZE; switch (offset_size) { case 1: - DBUG_ASSERT(offset < 0x1f); /* all 1 value is reserved */ + if (offset >= 0x1f) /* all 1 value is reserved */ + return TRUE; place[0]= (uchar)val; break; case 2: - DBUG_ASSERT(offset < 0x1fff); /* all 1 value is reserved */ + if (offset >= 0x1fff) /* all 1 value is reserved */ + return TRUE; int2store(place, val); break; case 3: - DBUG_ASSERT(offset < 0x1fffff); /* all 1 value is reserved */ + if (offset >= 0x1fffff) /* all 1 value is reserved */ + return TRUE; int3store(place, val); break; case 4: - DBUG_ASSERT(offset < 0x1fffffff); /* all 1 value is reserved */ + if (offset >= 0x1fffffff) /* all 1 value is reserved */ + return TRUE; int4store(place, val); break; default: - DBUG_ASSERT(0); /* impossible */ + return TRUE; } + return FALSE; } @@ -941,45 +1273,40 @@ static void type_and_offset_store(uchar *place, size_t offset_size, @param type Where to put type info @param offset Where to put offset info - @param place Beginning of the index entry + @param place beginning of the type and offset @param offset_size Size of offset field in bytes */ -static void type_and_offset_read(DYNAMIC_COLUMN_TYPE *type, - size_t *offset, - uchar *place, size_t offset_size) +static my_bool type_and_offset_read(DYNAMIC_COLUMN_TYPE *type, + size_t *offset, + uchar *place, size_t offset_size) { ulong UNINIT_VAR(val); + ulong UNINIT_VAR(lim); - place+= COLUMN_NUMBER_SIZE; /* skip column number */ switch (offset_size) { case 1: val= (ulong)place[0]; + lim= 0x1f; break; case 2: val= uint2korr(place); + lim= 0x1fff; break; case 3: val= uint3korr(place); + lim= 0x1fffff; break; case 4: val= uint4korr(place); + lim= 0x1fffffff; break; default: DBUG_ASSERT(0); /* impossible */ } *type= (val & 0x7) + 1; *offset= val >> 3; -} - - -/** - Comparator function for references on column numbers for qsort -*/ - -static int column_sort(const void *a, const void *b) -{ - return **((uint **)a) - **((uint **)b); + return (*offset >= lim); } @@ -1003,27 +1330,13 @@ static void set_fixed_header(DYNAMIC_COLUMN *str, DBUG_ASSERT((str->str[0] & (~DYNCOL_FLG_KNOWN)) == 0); } -/* - Calculate entry size (E) and header size (H) by offset size (O) and column - count (C). -*/ - -#define calc_param(E,H,O,C) do { \ - (*(E))= (O) + COLUMN_NUMBER_SIZE; \ - (*(H))= (*(E)) * (C); \ -}while(0); - - /** Adds columns into the empty string - @param str String where to write the data - @param header_size Size of the header without fixed part - @param offset_size Size of offset field in bytes + @param str String where to write the data (the record) + @param hdr Dynamic columns record descriptor @param column_count Number of columns in the arrays - @parem not_null_count Number of non-null columns in the arrays - @param data_size Size of the data segment - @param column_numbers Array of columns numbers + @param column_keys Array of columns keys (uint or LEX_STRING) @param values Array of columns values @param new_str True if we need to allocate new string @@ -1032,42 +1345,51 @@ static void set_fixed_header(DYNAMIC_COLUMN *str, static enum enum_dyncol_func_result dynamic_new_column_store(DYNAMIC_COLUMN *str, - size_t header_size, - size_t offset_size, + DYN_HEADER *hdr, uint column_count, - uint not_null_count, - size_t data_size, - uint *column_numbers, + void *column_keys, DYNAMIC_COLUMN_VALUE *values, my_bool new_str) { - uchar *header_end; - uint **columns_order; + struct st_service_funcs *fmt= fmt_data + hdr->format; + void **columns_order; + uchar *element; uint i; - uint entry_size= COLUMN_NUMBER_SIZE + offset_size; enum enum_dyncol_func_result rc= ER_DYNCOL_RESOURCE; + size_t all_headers_size; - if (!(columns_order= malloc(sizeof(uint*)*column_count))) + if (!(columns_order= malloc(sizeof(void*)*column_count))) return ER_DYNCOL_RESOURCE; if (new_str) { if (dynamic_column_init_str(str, - data_size + header_size + DYNCOL_SYZERESERVE)) + fmt->fixed_hdr + + hdr->header_size + + hdr->nmpool_size + + hdr->data_size + + DYNCOL_SYZERESERVE)) goto err; } else { str->length= 0; - if (dynstr_realloc(str, data_size + header_size + DYNCOL_SYZERESERVE)) + if (dynstr_realloc(str, + fmt->fixed_hdr + + hdr->header_size + + hdr->nmpool_size + + hdr->data_size + + DYNCOL_SYZERESERVE)) goto err; - bzero(str->str, FIXED_HEADER_SIZE); - str->length= FIXED_HEADER_SIZE; } + bzero(str->str, fmt->fixed_hdr); + str->length= fmt->fixed_hdr; /* sort columns for the header */ - for (i= 0; i < column_count; i++) - columns_order[i]= column_numbers + i; - qsort(columns_order, (size_t)column_count, sizeof(uint*), &column_sort); + for (i= 0, element= (uchar *) column_keys; + i < column_count; + i++, element+= fmt->key_size_in_array) + columns_order[i]= (void *)element; + qsort(columns_order, (size_t)column_count, sizeof(void*), fmt->column_sort); /* For now we don't allow creating two columns with the same number @@ -1076,38 +1398,43 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str, */ for (i= 0; i < column_count - 1; i++) { - if (columns_order[i][0] > UINT_MAX16 || - columns_order[i][0] == columns_order[i + 1][0]) + if ((*fmt->check_limit)(&columns_order[i]) || + (*fmt->column_sort)(&columns_order[i], &columns_order[i + 1]) == 0) { rc= ER_DYNCOL_DATA; goto err; } } - if (columns_order[i][0] > UINT_MAX16) + if ((*fmt->check_limit)(&columns_order[i])) { rc= ER_DYNCOL_DATA; goto err; } - DBUG_ASSERT(str->max_length >= str->length + header_size); - set_fixed_header(str, offset_size, not_null_count); - str->length+= header_size; /* reserve place for header */ - header_end= (uchar *)str->str + FIXED_HEADER_SIZE; + (*fmt->set_fixed_hdr)(str, hdr); + /* reserve place for header and name pool */ + str->length+= hdr->header_size + hdr->nmpool_size; + + hdr->entry= hdr->header; + hdr->name= hdr->nmpool; + all_headers_size= fmt->fixed_hdr + hdr->header_size + hdr->nmpool_size; for (i= 0; i < column_count; i++) { - uint ord= columns_order[i] - column_numbers; + uint ord= ((uchar*)columns_order[i] - (uchar*)column_keys) / + fmt->key_size_in_array; if (values[ord].type != DYN_COL_NULL) { /* Store header first in the str */ - int2store(header_end, column_numbers[ord]); - type_and_offset_store(header_end, offset_size, - values[ord].type, - str->length - header_size - FIXED_HEADER_SIZE); + if ((*fmt->put_header_entry)(hdr, columns_order[i], values + ord, + str->length - all_headers_size)) + { + rc= ER_DYNCOL_FORMAT; + goto err; + } /* Store value in 'str + str->length' and increase str->length */ if ((rc= data_store(str, values + ord))) goto err; - header_end+= entry_size; } } rc= ER_DYNCOL_OK; @@ -1117,61 +1444,88 @@ err: } /** - Create packed string which contains given columns (internal) + Calculate size of header, name pool and data pool - @param str String where to write the data + @param hdr descriptor of dynamic column record + @param column_count number of elements in arrays @param column_count Number of columns in the arrays - @param column_numbers Array of columns numbers + @param column_keys Array of columns keys (uint or LEX_STRING) @param values Array of columns values - @param new_str True if we need allocate new string @return ER_DYNCOL_* return code */ static enum enum_dyncol_func_result -dynamic_column_create_many_internal(DYNAMIC_COLUMN *str, - uint column_count, - uint *column_numbers, - DYNAMIC_COLUMN_VALUE *values, - my_bool new_str) -{ - size_t data_size= 0; - size_t header_size, offset_size; +calc_var_sizes(DYN_HEADER *hdr, + uint column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values) +{ + struct st_service_funcs *fmt= fmt_data + hdr->format; uint i; - int not_null_column_count= 0; - - if (new_str) - { - /* to make dynstr_free() working in case of errors */ - bzero(str, sizeof(DYNAMIC_COLUMN)); - } - + hdr->nmpool_size= hdr->data_size= 0; + hdr->column_count= 0; for (i= 0; i < column_count; i++) { if (values[i].type != DYN_COL_NULL) { size_t tmp; - not_null_column_count++; - data_size+= (tmp=dynamic_column_value_len(values + i)); + hdr->column_count++; + hdr->data_size+= (tmp= dynamic_column_value_len(values + i)); if (tmp == (size_t) ~0) return ER_DYNCOL_DATA; + hdr->nmpool_size+= (*fmt->name_size)(column_keys, i); } } - /* We can handle data up to 1fffffff = 536870911 bytes now */ - if ((offset_size= dynamic_column_offset_bytes(data_size)) >= + if ((hdr->offset_size= dynamic_column_offset_bytes(hdr->data_size)) >= MAX_OFFSET_LENGTH) return ER_DYNCOL_LIMIT; - /* header entry is column number + offset & type */ - header_size= not_null_column_count * (offset_size + 2); + /* header entry is column number or string pointer + offset & type */ + hdr->entry_size= fmt->fixed_hdr_entry + hdr->offset_size; + hdr->header_size= hdr->column_count * hdr->entry_size; + return ER_DYNCOL_OK; +} + +/** + Create packed string which contains given columns (internal multi format) + + @param str String where to write the data + @param column_count Number of columns in the arrays + @param column_keys Array of columns keys (format dependent) + @param values Array of columns values + @param new_str True if we need allocate new string + @param string_keys keys are strings + + @return ER_DYNCOL_* return code +*/ + +static enum enum_dyncol_func_result +dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str, + uint column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_str, + my_bool string_keys) +{ + DYN_HEADER header; + enum enum_dyncol_func_result rc; + bzero(&header, sizeof(header)); + header.format= (string_keys ? 1 : 0); + + if (new_str) + { + /* to make dynstr_free() working in case of errors */ + bzero(str, sizeof(DYNAMIC_COLUMN)); + } + + if ((rc= calc_var_sizes(&header, column_count, column_keys, values)) < 0) + return rc; - return dynamic_new_column_store(str, - header_size, offset_size, + return dynamic_new_column_store(str, &header, column_count, - not_null_column_count, - data_size, - column_numbers, values, + column_keys, values, new_str); } @@ -1194,11 +1548,35 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str, DYNAMIC_COLUMN_VALUE *values) { DBUG_ENTER("dynamic_column_create_many"); - DBUG_RETURN(dynamic_column_create_many_internal(str, column_count, - column_numbers, values, - TRUE)); + DBUG_RETURN(dynamic_column_create_many_internal_fmt(str, column_count, + column_numbers, values, + TRUE, FALSE)); } +/** + Create packed string which contains given columns + + @param str String where to write the data + @param column_count Number of columns in the arrays + @param column_keys Array of columns keys + @param values Array of columns value + @param names use string names as keys + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str, + uint column_count, + uchar *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool names) +{ + DBUG_ENTER("dynamic_column_create_many"); + DBUG_RETURN(dynamic_column_create_many_internal_fmt(str, column_count, + column_keys, values, + TRUE, names)); +} /** Create packed string which contains given column @@ -1239,32 +1617,46 @@ static size_t get_length_interval(uchar *entry, uchar *entry_next, DYNAMIC_COLUMN_TYPE type, type_next; DBUG_ASSERT(entry < entry_next); - type_and_offset_read(&type, &offset, entry, offset_size); + if (type_and_offset_read(&type, &offset, entry + COLUMN_NUMBER_SIZE, + offset_size)) + return DYNCOL_OFFSET_ERROR; if (entry_next >= header_end) return (last_offset - offset); - type_and_offset_read(&type_next, &offset_next, entry_next, offset_size); + if (type_and_offset_read(&type_next, &offset_next, + entry_next + COLUMN_NUMBER_SIZE, offset_size)) + return DYNCOL_OFFSET_ERROR; return (offset_next - offset); } -/* - Calculate length of data of one column +/** + Calculate length of data between given hdr->entry and next_entry - @param entry Pointer to the first entry - @param header_end Pointer to the header end - @param offset_size Size of offset field in bytes - @param last_offset Size of the data segment + @param hdr descriptor of dynamic column record + @param next_entry next header entry (can point just after last header + entry) @return number of bytes */ -static size_t get_length(uchar *entry, uchar *header_end, - size_t offset_size, - size_t last_offset) +static size_t hdr_interval_length(DYN_HEADER *hdr, uchar *next_entry) { - return get_length_interval(entry, - entry + offset_size + COLUMN_NUMBER_SIZE, - header_end, offset_size, last_offset); + struct st_service_funcs *fmt= fmt_data + hdr->format; + size_t next_entry_offset; + DYNAMIC_COLUMN_TYPE next_entry_type; + DBUG_ASSERT(hdr->entry < next_entry); + DBUG_ASSERT(hdr->entry >= hdr->header); + DBUG_ASSERT(next_entry <= hdr->header + hdr->header_size); + + if (type_and_offset_read(&hdr->type, &hdr->offset, + hdr->entry + fmt->fixed_hdr_entry, hdr->offset_size)) + return DYNCOL_OFFSET_ERROR; + if (next_entry == hdr->header + hdr->header_size) + return hdr->data_size - hdr->offset; + if (type_and_offset_read(&next_entry_type, &next_entry_offset, + next_entry + fmt->fixed_hdr_entry, hdr->offset_size)) + return DYNCOL_OFFSET_ERROR; + return (next_entry_offset - hdr->offset); } @@ -1272,7 +1664,7 @@ static size_t get_length(uchar *entry, uchar *header_end, Comparator function for references to header entries for qsort */ -static int header_compar(const void *a, const void *b) +static int header_compar_num(const void *a, const void *b) { uint va= uint2korr((uchar*)a), vb= uint2korr((uchar*)b); return (va > vb ? 1 : (va < vb ? -1 : 0)); @@ -1280,96 +1672,182 @@ static int header_compar(const void *a, const void *b) /** - Find column and fill information about it + Find entry in the numeric format header by the column number - @param type Returns type of the column - @param data Returns a pointer to the data - @param length Returns length of the data - @param offset_size Size of offset field in bytes - @param column_count Number of column in the packed string - @param data_end Pointer to the data end - @param num Number of the column we want to fetch - @param entry_pos NULL or place where to put reference to the entry + @param hdr descriptor of dynamic column record + @param key number to find - @return 0 ok - @return 1 error in data + @return pointer to the entry or NULL */ -static my_bool -find_column(DYNAMIC_COLUMN_TYPE *type, uchar **data, size_t *length, - uchar *header, size_t offset_size, uint column_count, - uchar *data_end, uint num, uchar **entry_pos) +static uchar *find_entry_num(DYN_HEADER *hdr, uint key) { - uchar *entry; - size_t offset, total_data, header_size, entry_size; - uchar key[2+4]; + uchar header_entry[2+4]; + DBUG_ASSERT(hdr->format == DYNCOL_FMT_NUM); + int2store(header_entry, key); + return hdr->entry= bsearch(header_entry, hdr->header, + (size_t)hdr->column_count, + hdr->entry_size, &header_compar_num); +} - if (!entry_pos) - entry_pos= &entry; - calc_param(&entry_size, &header_size, offset_size, column_count); +/** + Find entry in the names format header by the column number - if (header + header_size > data_end) - return 1; + @param hdr descriptor of dynamic column record + @param key name to find - int2store(key, num); - entry= bsearch(key, header, (size_t)column_count, entry_size, - &header_compar); - if (!entry) + @return pointer to the entry or NULL +*/ +static uchar *find_entry_str(DYN_HEADER *hdr, LEX_STRING *key) +{ + uchar *min= hdr->header; + uchar *max= hdr->header + (hdr->column_count - 1) * hdr->entry_size; + uchar *mid; + DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); + DBUG_ASSERT(hdr->nmpool != NULL); + while (max >= min) { - /* Column not found */ - *type= DYN_COL_NULL; - *entry_pos= NULL; - return 0; + uint len; + int cmp; + mid= hdr->header + ((min - hdr->header) + (max - hdr->header)) / 2 / hdr->entry_size * hdr->entry_size; + len= mid[0]; + cmp= len - key->length; + if (cmp == 0) + cmp= memcmp(hdr->nmpool + uint2korr(mid + 1), key->str, len); + if (cmp < 0) + min= mid + hdr->entry_size; + else if (cmp > 0) + max= mid - hdr->entry_size; + else + return mid; } - type_and_offset_read(type, &offset, entry, offset_size); - total_data= data_end - (header + header_size); - if (offset > total_data) - return 1; - *data= header + header_size + offset; - *length= get_length(entry, header + header_size, offset_size, - total_data); - /* - Check that the found data is withing the ranges. This can happen if - we get data with wrong offsets. - */ - if ((long) *length < 0 || offset + *length > total_data) - return 1; - - *entry_pos= entry; - return 0; + return NULL; } /** - Read and check the header of the dynamic string - - @param str Dynamic string + Write number in the buffer (backward direction - starts from the buffer end) - @retval FALSE OK - @retval TRUE error - - Note - We don't check for str->length == 0 as all code that calls this - already have handled this case. + @return pointer on the number begining */ -static inline my_bool read_fixed_header(DYNAMIC_COLUMN *str, - size_t *offset_size, - uint *column_count) +static char *backwritenum(char *chr, uint numkey) { - DBUG_ASSERT(str != NULL && str->length != 0); - if ((str->length < FIXED_HEADER_SIZE) || - (str->str[0] & (~DYNCOL_FLG_KNOWN))) - return 1; /* Wrong header */ - *offset_size= (str->str[0] & DYNCOL_FLG_OFFSET) + 1; - *column_count= uint2korr(str->str + 1); - return 0; -} - + if (numkey == 0) + *(--chr)= '0'; + else + while (numkey > 0) + { + *(--chr)= '0' + numkey % 10; + numkey/= 10; + } + return chr; +} + + +/** + Find column and fill information about it + + @param hdr descriptor of dynamic column record + @param numkey Number of the column to fetch (if strkey is NULL) + @param strkey Name of the column to fetch (or NULL) + + @return 0 ok + @return 1 error in data +*/ + +static my_bool +find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey) +{ + LEX_STRING nmkey; + char nmkeybuff[6]; /* to fit max 2 bytes number */ + DBUG_ASSERT(hdr->header != NULL); + + if (hdr->header + hdr->header_size > hdr->data_end) + return TRUE; + + /* fix key */ + if (hdr->format == DYNCOL_FMT_NUM && strkey != NULL) + { + char *end; + numkey= (uint) strtoul(strkey->str, &end, 10); + if (end != strkey->str + strkey->length) + { + /* we can't find non-numeric key among numeric ones */ + hdr->type= DYN_COL_NULL; + return 0; + } + } + else if (hdr->format == DYNCOL_FMT_STR && strkey == NULL) + { + nmkey.str= backwritenum(nmkeybuff + sizeof(nmkeybuff), numkey); + nmkey.length= (nmkeybuff + sizeof(nmkeybuff)) - nmkey.str; + strkey= &nmkey; + } + if (hdr->format == DYNCOL_FMT_NUM) + hdr->entry= find_entry_num(hdr, numkey); + else + hdr->entry= find_entry_str(hdr, strkey); + + if (!hdr->entry) + { + /* Column not found */ + hdr->type= DYN_COL_NULL; + return 0; + } + hdr->length= hdr_interval_length(hdr, hdr->entry + hdr->entry_size); + hdr->data= hdr->dtpool + hdr->offset; + /* + Check that the found data is withing the ranges. This can happen if + we get data with wrong offsets. + */ + if (hdr->length == DYNCOL_OFFSET_ERROR || + hdr->length > INT_MAX || hdr->offset > hdr->data_size) + return 1; + + return 0; +} + + +/** + Read and check the header of the dynamic string + + @param hdr descriptor of dynamic column record + @param str Dynamic string + + @retval FALSE OK + @retval TRUE error + + Note + We don't check for str->length == 0 as all code that calls this + already have handled this case. +*/ + +static inline my_bool read_fixed_header(DYN_HEADER *hdr, + DYNAMIC_COLUMN *str) +{ + DBUG_ASSERT(str != NULL && str->length != 0); + if ((str->length < 1) || + (str->str[0] & (~DYNCOL_FLG_KNOWN))) + return 1; + hdr->format= ((str->str[0] & DYNCOL_FLG_NAMES) ? + DYNCOL_FMT_STR: + DYNCOL_FMT_NUM); + if ((str->length < fmt_data[hdr->format].fixed_hdr)) + return 1; /* Wrong header */ + hdr->offset_size= (str->str[0] & DYNCOL_FLG_OFFSET) + 1; + hdr->column_count= uint2korr(str->str + 1); + if (hdr->format == DYNCOL_FMT_STR) + hdr->nmpool_size= uint2korr(str->str + 3); + else + hdr->nmpool_size= 0; + return 0; +} + /** - Get dynamic column value + Get dynamic column value by column number @param str The packed string to extract the column @param column_nr Number of column to fetch @@ -1378,226 +1856,232 @@ static inline my_bool read_fixed_header(DYNAMIC_COLUMN *str, @return ER_DYNCOL_* return code */ -int dynamic_column_get(DYNAMIC_COLUMN *str, uint column_nr, +enum enum_dyncol_func_result +dynamic_column_get(DYNAMIC_COLUMN *str, uint column_nr, DYNAMIC_COLUMN_VALUE *store_it_here) { - uchar *data; - size_t offset_size, length; - uint column_count; - enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT; + return dynamic_column_get_internal(str, store_it_here, column_nr, NULL); +} - if (str->length == 0) - goto null; - if (read_fixed_header(str, &offset_size, &column_count)) - goto err; +/** + Get dynamic column value by name - if (column_count == 0) - goto null; + @param str The packed string to extract the column + @param name Name of column to fetch + @param store_it_here Where to store the extracted value - if (find_column(&store_it_here->type, &data, &length, - (uchar*)str->str + FIXED_HEADER_SIZE, - offset_size, column_count, (uchar*)str->str + str->length, - column_nr, NULL)) - goto err; + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_get_str(DYNAMIC_COLUMN *str, LEX_STRING *name, + DYNAMIC_COLUMN_VALUE *store_it_here) +{ + DBUG_ASSERT(name != NULL); + return dynamic_column_get_internal(str, store_it_here, 0, name); +} - switch (store_it_here->type) { + +/** + Get dynamic column value by number or name + + @param str The packed string to extract the column + @param key Name or number of column to fetch + (depends on string_key) + @param store_it_here Where to store the extracted value + @param string_key True if we gave pointer to LEX_STRING. + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_get_fmt(DYNAMIC_COLUMN *str, void *key, + DYNAMIC_COLUMN_VALUE *store_it_here, + my_bool string_key) +{ + DBUG_ASSERT(key != NULL); + if (string_key) + return dynamic_column_get_internal(str, store_it_here, + 0, (LEX_STRING *)key); + return dynamic_column_get_internal(str, store_it_here, + *((uint *)key), NULL); +} + +static enum enum_dyncol_func_result +dynamic_column_get_value(DYN_HEADER *hdr, DYNAMIC_COLUMN_VALUE *store_it_here) +{ + static enum enum_dyncol_func_result rc; + switch ((store_it_here->type= hdr->type)) { case DYN_COL_INT: - rc= dynamic_column_sint_read(store_it_here, data, length); + rc= dynamic_column_sint_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_UINT: - rc= dynamic_column_uint_read(store_it_here, data, length); + rc= dynamic_column_uint_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_DOUBLE: - rc= dynamic_column_double_read(store_it_here, data, length); + rc= dynamic_column_double_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_STRING: - rc= dynamic_column_string_read(store_it_here, data, length); + rc= dynamic_column_string_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_DECIMAL: - rc= dynamic_column_decimal_read(store_it_here, data, length); + rc= dynamic_column_decimal_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_DATETIME: - rc= dynamic_column_date_time_read(store_it_here, data, length); + rc= dynamic_column_date_time_read(store_it_here, hdr->data, + hdr->length); break; case DYN_COL_DATE: - rc= dynamic_column_date_read(store_it_here, data, length); + rc= dynamic_column_date_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_TIME: - rc= dynamic_column_time_read(store_it_here, data, length); + rc= dynamic_column_time_read(store_it_here, hdr->data, hdr->length); break; case DYN_COL_NULL: rc= ER_DYNCOL_OK; break; default: - goto err; + rc= ER_DYNCOL_FORMAT; + store_it_here->type= DYN_COL_NULL; + break; } return rc; - -null: - rc= ER_DYNCOL_OK; -err: - store_it_here->type= DYN_COL_NULL; - return rc; } /** - Delete column with given number from the packed string + Get dynamic column value by number or name - @param str The packed string to delete the column - @param column_nr Number of column to delete + @param str The packed string to extract the column + @param store_it_here Where to store the extracted value + @param numkey Number of the column to fetch (if strkey is NULL) + @param strkey Name of the column to fetch (or NULL) @return ER_DYNCOL_* return code */ -int dynamic_column_delete(DYNAMIC_COLUMN *str, uint column_nr) +static enum enum_dyncol_func_result +dynamic_column_get_internal(DYNAMIC_COLUMN *str, + DYNAMIC_COLUMN_VALUE *store_it_here, + uint num_key, LEX_STRING *str_key) { - uchar *data, *header_entry, *read, *write; - size_t offset_size, new_offset_size, length, entry_size, new_entry_size, - header_size, new_header_size, data_size, new_data_size, - deleted_entry_offset; - uint column_count, i; - DYNAMIC_COLUMN_TYPE type; + DYN_HEADER header; + enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT; + bzero(&header, sizeof(header)); if (str->length == 0) - return ER_DYNCOL_OK; /* no columns */ - - if (read_fixed_header(str, &offset_size, &column_count)) - return ER_DYNCOL_FORMAT; + goto null; - if (column_count == 0) - { - str->length= 0; - return ER_DYNCOL_OK; /* no columns */ - } + if ((rc= init_read_hdr(&header, str)) < 0) + goto err; - if (find_column(&type, &data, &length, (uchar*)str->str + FIXED_HEADER_SIZE, - offset_size, column_count, (uchar*)str->str + str->length, - column_nr, &header_entry)) - return ER_DYNCOL_FORMAT; + if (header.column_count == 0) + goto null; - if (type == DYN_COL_NULL) - return ER_DYNCOL_OK; /* no such column */ + if (find_column(&header, num_key, str_key)) + goto err; - if (column_count == 1) - { - /* delete the only column; Return empty string */ - str->length= 0; - return ER_DYNCOL_OK; - } + rc= dynamic_column_get_value(&header, store_it_here); + return rc; - /* Calculate entry_size and header_size */ - calc_param(&entry_size, &header_size, offset_size, column_count); - data_size= str->length - FIXED_HEADER_SIZE - header_size; +null: + rc= ER_DYNCOL_OK; +err: + store_it_here->type= DYN_COL_NULL; + return rc; +} - new_data_size= data_size - length; - if ((new_offset_size= dynamic_column_offset_bytes(new_data_size)) >= - MAX_OFFSET_LENGTH) - return ER_DYNCOL_LIMIT; - DBUG_ASSERT(new_offset_size <= offset_size); - calc_param(&new_entry_size, &new_header_size, - new_offset_size, column_count - 1); +/** + Check existence of the column in the packed string (by number) - deleted_entry_offset= ((data - (uchar*) str->str) - - header_size - FIXED_HEADER_SIZE); + @param str The packed string to check the column + @param column_nr Number of column to check - /* rewrite header*/ - set_fixed_header(str, new_offset_size, column_count - 1); - for (i= 0, write= read= (uchar *)str->str + FIXED_HEADER_SIZE; - i < column_count; - i++, read+= entry_size, write+= new_entry_size) - { - size_t offs; - uint nm; - DYNAMIC_COLUMN_TYPE tp; - if (read == header_entry) - { -#ifndef DBUG_OFF - nm= uint2korr(read); - type_and_offset_read(&tp, &offs, read, - offset_size); - DBUG_ASSERT(nm == column_nr); - DBUG_ASSERT(offs == deleted_entry_offset); -#endif - write-= new_entry_size; /* do not move writer */ - continue; /* skip removed field */ - } + @return ER_DYNCOL_* return code +*/ - nm= uint2korr(read), - type_and_offset_read(&tp, &offs, read, - offset_size); +enum enum_dyncol_func_result +dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr) +{ + return dynamic_column_exists_internal(str, column_nr, NULL); +} - if (offs > deleted_entry_offset) - offs-= length; /* data stored after removed data */ - int2store(write, nm); - type_and_offset_store(write, new_offset_size, tp, offs); - } +/** + Check existence of the column in the packed string (by name) - /* move data */ - { - size_t first_chunk_len= ((data - (uchar *)str->str) - - FIXED_HEADER_SIZE - header_size); - size_t second_chunk_len= new_data_size - first_chunk_len; - if (first_chunk_len) - memmove(str->str + FIXED_HEADER_SIZE + new_header_size, - str->str + FIXED_HEADER_SIZE + header_size, - first_chunk_len); - if (second_chunk_len) - memmove(str->str + - FIXED_HEADER_SIZE + new_header_size + first_chunk_len, - str->str + - FIXED_HEADER_SIZE + header_size + first_chunk_len + length, - second_chunk_len); - } + @param str The packed string to check the column + @param name Name of column to check - /* fix str length */ - DBUG_ASSERT(str->length >= - FIXED_HEADER_SIZE + new_header_size + new_data_size); - str->length= FIXED_HEADER_SIZE + new_header_size + new_data_size; + @return ER_DYNCOL_* return code +*/ - return ER_DYNCOL_OK; +enum enum_dyncol_func_result +dynamic_column_exists_str(DYNAMIC_COLUMN *str, LEX_STRING *name) +{ + DBUG_ASSERT(name != NULL); + return dynamic_column_exists_internal(str, 0, name); } /** - Check existence of the column in the packed string + Check existence of the column in the packed string (by name of number) @param str The packed string to check the column - @param column_nr Number of column to check + @param key Name or number of column to fetch + (depends on string_key) + @param string_key True if we gave pointer to LEX_STRING. @return ER_DYNCOL_* return code */ enum enum_dyncol_func_result -dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr) +dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_key) { - uchar *data; - size_t offset_size, length; - uint column_count; - DYNAMIC_COLUMN_TYPE type; + DBUG_ASSERT(key != NULL); + if (string_key) + return dynamic_column_exists_internal(str, 0, (LEX_STRING *) key); + return dynamic_column_exists_internal(str, *((uint *)key), NULL); +} + + +/** + Check existence of the column in the packed string (by name of number) + + @param str The packed string to check the column + @param num_key Number of the column to fetch (if strkey is NULL) + @param str_key Name of the column to fetch (or NULL) + + @return ER_DYNCOL_* return code +*/ + +static enum enum_dyncol_func_result +dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, + LEX_STRING *str_key) +{ + DYN_HEADER header; + enum enum_dyncol_func_result rc; + bzero(&header, sizeof(header)); if (str->length == 0) return ER_DYNCOL_NO; /* no columns */ - if (read_fixed_header(str, &offset_size, &column_count)) - return ER_DYNCOL_FORMAT; + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; - if (column_count == 0) + if (header.column_count == 0) return ER_DYNCOL_NO; /* no columns */ - if (find_column(&type, &data, &length, (uchar*)str->str + FIXED_HEADER_SIZE, - offset_size, column_count, (uchar*)str->str + str->length, - column_nr, NULL)) + if (find_column(&header, num_key, str_key)) return ER_DYNCOL_FORMAT; - return (type != DYN_COL_NULL ? ER_DYNCOL_YES : ER_DYNCOL_NO); + return (header.type != DYN_COL_NULL ? ER_DYNCOL_YES : ER_DYNCOL_NO); } /** - List not-null columns in the packed string + List not-null columns in the packed string (only numeric foemat) @param str The packed string @param array_of_uint Where to put reference on created array @@ -1608,28 +2092,31 @@ dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr) enum enum_dyncol_func_result dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) { + DYN_HEADER header; uchar *read; - size_t offset_size, entry_size; - uint column_count, i; + uint i; + enum enum_dyncol_func_result rc; bzero(array_of_uint, sizeof(*array_of_uint)); /* In case of errors */ if (str->length == 0) return ER_DYNCOL_OK; /* no columns */ - if (read_fixed_header(str, &offset_size, &column_count)) - return ER_DYNCOL_FORMAT; + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; - entry_size= COLUMN_NUMBER_SIZE + offset_size; + if (header.format != DYNCOL_FMT_NUM) + return ER_DYNCOL_FORMAT; - if (entry_size * column_count + FIXED_HEADER_SIZE > str->length) + if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > + str->length) return ER_DYNCOL_FORMAT; - if (init_dynamic_array(array_of_uint, sizeof(uint), column_count, 0)) + if (init_dynamic_array(array_of_uint, sizeof(uint), header.column_count, 0)) return ER_DYNCOL_RESOURCE; - for (i= 0, read= (uchar *)str->str + FIXED_HEADER_SIZE; - i < column_count; - i++, read+= entry_size) + for (i= 0, read= header.header; + i < header.column_count; + i++, read+= header.entry_size) { uint nm= uint2korr(read); /* Insert can't never fail as it's pre-allocated above */ @@ -1639,84 +2126,764 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) } +/** + List not-null columns in the packed string (any format) + + @param str The packed string + @param array_of_lexstr Where to put reference on created array + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr) +{ + DYN_HEADER header; + uchar *read; + struct st_service_funcs *fmt; + uint i; + enum enum_dyncol_func_result rc; + + bzero(array_of_lexstr, sizeof(*array_of_lexstr)); /* In case of errors */ + if (str->length == 0) + return ER_DYNCOL_OK; /* no columns */ + + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; + + fmt= fmt_data + header.format; + + if (header.entry_size * header.column_count + fmt->fixed_hdr > + str->length) + return ER_DYNCOL_FORMAT; + + if (init_dynamic_array(array_of_lexstr, sizeof(LEX_STRING), + header.column_count, 0)) + return ER_DYNCOL_RESOURCE; + + for (i= 0, read= header.header; + i < header.column_count; + i++, read+= header.entry_size) + { + LEX_STRING tmp; + if (header.format == DYNCOL_FMT_NUM) + { + uint nm= uint2korr(read); + tmp.str= my_malloc(6, MYF(0)); + if (!tmp.str) + return ER_DYNCOL_RESOURCE; + tmp.length= snprintf(tmp.str, 6, "%u", nm); + } + else + { + tmp.length= read[0]; + tmp.str= my_malloc(tmp.length + 1, MYF(0)); + if(!tmp.str) + return ER_DYNCOL_RESOURCE; + memcpy(tmp.str, (const void *)header.nmpool + uint2korr(read + 1), + tmp.length); + tmp.str[tmp.length]= '\0'; // just for safety + } + /* Insert can't never fail as it's pre-allocated above */ + (void) insert_dynamic(array_of_lexstr, (uchar *)&tmp); + } + return ER_DYNCOL_OK; +} + /** Find the place of the column in the header or place where it should be put - @param num Number of the column - @param header Pointer to the header - @param entry_size Size of a header entry - @param column_count Number of columns in the packed string - @param entry Return pointer to the entry or next entry + @param hdr descriptor of dynamic column record + @param key Name or number of column to fetch + (depends on string_key) + @param string_key True if we gave pointer to LEX_STRING. @retval TRUE found @retval FALSE pointer set to the next row */ static my_bool -find_place(uint num, uchar *header, size_t entry_size, - uint column_count, uchar **entry) +find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) { uint mid, start, end, val; int flag; + LEX_STRING str; + char buff[6]; + my_bool need_conversion= ((string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM) != + hdr->format); LINT_INIT(flag); /* 100 % safe */ + /* new format can't be numeric if the old one is names */ + DBUG_ASSERT(string_keys || + hdr->format == DYNCOL_FMT_NUM); + + start= 0; + end= hdr->column_count -1; + mid= 1; + while (start != end) + { + uint val; + mid= (start + end) / 2; + hdr->entry= hdr->header + mid * hdr->entry_size; + if (!string_keys) + { + val= uint2korr(hdr->entry); + flag= CMP_NUM(*((uint *)key), val); + } + else + { + if (need_conversion) + { + str.str= backwritenum(buff + sizeof(buff), uint2korr(hdr->entry)); + str.length= (buff + sizeof(buff)) - str.str; + } + else + { + DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); + str.length= hdr->entry[0]; + str.str= (char *)hdr->nmpool + uint2korr(hdr->entry + 1); + } + flag= ((LEX_STRING *) key)->length - str.length; + if (flag == 0) + flag= memcmp(((LEX_STRING *) key)->str, str.str, str.length); + } + if (flag <= 0) + end= mid; + else + start= mid + 1; + } + hdr->entry= hdr->header + start * hdr->entry_size; + if (start != mid) + { + if (!string_keys) + { + val= uint2korr(hdr->entry); + flag= CMP_NUM(*((uint *)key), val); + } + else + { + if (need_conversion) + { + str.str= backwritenum(buff + sizeof(buff), uint2korr(hdr->entry)); + str.length= (buff + sizeof(buff)) - str.str; + } + else + { + DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); + str.length= hdr->entry[0]; + str.str= (char*) hdr->nmpool + uint2korr(hdr->entry + 1); + } + flag= ((LEX_STRING *) key)->length - str.length; + if (flag == 0) + flag= memcmp(((LEX_STRING *) key)->str, str.str, str.length); + } + } + if (flag > 0) + hdr->entry+= hdr->entry_size; /* Point at next bigger key */ + return flag == 0; +} + + +/* + It is internal structure which describes plan of chenging the record + of dynamic columns +*/ + +typedef enum {PLAN_REPLACE, PLAN_ADD, PLAN_DELETE, PLAN_NOP} PLAN_ACT; + +struct st_plan { + DYNAMIC_COLUMN_VALUE *val; + void *key; + uchar *place; + size_t length; + int hdelta, ddelta, ndelta; + uint mv_offset, mv_length, mv_end; + PLAN_ACT act; +}; +typedef struct st_plan PLAN; + + +/** + Sort function for plan by column number +*/ + +static int plan_sort_num(const void *a, const void *b) +{ + return *((uint *)((PLAN *)a)->key) - *((uint *)((PLAN *)b)->key); +} + + +/** + Sort function for plan by column name +*/ + +static int plan_sort_str(const void *a, const void *b) +{ + int res= (((LEX_STRING *)((PLAN *)a)->key)->length - + ((LEX_STRING *)((PLAN *)b)->key)->length); + if (res == 0) + res= memcmp(((LEX_STRING *)((PLAN *)a)->key)->str, + ((LEX_STRING *)((PLAN *)b)->key)->str, + ((LEX_STRING *)((PLAN *)a)->key)->length); + return res; +} + +#define DELTA_CHECK(S, D, C) \ + if ((S) == 0) \ + (S)= (D); \ + else if (((S) > 0 && (D) < 0) || \ + ((S) < 0 && (D) > 0)) \ + { \ + (C)= TRUE; \ + } + +/** + Update dynamic column by copying in a new record (string). + + @param str Dynamic column record to change + @param plan Plan of changing the record + @param add_column_count number of records in the plan array. + @param hdr descriptor of old dynamic column record + @param new_hdr descriptor of new dynamic column record + @param convert need conversion from numeric to names format + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, + uint add_column_count, + DYN_HEADER *hdr, DYN_HEADER *new_hdr, + my_bool convert) +{ + DYNAMIC_COLUMN tmp; + struct st_service_funcs *fmt= fmt_data + hdr->format, + *new_fmt= fmt_data + new_hdr->format; + uint i, j, k; + size_t all_headers_size; + + if (dynamic_column_init_str(&tmp, + (new_fmt->fixed_hdr + new_hdr->header_size + + new_hdr->nmpool_size + + new_hdr->data_size + DYNCOL_SYZERESERVE))) + { + return ER_DYNCOL_RESOURCE; + } + bzero(tmp.str, new_fmt->fixed_hdr); + (*new_fmt->set_fixed_hdr)(&tmp, new_hdr); + /* Adjust tmp to contain whole the future header */ + tmp.length= new_fmt->fixed_hdr + new_hdr->header_size + new_hdr->nmpool_size; + + + /* + Copy data to the new string + i= index in array of changes + j= index in packed string header index + */ + new_hdr->entry= new_hdr->header; + new_hdr->name= new_hdr->nmpool; + all_headers_size= new_fmt->fixed_hdr + + new_hdr->header_size + new_hdr->nmpool_size; + for (i= 0, j= 0; i < add_column_count || j < hdr->column_count; i++) + { + size_t first_offset; + uint start= j, end; + LINT_INIT(first_offset); + + /* + Search in i and j for the next column to add from i and where to + add. + */ + + while (i < add_column_count && plan[i].act == PLAN_NOP) + i++; /* skip NOP */ + + if (i == add_column_count) + j= end= hdr->column_count; + else + { + /* + old data portion. We don't need to check that j < column_count + as plan[i].place is guaranteed to have a pointer inside the + data. + */ + while (hdr->header + j * hdr->entry_size < plan[i].place) + j++; + end= j; + if ((plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) + j++; /* data at 'j' will be removed */ + } + + /* + Adjust all headers since last loop. + We have to do this as the offset for data has moved + */ + for (k= start; k < end; k++) + { + uchar *read= hdr->header + k * hdr->entry_size; + void *key; + LEX_STRING name; + size_t offs; + uint nm; + DYNAMIC_COLUMN_TYPE tp; + char buff[6]; + + if (hdr->format == DYNCOL_FMT_NUM) + { + if (convert) + { + name.str= backwritenum(buff + sizeof(buff), uint2korr(read)); + name.length= (buff + sizeof(buff)) - name.str; + key= &name; + } + else + { + nm= uint2korr(read); /* Column nummber */ + key= &nm; + } + } + else + { + name.length= read[0]; + name.str= (char *) hdr->nmpool + uint2korr(read + 1); + key= &name; + } + if (type_and_offset_read(&tp, &offs, + read + fmt->fixed_hdr_entry, hdr->offset_size)) + goto err; + if (k == start) + first_offset= offs; + else if (offs < first_offset) + goto err; + + offs+= plan[i].ddelta; + { + DYNAMIC_COLUMN_VALUE val; + val.type= tp; // only the type used in the header + if ((*new_fmt->put_header_entry)(new_hdr, key, &val, offs)) + goto err; + } + } + + /* copy first the data that was not replaced in original packed data */ + if (start < end) + { + size_t data_size; + /* Add old data last in 'tmp' */ + hdr->entry= hdr->header + start * hdr->entry_size; + data_size= + hdr_interval_length(hdr, hdr->header + end * hdr->entry_size); + if (data_size == DYNCOL_OFFSET_ERROR || + (long) data_size < 0 || + data_size > hdr->data_size - first_offset) + goto err; + + memcpy(tmp.str + tmp.length, (char *)hdr->dtpool + first_offset, + data_size); + tmp.length+= data_size; + } + + /* new data adding */ + if (i < add_column_count) + { + if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + { + if ((*new_fmt->put_header_entry)(new_hdr, plan[i].key, + plan[i].val, + tmp.length - all_headers_size)) + goto err; + data_store(&tmp, plan[i].val); /* Append new data */ + } + } + } + dynamic_column_column_free(str); + *str= tmp; + return ER_DYNCOL_OK; +err: + dynamic_column_column_free(&tmp); + return ER_DYNCOL_FORMAT; +} + +enum enum_dyncol_func_result +dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, + size_t offset_size, + size_t entry_size, + size_t header_size, + size_t new_offset_size, + size_t new_entry_size, + size_t new_header_size, + uint column_count, + uint new_column_count, + uint add_column_count, + uchar *header_end, + size_t max_offset) +{ + uchar *write; + uchar *header_base= (uchar *)str->str + FIXED_HEADER_SIZE; + uint i, j, k; + size_t curr_offset; + + write= (uchar *)str->str + FIXED_HEADER_SIZE; + set_fixed_header(str, new_offset_size, new_column_count); + + /* + Move headers first. + i= index in array of changes + j= index in packed string header index + */ + for (curr_offset= 0, i= 0, j= 0; + i < add_column_count || j < column_count; + i++) + { + size_t first_offset; + uint start= j, end; + LINT_INIT(first_offset); + + /* + Search in i and j for the next column to add from i and where to + add. + */ + + while (i < add_column_count && plan[i].act == PLAN_NOP) + i++; /* skip NOP */ + + if (i == add_column_count) + j= end= column_count; + else + { + /* + old data portion. We don't need to check that j < column_count + as plan[i].place is guaranteed to have a pointer inside the + data. + */ + while (header_base + j * entry_size < plan[i].place) + j++; + end= j; + if ((plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) + j++; /* data at 'j' will be removed */ + } + plan[i].mv_end= end; + + { + DYNAMIC_COLUMN_TYPE tp; + if (type_and_offset_read(&tp, &first_offset, + header_base + start * entry_size + + COLUMN_NUMBER_SIZE, offset_size)) + return ER_DYNCOL_FORMAT; + } + /* find data to be moved */ + if (start < end) + { + size_t data_size= + get_length_interval(header_base + start * entry_size, + header_base + end * entry_size, + header_end, offset_size, max_offset); + if (data_size == DYNCOL_OFFSET_ERROR || + (long) data_size < 0 || + data_size > max_offset - first_offset) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } + DBUG_ASSERT(curr_offset == first_offset + plan[i].ddelta); + plan[i].mv_offset= first_offset; + plan[i].mv_length= data_size; + curr_offset+= data_size; + } + else + { + plan[i].mv_length= 0; + plan[i].mv_offset= curr_offset; + } + + if (plan[i].ddelta == 0 && offset_size == new_offset_size && + plan[i].act != PLAN_DELETE) + write+= entry_size * (end - start); + else + { + /* + Adjust all headers since last loop. + We have to do this as the offset for data has moved + */ + for (k= start; k < end; k++) + { + uchar *read= header_base + k * entry_size; + size_t offs; + uint nm; + DYNAMIC_COLUMN_TYPE tp; + + nm= uint2korr(read); /* Column nummber */ + if (type_and_offset_read(&tp, &offs, read + COLUMN_NUMBER_SIZE, + offset_size)) + return ER_DYNCOL_FORMAT; + + if (k > start && offs < first_offset) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } + + offs+= plan[i].ddelta; + int2store(write, nm); + /* write rest of data at write + COLUMN_NUMBER_SIZE */ + type_and_offset_store(write, new_offset_size, tp, offs); + write+= new_entry_size; + } + } + + /* new data adding */ + if (i < add_column_count) + { + if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + { + int2store(write, *((uint *)plan[i].key)); + type_and_offset_store(write, new_offset_size, + plan[i].val[0].type, + curr_offset); + write+= new_entry_size; + curr_offset+= plan[i].length; + } + } + } + + /* + Move data. + i= index in array of changes + j= index in packed string header index + */ + str->length= (FIXED_HEADER_SIZE + new_header_size); + for (i= 0, j= 0; + i < add_column_count || j < column_count; + i++) + { + uint start= j, end; + + /* + Search in i and j for the next column to add from i and where to + add. + */ + + while (i < add_column_count && plan[i].act == PLAN_NOP) + i++; /* skip NOP */ + + j= end= plan[i].mv_end; + if (i != add_column_count && + (plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) + j++; + + /* copy first the data that was not replaced in original packed data */ + if (start < end && plan[i].mv_length) + { + memmove((header_base + new_header_size + + plan[i].mv_offset + plan[i].ddelta), + header_base + header_size + plan[i].mv_offset, + plan[i].mv_length); + } + str->length+= plan[i].mv_length; + + /* new data adding */ + if (i < add_column_count) + { + if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + { + data_store(str, plan[i].val); /* Append new data */ + } + } + } + return ER_DYNCOL_OK; +} + +enum enum_dyncol_func_result +dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, + size_t offset_size, + size_t entry_size, + size_t header_size, + size_t new_offset_size, + size_t new_entry_size, + size_t new_header_size, + uint column_count, + uint new_column_count, + uint add_column_count, + uchar *header_end, + size_t max_offset) +{ + uchar *write; + uchar *header_base= (uchar *)str->str + FIXED_HEADER_SIZE; + uint i, j, k; + size_t curr_offset; + + write= (uchar *)str->str + FIXED_HEADER_SIZE; + set_fixed_header(str, new_offset_size, new_column_count); + + /* + Move data first. + i= index in array of changes + j= index in packed string header index + */ + for (curr_offset= 0, i= 0, j= 0; + i < add_column_count || j < column_count; + i++) + { + size_t first_offset; + uint start= j, end; + LINT_INIT(first_offset); + + /* + Search in i and j for the next column to add from i and where to + add. + */ + + while (i < add_column_count && plan[i].act == PLAN_NOP) + i++; /* skip NOP */ + + if (i == add_column_count) + j= end= column_count; + else + { + /* + old data portion. We don't need to check that j < column_count + as plan[i].place is guaranteed to have a pointer inside the + data. + */ + while (header_base + j * entry_size < plan[i].place) + j++; + end= j; + if ((plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) + j++; /* data at 'j' will be removed */ + } + plan[i].mv_end= end; + + { + DYNAMIC_COLUMN_TYPE tp; + type_and_offset_read(&tp, &first_offset, + header_base + start * entry_size + COLUMN_NUMBER_SIZE, offset_size); + } + /* find data to be moved */ + if (start < end) + { + size_t data_size= + get_length_interval(header_base + start * entry_size, + header_base + end * entry_size, + header_end, offset_size, max_offset); + if (data_size == DYNCOL_OFFSET_ERROR || + (long) data_size < 0 || + data_size > max_offset - first_offset) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } + DBUG_ASSERT(curr_offset == first_offset + plan[i].ddelta); + plan[i].mv_offset= first_offset; + plan[i].mv_length= data_size; + curr_offset+= data_size; + } + else + { + plan[i].mv_length= 0; + plan[i].mv_offset= curr_offset; + } + + if (plan[i].ddelta == 0 && offset_size == new_offset_size && + plan[i].act != PLAN_DELETE) + write+= entry_size * (end - start); + else + { + /* + Adjust all headers since last loop. + We have to do this as the offset for data has moved + */ + for (k= start; k < end; k++) + { + uchar *read= header_base + k * entry_size; + size_t offs; + uint nm; + DYNAMIC_COLUMN_TYPE tp; + + nm= uint2korr(read); /* Column nummber */ + type_and_offset_read(&tp, &offs, read + COLUMN_NUMBER_SIZE, offset_size); + if (k > start && offs < first_offset) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } - start= 0; - end= column_count -1; - mid= 1; - while (start != end) - { - uint val; - mid= (start + end) / 2; - val= uint2korr(header + mid * entry_size); - if ((flag= CMP_NUM(num, val)) <= 0) - end= mid; - else - start= mid + 1; - } - if (start != mid) - { - val= uint2korr(header + start * entry_size); - flag= CMP_NUM(num, val); + offs+= plan[i].ddelta; + int2store(write, nm); + /* write rest of data at write + COLUMN_NUMBER_SIZE */ + if (type_and_offset_store(write, new_offset_size, tp, offs)) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } + write+= new_entry_size; + } + } + + /* new data adding */ + if (i < add_column_count) + { + if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + { + int2store(write, *((uint *)plan[i].key)); + if (type_and_offset_store(write, new_offset_size, + plan[i].val[0].type, + curr_offset)) + { + str->length= 0; // just something valid + return ER_DYNCOL_FORMAT; + } + write+= new_entry_size; + curr_offset+= plan[i].length; + } + } } - *entry= header + start * entry_size; - if (flag > 0) - *entry+= entry_size; /* Point at next bigger key */ - return flag == 0; -} + /* + Move headers. + i= index in array of changes + j= index in packed string header index + */ + str->length= (FIXED_HEADER_SIZE + new_header_size); + for (i= 0, j= 0; + i < add_column_count || j < column_count; + i++) + { + uint start= j, end; -/* - Description of plan of adding/removing/updating a packed string -*/ + /* + Search in i and j for the next column to add from i and where to + add. + */ -typedef enum {PLAN_REPLACE, PLAN_ADD, PLAN_DELETE, PLAN_NOP} PLAN_ACT; + while (i < add_column_count && plan[i].act == PLAN_NOP) + i++; /* skip NOP */ -struct st_plan { - DYNAMIC_COLUMN_VALUE *val; - uint *num; - uchar *place; - size_t length; - int hdelta, ddelta; - PLAN_ACT act; -}; -typedef struct st_plan PLAN; + j= end= plan[i].mv_end; + if (i != add_column_count && + (plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) + j++; + /* copy first the data that was not replaced in original packed data */ + if (start < end && plan[i].mv_length) + { + memmove((header_base + new_header_size + + plan[i].mv_offset + plan[i].ddelta), + header_base + header_size + plan[i].mv_offset, + plan[i].mv_length); + } + str->length+= plan[i].mv_length; -static int plan_sort(const void *a, const void *b) -{ - return ((PLAN *)a)->num[0] - ((PLAN *)b)->num[0]; + /* new data adding */ + if (i < add_column_count) + { + if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + { + data_store(str, plan[i].val); /* Append new data */ + } + } + } + return ER_DYNCOL_OK; } -#define DELTA_CHECK(S, D, C) \ - if ((S) == 0) \ - (S)= (D); \ - else if (((S) > 0 && (D) < 0) || \ - ((S) < 0 && (D) > 0)) \ - { \ - (C)= TRUE; \ - break; \ - } \ - /** Update the packed string with the given columns @@ -1728,6 +2895,8 @@ static int plan_sort(const void *a, const void *b) @return ER_DYNCOL_* return code */ +/* plan allocated on the stack */ +#define IN_PLACE_PLAN 4 enum enum_dyncol_func_result dynamic_column_update_many(DYNAMIC_COLUMN *str, @@ -1735,39 +2904,75 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, uint *column_numbers, DYNAMIC_COLUMN_VALUE *values) { - PLAN *plan; - uchar *header_end; - long data_delta= 0; - uint i, j, k; - uint new_column_count, column_count, not_null; + return dynamic_column_update_many_fmt(str, add_column_count, column_numbers, + values, FALSE); +} + +uint numlen(uint val) +{ + uint res; + if (val == 0) + return 1; + res= 0; + while(val) + { + res++; + val/=10; + } + return res; +} + +enum enum_dyncol_func_result +dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, + uint add_column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool string_keys) +{ + PLAN *plan, *alloc_plan= NULL, in_place_plan[IN_PLACE_PLAN]; + uchar *element; + DYN_HEADER header, new_header; + struct st_service_funcs *fmt, *new_fmt; + long data_delta= 0, name_delta= 0; + uint i; + uint not_null; + int header_delta= 0; + int copy= FALSE; + int header_delta_sign, data_delta_sign; enum enum_dyncol_func_result rc; - int header_delta; - size_t offset_size, entry_size, header_size, data_size; - size_t new_offset_size, new_entry_size, new_header_size, new_data_size; - size_t max_offset; + my_bool convert; if (add_column_count == 0) return ER_DYNCOL_OK; + bzero(&header, sizeof(header)); + bzero(&new_header, sizeof(new_header)); + new_header.format= (string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM); + new_fmt= fmt_data + new_header.format; + /* Get columns in column order. As the data in 'str' is already in column order this allows to replace all columns in one loop. */ - - if (!(plan= my_malloc(sizeof(PLAN) * (add_column_count + 1), MYF(0)))) + if (IN_PLACE_PLAN > add_column_count) + plan= in_place_plan; + else if (!(alloc_plan= plan= + my_malloc(sizeof(PLAN) * (add_column_count + 1), MYF(0)))) return ER_DYNCOL_RESOURCE; not_null= add_column_count; - for (i= 0; i < add_column_count; i++) + for (i= 0, element= (uchar *) column_keys; + i < add_column_count; + i++, element+= new_fmt->key_size_in_array) { - if (column_numbers[i] > UINT_MAX16) + if ((*new_fmt->check_limit)(&element)) { rc= ER_DYNCOL_DATA; goto end; } plan[i].val= values + i; - plan[i].num= column_numbers + i; + plan[i].key= element; if (values[i].type == DYN_COL_NULL) not_null--; @@ -1783,22 +2988,32 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, } /* Check that header is ok */ - if (read_fixed_header(str, &offset_size, &column_count)) - { - rc= ER_DYNCOL_FORMAT; + if ((rc= init_read_hdr(&header, str)) < 0) goto end; - } - if (column_count == 0) + fmt= fmt_data + header.format; + /* new format can't be numeric if the old one is names */ + DBUG_ASSERT(new_header.format == DYNCOL_FMT_STR || + header.format == DYNCOL_FMT_NUM); + if (header.column_count == 0) goto create_new_string; - qsort(plan, (size_t)add_column_count, sizeof(PLAN), &plan_sort); + qsort(plan, (size_t)add_column_count, sizeof(PLAN), new_fmt->plan_sort); - new_column_count= column_count; - calc_param(&entry_size, &header_size, offset_size, column_count); - max_offset= str->length - (FIXED_HEADER_SIZE + header_size); - header_end= (uchar*) str->str + FIXED_HEADER_SIZE + header_size; + new_header.column_count= header.column_count; + new_header.nmpool_size= header.nmpool_size; + if ((convert= (new_header.format == DYNCOL_FMT_STR && + header.format == DYNCOL_FMT_NUM))) + { + DBUG_ASSERT(new_header.nmpool_size == 0); + for(i= 0, header.entry= header.header; + i < header.column_count; + i++, header.entry+= header.entry_size) + { + new_header.nmpool_size+= numlen(uint2korr(header.entry)); + } + } - if (header_size + FIXED_HEADER_SIZE > str->length) + if (fmt->fixed_hdr + header.header_size + header.nmpool_size > str->length) { rc= ER_DYNCOL_FORMAT; goto end; @@ -1808,17 +3023,15 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, Calculate how many columns and data is added/deleted and make a 'plan' for each of them. */ - header_delta= 0; for (i= 0; i < add_column_count; i++) { - uchar *entry; - /* For now we don't allow creating two columns with the same number at the time of create. This can be fixed later to just use the later by comparing the pointers. */ - if (i < add_column_count - 1 && plan[i].num[0] == plan[i + 1].num[0]) + if (i < add_column_count - 1 && + new_fmt->column_sort(&plan[i].key, &plan[i + 1].key) == 0) { rc= ER_DYNCOL_DATA; goto end; @@ -1826,26 +3039,36 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, /* Set common variables for all plans */ plan[i].ddelta= data_delta; + plan[i].ndelta= name_delta; /* get header delta in entries */ plan[i].hdelta= header_delta; plan[i].length= 0; /* Length if NULL */ - if (find_place(plan[i].num[0], - (uchar *)str->str + FIXED_HEADER_SIZE, - entry_size, column_count, &entry)) + if (find_place(&header, plan[i].key, string_keys)) { - size_t entry_data_size; + size_t entry_data_size, entry_name_size= 0; /* Data existed; We have to replace or delete it */ - entry_data_size= get_length(entry, header_end, - offset_size, max_offset); - if ((long) entry_data_size < 0) + entry_data_size= hdr_interval_length(&header, header.entry + + header.entry_size); + if (entry_data_size == DYNCOL_OFFSET_ERROR || + (long) entry_data_size < 0) { rc= ER_DYNCOL_FORMAT; goto end; } + //get_length(header.entry, header.dtpool, header.offset_size, + //header.data_size); + if (new_header.format == DYNCOL_FMT_STR) + { + if (header.format == DYNCOL_FMT_STR) + entry_name_size= header.entry[0]; + else + entry_name_size= numlen(uint2korr(header.entry)); + } + if (plan[i].val->type == DYN_COL_NULL) { /* Inserting a NULL means delete the old data */ @@ -1853,6 +3076,7 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, plan[i].act= PLAN_DELETE; /* Remove old value */ header_delta--; /* One row less in header */ data_delta-= entry_data_size; /* Less data to store */ + name_delta-= entry_name_size; } else { @@ -1867,6 +3091,10 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, goto end; } data_delta+= plan[i].length - entry_data_size; + if (new_header.format == DYNCOL_FMT_STR) + { + name_delta+= ((LEX_STRING *)(plan[i].key))->length - entry_name_size; + } } } else @@ -1891,219 +3119,515 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, goto end; } data_delta+= plan[i].length; + if (new_header.format == DYNCOL_FMT_STR) + name_delta+= ((LEX_STRING *)plan[i].key)->length; } } - plan[i].place= entry; + plan[i].place= header.entry; } plan[add_column_count].hdelta= header_delta; plan[add_column_count].ddelta= data_delta; - new_column_count= column_count + header_delta; + plan[add_column_count].act= PLAN_NOP; + plan[add_column_count].place= header.dtpool; + + new_header.column_count= header.column_count + header_delta; /* Check if it is only "increasing" or only "decreasing" plan for (header and data separately). */ - data_size= str->length - header_size - FIXED_HEADER_SIZE; - new_data_size= data_size + data_delta; - if ((new_offset_size= dynamic_column_offset_bytes(new_data_size)) >= + new_header.data_size= header.data_size + data_delta; + new_header.nmpool_size= new_header.nmpool_size + name_delta; + DBUG_ASSERT(new_header.format != DYNCOL_FMT_NUM || + new_header.nmpool_size == 0); + if ((new_header.offset_size= + dynamic_column_offset_bytes(new_header.data_size)) >= MAX_OFFSET_LENGTH) { rc= ER_DYNCOL_LIMIT; goto end; } -#ifdef NOT_IMPLEMENTED - /* if (new_offset_size != offset_size) then we have to rewrite header */ - header_delta_sign= new_offset_size - offset_size; + copy= ((header.format != new_header.format) || + (new_header.format == DYNCOL_FMT_STR)); + /* if (new_header.offset_size!=offset_size) then we have to rewrite header */ + header_delta_sign= + ((int)new_header.offset_size + new_fmt->fixed_hdr_entry) - + ((int)header.offset_size + fmt->fixed_hdr_entry); data_delta_sign= 0; - for (i= 0; i < add_column_count; i++) + // plan[add_column_count] contains last deltas. + for (i= 0; i <= add_column_count && !copy; i++) { /* This is the check for increasing/decreasing */ DELTA_CHECK(header_delta_sign, plan[i].hdelta, copy); DELTA_CHECK(data_delta_sign, plan[i].ddelta, copy); } -#endif - calc_param(&new_entry_size, &new_header_size, - new_offset_size, new_column_count); + calc_param(&new_header.entry_size, &new_header.header_size, + new_fmt->fixed_hdr_entry, + new_header.offset_size, new_header.column_count); /* - The following code always make a copy. In future we can do a more - optimized version when data is only increasing / decreasing. + Need copy because: + 1. Header/data parts moved in different directions. + 2. There is no enough allocated space in the string. + 3. Header and data moved in different directions. */ + if (copy || /*1*/ + str->max_length < str->length + header_delta + data_delta || /*2*/ + ((header_delta_sign < 0 && data_delta_sign > 0) || + (header_delta_sign > 0 && data_delta_sign < 0))) /*3*/ + rc= dynamic_column_update_copy(str, plan, add_column_count, + &header, &new_header, + convert); + else + if (header_delta_sign < 0) + rc= dynamic_column_update_move_left(str, plan, header.offset_size, + header.entry_size, + header.header_size, + new_header.offset_size, + new_header.entry_size, + new_header.header_size, + header.column_count, + new_header.column_count, + add_column_count, header.dtpool, + header.data_size); + else + /* + rc= dynamic_column_update_move_right(str, plan, offset_size, + entry_size, header_size, + new_header.offset_size, + new_header.entry_size, + new_heder.header_size, column_count, + new_header.column_count, + add_column_count, header_end, + header.data_size); + */ + rc= dynamic_column_update_copy(str, plan, add_column_count, + &header, &new_header, + convert); +end: + my_free(alloc_plan); + return rc; + +create_new_string: + /* There is no columns from before, so let's just add the new ones */ + rc= ER_DYNCOL_OK; + my_free(alloc_plan); + if (not_null != 0) + rc= dynamic_column_create_many_internal_fmt(str, add_column_count, + (uint*)column_keys, values, + str->str == NULL, + string_keys); + goto end; +} + + +/** + Update the packed string with the given column + + @param str String where to write the data + @param column_number Array of columns number + @param values Array of columns values + + @return ER_DYNCOL_* return code +*/ + + +int dynamic_column_update(DYNAMIC_COLUMN *str, uint column_nr, + DYNAMIC_COLUMN_VALUE *value) +{ + return dynamic_column_update_many(str, 1, &column_nr, value); +} + + +enum enum_dyncol_func_result +dynamic_column_check(DYNAMIC_COLUMN *str) +{ + struct st_service_funcs *fmt; + enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT; + DYN_HEADER header; + uint i; + size_t data_offset= 0, name_offset= 0; + size_t prev_data_offset= 0, prev_name_offset= 0; + LEX_STRING name= {0,0}, prev_name= {0,0}; + uint num= 0, prev_num= 0; + void *key, *prev_key; + enum enum_dynamic_column_type type= DYN_COL_NULL, prev_type= DYN_COL_NULL; + + DBUG_ENTER("dynamic_column_check"); - /*if (copy) */ + if (str->length == 0) { - DYNAMIC_COLUMN tmp; - uchar *header_base= (uchar *)str->str + FIXED_HEADER_SIZE, - *write; - if (dynamic_column_init_str(&tmp, - (FIXED_HEADER_SIZE + new_header_size + - new_data_size + DYNCOL_SYZERESERVE))) - { - rc= ER_DYNCOL_RESOURCE; - goto end; - } - write= (uchar *)tmp.str + FIXED_HEADER_SIZE; - /* Adjust tmp to contain whole the future header */ - tmp.length= FIXED_HEADER_SIZE + new_header_size; - set_fixed_header(&tmp, new_offset_size, new_column_count); - data_delta= 0; + DBUG_PRINT("info", ("empty string is OK")); + DBUG_RETURN(ER_DYNCOL_OK); + } - /* - Copy data to the new string - i= index in array of changes - j= index in packed string header index - */ + bzero(&header, sizeof(header)); - for (i= 0, j= 0; i < add_column_count || j < column_count; i++) - { - size_t first_offset; - uint start= j, end; - LINT_INIT(first_offset); + /* Check that header is OK */ + if (read_fixed_header(&header, str)) + { + DBUG_PRINT("info", ("Reading fixed string header failed")); + goto end; + } + fmt= fmt_data + header.format; + calc_param(&header.entry_size, &header.header_size, + fmt->fixed_hdr_entry, header.offset_size, + header.column_count); + /* headers are out of string length (no space for data and part of headers) */ + if (fmt->fixed_hdr + header.header_size + header.nmpool_size > str->length) + { + DBUG_PRINT("info", ("Fixed header: %u Header size: %u " + "Name pool size: %u but Strig length: %u", + (uint)fmt->fixed_hdr, + (uint)header.header_size, + (uint)header.nmpool_size, + (uint)str->length)); + goto end; + } + header.header= (uchar*)str->str + fmt->fixed_hdr; + header.nmpool= header.header + header.header_size; + header.dtpool= header.nmpool + header.nmpool_size; + header.data_size= str->length - fmt->fixed_hdr - + header.header_size - header.nmpool_size; + + /* read and check headers */ + if (header.format == DYNCOL_FMT_NUM) + { + key= # + prev_key= &prev_num; + } + else + { + key= &name; + prev_key= &prev_name; + } + for (i= 0, header.entry= header.header; + i < header.column_count; + i++, header.entry+= header.entry_size) + { - /* - Search in i and j for the next column to add from i and where to - add. - */ + if (header.format == DYNCOL_FMT_NUM) + { + num= uint2korr(header.entry); + } + else + { + DBUG_ASSERT(header.format == DYNCOL_FMT_STR); + name.length= header.entry[0]; + name_offset= uint2korr(header.entry + 1); + name.str= (char *)header.nmpool + name_offset; + } + if (type_and_offset_read(&type, &data_offset, + header.entry + fmt->fixed_hdr_entry, + header.offset_size)) + goto end; - while (i < add_column_count && plan[i].act == PLAN_NOP) - i++; /* skip NOP */ - if (i == add_column_count) - j= end= column_count; - else + DBUG_ASSERT(type != DYN_COL_NULL); + if (data_offset > header.data_size) + { + DBUG_PRINT("info", ("Field order: %u Data offset: %u" + " > Data pool size: %u", + (uint)i, + (uint)name_offset, + (uint)header.nmpool_size)); + goto end; + } + if (name_offset > header.nmpool_size) + { + DBUG_PRINT("info", ("Field order: %u Name offset: %u" + " > Name pool size: %u", + (uint)i, + (uint)name_offset, + (uint)header.nmpool_size)); + goto end; + } + if (prev_type != DYN_COL_NULL) + { + /* It is not first entry */ + if (prev_data_offset >= data_offset) { - /* - old data portion. We don't need to check that j < column_count - as plan[i].place is guaranteed to have a pointer inside the - data. - */ - while (header_base + j * entry_size < plan[i].place) - j++; - end= j; - if ((plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE)) - j++; /* data at 'j' will be removed */ + DBUG_PRINT("info", ("Field order: %u Previous data offset: %u" + " >= Current data offset: %u", + (uint)i, + (uint)prev_data_offset, + (uint)data_offset)); + goto end; } - - if (plan[i].ddelta == 0 && offset_size == new_offset_size) + if (prev_name_offset > name_offset) { - uchar *read= header_base + start * entry_size; - DYNAMIC_COLUMN_TYPE tp; - /* - It's safe to copy the header unchanged. This is usually the - case for the first header block before any changed data. - */ - if (start < end) /* Avoid memcpy with 0 */ - { - size_t length= entry_size * (end - start); - memcpy(write, read, length); - write+= length; - } - /* Read first_offset */ - type_and_offset_read(&tp, &first_offset, read, offset_size); + DBUG_PRINT("info", ("Field order: %u Previous name offset: %u" + " > Current name offset: %u", + (uint)i, + (uint)prev_data_offset, + (uint)data_offset)); + goto end; } - else + if ((*fmt->column_sort)(&prev_key, &key) >= 0) { - /* - Adjust all headers since last loop. - We have to do this as the offset for data has moved - */ - for (k= start; k < end; k++) - { - uchar *read= header_base + k * entry_size; - size_t offs; - uint nm; - DYNAMIC_COLUMN_TYPE tp; - - nm= uint2korr(read); /* Column nummber */ - type_and_offset_read(&tp, &offs, read, offset_size); - if (k == start) - first_offset= offs; - else if (offs < first_offset) - { - dynamic_column_column_free(&tmp); - rc= ER_DYNCOL_FORMAT; - goto end; - } - - offs+= plan[i].ddelta; - int2store(write, nm); - /* write rest of data at write + COLUMN_NUMBER_SIZE */ - type_and_offset_store(write, new_offset_size, tp, offs); - write+= new_entry_size; - } + DBUG_PRINT("info", ("Field order: %u Previous key >= Current key", + (uint)i)); + goto end; } + } + prev_num= num; + prev_name= name; + prev_data_offset= data_offset; + prev_name_offset= name_offset; + prev_type= type; + } - /* copy first the data that was not replaced in original packed data */ - if (start < end) - { - /* Add old data last in 'tmp' */ - size_t data_size= - get_length_interval(header_base + start * entry_size, - header_base + end * entry_size, - header_end, offset_size, max_offset); - if ((long) data_size < 0 || - data_size > max_offset - first_offset) - { - dynamic_column_column_free(&tmp); - rc= ER_DYNCOL_FORMAT; - goto end; - } + /* check data, which we can */ + for (i= 0, header.entry= header.header; + i < header.column_count; + i++, header.entry+= header.entry_size) + { + DYNAMIC_COLUMN_VALUE store; + // already checked by previouse pass + type_and_offset_read(&header.type, &header.offset, + header.entry + fmt->fixed_hdr_entry, + header.offset_size); + header.length= + hdr_interval_length(&header, header.entry + header.entry_size); + header.data= header.dtpool + header.offset; + switch ((header.type)) { + case DYN_COL_INT: + rc= dynamic_column_sint_read(&store, header.data, header.length); + break; + case DYN_COL_UINT: + rc= dynamic_column_uint_read(&store, header.data, header.length); + break; + case DYN_COL_DOUBLE: + rc= dynamic_column_double_read(&store, header.data, header.length); + break; + case DYN_COL_STRING: + rc= dynamic_column_string_read(&store, header.data, header.length); + break; + case DYN_COL_DECIMAL: + rc= dynamic_column_decimal_read(&store, header.data, header.length); + break; + case DYN_COL_DATETIME: + rc= dynamic_column_date_time_read(&store, header.data, + header.length); + break; + case DYN_COL_DATE: + rc= dynamic_column_date_read(&store, header.data, header.length); + break; + case DYN_COL_TIME: + rc= dynamic_column_time_read(&store, header.data, header.length); + break; + case DYN_COL_NULL: + default: + rc= ER_DYNCOL_FORMAT; + goto end; + } + if (rc != ER_DYNCOL_OK) + { + DBUG_ASSERT(rc < 0); + DBUG_PRINT("info", ("Field order: %u Can't read data: %i", + (uint)i, (int) rc)); + goto end; + } + } - memcpy(tmp.str + tmp.length, (char *)header_end + first_offset, - data_size); - tmp.length+= data_size; - } + rc= ER_DYNCOL_OK; +end: + DBUG_RETURN(rc); +} - /* new data adding */ - if (i < add_column_count) + +enum enum_dyncol_func_result +dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, + my_bool quote) +{ + char buff[40]; + int len; + switch (val->type) { + case DYN_COL_INT: + len= snprintf(buff, sizeof(buff), "%lld", val->x.long_value); + if (dynstr_append_mem(str, buff, len)) + return ER_DYNCOL_RESOURCE; + break; + case DYN_COL_UINT: + len= snprintf(buff, sizeof(buff), "%llu", val->x.ulong_value); + if (dynstr_append_mem(str, buff, len)) + return ER_DYNCOL_RESOURCE; + break; + case DYN_COL_DOUBLE: + len= snprintf(buff, sizeof(buff), "%lg", val->x.double_value); + if (dynstr_realloc(str, len + (quote ? 2 : 0))) + return ER_DYNCOL_RESOURCE; + if (quote) + str->str[str->length++]= '"'; + dynstr_append_mem(str, buff, len); + if (quote) + str->str[str->length++]= '"'; + break; + case DYN_COL_STRING: { - if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) + char *alloc= NULL; + char *from= val->x.string.value.str; + uint bufflen; + my_bool conv= !my_charset_same(val->x.string.charset, + &my_charset_utf8_general_ci); + my_bool rc; + len= val->x.string.value.length; + bufflen= (len * (conv ? my_charset_utf8_general_ci.mbmaxlen : 1)); + if (dynstr_realloc(str, bufflen)) + return ER_DYNCOL_RESOURCE; + + // guaranty UTF-8 string for value + if (!my_charset_same(val->x.string.charset, + &my_charset_utf8_general_ci)) { - int2store(write, plan[i].num[0]); - type_and_offset_store(write, new_offset_size, - plan[i].val[0].type, - tmp.length - - (FIXED_HEADER_SIZE + new_header_size)); - write+= new_entry_size; - data_store(&tmp, plan[i].val); /* Append new data */ + uint dummy_errors; + if (!quote) + { + /* convert to the destination */ + str->length+= copy_and_convert_extended(str->str, bufflen, + &my_charset_utf8_general_ci, + from, len, + val->x.string.charset, + &dummy_errors); + return ER_DYNCOL_OK; + } + if ((alloc= (char *)my_malloc(bufflen, MYF(0)))) + { + len= + copy_and_convert_extended(alloc, bufflen, + &my_charset_utf8_general_ci, + from, len, val->x.string.charset, + &dummy_errors); + from= alloc; + } + else + return ER_DYNCOL_RESOURCE; } - data_delta= plan[i].ddelta; + if (quote) + rc= dynstr_append_quoted(str, from, len); + else + rc= dynstr_append_mem(str, from, len); + if (alloc) + my_free(alloc); + if (rc) + return ER_DYNCOL_RESOURCE; + break; } - } - dynamic_column_column_free(str); - *str= tmp; + case DYN_COL_DECIMAL: + len= sizeof(buff); + decimal2string(&val->x.decimal.value, buff, &len, + 0, val->x.decimal.value.frac, + '0'); + if (dynstr_append_mem(str, buff, len)) + return ER_DYNCOL_RESOURCE; + break; + case DYN_COL_DATETIME: + case DYN_COL_DATE: + case DYN_COL_TIME: + len= my_TIME_to_str(&val->x.time_value, buff, AUTO_SEC_PART_DIGITS); + if (dynstr_realloc(str, len + (quote ? 2 : 0))) + return ER_DYNCOL_RESOURCE; + if (quote) + str->str[str->length++]= '"'; + dynstr_append_mem(str, buff, len); + if (quote) + str->str[str->length++]= '"'; + break; + case DYN_COL_NULL: + if (dynstr_append_mem(str, "null", 4)) + return ER_DYNCOL_RESOURCE; + break; + default: + return(ER_DYNCOL_FORMAT); } - - rc= ER_DYNCOL_OK; - -end: - my_free(plan); - return rc; - -create_new_string: - /* There is no columns from before, so let's just add the new ones */ - rc= ER_DYNCOL_OK; - if (not_null != 0) - rc= dynamic_column_create_many_internal(str, add_column_count, - column_numbers, values, - str->str == NULL); - goto end; + return(ER_DYNCOL_OK); } - /** - Update the packed string with the given column + Convert to JSON - @param str String where to write the data - @param column_number Array of columns number - @param values Array of columns values + @param str The packed string + @param json Where to put json result @return ER_DYNCOL_* return code */ - -int dynamic_column_update(DYNAMIC_COLUMN *str, uint column_nr, - DYNAMIC_COLUMN_VALUE *value) +enum enum_dyncol_func_result +dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) { - return dynamic_column_update_many(str, 1, &column_nr, value); + DYN_HEADER header; + uint i; + enum enum_dyncol_func_result rc; + + bzero(json, sizeof(DYNAMIC_STRING)); /* In case of errors */ + if (str->length == 0) + return ER_DYNCOL_OK; /* no columns */ + + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; + + if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > + str->length) + return ER_DYNCOL_FORMAT; + + if (init_dynamic_string(json, NULL, str->length * 2, 100)) + return ER_DYNCOL_RESOURCE; + + if (dynstr_append_mem(json, "[", 1)) + return ER_DYNCOL_RESOURCE; + rc= ER_DYNCOL_RESOURCE; + for (i= 0, header.entry= header.header; + i < header.column_count; + i++, header.entry+= header.entry_size) + { + DYNAMIC_COLUMN_VALUE val; + if (i != 0 && dynstr_append_mem(json, ",", 1)) + goto err; + header.length= + hdr_interval_length(&header, header.entry + header.entry_size); + header.data= header.dtpool + header.offset; + /* + Check that the found data is withing the ranges. This can happen if + we get data with wrong offsets. + */ + if (header.length == DYNCOL_OFFSET_ERROR || + header.length > INT_MAX || header.offset > header.data_size) + { + rc= ER_DYNCOL_FORMAT; + goto err; + } + if ((rc= dynamic_column_get_value(&header, &val)) < 0 || + dynstr_append_mem(json, "{", 1)) + goto err; + if (header.format == DYNCOL_FMT_NUM) + { + uint nm= uint2korr(header.entry); + if (dynstr_realloc(json, 6 + 3)) + goto err; + json->str[json->length++]= '"'; + json->length+= (snprintf(json->str + json->length, 6, "%u", nm)); + } + else + { + uint len= header.entry[0]; + if (dynstr_realloc(json, len + 3)) + goto err; + json->str[json->length++]= '"'; + memcpy(json->str + json->length, (const void *)header.nmpool + + uint2korr(header.entry + 1), len); + json->length+= len; + } + json->str[json->length++]= '"'; + json->str[json->length++]= ':'; + if ((rc= dynamic_column_val_str(json, &val, TRUE)) < 0 || + dynstr_append_mem(json, "}", 1)) + goto err; + } + if (dynstr_append_mem(json, "]", 1)) + return ER_DYNCOL_RESOURCE; + return ER_DYNCOL_OK; + +err: + json->length= 0; + return rc; } diff --git a/mysys/string.c b/mysys/string.c index d9791341c60..0cf8f939260 100644 --- a/mysys/string.c +++ b/mysys/string.c @@ -175,6 +175,34 @@ my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...) return ret; } +my_bool dynstr_append_quoted(DYNAMIC_STRING *str, + const char *append, size_t len) +{ + uint additional= (str->alloc_increment ? str->alloc_increment : 10); + uint lim= additional; + uint i; + if (dynstr_realloc(str, len + additional + 2)) + return TRUE; + str->str[str->length++]= '"'; + for (i= 0; i < len; i++) + { + register char c= append[i]; + if (c == '"' || c == '\\') + { + if (!lim) + { + if (dynstr_realloc(str, additional)) + return TRUE; + lim= additional; + } + lim--; + str->str[str->length++]= '\\'; + } + str->str[str->length++]= c; + } + str->str[str->length++]= '"'; + return FALSE; +} void dynstr_free(DYNAMIC_STRING *str) { @@ -193,3 +221,77 @@ void dynstr_reassociate(DYNAMIC_STRING *str, char **ptr, size_t *length, *alloc_length= str->max_length; str->str=0; } + + +/* + copy a string from one character set to another + + SYNOPSIS + copy_and_convert() + to Store result here + to_cs Character set of result string + from Copy from here + from_length Length of from string + from_cs From character set + + NOTES + 'to' must be big enough as form_length * to_cs->mbmaxlen + + RETURN + length of bytes copied to 'to' +*/ + +uint32 +copy_and_convert_extended(char *to, uint32 to_length, CHARSET_INFO *to_cs, + const char *from, uint32 from_length, + CHARSET_INFO *from_cs, + uint *errors) +{ + int cnvres; + my_wc_t wc; + const uchar *from_end= (const uchar*) from+from_length; + char *to_start= to; + uchar *to_end= (uchar*) to+to_length; + my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc; + my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb; + uint error_count= 0; + + while (1) + { + if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, + from_end)) > 0) + from+= cnvres; + else if (cnvres == MY_CS_ILSEQ) + { + error_count++; + from++; + wc= '?'; + } + else if (cnvres > MY_CS_TOOSMALL) + { + /* + A correct multibyte sequence detected + But it doesn't have Unicode mapping. + */ + error_count++; + from+= (-cnvres); + wc= '?'; + } + else + break; // Not enough characters + +outp: + if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0) + to+= cnvres; + else if (cnvres == MY_CS_ILUNI && wc != '?') + { + error_count++; + wc= '?'; + goto outp; + } + else + break; + } + *errors= error_count; + return (uint32) (to - to_start); +} diff --git a/sql/item.h b/sql/item.h index f7f3edda384..906d3d21d6f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -523,7 +523,7 @@ public: struct st_dyncall_create_def { - Item *num, *value; + Item *key, *value; CHARSET_INFO *cs; uint len, frac; DYNAMIC_COLUMN_TYPE type; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2a0ca19a4e9..72d28bb2e7e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -6048,24 +6048,87 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) return NULL; } - -longlong Item_func_dyncol_exists::val_int() +longlong Item_func_dyncol_check::val_int() { char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); DYNAMIC_COLUMN col; String *str; - ulonglong num; enum enum_dyncol_func_result rc; - num= args[1]->val_int(); + str= args[0]->val_str(&tmp); + if (args[0]->null_value) + goto null; + col.length= str->length(); + /* We do not change the string, so could do this trick */ + col.str= (char *)str->ptr(); + rc= dynamic_column_check(&col); + if (rc < 0 && rc != ER_DYNCOL_FORMAT) + { + dynamic_column_error_message(rc); + goto null; + } + null_value= FALSE; + return rc == ER_DYNCOL_OK; + +null: + null_value= TRUE; + return 0; +} + +longlong Item_func_dyncol_exists::val_int() +{ + char buff[STRING_BUFFER_USUAL_SIZE], nmstrbuf[11]; + String tmp(buff, sizeof(buff), &my_charset_bin), + nmbuf(nmstrbuf, sizeof(nmstrbuf), system_charset_info); + DYNAMIC_COLUMN col; + String *str; + LEX_STRING buf, *name= NULL; + ulonglong num= 0; + enum enum_dyncol_func_result rc; + + if (args[1]->result_type() == INT_RESULT) + num= args[1]->val_int(); + else + { + String *nm= args[1]->val_str(&nmbuf); + if (!nm || args[1]->null_value) + { + null_value= 1; + return 1; + } + if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + { + buf.str= (char *) nm->ptr(); + buf.length= nm->length(); + } + else + { + uint strlen; + uint dummy_errors; + buf.str= (char *)sql_alloc((strlen= nm->length() * + my_charset_utf8_general_ci.mbmaxlen + 1)); + if (buf.str) + { + buf.length= + copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + nm->ptr(), nm->length(), nm->charset(), + &dummy_errors); + } + else + buf.length= 0; + } + name= &buf; + } str= args[0]->val_str(&tmp); if (args[0]->null_value || args[1]->null_value || num > UINT_MAX16) goto null; col.length= str->length(); /* We do not change the string, so could do this trick */ col.str= (char *)str->ptr(); - rc= dynamic_column_exists(&col, (uint) num); + rc= ((name == NULL) ? + dynamic_column_exists(&col, (uint) num) : + dynamic_column_exists_str(&col, name)); if (rc < 0) { dynamic_column_error_message(rc); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 34d1a0bd0ae..f183ee9f8a8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1861,6 +1861,14 @@ public: Item *neg_transformer(THD *thd); }; +class Item_func_dyncol_check :public Item_bool_func +{ +public: + Item_func_dyncol_check(Item *str) :Item_bool_func(str) {} + longlong val_int(); + const char *func_name() const { return "column_check"; } +}; + class Item_func_dyncol_exists :public Item_bool_func { public: diff --git a/sql/item_create.cc b/sql/item_create.cc index 96837a8f262..f886b3d598b 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5704,7 +5704,7 @@ static List *create_func_dyncol_prepare(THD *thd, for (uint i= 0; (def= li++) ;) { dfs[0][i++]= *def; - args->push_back(def->num); + args->push_back(def->key); args->push_back(def->value); } return args; @@ -5720,6 +5720,10 @@ Item *create_func_dyncol_create(THD *thd, List &list) return new (thd->mem_root) Item_func_dyncol_create(*args, dfs); } +Item *create_func_dyncol_json(THD *thd, Item *str) +{ + return new (thd->mem_root) Item_func_dyncol_json(str); +} Item *create_func_dyncol_add(THD *thd, Item *str, List &list) @@ -5740,7 +5744,7 @@ Item *create_func_dyncol_add(THD *thd, Item *str, Item *create_func_dyncol_delete(THD *thd, Item *str, List &nums) { DYNCALL_CREATE_DEF *dfs; - Item *num; + Item *key; List_iterator_fast it(nums); List *args= new (thd->mem_root) List; @@ -5750,12 +5754,12 @@ Item *create_func_dyncol_delete(THD *thd, Item *str, List &nums) if (!args || !dfs) return NULL; - for (uint i= 0; (num= it++); i++) + for (uint i= 0; (key= it++); i++) { - dfs[i].num= num; + dfs[i].key= key; dfs[i].value= new Item_null(); dfs[i].type= DYN_COL_INT; - args->push_back(dfs[i].num); + args->push_back(dfs[i].key); args->push_back(dfs[i].value); } diff --git a/sql/item_create.h b/sql/item_create.h index ac6b0f8454f..5ecb45e9eae 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -180,5 +180,6 @@ Item *create_func_dyncol_get(THD *thd, Item *num, Item *str, Cast_target cast_type, const char *c_len, const char *c_dec, CHARSET_INFO *cs); +Item *create_func_dyncol_json(THD *thd, Item *str); #endif diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c5d1edbe475..ca6a6b2cea3 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3760,7 +3760,8 @@ String *Item_func_uuid::val_str(String *str) Item_func_dyncol_create::Item_func_dyncol_create(List &args, DYNCALL_CREATE_DEF *dfs) - : Item_str_func(args), defs(dfs), vals(0), nums(0) + : Item_str_func(args), defs(dfs), vals(0), keys(NULL), names(FALSE), + force_names(FALSE) { DBUG_ASSERT((args.elements & 0x1) == 0); // even number of arguments } @@ -3768,13 +3769,26 @@ Item_func_dyncol_create::Item_func_dyncol_create(List &args, bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref) { + uint i; bool res= Item_func::fix_fields(thd, ref); // no need Item_str_func here - vals= (DYNAMIC_COLUMN_VALUE *) alloc_root(thd->mem_root, - sizeof(DYNAMIC_COLUMN_VALUE) * - (arg_count / 2)); - nums= (uint *) alloc_root(thd->mem_root, - sizeof(uint) * (arg_count / 2)); - return res || vals == 0 || nums == 0; + if (!res) + { + vals= (DYNAMIC_COLUMN_VALUE *) alloc_root(thd->mem_root, + sizeof(DYNAMIC_COLUMN_VALUE) * + (arg_count / 2)); + for (i= 0; i + 1 < arg_count && args[i]->result_type() == INT_RESULT; i+= 2); + if (i + 1 < arg_count) + { + names= TRUE; + } + + keys= (uchar *) alloc_root(thd->mem_root, + (sizeof(LEX_STRING) > sizeof(uint) ? + sizeof(LEX_STRING) : + sizeof(uint)) * + (arg_count / 2)); + } + return res || vals == 0 || keys == 0; } @@ -3785,13 +3799,14 @@ void Item_func_dyncol_create::fix_length_and_dec() decimals= 0; } -void Item_func_dyncol_create::prepare_arguments() +bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) { char buff[STRING_BUFFER_USUAL_SIZE]; String *res, tmp(buff, sizeof(buff), &my_charset_bin); uint column_count= (arg_count / 2); uint i; my_decimal dtmp, *dres; + force_names= force_names_arg; /* get values */ for (i= 0; i < column_count; i++) @@ -3850,7 +3865,54 @@ void Item_func_dyncol_create::prepare_arguments() break; } } - nums[i]= (uint) args[i * 2]->val_int(); + if (names || force_names) + { + res= args[i * 2]->val_str(&tmp); + if (res) + { + // guaranty UTF-8 string for names + if (my_charset_same(res->charset(), &my_charset_utf8_general_ci)) + { + ((LEX_STRING *)keys)[i].length= res->length(); + if (!(((LEX_STRING *)keys)[i].str= + (char *)sql_memdup(res->ptr(), res->length()))) + ((LEX_STRING *)keys)[i].length= 0; + } + else + { + uint strlen; + uint dummy_errors; + char *str= + (char *)sql_alloc((strlen= res->length() * + my_charset_utf8_general_ci.mbmaxlen + 1)); + if (str) + { + ((LEX_STRING *)keys)[i].length= + copy_and_convert(str, strlen, &my_charset_utf8_general_ci, + res->ptr(), res->length(), res->charset(), + &dummy_errors); + ((LEX_STRING *)keys)[i].str= str; + } + else + ((LEX_STRING *)keys)[i].length= 0; + + } + } + else + { + ((LEX_STRING *)keys)[i].length= 0; + ((LEX_STRING *)keys)[i].str= NULL; + } + } + else + ((uint *)keys)[i]= (uint) args[i * 2]->val_int(); + if (args[i * 2]->null_value) + { + /* to make cleanup possible */ + for (; i < column_count; i++) + vals[i].type= DYN_COL_NULL; + return 1; + } vals[i].type= type; switch (type) { case DYN_COL_NULL: @@ -3918,6 +3980,7 @@ void Item_func_dyncol_create::prepare_arguments() vals[i].type= DYN_COL_NULL; } } + return FALSE; } void Item_func_dyncol_create::cleanup_arguments() @@ -3930,6 +3993,7 @@ void Item_func_dyncol_create::cleanup_arguments() if (vals[i].type == DYN_COL_STRING) my_free(vals[i].x.string.value.str); } + force_names= FALSE; } String *Item_func_dyncol_create::val_str(String *str) @@ -3940,25 +4004,32 @@ String *Item_func_dyncol_create::val_str(String *str) enum enum_dyncol_func_result rc; DBUG_ASSERT((arg_count & 0x1) == 0); // even number of arguments - prepare_arguments(); - - if ((rc= dynamic_column_create_many(&col, column_count, nums, vals))) + if (prepare_arguments(FALSE)) { - dynamic_column_error_message(rc); - dynamic_column_column_free(&col); res= NULL; - null_value= TRUE; + null_value= 1; } else { - /* Move result from DYNAMIC_COLUMN to str_value */ - char *ptr; - size_t length, alloc_length; - dynamic_column_reassociate(&col, &ptr, &length, &alloc_length); - str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length, - &my_charset_bin); - res= &str_value; - null_value= FALSE; + if ((rc= dynamic_column_create_many_fmt(&col, column_count, keys, + vals, names || force_names))) + { + dynamic_column_error_message(rc); + dynamic_column_column_free(&col); + res= NULL; + null_value= TRUE; + } + else + { + /* Move result from DYNAMIC_COLUMN to str_value */ + char *ptr; + size_t length, alloc_length; + dynamic_column_reassociate(&col, &ptr, &length, &alloc_length); + str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length, + &my_charset_bin); + res= &str_value; + null_value= FALSE; + } } /* cleanup */ @@ -4026,6 +4097,40 @@ void Item_func_dyncol_create::print(String *str, str->append(')'); } +String *Item_func_dyncol_json::val_str(String *str) +{ + DYNAMIC_STRING json, col; + String *res; + enum enum_dyncol_func_result rc; + + res= args[0]->val_str(str); + if (args[0]->null_value) + goto null; + + col.str= (char *)res->ptr(); + col.length= res->length(); + if ((rc= dynamic_column_json(&col, &json))) + { + dynamic_column_error_message(rc); + goto null; + } + bzero(&col, sizeof(col)); + { + /* Move result from DYNAMIC_COLUMN to str */ + char *ptr; + size_t length, alloc_length; + dynstr_reassociate(&json, &ptr, &length, &alloc_length); + str->reassociate(ptr, (uint32) length, (uint32) alloc_length, + &my_charset_utf8_general_ci); + null_value= FALSE; + } + return str; + +null: + bzero(&col, sizeof(col)); + null_value= TRUE; + return NULL; +} String *Item_func_dyncol_add::val_str(String *str) { @@ -4037,17 +4142,19 @@ String *Item_func_dyncol_add::val_str(String *str) /* We store the packed data last */ res= args[arg_count - 1]->val_str(str); - if (args[arg_count - 1]->null_value) + if (args[arg_count - 1]->null_value || + init_dynamic_string(&col, NULL, res->length() + STRING_BUFFER_USUAL_SIZE, + STRING_BUFFER_USUAL_SIZE)) goto null; - init_dynamic_string(&col, NULL, res->length() + STRING_BUFFER_USUAL_SIZE, - STRING_BUFFER_USUAL_SIZE); col.length= res->length(); memcpy(col.str, res->ptr(), col.length); - prepare_arguments(); + if (prepare_arguments(dynamic_column_has_names(&col))) + goto null; - if ((rc= dynamic_column_update_many(&col, column_count, nums, vals))) + if ((rc= dynamic_column_update_many_fmt(&col, column_count, keys, + vals, names || force_names))) { dynamic_column_error_message(rc); dynamic_column_column_free(&col); @@ -4066,7 +4173,6 @@ String *Item_func_dyncol_add::val_str(String *str) } /* cleanup */ - dynamic_column_column_free(&col); cleanup_arguments(); return str; @@ -4100,10 +4206,48 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) { DYNAMIC_COLUMN dyn_str; String *res; - longlong num; + longlong num= 0; + LEX_STRING buf, *name= NULL; + char nmstrbuf[11]; + String nmbuf(nmstrbuf, sizeof(nmstrbuf), system_charset_info); enum enum_dyncol_func_result rc; - num= args[1]->val_int(); + if (args[1]->result_type() == INT_RESULT) + num= args[1]->val_int(); + else + { + String *nm= args[1]->val_str(&nmbuf); + if (!nm || args[1]->null_value) + { + null_value= 1; + return 1; + } + + if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci)) + { + buf.str= (char *) nm->ptr(); + buf.length= nm->length(); + } + else + { + uint strlen; + uint dummy_errors; + buf.str= (char *)sql_alloc((strlen= nm->length() * + my_charset_utf8_general_ci.mbmaxlen + 1)); + if (buf.str) + { + buf.length= + copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci, + nm->ptr(), nm->length(), nm->charset(), + &dummy_errors); + } + else + buf.length= 0; + } + name= &buf; + } + + if (args[1]->null_value || num < 0 || num > INT_MAX) { null_value= 1; @@ -4119,7 +4263,9 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) dyn_str.str= (char*) res->ptr(); dyn_str.length= res->length(); - if ((rc= dynamic_column_get(&dyn_str, (uint) num, val))) + if ((rc= ((name == NULL) ? + dynamic_column_get(&dyn_str, (uint) num, val) : + dynamic_column_get_str(&dyn_str, name, val)))) { dynamic_column_error_message(rc); null_value= 1; @@ -4468,6 +4614,8 @@ null: return 1; } +void +append_identifier(THD *thd, String *packet, const char *name, uint length); void Item_dyncol_get::print(String *str, enum_query_type query_type) { @@ -4492,26 +4640,30 @@ String *Item_func_dyncol_list::val_str(String *str) col.length= res->length(); /* We do not change the string, so could do this trick */ col.str= (char *)res->ptr(); - if ((rc= dynamic_column_list(&col, &arr))) + if ((rc= dynamic_column_list_str(&col, &arr))) { dynamic_column_error_message(rc); + for (i= 0; i < arr.elements; i++) + my_free(dynamic_element(&arr, i, LEX_STRING*)->str); delete_dynamic(&arr); goto null; } /* - We support elements from 0 - 65536, so max size for one element is - 6 (including ,). + We estimate average name length as 10 */ - if (str->alloc(arr.elements * 6)) + if (str->alloc(arr.elements * 13)) goto null; str->length(0); + str->set_charset(&my_charset_utf8_general_ci); for (i= 0; i < arr.elements; i++) { - str->qs_append(*dynamic_element(&arr, i, uint*)); + LEX_STRING *name= dynamic_element(&arr, i, LEX_STRING *); + append_identifier(current_thd, str, name->str, name->length); if (i < arr.elements - 1) str->qs_append(','); + my_free(name->str); } null_value= FALSE; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 9ed2627a518..e6a7e1291b8 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1001,8 +1001,9 @@ class Item_func_dyncol_create: public Item_str_func protected: DYNCALL_CREATE_DEF *defs; DYNAMIC_COLUMN_VALUE *vals; - uint *nums; - void prepare_arguments(); + uchar *keys; + bool names, force_names; + bool prepare_arguments(bool force_names); void cleanup_arguments(); void print_arguments(String *str, enum_query_type query_type); public: @@ -1026,6 +1027,19 @@ public: virtual void print(String *str, enum_query_type query_type); }; +class Item_func_dyncol_json: public Item_str_func +{ +public: + Item_func_dyncol_json(Item *str) :Item_str_func(str) {} + const char *func_name() const{ return "column_json"; } + String *val_str(String *); + void fix_length_and_dec() + { + maybe_null= TRUE; + collation.set(&my_charset_bin); + decimals= 0; + } +}; /* The following functions is always called from an Item_cast function diff --git a/sql/lex.h b/sql/lex.h index 9f4369630a0..ea68ea0972a 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -123,10 +123,12 @@ static SYMBOL symbols[] = { { "COLUMN_NAME", SYM(COLUMN_NAME_SYM)}, { "COLUMNS", SYM(COLUMNS)}, { "COLUMN_ADD", SYM(COLUMN_ADD_SYM)}, + { "COLUMN_CHECK", SYM(COLUMN_CHECK_SYM)}, { "COLUMN_CREATE", SYM(COLUMN_CREATE_SYM)}, { "COLUMN_DELETE", SYM(COLUMN_DELETE_SYM)}, { "COLUMN_EXISTS", SYM(COLUMN_EXISTS_SYM)}, { "COLUMN_GET", SYM(COLUMN_GET_SYM)}, + { "COLUMN_JSON", SYM(COLUMN_JSON_SYM)}, { "COLUMN_LIST", SYM(COLUMN_LIST_SYM)}, { "COMMENT", SYM(COMMENT_SYM)}, { "COMMIT", SYM(COMMIT_SYM)}, diff --git a/sql/sql_string.cc b/sql/sql_string.cc index c4f5f315b08..bfd0d82c40a 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -750,79 +750,6 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) Help functions ****************************************************************************/ -/* - copy a string from one character set to another - - SYNOPSIS - copy_and_convert() - to Store result here - to_cs Character set of result string - from Copy from here - from_length Length of from string - from_cs From character set - - NOTES - 'to' must be big enough as form_length * to_cs->mbmaxlen - - RETURN - length of bytes copied to 'to' -*/ - - -static uint32 -copy_and_convert_extended(char *to, uint32 to_length, CHARSET_INFO *to_cs, - const char *from, uint32 from_length, - CHARSET_INFO *from_cs, - uint *errors) -{ - int cnvres; - my_wc_t wc; - const uchar *from_end= (const uchar*) from+from_length; - char *to_start= to; - uchar *to_end= (uchar*) to+to_length; - my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc; - my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb; - uint error_count= 0; - - while (1) - { - if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, - from_end)) > 0) - from+= cnvres; - else if (cnvres == MY_CS_ILSEQ) - { - error_count++; - from++; - wc= '?'; - } - else if (cnvres > MY_CS_TOOSMALL) - { - /* - A correct multibyte sequence detected - But it doesn't have Unicode mapping. - */ - error_count++; - from+= (-cnvres); - wc= '?'; - } - else - break; // Not enough characters - -outp: - if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0) - to+= cnvres; - else if (cnvres == MY_CS_ILUNI && wc != '?') - { - error_count++; - wc= '?'; - goto outp; - } - else - break; - } - *errors= error_count; - return (uint32) (to - to_start); -} /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4e3629080be..48dd47bccea 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -882,10 +882,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COLLATION_SYM /* SQL-2003-N */ %token COLUMNS %token COLUMN_ADD_SYM +%token COLUMN_CHECK_SYM %token COLUMN_CREATE_SYM %token COLUMN_DELETE_SYM %token COLUMN_EXISTS_SYM %token COLUMN_GET_SYM +%token COLUMN_JSON_SYM %token COLUMN_LIST_SYM %token COLUMN_SYM /* SQL-2003-R */ %token COLUMN_NAME_SYM /* SQL-2003-N */ @@ -8245,7 +8247,7 @@ dyncall_create_element: alloc_root(YYTHD->mem_root, sizeof(DYNCALL_CREATE_DEF)); if ($$ == NULL) MYSQL_YYABORT; - $$->num= $1; + $$->key= $1; $$->value= $3; $$->type= (DYNAMIC_COLUMN_TYPE)$4; $$->cs= lex->charset; @@ -8798,6 +8800,13 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } + | + COLUMN_CHECK_SYM '(' expr ')' + { + $$= new (YYTHD->mem_root) Item_func_dyncol_check($3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COLUMN_EXISTS_SYM '(' expr ',' expr ')' { @@ -8819,6 +8828,13 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } + | + COLUMN_JSON_SYM '(' expr ')' + { + $$= create_func_dyncol_json(YYTHD, $3); + if ($$ == NULL) + MYSQL_YYABORT; + } | COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { @@ -12908,10 +12924,12 @@ keyword: | CHECKPOINT_SYM {} | CLOSE_SYM {} | COLUMN_ADD_SYM {} + | COLUMN_CHECK_SYM {} | COLUMN_CREATE_SYM {} | COLUMN_DELETE_SYM {} | COLUMN_EXISTS_SYM {} | COLUMN_GET_SYM {} + | COLUMN_JSON_SYM {} | COLUMN_LIST_SYM {} | COMMENT_SYM {} | COMMIT_SYM {} -- cgit v1.2.1 From 245298f25debbeb9556abbea195fc24c4a2845de Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Sep 2012 15:27:16 +0300 Subject: MDEV-506 Cassandra dynamic columns access --- include/ma_dyncol.h | 32 +- mysql-test/r/cassandra.result | 143 ++- mysql-test/r/mysqld--help.result | 26 + mysql-test/t/cassandra.test | 126 ++- mysys/ma_dyncol.c | 289 +++++- sql/sql_base.cc | 1 + sql/sql_base.h | 1 + storage/cassandra/CMakeLists.txt | 2 +- storage/cassandra/cassandra_se.cc | 79 +- storage/cassandra/cassandra_se.h | 19 +- storage/cassandra/gen-cpp/cassandra_constants.cpp | 2 +- storage/cassandra/ha_cassandra.cc | 1043 +++++++++++++++++++-- storage/cassandra/ha_cassandra.h | 53 +- 13 files changed, 1673 insertions(+), 143 deletions(-) diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h index b4b9df7da19..2264ec6f53f 100644 --- a/include/ma_dyncol.h +++ b/include/ma_dyncol.h @@ -39,6 +39,12 @@ */ #define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL +/* + Limits of implementation +*/ +#define MAX_NAME_LENGTH 255 +#define MAX_TOTAL_NAME_LENGTH 65535 + /* NO and OK is the same used just to show semantics */ #define ER_DYNCOL_NO ER_DYNCOL_OK @@ -50,7 +56,8 @@ enum enum_dyncol_func_result ER_DYNCOL_LIMIT= -2, /* Some limit reached */ ER_DYNCOL_RESOURCE= -3, /* Out of resourses */ ER_DYNCOL_DATA= -4, /* Incorrect input data */ - ER_DYNCOL_UNKNOWN_CHARSET= -5 /* Unknown character set */ + ER_DYNCOL_UNKNOWN_CHARSET= -5, /* Unknown character set */ + ER_DYNCOL_TRUNCATED= 2 /* OK, but data was truncated */ }; typedef DYNAMIC_STRING DYNAMIC_COLUMN; @@ -81,6 +88,7 @@ struct st_dynamic_column_value struct { LEX_STRING value; CHARSET_INFO *charset; + my_bool nonfreeable; } string; struct { decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; @@ -108,6 +116,13 @@ dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str, uchar *column_keys, DYNAMIC_COLUMN_VALUE *values, my_bool names); +enum enum_dyncol_func_result +dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str, + uint column_count, + void *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_str, + my_bool string_keys); enum enum_dyncol_func_result dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, @@ -163,6 +178,21 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); #define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A))) #define dynamic_column_column_free(V) dynstr_free(V) +/* conversion of values to 3 base types */ +enum enum_dyncol_func_result +dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, + CHARSET_INFO *cs, my_bool quote); +enum enum_dyncol_func_result +dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); +enum enum_dyncol_func_result +dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val); + + +enum enum_dyncol_func_result +dynamic_column_vals(DYNAMIC_COLUMN *str, + DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals, + char **free_names); + /*************************************************************************** Internal functions, don't use if you don't know what you are doing... ***************************************************************************/ diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 07720bb5b23..3cf286013b8 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -365,8 +365,9 @@ CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; select * from t2; rowkey datecol -1 1346189025000 -10 1346189026000 +1 1346192625000 +10 1346192626000 +delete from t2; drop table t2; # # Check whether changing parameters with ALTER TABLE works. @@ -407,3 +408,141 @@ new-rowkey12 data1-value3 454 rowkey11 updated-1 34543 delete from t1; drop table t1; +# +# Dynamic columns support +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +drop table t2; +#error: dynamic column is not a blob +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36) DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +ERROR 42000: Incorrect column specifier for column 'uuidcol' +#error: double dynamic column +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1, textcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +ERROR 42000: Incorrect column specifier for column 'textcol' +# +# Dynamic column read +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; +insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09'); +insert into t2 values(2,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); +drop table t2; +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +select rowkey, column_list(dyn), column_get(dyn, 'uuidcol' as char) from t2; +rowkey column_list(dyn) column_get(dyn, 'uuidcol' as char) +1 `uuidcol` 9b5658dc-f32f-11e1-94cd-f46d046e9f09 +2 `uuidcol` 9b5658dc-f32f-11e1-94cd-f46d046e9f0a +drop table t2; +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA +thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; +drop table t2; +# +# Dynamic column insert +# +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +insert into t2 values (1, column_create("dyn1", 1, "dyn2", "two")); +select rowkey, column_json(dyn) from t2; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn2":"two"}] +delete from t2; +drop table t2; +# bigint +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'a', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'a', 2543)); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":254324},{"dyn1":"1"},{"dyn2":"two"}] +2 [{"a":2543},{"dyn1":"1"},{"dyn2":"two"}] +delete from t1; +drop table t1; +# int +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'intcol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543)); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":254324}] +2 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":2543}] +delete from t1; +drop table t1; +# timestamp +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'datecol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'datecol', 2543)); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":254324}] +2 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":2543}] +delete from t1; +drop table t1; +# boolean +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 0)); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}] +2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}] +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}] +2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}] +update t1 set dyn=column_add(dyn, "dyn2", null, "dyn3", "3"); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":1}] +2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}] +update t1 set dyn=column_add(dyn, "dyn1", null) where rowkey= 1; +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"dyn3":"3"},{"boolcol":1}] +2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}] +update t1 set dyn=column_add(dyn, "dyn3", null, "a", "ddd"); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":"ddd"},{"boolcol":1}] +2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}] +update t1 set dyn=column_add(dyn, "12345678901234", "ddd"); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":"ddd"},{"boolcol":1},{"12345678901234":"ddd"}] +2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0},{"12345678901234":"ddd"}] +update t1 set dyn=column_add(dyn, "12345678901234", null); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":"ddd"},{"boolcol":1}] +2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}] +update t1 set dyn=column_add(dyn, 'boolcol', null) where rowkey= 2; +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":"ddd"},{"boolcol":1}] +2 [{"a":"ddd"},{"dyn1":"1"}] +update t1 set rowkey= 3, dyn=column_add(dyn, "dyn1", null, 'boolcol', 0) where rowkey= 2; +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +1 [{"a":"ddd"},{"boolcol":1}] +3 [{"a":"ddd"},{"boolcol":0}] +delete from t1; +drop table t1; +CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1'; +select * from t1; +ERROR HY000: Internal error: 'Unable to convert value for field `dyn` from Cassandra's data format. Name length exceed limit of 255: 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_ver' +drop table t1; +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +DELETE FROM t1; +insert into t1 values (1, column_create("dyn", 1)); +select rowkey, column_list(dyn) from t1; +rowkey column_list(dyn) +1 `dyn` +delete from t1; +DROP TABLE t1; +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); +ERROR HY000: Encountered illegal format of dynamic column string +delete from t1; +DROP TABLE t1; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index ad55bfa3003..e3c08d80876 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -89,6 +89,24 @@ The following options may be given as the first argument: --bulk-insert-buffer-size=# Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread! + --cassandra[=name] Enable or disable CASSANDRA plugin. Possible values are + ON, OFF, FORCE (don't start if the plugin fails to load). + --cassandra-default-thrift-host=name + Default host for Cassandra thrift connections + --cassandra-failure-retries=# + Number of times to retry Cassandra calls that failed due + to timeouts or network communication problems. The + default, 0, means not to retry. + --cassandra-insert-batch-size=# + Number of rows in an INSERT batch + --cassandra-multiget-batch-size=# + Number of rows in a multiget(MRR) batch + --cassandra-read-consistency=name + Cassandra consistency level to use for read operations + --cassandra-rnd-batch-size=# + Number of rows in an rnd_read (full scan) batch + --cassandra-write-consistency=name + Cassandra consistency level to use for write operations --character-set-client-handshake Don't ignore client side character set value sent during handshake. @@ -863,6 +881,14 @@ binlog-optimize-thread-scheduling TRUE binlog-row-event-max-size 1024 binlog-stmt-cache-size 32768 bulk-insert-buffer-size 8388608 +cassandra ON +cassandra-default-thrift-host (No default value) +cassandra-failure-retries 0 +cassandra-insert-batch-size 100 +cassandra-multiget-batch-size 100 +cassandra-read-consistency ONE +cassandra-rnd-batch-size 10000 +cassandra-write-consistency ONE character-set-client-handshake TRUE character-set-filesystem binary character-set-server latin1 diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 7e5b327580c..b0b29c52f21 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -94,6 +94,18 @@ CREATE COLUMN FAMILY cf10 WITH comparator = UTF8Type AND key_validation_class=UTF8Type AND default_validation_class = UTF8Type; + +CREATE COLUMN FAMILY cfd1 + WITH comparator = UTF8Type + AND key_validation_class=UTF8Type + AND default_validation_class = UTF8Type; +SET cfd1['1']['very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_name']='1'; + +CREATE COLUMN FAMILY cfd2 + WITH comparator = UTF8Type + AND key_validation_class=Int32Type + AND default_validation_class = UTF8Type; + EOF --error 0,1,2 @@ -463,7 +475,7 @@ drop table t2; CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; select * from t2; - +delete from t2; drop table t2; --echo # @@ -511,6 +523,118 @@ select * from t1; delete from t1; drop table t1; +--echo # +--echo # Dynamic columns support +--echo # +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +drop table t2; + +--echo #error: dynamic column is not a blob +--error ER_WRONG_FIELD_SPEC +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36) DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; + +--echo #error: double dynamic column +--error ER_WRONG_FIELD_SPEC +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1, textcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; + +--echo # +--echo # Dynamic column read +--echo # +#prepare data +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; +insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09'); +insert into t2 values(2,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); +drop table t2; + +#test dynamic column read +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +select rowkey, column_list(dyn), column_get(dyn, 'uuidcol' as char) from t2; +drop table t2; + +#cleanup data +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA + thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +delete from t2; +drop table t2; + +--echo # +--echo # Dynamic column insert +--echo # +CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5'; +insert into t2 values (1, column_create("dyn1", 1, "dyn2", "two")); +select rowkey, column_json(dyn) from t2; +delete from t2; +drop table t2; +--echo # bigint +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'a', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'a', 2543)); +select rowkey, column_json(dyn) from t1; +delete from t1; +drop table t1; +--echo # int +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'intcol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543)); +select rowkey, column_json(dyn) from t1; +delete from t1; +drop table t1; +--echo # timestamp +CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'datecol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'datecol', 2543)); +select rowkey, column_json(dyn) from t1; +delete from t1; +drop table t1; +--echo # boolean +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7'; +insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 254324)); +insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 0)); +select rowkey, column_json(dyn) from t1; +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, "dyn2", null, "dyn3", "3"); +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, "dyn1", null) where rowkey= 1; +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, "dyn3", null, "a", "ddd"); +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, "12345678901234", "ddd"); +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, "12345678901234", null); +select rowkey, column_json(dyn) from t1; +update t1 set dyn=column_add(dyn, 'boolcol', null) where rowkey= 2; +select rowkey, column_json(dyn) from t1; +update t1 set rowkey= 3, dyn=column_add(dyn, "dyn1", null, 'boolcol', 0) where rowkey= 2; +select rowkey, column_json(dyn) from t1; +delete from t1; +drop table t1; + +CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1'; +--error ER_INTERNAL_ERROR +select * from t1; +drop table t1; + +# MDEV-560 +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +DELETE FROM t1; +insert into t1 values (1, column_create("dyn", 1)); +select rowkey, column_list(dyn) from t1; +# Cleanup +delete from t1; +DROP TABLE t1; + +# MDEV-561 (incorrect format data to dynamic column) +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +--error ER_DYN_COL_WRONG_FORMAT +insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); +delete from t1; +DROP TABLE t1; + + ############################################################################ ## Cassandra cleanup ############################################################################ diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 70ae4935528..e7c9b835454 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -68,6 +68,8 @@ uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, #define MAX_OFFSET_LENGTH 5 +#define DYNCOL_NUM_CHAR 6 + my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str) { if (str->length < 1) @@ -211,7 +213,7 @@ static my_bool check_limit_num(const void *val) static my_bool check_limit_str(const void *val) { - return (*((LEX_STRING **)val))->length > 255; + return (*((LEX_STRING **)val))->length > MAX_NAME_LENGTH; } @@ -288,7 +290,7 @@ my_bool put_header_entry_str(DYN_HEADER *hdr, size_t offset) { LEX_STRING *column_name= (LEX_STRING *)column_key; - DBUG_ASSERT(column_name->length <= 255); + DBUG_ASSERT(column_name->length <= MAX_NAME_LENGTH); hdr->entry[0]= column_name->length; DBUG_ASSERT(hdr->name - hdr->nmpool < (long) 0x10000L); int2store(hdr->entry + 1, hdr->name - hdr->nmpool); @@ -1381,6 +1383,9 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str, DYNCOL_SYZERESERVE)) goto err; } + if (!column_count) + return ER_DYNCOL_OK; + bzero(str->str, fmt->fixed_hdr); str->length= fmt->fixed_hdr; @@ -1501,7 +1506,7 @@ calc_var_sizes(DYN_HEADER *hdr, @return ER_DYNCOL_* return code */ -static enum enum_dyncol_func_result +enum enum_dyncol_func_result dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str, uint column_count, void *column_keys, @@ -1761,7 +1766,7 @@ static my_bool find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey) { LEX_STRING nmkey; - char nmkeybuff[6]; /* to fit max 2 bytes number */ + char nmkeybuff[DYNCOL_NUM_CHAR]; /* to fit max 2 bytes number */ DBUG_ASSERT(hdr->header != NULL); if (hdr->header + hdr->header_size > hdr->data_end) @@ -2169,10 +2174,10 @@ dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr) if (header.format == DYNCOL_FMT_NUM) { uint nm= uint2korr(read); - tmp.str= my_malloc(6, MYF(0)); + tmp.str= my_malloc(DYNCOL_NUM_CHAR, MYF(0)); if (!tmp.str) return ER_DYNCOL_RESOURCE; - tmp.length= snprintf(tmp.str, 6, "%u", nm); + tmp.length= snprintf(tmp.str, DYNCOL_NUM_CHAR, "%u", nm); } else { @@ -2208,7 +2213,7 @@ find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) uint mid, start, end, val; int flag; LEX_STRING str; - char buff[6]; + char buff[DYNCOL_NUM_CHAR]; my_bool need_conversion= ((string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM) != hdr->format); LINT_INIT(flag); /* 100 % safe */ @@ -2425,7 +2430,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, size_t offs; uint nm; DYNAMIC_COLUMN_TYPE tp; - char buff[6]; + char buff[DYNCOL_NUM_CHAR]; if (hdr->format == DYNCOL_FMT_NUM) { @@ -3438,7 +3443,7 @@ end: enum enum_dyncol_func_result dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, - my_bool quote) + CHARSET_INFO *cs, my_bool quote) { char buff[40]; int len; @@ -3468,24 +3473,22 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, char *alloc= NULL; char *from= val->x.string.value.str; uint bufflen; - my_bool conv= !my_charset_same(val->x.string.charset, - &my_charset_utf8_general_ci); + my_bool conv= !my_charset_same(val->x.string.charset, cs); my_bool rc; len= val->x.string.value.length; - bufflen= (len * (conv ? my_charset_utf8_general_ci.mbmaxlen : 1)); + bufflen= (len * (conv ? cs->mbmaxlen : 1)); if (dynstr_realloc(str, bufflen)) return ER_DYNCOL_RESOURCE; // guaranty UTF-8 string for value - if (!my_charset_same(val->x.string.charset, - &my_charset_utf8_general_ci)) + if (!my_charset_same(val->x.string.charset, cs)) { uint dummy_errors; if (!quote) { /* convert to the destination */ str->length+= copy_and_convert_extended(str->str, bufflen, - &my_charset_utf8_general_ci, + cs, from, len, val->x.string.charset, &dummy_errors); @@ -3494,8 +3497,7 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, if ((alloc= (char *)my_malloc(bufflen, MYF(0)))) { len= - copy_and_convert_extended(alloc, bufflen, - &my_charset_utf8_general_ci, + copy_and_convert_extended(alloc, bufflen, cs, from, len, val->x.string.charset, &dummy_errors); from= alloc; @@ -3543,6 +3545,155 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, return(ER_DYNCOL_OK); } + +enum enum_dyncol_func_result +dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) +{ + enum enum_dyncol_func_result rc= ER_DYNCOL_OK; + *ll= 0; + switch (val->type) { + case DYN_COL_INT: + *ll= val->x.long_value; + break; + case DYN_COL_UINT: + *ll= (longlong)val->x.ulong_value; + if (val->x.ulong_value > ULONGLONG_MAX) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_DOUBLE: + *ll= (longlong)val->x.double_value; + if (((double) *ll) != val->x.double_value) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_STRING: + { + longlong i= 0, sign= 1; + char *src= val->x.string.value.str; + uint len= val->x.string.value.length; + + while (len && my_isspace(&my_charset_latin1, *src)) src++,len--; + + if (len) + { + if (*src == '-') + { + sign= -1; + src++; + } else if (*src == '-') + src++; + while(len && my_isdigit(&my_charset_latin1, *src)) + { + i= i * 10 + (*src - '0'); + src++; + } + } + else + rc= ER_DYNCOL_TRUNCATED; + if (len) + rc= ER_DYNCOL_TRUNCATED; + *ll= i * sign; + break; + } + case DYN_COL_DECIMAL: + if (decimal2longlong(&val->x.decimal.value, ll) != E_DEC_OK) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_DATETIME: + *ll= (val->x.time_value.year * 10000000000L + + val->x.time_value.month * 100000000L + + val->x.time_value.day * 1000000 + + val->x.time_value.hour * 10000 + + val->x.time_value.minute * 100 + + val->x.time_value.second) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_DATE: + *ll= (val->x.time_value.year * 10000 + + val->x.time_value.month * 100 + + val->x.time_value.day) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_TIME: + *ll= (val->x.time_value.hour * 10000 + + val->x.time_value.minute * 100 + + val->x.time_value.second) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_NULL: + rc= ER_DYNCOL_TRUNCATED; + break; + default: + return(ER_DYNCOL_FORMAT); + } + return(rc); +} + + +enum enum_dyncol_func_result +dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val) +{ + enum enum_dyncol_func_result rc= ER_DYNCOL_OK; + *dbl= 0; + switch (val->type) { + case DYN_COL_INT: + *dbl= (double)val->x.long_value; + if (((longlong) *dbl) != val->x.long_value) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_UINT: + *dbl= (double)val->x.ulong_value; + if (((ulonglong) *dbl) != val->x.ulong_value) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_DOUBLE: + *dbl= val->x.double_value; + break; + case DYN_COL_STRING: + { + char *str, *end; + if ((str= malloc(val->x.string.value.length + 1))) + return ER_DYNCOL_RESOURCE; + memcpy(str, val->x.string.value.str, val->x.string.value.length); + str[val->x.string.value.length]= '\0'; + *dbl= strtod(str, &end); + if (*end != '\0') + rc= ER_DYNCOL_TRUNCATED; + } + case DYN_COL_DECIMAL: + if (decimal2double(&val->x.decimal.value, dbl) != E_DEC_OK) + rc= ER_DYNCOL_TRUNCATED; + break; + case DYN_COL_DATETIME: + *dbl= (double)(val->x.time_value.year * 10000000000L + + val->x.time_value.month * 100000000L + + val->x.time_value.day * 1000000 + + val->x.time_value.hour * 10000 + + val->x.time_value.minute * 100 + + val->x.time_value.second) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_DATE: + *dbl= (double)(val->x.time_value.year * 10000 + + val->x.time_value.month * 100 + + val->x.time_value.day) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_TIME: + *dbl= (double)(val->x.time_value.hour * 10000 + + val->x.time_value.minute * 100 + + val->x.time_value.second) * + (val->x.time_value.neg ? -1 : 1); + break; + case DYN_COL_NULL: + rc= ER_DYNCOL_TRUNCATED; + break; + default: + return(ER_DYNCOL_FORMAT); + } + return(rc); +} + + /** Convert to JSON @@ -3602,10 +3753,11 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) if (header.format == DYNCOL_FMT_NUM) { uint nm= uint2korr(header.entry); - if (dynstr_realloc(json, 6 + 3)) + if (dynstr_realloc(json, DYNCOL_NUM_CHAR + 3)) goto err; json->str[json->length++]= '"'; - json->length+= (snprintf(json->str + json->length, 6, "%u", nm)); + json->length+= (snprintf(json->str + json->length, + DYNCOL_NUM_CHAR, "%u", nm)); } else { @@ -3619,7 +3771,8 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) } json->str[json->length++]= '"'; json->str[json->length++]= ':'; - if ((rc= dynamic_column_val_str(json, &val, TRUE)) < 0 || + if ((rc= dynamic_column_val_str(json, &val, + &my_charset_utf8_general_ci, TRUE)) < 0 || dynstr_append_mem(json, "}", 1)) goto err; } @@ -3631,3 +3784,99 @@ err: json->length= 0; return rc; } + + +/** + Convert to DYNAMIC_COLUMN_VALUE values and names (LEX_STING) dynamic array + + @param str The packed string + @param names Where to put names + @param vals Where to put values + @param free_names pointer to free names buffer if there is it. + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +dynamic_column_vals(DYNAMIC_COLUMN *str, + DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals, + char **free_names) +{ + DYN_HEADER header; + char *nm; + uint i; + enum enum_dyncol_func_result rc; + + *free_names= 0; + bzero(names, sizeof(DYNAMIC_ARRAY)); /* In case of errors */ + bzero(vals, sizeof(DYNAMIC_ARRAY)); /* In case of errors */ + if (str->length == 0) + return ER_DYNCOL_OK; /* no columns */ + + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; + + if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > + str->length) + return ER_DYNCOL_FORMAT; + + if (init_dynamic_array(names, sizeof(LEX_STRING), + header.column_count, 0) || + init_dynamic_array(vals, sizeof(DYNAMIC_COLUMN_VALUE), + header.column_count, 0) || + (header.format == DYNCOL_FMT_NUM && + !(*free_names= (char *)malloc(DYNCOL_NUM_CHAR * header.column_count)))) + { + rc= ER_DYNCOL_RESOURCE; + goto err; + } + nm= *free_names; + + for (i= 0, header.entry= header.header; + i < header.column_count; + i++, header.entry+= header.entry_size) + { + DYNAMIC_COLUMN_VALUE val; + LEX_STRING name; + header.length= + hdr_interval_length(&header, header.entry + header.entry_size); + header.data= header.dtpool + header.offset; + /* + Check that the found data is withing the ranges. This can happen if + we get data with wrong offsets. + */ + if (header.length == DYNCOL_OFFSET_ERROR || + header.length > INT_MAX || header.offset > header.data_size) + { + rc= ER_DYNCOL_FORMAT; + goto err; + } + if ((rc= dynamic_column_get_value(&header, &val)) < 0) + goto err; + + if (header.format == DYNCOL_FMT_NUM) + { + uint num= uint2korr(header.entry); + name.str= nm; + name.length= snprintf(nm, DYNCOL_NUM_CHAR, "%u", num); + nm+= name.length + 1; + } + else + { + name.length= header.entry[0]; + name.str= (char *)header.nmpool + uint2korr(header.entry + 1); + } + /* following is preallocated and so do not fail */ + (void) insert_dynamic(names, (uchar *)&name); + (void) insert_dynamic(vals, (uchar *)&val); + } + return ER_DYNCOL_OK; + +err: + delete_dynamic(names); + delete_dynamic(vals); + if (*free_names) + my_free(*free_names); + *free_names= 0; + return rc; +} diff --git a/sql/sql_base.cc b/sql/sql_base.cc index acd330dd4d2..8f793f641ce 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9773,6 +9773,7 @@ int dynamic_column_error_message(enum_dyncol_func_result rc) switch (rc) { case ER_DYNCOL_YES: case ER_DYNCOL_OK: + case ER_DYNCOL_TRUNCATED: break; // it is not an error case ER_DYNCOL_FORMAT: my_error(ER_DYN_COL_WRONG_FORMAT, MYF(0)); diff --git a/sql/sql_base.h b/sql/sql_base.h index 3deb97c9730..cb7abc972ea 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -272,6 +272,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db, const char *table_name); bool is_equal(const LEX_STRING *a, const LEX_STRING *b); +class Open_tables_backup; /* Functions to work with system tables. */ bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list, Open_tables_backup *backup); diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt index 7986b0244bb..f11dfaf4a29 100644 --- a/storage/cassandra/CMakeLists.txt +++ b/storage/cassandra/CMakeLists.txt @@ -12,7 +12,7 @@ SET(cassandra_sources gen-cpp/Cassandra.h) #INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/) +INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) # STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 7d48bbc30d6..99a9a08b69d 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -17,6 +17,12 @@ #include "cassandra_se.h" +struct st_mysql_lex_string +{ + char *str; + size_t length; +}; + using namespace std; using namespace apache::thrift; using namespace apache::thrift::transport; @@ -74,6 +80,7 @@ class Cassandra_se_impl: public Cassandra_se_interface std::string rowkey; /* key of the record we're returning now */ SlicePredicate slice_pred; + SliceRange slice_pred_sr; bool get_slices_returned_less; bool get_slice_found_rows; public: @@ -91,6 +98,8 @@ public: void first_ddl_column(); bool next_ddl_column(char **name, int *name_len, char **value, int *value_len); void get_rowkey_type(char **name, char **type); + size_t get_ddl_size(); + const char* get_default_validator(); /* Settings */ void set_consistency_levels(ulong read_cons_level, ulong write_cons_level); @@ -98,15 +107,19 @@ public: /* Writes */ void clear_insert_buffer(); void start_row_insert(const char *key, int key_len); - void add_insert_column(const char *name, const char *value, int value_len); + void add_insert_column(const char *name, int name_len, + const char *value, int value_len); + void add_insert_delete_column(const char *name, int name_len); void add_row_deletion(const char *key, int key_len, - Column_name_enumerator *col_names); - + Column_name_enumerator *col_names, + LEX_STRING *names, uint nnames); + bool do_insert(); /* Reads, point lookups */ bool get_slice(char *key, size_t key_len, bool *found); - bool get_next_read_column(char **name, char **value, int *value_len); + bool get_next_read_column(char **name, int *name_len, + char **value, int *value_len ); void get_read_rowkey(char **value, int *value_len); /* Reads, multi-row scans */ @@ -122,6 +135,7 @@ public: /* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */ void clear_read_columns(); + void clear_read_all_columns(); void add_read_column(const char *name); /* Reads, MRR scans */ @@ -277,6 +291,16 @@ void Cassandra_se_impl::get_rowkey_type(char **name, char **type) *name= NULL; } +size_t Cassandra_se_impl::get_ddl_size() +{ + return cf_def.column_metadata.size(); +} + +const char* Cassandra_se_impl::get_default_validator() +{ + return cf_def.default_validation_class.c_str(); +} + ///////////////////////////////////////////////////////////////////////////// // Data writes @@ -315,8 +339,9 @@ void Cassandra_se_impl::start_row_insert(const char *key, int key_len) } -void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, - Column_name_enumerator *col_names) +void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, + Column_name_enumerator *col_names, + LEX_STRING *names, uint nnames) { std::string key_to_delete; key_to_delete.assign(key, key_len); @@ -344,6 +369,9 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, const char *col_name; while ((col_name= col_names->get_next_name())) slice_pred.column_names.push_back(std::string(col_name)); + for (uint i= 0; i < nnames; i++) + slice_pred.column_names.push_back(std::string(names[i].str, + names[i].length)); mut.deletion.predicate= slice_pred; @@ -351,7 +379,9 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, } -void Cassandra_se_impl::add_insert_column(const char *name, const char *value, +void Cassandra_se_impl::add_insert_column(const char *name, + int name_len, + const char *value, int value_len) { Mutation mut; @@ -359,7 +389,10 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value, mut.column_or_supercolumn.__isset.column= true; Column& col=mut.column_or_supercolumn.column; - col.name.assign(name); + if (name_len) + col.name.assign(name, name_len); + else + col.name.assign(name); col.value.assign(value, value_len); col.timestamp= insert_timestamp; col.__isset.value= true; @@ -367,6 +400,23 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value, insert_list->push_back(mut); } +void Cassandra_se_impl::add_insert_delete_column(const char *name, + int name_len) +{ + Mutation mut; + mut.__isset.deletion= true; + mut.deletion.__isset.timestamp= true; + mut.deletion.timestamp= insert_timestamp; + mut.deletion.__isset.predicate= true; + + SlicePredicate slice_pred; + slice_pred.__isset.column_names= true; + slice_pred.column_names.push_back(std::string(name, name_len)); + mut.deletion.predicate= slice_pred; + + insert_list->push_back(mut); +} + bool Cassandra_se_impl::retryable_do_insert() { @@ -444,8 +494,8 @@ bool Cassandra_se_impl::retryable_get_slice() } -bool Cassandra_se_impl::get_next_read_column(char **name, char **value, - int *value_len) +bool Cassandra_se_impl::get_next_read_column(char **name, int *name_len, + char **value, int *value_len) { bool use_counter=false; while (1) @@ -468,12 +518,14 @@ bool Cassandra_se_impl::get_next_read_column(char **name, char **value, ColumnOrSuperColumn& cs= *column_data_it; if (use_counter) { + *name_len= cs.counter_column.name.size(); *name= (char*)cs.counter_column.name.c_str(); *value= (char*)&cs.counter_column.value; *value_len= sizeof(cs.counter_column.value); } else { + *name_len= cs.column.name.size(); *name= (char*)cs.column.name.c_str(); *value= (char*)cs.column.value.c_str(); *value_len= cs.column.value.length(); @@ -601,6 +653,13 @@ void Cassandra_se_impl::clear_read_columns() slice_pred.column_names.clear(); } +void Cassandra_se_impl::clear_read_all_columns() +{ + slice_pred_sr.start = ""; + slice_pred_sr.finish = ""; + slice_pred.__set_slice_range(slice_pred_sr); +} + void Cassandra_se_impl::add_read_column(const char *name_arg) { diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index 33c602d93a6..f74d8cbd909 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -6,6 +6,8 @@ both together causes compile errors due to conflicts). */ +struct st_mysql_lex_string; +typedef struct st_mysql_lex_string LEX_STRING; /* We need to define this here so that ha_cassandra.cc also has access to it */ typedef enum @@ -50,19 +52,25 @@ public: virtual bool next_ddl_column(char **name, int *name_len, char **value, int *value_len)=0; virtual void get_rowkey_type(char **name, char **type)=0; + virtual size_t get_ddl_size()=0; + virtual const char* get_default_validator()=0; /* Writes */ virtual void clear_insert_buffer()=0; virtual void add_row_deletion(const char *key, int key_len, - Column_name_enumerator *col_names)=0; + Column_name_enumerator *col_names, + LEX_STRING *names, uint nnames)=0; virtual void start_row_insert(const char *key, int key_len)=0; - virtual void add_insert_column(const char *name, const char *value, + virtual void add_insert_delete_column(const char *name, int name_len)= 0; + virtual void add_insert_column(const char *name, int name_len, + const char *value, int value_len)=0; virtual bool do_insert()=0; /* Reads */ virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ; - virtual bool get_next_read_column(char **name, char **value, int *value_len)=0; + virtual bool get_next_read_column(char **name, int *name_len, + char **value, int *value_len)=0; virtual void get_read_rowkey(char **value, int *value_len)=0; /* Reads, multi-row scans */ @@ -70,7 +78,7 @@ public: virtual bool get_range_slices(bool last_key_as_start_key)=0; virtual void finish_reading_range_slices()=0; virtual bool get_next_range_slice_row(bool *eof)=0; - + /* Reads, MRR scans */ virtual void new_lookup_keys()=0; virtual int add_lookup_key(const char *key, size_t key_len)=0; @@ -79,8 +87,9 @@ public: /* read_set setup */ virtual void clear_read_columns()=0; + virtual void clear_read_all_columns()=0; virtual void add_read_column(const char *name)=0; - + virtual bool truncate()=0; virtual bool remove_row()=0; diff --git a/storage/cassandra/gen-cpp/cassandra_constants.cpp b/storage/cassandra/gen-cpp/cassandra_constants.cpp index 621d39027ad..49a01d2773e 100644 --- a/storage/cassandra/gen-cpp/cassandra_constants.cpp +++ b/storage/cassandra/gen-cpp/cassandra_constants.cpp @@ -11,7 +11,7 @@ namespace org { namespace apache { namespace cassandra { const cassandraConstants g_cassandra_constants; cassandraConstants::cassandraConstants() { - cassandra_const_VERSION = "19.32.0"; + cassandra_const_VERSION = (char *)"19.32.0"; } }}} // namespace diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index c4069458c41..8459e1abf7b 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -22,15 +22,21 @@ #include "ha_cassandra.h" #include "sql_class.h" +#define DYNCOL_USUAL 20 +#define DYNCOL_DELTA 100 +#define DYNCOL_USUAL_REC 1024 +#define DYNCOL_DELTA_REC 1024 + static handler *cassandra_create_handler(handlerton *hton, - TABLE_SHARE *table, + TABLE_SHARE *table, MEM_ROOT *mem_root); +extern int dynamic_column_error_message(enum_dyncol_func_result rc); handlerton *cassandra_hton; -/* +/* Hash used to track the number of open tables; variable for example share methods */ @@ -69,6 +75,25 @@ ha_create_table_option cassandra_table_option_list[]= HA_TOPTION_END }; +/** + Structure for CREATE TABLE options (field options). +*/ + +struct ha_field_option_struct +{ + bool dyncol_field; +}; + +ha_create_table_option cassandra_field_option_list[]= +{ + /* + Collect all other columns as dynamic here, + the valid values are YES/NO, ON/OFF, 1/0. + The default is 0, that is true, yes, on. + */ + HA_FOPTION_BOOL("DYNAMIC_COLUMN_STORAGE", dyncol_field, 0), + HA_FOPTION_END +}; static MYSQL_THDVAR_ULONG(insert_batch_size, PLUGIN_VAR_RQCMDARG, "Number of rows in an INSERT batch", @@ -245,17 +270,16 @@ static int cassandra_init_func(void *p) cassandra_hton->state= SHOW_OPTION_YES; cassandra_hton->create= cassandra_create_handler; - /* + /* Don't specify HTON_CAN_RECREATE in flags. re-create is used by TRUNCATE TABLE to create an *empty* table from scratch. Cassandra table won't be emptied if re-created. */ - cassandra_hton->flags= 0; + cassandra_hton->flags= 0; cassandra_hton->table_options= cassandra_table_option_list; - //cassandra_hton->field_options= example_field_option_list; - cassandra_hton->field_options= NULL; - - mysql_mutex_init(0 /* no instrumentation */, + cassandra_hton->field_options= cassandra_field_option_list; + + mysql_mutex_init(0 /* no instrumentation */, &cassandra_default_host_lock, MY_MUTEX_INIT_FAST); DBUG_RETURN(0); @@ -352,7 +376,7 @@ static int free_share(CASSANDRA_SHARE *share) static handler* cassandra_create_handler(handlerton *hton, - TABLE_SHARE *table, + TABLE_SHARE *table, MEM_ROOT *mem_root) { return new (mem_root) ha_cassandra(hton, table); @@ -361,7 +385,11 @@ static handler* cassandra_create_handler(handlerton *hton, ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), - se(NULL), field_converters(NULL), rowkey_converter(NULL) + se(NULL), field_converters(NULL), + special_type_field_converters(NULL), + special_type_field_names(NULL), n_special_type_fields(0), + rowkey_converter(NULL), + dyncol_field(0), dyncol_set(0) {} @@ -381,7 +409,8 @@ int ha_cassandra::connect_and_check_options(TABLE *table_arg) int res; DBUG_ENTER("ha_cassandra::connect_and_check_options"); - if ((res= check_table_options(options))) + if ((res= check_field_options(table_arg->s->field)) || + (res= check_table_options(options))) DBUG_RETURN(res); se= create_cassandra_se(); @@ -403,6 +432,32 @@ int ha_cassandra::connect_and_check_options(TABLE *table_arg) } +int ha_cassandra::check_field_options(Field **fields) +{ + Field **field; + uint i; + DBUG_ENTER("ha_cassandra::check_field_options"); + for (field= fields, i= 0; *field; field++, i++) + { + ha_field_option_struct *field_options= (*field)->option_struct; + if (field_options && field_options->dyncol_field) + { + if (dyncol_set || (*field)->type() != MYSQL_TYPE_BLOB) + { + my_error(ER_WRONG_FIELD_SPEC, MYF(0), (*field)->field_name); + DBUG_RETURN(HA_WRONG_CREATE_OPTION); + } + dyncol_set= 1; + dyncol_field= i; + bzero(&dynamic_values, sizeof(dynamic_values)); + bzero(&dynamic_names, sizeof(dynamic_names)); + bzero(&dynamic_rec, sizeof(dynamic_rec)); + } + } + DBUG_RETURN(0); +} + + int ha_cassandra::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_cassandra::open"); @@ -578,7 +633,7 @@ public: field->store(*pdata); return 0; } - + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { buf= field->val_real(); @@ -770,6 +825,43 @@ static int convert_hex_digit(const char c) const char map2number[]="0123456789abcdef"; +static void convert_uuid2string(char *str, const char *cass_data) +{ + char *ptr= str; + /* UUID arrives as 16-byte number in network byte order */ + for (uint i=0; i < 16; i++) + { + *(ptr++)= map2number[(cass_data[i] >> 4) & 0xF]; + *(ptr++)= map2number[cass_data[i] & 0xF]; + if (i == 3 || i == 5 || i == 7 || i == 9) + *(ptr++)= '-'; + } + *ptr= 0; +} + +static bool convert_string2uuid(char *buf, const char *str) +{ + int lower, upper; + for (uint i= 0; i < 16; i++) + { + if ((upper= convert_hex_digit(str[0])) == -1 || + (lower= convert_hex_digit(str[1])) == -1) + { + return true; + } + buf[i]= lower | (upper << 4); + str += 2; + if (i == 3 || i == 5 || i == 7 || i == 9) + { + if (str[0] != '-') + return true; + str++; + } + } + return false; +} + + class UuidDataConverter : public ColumnDataConverter { char buf[16]; /* Binary UUID representation */ @@ -779,16 +871,7 @@ public: { DBUG_ASSERT(cass_data_len==16); char str[37]; - char *ptr= str; - /* UUID arrives as 16-byte number in network byte order */ - for (uint i=0; i < 16; i++) - { - *(ptr++)= map2number[(cass_data[i] >> 4) & 0xF]; - *(ptr++)= map2number[cass_data[i] & 0xF]; - if (i == 3 || i == 5 || i == 7 || i == 9) - *(ptr++)= '-'; - } - *ptr= 0; + convert_uuid2string(str, cass_data); field->store(str, 36,field->charset()); return 0; } @@ -796,29 +879,12 @@ public: bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { String *uuid_str= field->val_str(&str_buf); - char *pstr= (char*)uuid_str->c_ptr(); - if (uuid_str->length() != 36) + if (uuid_str->length() != 36) + return true; + + if (convert_string2uuid(buf, (char*)uuid_str->c_ptr())) return true; - - int lower, upper; - for (uint i=0; i < 16; i++) - { - if ((upper= convert_hex_digit(pstr[0])) == -1 || - (lower= convert_hex_digit(pstr[1])) == -1) - { - return true; - } - buf[i]= lower | (upper << 4); - pstr += 2; - if (i == 3 || i == 5 || i == 7 || i == 9) - { - if (pstr[0] != '-') - return true; - pstr++; - } - } - *cass_data= buf; *cass_data_len= 16; return false; @@ -826,6 +892,302 @@ public: ~UuidDataConverter(){} }; +/** + Converting dynamic columns types to/from casandra types +*/ +bool cassandra_to_dyncol_intLong(const char *cass_data, + int cass_data_len __attribute__((unused)), + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_INT; +#ifdef WORDS_BIGENDIAN + value->x.long_value= (longlong *)*cass_data; +#else + flip64(cass_data, (char *)&value->x.long_value); +#endif + return 0; +} + +bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + longlong *tmp= (longlong *) buff; + enum enum_dyncol_func_result rc= + dynamic_column_val_long(tmp, value); + if (rc < 0) + return true; + *cass_data_len= sizeof(longlong); +#ifdef WORDS_BIGENDIAN + *cass_data= (char *)buff; +#else + flip64((char *)buff, (char *)buff + sizeof(longlong)); + *cass_data= (char *)buff + sizeof(longlong); +#endif + *freemem= NULL; + return false; +} + +bool cassandra_to_dyncol_intInt32(const char *cass_data, + int cass_data_len __attribute__((unused)), + DYNAMIC_COLUMN_VALUE *value) +{ + int32 tmp; + value->type= DYN_COL_INT; +#ifdef WORDS_BIGENDIAN + tmp= *((int32 *)cass_data); +#else + flip32(cass_data, (char *)&tmp); +#endif + value->x.long_value= tmp; + return 0; +} + + +bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + longlong *tmp= (longlong *) ((char *)buff + sizeof(longlong)); + enum enum_dyncol_func_result rc= + dynamic_column_val_long(tmp, value); + if (rc < 0) + return true; + *cass_data_len= sizeof(int32); + *cass_data= (char *)buff; +#ifdef WORDS_BIGENDIAN + *((int32 *) buff) = (int32) *tmp; +#else + { + int32 tmp2= (int32) *tmp; + flip32((char *)&tmp2, (char *)buff); + } +#endif + *freemem= NULL; + return false; +} + + +bool cassandra_to_dyncol_intCounter(const char *cass_data, + int cass_data_len __attribute__((unused)), + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_INT; + value->x.long_value= *((longlong *)cass_data); + return 0; +} + + +bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + longlong *tmp= (longlong *)buff; + enum enum_dyncol_func_result rc= + dynamic_column_val_long(tmp, value); + if (rc < 0) + return true; + *cass_data_len= sizeof(longlong); + *cass_data= (char *)buff; + *freemem= NULL; + return false; +} + +bool cassandra_to_dyncol_doubleFloat(const char *cass_data, + int cass_data_len __attribute__((unused)), + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_DOUBLE; + value->x.double_value= *((float *)cass_data); + return 0; +} + +bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + double tmp; + enum enum_dyncol_func_result rc= + dynamic_column_val_double(&tmp, value); + if (rc < 0) + return true; + *((float *)buff)= (float) tmp; + *cass_data_len= sizeof(float); + *cass_data= (char *)buff; + *freemem= NULL; + return false; +} + +bool cassandra_to_dyncol_doubleDouble(const char *cass_data, + int cass_data_len __attribute__((unused)), + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_DOUBLE; + value->x.double_value= *((double *)cass_data); + return 0; +} + +bool dyncol_to_cassandraDouble(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + double *tmp= (double *)buff; + enum enum_dyncol_func_result rc= + dynamic_column_val_double(tmp, value); + if (rc < 0) + return true; + *cass_data_len= sizeof(double); + *cass_data= (char *)buff; + *freemem= NULL; + return false; +} + +bool cassandra_to_dyncol_strStr(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value, + CHARSET_INFO *cs) +{ + value->type= DYN_COL_STRING; + value->x.string.charset= cs; + value->x.string.value.str= (char *)cass_data; + value->x.string.value.length= cass_data_len; + value->x.string.nonfreeable= TRUE; // do not try to free + return 0; +} + +bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem, CHARSET_INFO *cs) +{ + DYNAMIC_STRING tmp; + if (init_dynamic_string(&tmp, NULL, 1024, 1024)) + return 1; + enum enum_dyncol_func_result rc= + dynamic_column_val_str(&tmp, value, cs, FALSE); + if (rc < 0) + { + dynstr_free(&tmp); + return 1; + } + *cass_data_len= tmp.length; + *(cass_data)= tmp.str; + *freemem= tmp.str; + return 0; +} + +bool cassandra_to_dyncol_strBytes(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value) +{ + return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, + &my_charset_bin); +} + +bool dyncol_to_cassandraBytes(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + return dyncol_to_cassandraStr(value, cass_data, cass_data_len, + buff, freemem, &my_charset_bin); +} + +bool cassandra_to_dyncol_strAscii(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value) +{ + return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, + &my_charset_latin1_bin); +} + +bool dyncol_to_cassandraAscii(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + return dyncol_to_cassandraStr(value, cass_data, cass_data_len, + buff, freemem, &my_charset_latin1_bin); +} + +bool cassandra_to_dyncol_strUTF8(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value) +{ + return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, + &my_charset_utf8_unicode_ci); +} + +bool dyncol_to_cassandraUTF8(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + return dyncol_to_cassandraStr(value, cass_data, cass_data_len, + buff, freemem, &my_charset_utf8_unicode_ci); +} + +bool cassandra_to_dyncol_strUUID(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_STRING; + value->x.string.charset= &my_charset_bin; + value->x.string.value.str= (char *)my_malloc(37, MYF(0)); + if (!value->x.string.value.str) + { + value->x.string.value.length= 0; + value->x.string.nonfreeable= TRUE; + return 1; + } + convert_uuid2string(value->x.string.value.str, cass_data); + value->x.string.value.length= 36; + value->x.string.nonfreeable= FALSE; + return 0; +} + +bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + DYNAMIC_STRING tmp; + if (init_dynamic_string(&tmp, NULL, 1024, 1024)) + return true; + enum enum_dyncol_func_result rc= + dynamic_column_val_str(&tmp, value, &my_charset_latin1_bin, FALSE); + if (rc < 0 || tmp.length != 36 || convert_string2uuid((char *)buff, tmp.str)) + { + dynstr_free(&tmp); + return true; + } + + *cass_data_len= tmp.length; + *(cass_data)= tmp.str; + *freemem= tmp.str; + return 0; +} + +bool cassandra_to_dyncol_intBool(const char *cass_data, + int cass_data_len, + DYNAMIC_COLUMN_VALUE *value) +{ + value->type= DYN_COL_INT; + value->x.long_value= (cass_data[0] ? 1 : 0); + return 0; +} + +bool dyncol_to_cassandraBool(DYNAMIC_COLUMN_VALUE *value, + char **cass_data, int *cass_data_len, + void* buff, void **freemem) +{ + longlong tmp; + enum enum_dyncol_func_result rc= + dynamic_column_val_long(&tmp, value); + if (rc < 0) + return true; + ((char *)buff)[0]= (tmp ? 1 : 0); + *cass_data_len= 1; + *(cass_data)= (char *)buff; + *freemem= 0; + return 0; +} + const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType"; const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type"; @@ -849,6 +1211,126 @@ const char * const validator_varint= "org.apache.cassandra.db.marshal.IntegerTyp const char * const validator_decimal= "org.apache.cassandra.db.marshal.DecimalType"; +static CASSANDRA_TYPE_DEF cassandra_types[]= +{ + { + validator_bigint, + &cassandra_to_dyncol_intLong, + &dyncol_to_cassandraLong + }, + { + validator_int, + &cassandra_to_dyncol_intInt32, + &dyncol_to_cassandraInt32 + }, + { + validator_counter, + cassandra_to_dyncol_intCounter, + &dyncol_to_cassandraCounter + }, + { + validator_float, + &cassandra_to_dyncol_doubleFloat, + &dyncol_to_cassandraFloat + }, + { + validator_double, + &cassandra_to_dyncol_doubleDouble, + &dyncol_to_cassandraDouble + }, + { + validator_blob, + &cassandra_to_dyncol_strBytes, + &dyncol_to_cassandraBytes + }, + { + validator_ascii, + &cassandra_to_dyncol_strAscii, + &dyncol_to_cassandraAscii + }, + { + validator_text, + &cassandra_to_dyncol_strUTF8, + &dyncol_to_cassandraUTF8 + }, + { + validator_timestamp, + &cassandra_to_dyncol_intLong, + &dyncol_to_cassandraLong + }, + { + validator_uuid, + &cassandra_to_dyncol_strUUID, + &dyncol_to_cassandraUUID + }, + { + validator_boolean, + &cassandra_to_dyncol_intBool, + &dyncol_to_cassandraBool + }, + { + validator_varint, + &cassandra_to_dyncol_strBytes, + &dyncol_to_cassandraBytes + }, + { + validator_decimal, + &cassandra_to_dyncol_strBytes, + &dyncol_to_cassandraBytes + } +}; + +CASSANDRA_TYPE get_cassandra_type(const char *validator) +{ + CASSANDRA_TYPE rc; + switch(validator[32]) + { + case 'L': + rc= CT_BIGINT; + break; + case 'I': + rc= (validator[35] == '3' ? CT_INT : CT_VARINT); + rc= CT_INT; + break; + case 'C': + rc= CT_COUNTER; + break; + case 'F': + rc= CT_FLOAT; + break; + case 'D': + switch (validator[33]) + { + case 'o': + rc= CT_DOUBLE; + break; + case 'a': + rc= CT_TIMESTAMP; + break; + case 'e': + rc= CT_DECIMAL; + break; + default: + rc= CT_BLOB; + break; + } + break; + case 'B': + rc= (validator[33] == 'o' ? CT_BOOLEAN : CT_BLOB); + break; + case 'A': + rc= CT_ASCII; + break; + case 'U': + rc= (validator[33] == 'T' ? CT_TEXT : CT_UUID); + break; + default: + rc= CT_BLOB; + } + DBUG_ASSERT(strcmp(cassandra_types[rc].name, validator) == 0); + return rc; +} + ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_name) { ColumnDataConverter *res= NULL; @@ -880,16 +1362,16 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ if (!strcmp(validator_name, validator_double)) res= new DoubleDataConverter; break; - + case MYSQL_TYPE_TIMESTAMP: if (!strcmp(validator_name, validator_timestamp)) res= new TimestampDataConverter; break; case MYSQL_TYPE_STRING: // these are space padded CHAR(n) strings. - if (!strcmp(validator_name, validator_uuid) && + if (!strcmp(validator_name, validator_uuid) && field->real_type() == MYSQL_TYPE_STRING && - field->field_length == 36) + field->field_length == 36) { // UUID maps to CHAR(36), its text representation res= new UuidDataConverter; @@ -943,39 +1425,117 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) int col_name_len; char *col_type; int col_type_len; + size_t ddl_fields= se->get_ddl_size(); + const char *default_type= se->get_default_validator(); + uint max_non_default_fields; + DBUG_ENTER("ha_cassandra::setup_field_converters"); + DBUG_ASSERT(default_type); DBUG_ASSERT(!field_converters); - size_t memsize= sizeof(ColumnDataConverter*) * n_fields; + DBUG_ASSERT(dyncol_set == 0 || dyncol_set == 1); + + /* + We always should take into account that in case of using dynamic columns + sql description contain one field which does not described in + Cassandra DDL also key field is described separately. So that + is why we use "n_fields - dyncol_set - 1" or "ddl_fields + 2". + */ + max_non_default_fields= ddl_fields + 2 - n_fields; + if (ddl_fields < (n_fields - dyncol_set - 1)) + { + se->print_error("Some of SQL fields were not mapped to Cassandra's fields"); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + DBUG_RETURN(true); + } + + /* allocate memory in one chunk */ + size_t memsize= sizeof(ColumnDataConverter*) * n_fields + + (sizeof(LEX_STRING) + sizeof(CASSANDRA_TYPE_DEF))* + (dyncol_set ? max_non_default_fields : 0); if (!(field_converters= (ColumnDataConverter**)my_malloc(memsize, MYF(0)))) - return true; + DBUG_RETURN(true); bzero(field_converters, memsize); n_field_converters= n_fields; + if (dyncol_set) + { + special_type_field_converters= + (CASSANDRA_TYPE_DEF *)(field_converters + n_fields); + special_type_field_names= + ((LEX_STRING*)(special_type_field_converters + max_non_default_fields)); + } + + if (dyncol_set) + { + if (init_dynamic_array(&dynamic_values, + sizeof(DYNAMIC_COLUMN_VALUE), + DYNCOL_USUAL, DYNCOL_DELTA)) + DBUG_RETURN(true); + else + if (init_dynamic_array(&dynamic_names, + sizeof(LEX_STRING), + DYNCOL_USUAL, DYNCOL_DELTA)) + { + delete_dynamic(&dynamic_values); + DBUG_RETURN(true); + } + else + if (init_dynamic_string(&dynamic_rec, NULL, + DYNCOL_USUAL_REC, DYNCOL_DELTA_REC)) + { + delete_dynamic(&dynamic_values); + delete_dynamic(&dynamic_names); + DBUG_RETURN(true); + } + + /* Dynamic column field has special processing */ + field_converters[dyncol_field]= NULL; + + default_type_def= cassandra_types + get_cassandra_type(default_type); + } + se->first_ddl_column(); uint n_mapped= 0; while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, &col_type_len)) { + Field **field; + uint i; /* Mapping for the 1st field is already known */ - for (Field **field= field_arg + 1; *field; field++) + for (field= field_arg + 1, i= 1; *field; field++, i++) { - if (!strcmp((*field)->field_name, col_name)) + if ((!dyncol_set || dyncol_field != i) && + !strcmp((*field)->field_name, col_name)) { n_mapped++; ColumnDataConverter **conv= field_converters + (*field)->field_index; if (!(*conv= map_field_to_validator(*field, col_type))) { - se->print_error("Failed to map column %s to datatype %s", + se->print_error("Failed to map column %s to datatype %s", (*field)->field_name, col_type); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } (*conv)->field= *field; } } + if (dyncol_set && !(*field)) // is needed and not found + { + DBUG_PRINT("info",("Field not found: %s", col_name)); + if (strcmp(col_type, default_type)) + { + DBUG_PRINT("info",("Field '%s' non-default type: '%s'", + col_name, col_type)); + special_type_field_names[n_special_type_fields].length= col_name_len; + special_type_field_names[n_special_type_fields].str= col_name; + special_type_field_converters[n_special_type_fields]= + cassandra_types[get_cassandra_type(col_type)]; + n_special_type_fields++; + } + } } - if (n_mapped != n_fields - 1) + if (n_mapped != n_fields - 1 - dyncol_set) { Field *first_unmapped= NULL; /* Find the first field */ @@ -990,27 +1550,28 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) DBUG_ASSERT(first_unmapped); se->print_error("Field `%s` could not be mapped to any field in Cassandra", - first_unmapped->field_name); + first_unmapped->field_name); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } - - /* + + /* Setup type conversion for row_key. */ se->get_rowkey_type(&col_name, &col_type); if (col_name && strcmp(col_name, (*field_arg)->field_name)) { - se->print_error("PRIMARY KEY column must match Cassandra's name '%s'", col_name); + se->print_error("PRIMARY KEY column must match Cassandra's name '%s'", + col_name); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } if (!col_name && strcmp("rowkey", (*field_arg)->field_name)) { se->print_error("target column family has no key_alias defined, " "PRIMARY KEY column must be named 'rowkey'"); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } if (col_type != NULL) @@ -1019,7 +1580,7 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) { se->print_error("Failed to map PRIMARY KEY to datatype %s", col_type); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } rowkey_converter->field= *field_arg; } @@ -1027,10 +1588,10 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) { se->print_error("Cassandra's rowkey has no defined datatype (todo: support this)"); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - return true; + DBUG_RETURN(true); } - return false; + DBUG_RETURN(false); } @@ -1039,10 +1600,20 @@ void ha_cassandra::free_field_converters() delete rowkey_converter; rowkey_converter= NULL; + if (dyncol_set) + { + delete_dynamic(&dynamic_values); + delete_dynamic(&dynamic_names); + dynstr_free(&dynamic_rec); + } if (field_converters) { for (uint i=0; i < n_field_converters; i++) - delete field_converters[i]; + if (field_converters[i]) + { + DBUG_ASSERT(!dyncol_set || i == dyncol_field); + delete field_converters[i]; + } my_free(field_converters); field_converters= NULL; } @@ -1065,7 +1636,7 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, { int rc= 0; DBUG_ENTER("ha_cassandra::index_read_map"); - + if (find_flag != HA_READ_KEY_EXACT) DBUG_RETURN(HA_ERR_WRONG_COMMAND); @@ -1081,6 +1652,7 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, if (rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len)) { /* We get here when making lookups like uuid_column='not-an-uuid' */ + dbug_tmp_restore_column_map(table->read_set, old_map); DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); } @@ -1092,7 +1664,7 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); rc= HA_ERR_INTERNAL_ERROR; } - + /* TODO: what if we're not reading all columns?? */ if (!found) rc= HA_ERR_KEY_NOT_FOUND; @@ -1125,15 +1697,42 @@ void ha_cassandra::print_conversion_error(const char *field_name, } +void free_strings(DYNAMIC_COLUMN_VALUE *vals, uint num) +{ + for (uint i= 0; i < num; i++) + if (vals[i].type == DYN_COL_STRING && + !vals[i].x.string.nonfreeable) + my_free(vals[i].x.string.value.str); +} + + +CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name, + int cass_name_len) +{ + CASSANDRA_TYPE_DEF *type= default_type_def; + for(uint i= 0; i < n_special_type_fields; i++) + { + if (cass_name_len == (int)special_type_field_names[i].length && + memcmp(cass_name, special_type_field_names[i].str, + cass_name_len) == 0) + { + type= special_type_field_converters + i; + break; + } + } + return type; +} + int ha_cassandra::read_cassandra_columns(bool unpack_pk) { char *cass_name; char *cass_value; - int cass_value_len; + int cass_value_len, cass_name_len; Field **field; int res= 0; - - /* + ulong total_name_len= 0; + + /* cassandra_to_mariadb() calls will use field->store(...) methods, which require that the column is in the table->write_set */ @@ -1144,16 +1743,18 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) for (field= table->field + 1; *field; field++) (*field)->set_null(); - while (!se->get_next_read_column(&cass_name, &cass_value, &cass_value_len)) + while (!se->get_next_read_column(&cass_name, &cass_name_len, + &cass_value, &cass_value_len)) { // map to our column. todo: use hash or something.. - int idx=1; + bool found= 0; for (field= table->field + 1; *field; field++) { - idx++; - if (!strcmp((*field)->field_name, cass_name)) + uint fieldnr= (*field)->field_index; + if ((!dyncol_set || dyncol_field != fieldnr) && + !strcmp((*field)->field_name, cass_name)) { - int fieldnr= (*field)->field_index; + found= 1; (*field)->set_notnull(); if (field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len)) @@ -1166,8 +1767,86 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) break; } } + if (dyncol_set && !found) + { + DYNAMIC_COLUMN_VALUE val; + LEX_STRING nm; + CASSANDRA_TYPE_DEF *type= get_cassandra_field_def(cass_name, + cass_name_len); + nm.str= cass_name; + nm.length= cass_name_len; + if (nm.length > MAX_NAME_LENGTH) + { + se->print_error("Unable to convert value for field `%s`" + " from Cassandra's data format. Name" + " length exceed limit of %u: '%s'", + table->field[dyncol_field]->field_name, + (uint)MAX_NAME_LENGTH, cass_name); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + res=1; + goto err; + } + total_name_len+= cass_name_len; + if (nm.length > MAX_TOTAL_NAME_LENGTH) + { + se->print_error("Unable to convert value for field `%s`" + " from Cassandra's data format. Sum of all names" + " length exceed limit of %lu", + table->field[dyncol_field]->field_name, + cass_name, (uint)MAX_TOTAL_NAME_LENGTH); + my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); + res=1; + goto err; + } + + if ((res= (*(type->cassandra_to_dynamic))(cass_value, + cass_value_len, &val)) || + insert_dynamic(&dynamic_names, (uchar *) &nm) || + insert_dynamic(&dynamic_values, (uchar *) &val)) + { + if (res) + { + print_conversion_error(cass_name, cass_value, cass_value_len); + } + free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer, + dynamic_values.elements); + // EOM shouldm be already reported if happened + res=1; + goto err; + } + } } - + + dynamic_rec.length= 0; + if (dyncol_set) + { + if (dynamic_column_create_many_internal_fmt(&dynamic_rec, + dynamic_names.elements, + dynamic_names.buffer, + (DYNAMIC_COLUMN_VALUE *) + dynamic_values.buffer, + FALSE, + TRUE) < 0) + dynamic_rec.length= 0; + + free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer, + dynamic_values.elements); + dynamic_values.elements= dynamic_names.elements= 0; + } + if (dyncol_set) + { + if (dynamic_rec.length == 0) + table->field[dyncol_field]->set_null(); + else + { + Field_blob *blob= (Field_blob *)table->field[dyncol_field]; + blob->set_notnull(); + blob->store_length(dynamic_rec.length); + *((char **)(((char *)blob->ptr) + blob->pack_length_no_ptr()))= + dynamic_rec.str; + } + } + if (unpack_pk) { /* Unpack rowkey to primary key */ @@ -1187,6 +1866,82 @@ err: return res; } +int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, + String *valcol, char **freenames) +{ + String *strcol; + DYNAMIC_COLUMN col; + enum enum_dyncol_func_result rc; + DBUG_ENTER("ha_cassandra::read_dyncol"); + + Field *field= table->field[dyncol_field]; + DBUG_ASSERT(field->type() == MYSQL_TYPE_BLOB); + /* It is blob and it does not use buffer */ + strcol= field->val_str(NULL, valcol); + if (field->is_null()) + { + bzero(vals, sizeof(DYNAMIC_ARRAY)); + bzero(names, sizeof(DYNAMIC_ARRAY)); + DBUG_RETURN(0); // nothing to write + } + /* + dynamic_column_vals only read the string so we can + cheat here with assignment + */ + bzero(&col, sizeof(col)); + col.str= (char *)strcol->ptr(); + col.length= strcol->length(); + if ((rc= dynamic_column_vals(&col, names, vals, freenames)) < 0) + { + dynamic_column_error_message(rc); + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } + DBUG_RETURN(0); +} + +int ha_cassandra::write_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names) +{ + uint i; + DBUG_ENTER("ha_cassandra::write_dynamic_row"); + DBUG_ASSERT(dyncol_set); + + + DBUG_ASSERT(names->elements == vals->elements); + for (i= 0; i < names->elements; i++) + { + char buff[16]; + CASSANDRA_TYPE_DEF *type; + void *freemem= NULL; + char *cass_data; + int cass_data_len; + LEX_STRING *name= dynamic_element(names, i, LEX_STRING*); + DYNAMIC_COLUMN_VALUE *val= dynamic_element(vals, i, DYNAMIC_COLUMN_VALUE*); + + DBUG_PRINT("info", ("field %*s", (int)name->length, name->str)); + type= get_cassandra_field_def(name->str, (int) name->length); + if ((*type->dynamic_to_cassandra)(val, &cass_data, &cass_data_len, + buff, &freemem)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + name->str, insert_lineno); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } + se->add_insert_column(name->str, name->length, + cass_data, cass_data_len); + if (freemem) + my_free(freemem); + } + DBUG_RETURN(0); +} + +void ha_cassandra::free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, + char *free_names) +{ + delete_dynamic(names); + delete_dynamic(vals); + if (free_names) + my_free(free_names); +} int ha_cassandra::write_row(uchar *buf) { @@ -1221,15 +1976,35 @@ int ha_cassandra::write_row(uchar *buf) { char *cass_data; int cass_data_len; - if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len)) + if (dyncol_set && dyncol_field == i) { - my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), - field_converters[i]->field->field_name, insert_lineno); - dbug_tmp_restore_column_map(table->read_set, old_map); - DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + String valcol; + DYNAMIC_ARRAY vals, names; + char *free_names; + int rc; + DBUG_ASSERT(field_converters[i] == NULL); + if (!(rc= read_dyncol(&vals, &names, &valcol, &free_names))) + rc= write_dynamic_row(&vals, &names); + free_dynamic_row(&vals, &names, free_names); + if (rc) + { + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(rc); + } + } + else + { + if (field_converters[i]->mariadb_to_cassandra(&cass_data, + &cass_data_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + field_converters[i]->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } + se->add_insert_column(field_converters[i]->field->field_name, 0, + cass_data, cass_data_len); } - se->add_insert_column(field_converters[i]->field->field_name, - cass_data, cass_data_len); } dbug_tmp_restore_column_map(table->read_set, old_map); @@ -1296,9 +2071,16 @@ int ha_cassandra::rnd_init(bool scan) DBUG_RETURN(0); } - se->clear_read_columns(); - for (uint i= 1; i < table->s->fields; i++) - se->add_read_column(table->field[i]->field_name); + if (dyncol_set) + { + se->clear_read_all_columns(); + } + else + { + se->clear_read_columns(); + for (uint i= 1; i < table->s->fields; i++) + se->add_read_column(table->field[i]->field_name); + } se->read_batch_size= THDVAR(table->in_use, rnd_batch_size); bres= se->get_range_slices(false); @@ -1633,13 +2415,16 @@ public: int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) { + DYNAMIC_ARRAY oldvals, oldnames, vals, names; + String oldvalcol, valcol; + char *oldfree_names= NULL, *free_names= NULL; my_bitmap_map *old_map; + int res; DBUG_ENTER("ha_cassandra::update_row"); /* Currently, it is guaranteed that new_data == table->record[0] */ - + DBUG_ASSERT(new_data == table->record[0]); /* For now, just rewrite the full record */ se->clear_insert_buffer(); - old_map= dbug_tmp_use_all_columns(table, table->read_set); @@ -1668,6 +2453,22 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) else new_primary_key= false; + if (dyncol_set) + { + Field *field= table->field[dyncol_field]; + /* move to get old_data */ + my_ptrdiff_t diff; + diff= (my_ptrdiff_t) (old_data - new_data); + field->move_field_offset(diff); // Points now at old_data + if ((res= read_dyncol(&oldvals, &oldnames, &oldvalcol, &oldfree_names))) + DBUG_RETURN(res); + field->move_field_offset(-diff); // back to new_data + if ((res= read_dyncol(&vals, &names, &valcol, &free_names))) + { + free_dynamic_row(&oldnames, &oldvals, oldfree_names); + DBUG_RETURN(res); + } + } if (new_primary_key) { @@ -1676,7 +2477,10 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) Add a DELETE operation into the batch */ Column_name_enumerator_impl name_enumerator(this); - se->add_row_deletion(old_key, old_key_len, &name_enumerator); + se->add_row_deletion(old_key, old_key_len, &name_enumerator, + (LEX_STRING *)oldnames.buffer, + (dyncol_set ? oldnames.elements : 0)); + oldnames.elements= oldvals.elements= 0; // they will be deleted } se->start_row_insert(new_key, new_key_len); @@ -1686,23 +2490,64 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) { char *cass_data; int cass_data_len; - if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len)) + if (dyncol_set && dyncol_field == i) { - my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), - field_converters[i]->field->field_name, insert_lineno); - dbug_tmp_restore_column_map(table->read_set, old_map); - DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + DBUG_ASSERT(field_converters[i] == NULL); + if ((res= write_dynamic_row(&vals, &names))) + goto err; + } + else + { + if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len)) + { + my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), + field_converters[i]->field->field_name, insert_lineno); + dbug_tmp_restore_column_map(table->read_set, old_map); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + } + se->add_insert_column(field_converters[i]->field->field_name, 0, + cass_data, cass_data_len); + } + } + if (dyncol_set) + { + /* find removed fields */ + uint i= 0, j= 0; + LEX_STRING *onames= (LEX_STRING *)oldnames.buffer; + LEX_STRING *nnames= (LEX_STRING *)names.buffer; + /* both array are sorted */ + for(; i < oldnames.elements; i++) + { + int scmp= 0; + while (j < names.elements && + (nnames[j].length < onames[i].length || + (nnames[j].length == onames[i].length && + (scmp= memcmp(nnames[j].str, onames[i].str, + onames[i].length)) < 0))) + j++; + if (j < names.elements && + nnames[j].length == onames[i].length && + scmp == 0) + j++; + else + se->add_insert_delete_column(onames[i].str, onames[i].length); } - se->add_insert_column(field_converters[i]->field->field_name, - cass_data, cass_data_len); } + dbug_tmp_restore_column_map(table->read_set, old_map); - - bool res= se->do_insert(); + + res= se->do_insert(); if (res) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - + +err: + if (dyncol_set) + { + free_dynamic_row(&oldnames, &oldvals, oldfree_names); + free_dynamic_row(&names, &vals, free_names); + } + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index fb5236bf118..f32151849e5 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -40,6 +40,33 @@ class ColumnDataConverter; struct ha_table_option_struct; + +struct st_dynamic_column_value; + +typedef bool (* CAS2DYN_CONVERTER)(const char *cass_data, + int cass_data_len, + struct st_dynamic_column_value *value); +typedef bool (* DYN2CAS_CONVERTER)(struct st_dynamic_column_value *value, + char **cass_data, + int *cass_data_len, + void *buf, void **freemem); +struct cassandra_type_def +{ + const char *name; + CAS2DYN_CONVERTER cassandra_to_dynamic; + DYN2CAS_CONVERTER dynamic_to_cassandra; +}; + +typedef struct cassandra_type_def CASSANDRA_TYPE_DEF; + +enum cassandtra_type_enum {CT_BIGINT, CT_INT, CT_COUNTER, CT_FLOAT, CT_DOUBLE, + CT_BLOB, CT_ASCII, CT_TEXT, CT_TIMESTAMP, CT_UUID, CT_BOOLEAN, CT_VARINT, + CT_DECIMAL}; + +typedef enum cassandtra_type_enum CASSANDRA_TYPE; + + + /** @brief Class definition for the storage engine */ @@ -48,23 +75,35 @@ class ha_cassandra: public handler friend class Column_name_enumerator_impl; THR_LOCK_DATA lock; ///< MySQL lock CASSANDRA_SHARE *share; ///< Shared lock info - + Cassandra_se_interface *se; + /* description of static part of the table definition */ ColumnDataConverter **field_converters; uint n_field_converters; + CASSANDRA_TYPE_DEF *default_type_def; + /* description of dynamic columns part */ + CASSANDRA_TYPE_DEF *special_type_field_converters; + LEX_STRING *special_type_field_names; + uint n_special_type_fields; + DYNAMIC_ARRAY dynamic_values, dynamic_names; + DYNAMIC_STRING dynamic_rec; + ColumnDataConverter *rowkey_converter; bool setup_field_converters(Field **field, uint n_fields); void free_field_converters(); - + int read_cassandra_columns(bool unpack_pk); int check_table_options(struct ha_table_option_struct* options); bool doing_insert_batch; ha_rows insert_rows_batched; - + + uint dyncol_field; + bool dyncol_set; + /* Used to produce 'wrong column %s at row %lu' warnings */ ha_rows insert_lineno; void print_conversion_error(const char *field_name, @@ -191,6 +230,14 @@ public: private: bool source_exhausted; bool mrr_start_read(); + int check_field_options(Field **fields); + int read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, + String *valcol, char **freenames); + int write_dynamic_row(DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals); + void static free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, + char *free_names); + CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name, + int cass_name_length); public: /* -- cgit v1.2.1 From 3f8eaf7e87a0a77edf511856429baf517ada6fea Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Sep 2012 15:30:49 +0300 Subject: Ending spaces removed. --- storage/cassandra/cassandra_se.cc | 64 +++++++++++------------ storage/cassandra/cassandra_se.h | 8 +-- storage/cassandra/ha_cassandra.cc | 104 +++++++++++++++++++------------------- storage/cassandra/ha_cassandra.h | 24 ++++----- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 99a9a08b69d..9e2b815c488 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -51,11 +51,11 @@ class Cassandra_se_impl: public Cassandra_se_interface ConsistencyLevel::type write_consistency; ConsistencyLevel::type read_consistency; - + /* How many times to retry an operation before giving up */ int thrift_call_retries_to_do; - + /* DDL data */ KsDef ks_def; /* KeySpace we're using (TODO: put this in table->share) */ CfDef cf_def; /* Column family we're using (TODO: put in table->share)*/ @@ -68,15 +68,15 @@ class Cassandra_se_impl: public Cassandra_se_interface /* Insert preparation */ typedef std::map > ColumnFamilyToMutation; typedef std::map KeyToCfMutationMap; - + KeyToCfMutationMap batch_mutation; /* Prepare operation here */ int64_t insert_timestamp; std::vector* insert_list; - + /* Resultset we're reading */ std::vector key_slice_vec; std::vector::iterator key_slice_it; - + std::string rowkey; /* key of the record we're returning now */ SlicePredicate slice_pred; @@ -84,12 +84,12 @@ class Cassandra_se_impl: public Cassandra_se_interface bool get_slices_returned_less; bool get_slice_found_rows; public: - Cassandra_se_impl() : cass(NULL), + Cassandra_se_impl() : cass(NULL), write_consistency(ConsistencyLevel::ONE), read_consistency(ConsistencyLevel::ONE), thrift_call_retries_to_do(0) {} virtual ~Cassandra_se_impl(){ delete cass; } - + /* Connection and DDL checks */ bool connect(const char *host, int port, const char *keyspace); void set_column_family(const char *cfname) { column_family.assign(cfname); } @@ -137,7 +137,7 @@ public: void clear_read_columns(); void clear_read_all_columns(); void add_read_column(const char *name); - + /* Reads, MRR scans */ void new_lookup_keys(); int add_lookup_key(const char *key, size_t key_len); @@ -164,7 +164,7 @@ private: /* Non-inherited utility functions: */ int64_t get_i64_timestamp(); - + typedef bool (Cassandra_se_impl::*retryable_func_t)(); bool try_operation(retryable_func_t func); }; @@ -182,17 +182,17 @@ Cassandra_se_interface *create_cassandra_se() bool Cassandra_se_impl::connect(const char *host, int port, const char *keyspace_arg) { bool res= true; - + keyspace.assign(keyspace_arg); - + try { - boost::shared_ptr socket = + boost::shared_ptr socket = boost::shared_ptr(new TSocket(host, port)); - boost::shared_ptr tr = + boost::shared_ptr tr = boost::shared_ptr(new TFramedTransport (socket)); - boost::shared_ptr p = + boost::shared_ptr p = boost::shared_ptr(new TBinaryProtocol(tr)); - + cass= new CassandraClient(p); tr->open(); cass->set_keyspace(keyspace_arg); @@ -216,7 +216,7 @@ bool Cassandra_se_impl::connect(const char *host, int port, const char *keyspace } -void Cassandra_se_impl::set_consistency_levels(ulong read_cons_level, +void Cassandra_se_impl::set_consistency_levels(ulong read_cons_level, ulong write_cons_level) { write_cons_level= (ConsistencyLevel::type)(write_cons_level + 1); @@ -229,7 +229,7 @@ bool Cassandra_se_impl::retryable_setup_ddl_checks() try { cass->describe_keyspace(ks_def, keyspace); - + } catch (NotFoundException nfe) { print_error("keyspace `%s` not found: %s", keyspace.c_str(), nfe.what()); return true; @@ -261,7 +261,7 @@ void Cassandra_se_impl::first_ddl_column() } -bool Cassandra_se_impl::next_ddl_column(char **name, int *name_len, +bool Cassandra_se_impl::next_ddl_column(char **name, int *name_len, char **type, int *type_len) { if (column_ddl_it == cf_def.column_metadata.end()) @@ -314,7 +314,7 @@ int64_t Cassandra_se_impl::get_i64_timestamp() int64_t usec = td.tv_usec; usec = usec / 1000; ms += usec; - + return ms; } @@ -345,7 +345,7 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, { std::string key_to_delete; key_to_delete.assign(key, key_len); - + batch_mutation[key_to_delete]= ColumnFamilyToMutation(); ColumnFamilyToMutation& cf_mut= batch_mutation[key_to_delete]; @@ -357,7 +357,7 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len, mut.deletion.__isset.timestamp= true; mut.deletion.timestamp= get_i64_timestamp(); mut.deletion.__isset.predicate= true; - + /* Attempting to delete columns with SliceRange causes exception with message "Deletion does not yet support SliceRange predicates". @@ -439,7 +439,7 @@ bool Cassandra_se_impl::do_insert() */ if (batch_mutation.empty()) return false; - + return try_operation(&Cassandra_se_impl::retryable_do_insert); } @@ -449,7 +449,7 @@ bool Cassandra_se_impl::do_insert() ///////////////////////////////////////////////////////////////////////////// /* - Make one key lookup. If the record is found, the result is stored locally and + Make one key lookup. If the record is found, the result is stored locally and the caller should iterate over it. */ @@ -475,7 +475,7 @@ bool Cassandra_se_impl::retryable_get_slice() sr.finish = ""; slice_pred.__set_slice_range(sr); - cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, + cass->get_slice(column_data_vec, rowkey, cparent, slice_pred, read_consistency); if (column_data_vec.size() == 0) @@ -548,7 +548,7 @@ void Cassandra_se_impl::get_read_rowkey(char **value, int *value_len) bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) { get_range_slices_param_last_key_as_start_key= last_key_as_start_key; - + return try_operation(&Cassandra_se_impl::retryable_get_range_slices); } @@ -556,10 +556,10 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key) bool Cassandra_se_impl::retryable_get_range_slices() { bool last_key_as_start_key= get_range_slices_param_last_key_as_start_key; - + ColumnParent cparent; cparent.column_family= column_family; - + /* SlicePredicate can be used to limit columns we will retrieve */ KeyRange key_range; @@ -620,7 +620,7 @@ restart: return false; } } - + /* (1) - skip the last row that we have read in the previous batch. (2) - Rows that were deleted show up as rows without any columns. Skip @@ -710,16 +710,16 @@ bool Cassandra_se_impl::try_operation(retryable_func_t func_to_call) res= true; try { - + if ((res= (this->*func_to_call)())) { /* The function call was made successfully (without timeouts, etc), - but something inside it returned 'true'. + but something inside it returned 'true'. This is supposedly a failure (or "not found" or other negative result). We need to return this to the caller. */ - n_retries= 0; + n_retries= 0; } } catch (InvalidRequestException ire) { @@ -735,7 +735,7 @@ bool Cassandra_se_impl::try_operation(retryable_func_t func_to_call) print_error("TimedOutException: %s", te.what()); }catch(TException e){ /* todo: we may use retry for certain kinds of Thrift errors */ - n_retries= 0; + n_retries= 0; print_error("Thrift exception: %s", e.what()); } catch (...) { n_retries= 0; /* Don't retry */ diff --git a/storage/cassandra/cassandra_se.h b/storage/cassandra/cassandra_se.h index f74d8cbd909..050c65e6dde 100644 --- a/storage/cassandra/cassandra_se.h +++ b/storage/cassandra/cassandra_se.h @@ -37,7 +37,7 @@ class Cassandra_se_interface { public: Cassandra_se_interface() { err_buffer[0]=0; } - + virtual ~Cassandra_se_interface(){}; /* Init */ virtual bool connect(const char *host, int port, const char *keyspace)=0; @@ -45,11 +45,11 @@ public: /* Settings */ virtual void set_consistency_levels(ulong read_cons_level, ulong write_cons_level)=0; - + /* Check underlying DDL */ virtual bool setup_ddl_checks()=0; virtual void first_ddl_column()=0; - virtual bool next_ddl_column(char **name, int *name_len, char **value, + virtual bool next_ddl_column(char **name, int *name_len, char **value, int *value_len)=0; virtual void get_rowkey_type(char **name, char **type)=0; virtual size_t get_ddl_size()=0; @@ -106,7 +106,7 @@ class Cassandra_status_vars public: ulong row_inserts; ulong row_insert_batches; - + ulong multiget_reads; ulong multiget_keys_scanned; ulong multiget_rows_read; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 8459e1abf7b..d77a89bded3 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -113,7 +113,7 @@ static MYSQL_THDVAR_ULONG(failure_retries, PLUGIN_VAR_RQCMDARG, NULL, NULL, /*default*/ 0, /*min*/ 0, /*max*/ 1024*1024*1024, 0); /* These match values in enum_cassandra_consistency_level */ -const char *cassandra_consistency_level[] = +const char *cassandra_consistency_level[] = { "ONE", "QUORUM", @@ -145,19 +145,19 @@ mysql_mutex_t cassandra_default_host_lock; static char* cassandra_default_thrift_host = NULL; static char cassandra_default_host_buf[256]=""; -static void -cassandra_default_thrift_host_update(THD *thd, +static void +cassandra_default_thrift_host_update(THD *thd, struct st_mysql_sys_var* var, void* var_ptr, /*!< out: where the formal string goes */ - const void* save) /*!< in: immediate result + const void* save) /*!< in: immediate result from check function */ { const char *new_host= *((char**)save); const size_t max_len= sizeof(cassandra_default_host_buf); mysql_mutex_lock(&cassandra_default_host_lock); - + if (new_host) { strncpy(cassandra_default_host_buf, new_host, max_len); @@ -169,7 +169,7 @@ cassandra_default_thrift_host_update(THD *thd, cassandra_default_host_buf[0]= 0; cassandra_default_thrift_host= NULL; } - + *((const char**)var_ptr)= cassandra_default_thrift_host; mysql_mutex_unlock(&cassandra_default_host_lock); @@ -177,10 +177,10 @@ cassandra_default_thrift_host_update(THD *thd, static MYSQL_SYSVAR_STR(default_thrift_host, cassandra_default_thrift_host, - PLUGIN_VAR_RQCMDARG, - "Default host for Cassandra thrift connections", + PLUGIN_VAR_RQCMDARG, + "Default host for Cassandra thrift connections", /*check*/NULL, - cassandra_default_thrift_host_update, + cassandra_default_thrift_host_update, /*default*/NULL); static struct st_mysql_sys_var* cassandra_system_variables[]= { @@ -465,7 +465,7 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked) if (!(share = get_share(name, table))) DBUG_RETURN(1); thr_lock_data_init(&share->lock,&lock,NULL); - + DBUG_ASSERT(!se); /* Don't do the following on open: it prevents SHOW CREATE TABLE when the server @@ -501,7 +501,7 @@ int ha_cassandra::check_table_options(ha_table_option_struct *options) if (!options->thrift_host && (!cassandra_default_thrift_host || !cassandra_default_thrift_host[0])) { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "thrift_host table option must be specified, or " "@@cassandra_default_thrift_host must be set"); return HA_WRONG_CREATE_OPTION; @@ -509,7 +509,7 @@ int ha_cassandra::check_table_options(ha_table_option_struct *options) if (!options->keyspace || !options->column_family) { - my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), "keyspace and column_family table options must be specified"); return HA_WRONG_CREATE_OPTION; } @@ -543,7 +543,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, int res; DBUG_ENTER("ha_cassandra::create"); DBUG_ASSERT(options); - + Field **pfield= table_arg->s->field; if (!((*pfield)->flags & NOT_NULL_FLAG)) { @@ -555,7 +555,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, table_arg->key_info[0].key_parts != 1 || table_arg->key_info[0].key_part[0].fieldnr != 1) { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), + my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Table must have PRIMARY KEY defined over the first column"); DBUG_RETURN(HA_WRONG_CREATE_OPTION); } @@ -582,7 +582,7 @@ public: Field *field; /* This will save Cassandra's data in the Field */ - virtual int cassandra_to_mariadb(const char *cass_data, + virtual int cassandra_to_mariadb(const char *cass_data, int cass_data_len)=0; /* @@ -610,7 +610,7 @@ public: field->store(*pdata); return 0; } - + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { buf= field->val_real(); @@ -672,7 +672,7 @@ public: field->store(tmp); return 0; } - + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { longlong tmp= field->val_int(); @@ -731,7 +731,7 @@ public: field->store(tmp); return 0; } - + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { int32_t tmp= field->val_int(); @@ -756,7 +756,7 @@ public: field->store(cass_data, cass_data_len,field->charset()); return 0; } - + bool mariadb_to_cassandra(char **cass_data, int *cass_data_len) { String *pstr= field->val_str(&buf); @@ -780,7 +780,7 @@ public: DBUG_ASSERT(cass_data_len==8); flip64(cass_data, (char*)&tmp); /* - store_TIME's arguments: + store_TIME's arguments: - seconds since epoch - microsecond fraction of a second. */ @@ -794,7 +794,7 @@ public: ulong ts_microsec; int64_t tmp; ts_time= ((Field_timestamp*)field)->get_timestamp(&ts_microsec); - + /* Cassandra needs milliseconds-since-epoch */ tmp= ((int64_t)ts_time) * 1000 + ts_microsec/1000; flip64((const char*)&tmp, (char*)&buf); @@ -1383,7 +1383,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ { /* Cassandra's "varint" type is a binary-encoded arbitary-length - big-endian number. + big-endian number. - It can be mapped to VARBINARY(N), with sufficiently big N. - If the value does not fit into N bytes, it is an error. We should not truncate it, because that is just as good as returning garbage. @@ -1391,7 +1391,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ are zero-padded, which will work as multiplying the value by 2^k for some value of k. */ - if (field->type() == MYSQL_TYPE_VARCHAR && + if (field->type() == MYSQL_TYPE_VARCHAR && field->binary() && (!strcmp(validator_name, validator_varint) || !strcmp(validator_name, validator_decimal))) @@ -1675,7 +1675,7 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, } -void ha_cassandra::print_conversion_error(const char *field_name, +void ha_cassandra::print_conversion_error(const char *field_name, char *cass_value, int cass_value_len) { @@ -1691,7 +1691,7 @@ void ha_cassandra::print_conversion_error(const char *field_name, se->print_error("Unable to convert value for field `%s` from Cassandra's data" " format. Source data is %d bytes, 0x%s%s", - field_name, cass_value_len, buf, + field_name, cass_value_len, buf, (i == sizeof(buf) - 1)? "..." : ""); my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); } @@ -1759,7 +1759,7 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) if (field_converters[fieldnr]->cassandra_to_mariadb(cass_value, cass_value_len)) { - print_conversion_error((*field)->field_name, cass_value, + print_conversion_error((*field)->field_name, cass_value, cass_value_len); res=1; goto err; @@ -1948,7 +1948,7 @@ int ha_cassandra::write_row(uchar *buf) my_bitmap_map *old_map; int ires; DBUG_ENTER("ha_cassandra::write_row"); - + if (!se && (ires= connect_and_check_options(table))) DBUG_RETURN(ires); @@ -1956,7 +1956,7 @@ int ha_cassandra::write_row(uchar *buf) se->clear_insert_buffer(); old_map= dbug_tmp_use_all_columns(table, table->read_set); - + insert_lineno++; /* Convert the key */ @@ -2008,9 +2008,9 @@ int ha_cassandra::write_row(uchar *buf) } dbug_tmp_restore_column_map(table->read_set, old_map); - + bool res; - + if (doing_insert_batch) { res= 0; @@ -2025,7 +2025,7 @@ int ha_cassandra::write_row(uchar *buf) if (res) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - + DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); } @@ -2046,7 +2046,7 @@ void ha_cassandra::start_bulk_insert(ha_rows rows) int ha_cassandra::end_bulk_insert() { DBUG_ENTER("ha_cassandra::end_bulk_insert"); - + /* Flush out the insert buffer */ doing_insert_batch= false; bool bres= se->do_insert(); @@ -2133,7 +2133,7 @@ int ha_cassandra::delete_all_rows() DBUG_RETURN(ires); bres= se->truncate(); - + if (bres) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); @@ -2145,12 +2145,12 @@ int ha_cassandra::delete_row(const uchar *buf) { bool bres; DBUG_ENTER("ha_cassandra::delete_row"); - + bres= se->remove_row(); - + if (bres) my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str()); - + DBUG_RETURN(bres? HA_ERR_INTERNAL_ERROR: 0); } @@ -2158,7 +2158,7 @@ int ha_cassandra::delete_row(const uchar *buf) int ha_cassandra::info(uint flag) { DBUG_ENTER("ha_cassandra::info"); - + if (!table) return 1; @@ -2183,7 +2183,7 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, void ha_cassandra::position(const uchar *record) { DBUG_ENTER("ha_cassandra::position"); - + /* Copy the primary key to rowid */ key_copy(ref, (uchar*)record, &table->key_info[0], table->field[0]->key_length(), true); @@ -2196,7 +2196,7 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos) { int rc; DBUG_ENTER("ha_cassandra::rnd_pos"); - + int save_active_index= active_index; active_index= 0; /* The primary key */ rc= index_read_map(buf, pos, key_part_map(1), HA_READ_KEY_EXACT); @@ -2230,7 +2230,7 @@ int ha_cassandra::reset() - anything else? */ ha_rows ha_cassandra::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, - void *seq_init_param, + void *seq_init_param, uint n_ranges, uint *bufsz, uint *flags, COST_VECT *cost) { @@ -2240,7 +2240,7 @@ ha_rows ha_cassandra::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, ha_rows ha_cassandra::multi_range_read_info(uint keyno, uint n_ranges, uint keys, - uint key_parts, uint *bufsz, + uint key_parts, uint *bufsz, uint *flags, COST_VECT *cost) { /* Can only be equality lookups on the primary key... */ @@ -2269,14 +2269,14 @@ bool ha_cassandra::mrr_start_read() my_bitmap_map *old_map; old_map= dbug_tmp_use_all_columns(table, table->read_set); - + se->new_lookup_keys(); while (!(source_exhausted= mrr_funcs.next(mrr_iter, &mrr_cur_range))) { char *cass_key; int cass_key_len; - + DBUG_ASSERT(mrr_cur_range.range_flag & EQ_RANGE); uchar *key= (uchar*)mrr_cur_range.start_key.key; @@ -2285,9 +2285,9 @@ bool ha_cassandra::mrr_start_read() store_key_image_to_rec(table->field[0], (uchar*)key, key_len); rowkey_converter->mariadb_to_cassandra(&cass_key, &cass_key_len); - + // Primitive buffer control - if (se->add_lookup_key(cass_key, cass_key_len) > + if (se->add_lookup_key(cass_key, cass_key_len) > THDVAR(table->in_use, multiget_batch_size)) break; } @@ -2308,7 +2308,7 @@ int ha_cassandra::multi_range_read_next(range_id_t *range_info) res= read_cassandra_columns(true); break; } - else + else { if (source_exhausted) { @@ -2324,7 +2324,7 @@ int ha_cassandra::multi_range_read_next(range_id_t *range_info) } } } - /* + /* We get here if we've refilled the buffer and done another read. Try reading from results again */ @@ -2444,7 +2444,7 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) } /* - Compare it to the key we've read. For all types that Cassandra supports, + Compare it to the key we've read. For all types that Cassandra supports, binary byte-wise comparison can be used */ bool new_primary_key; @@ -2472,8 +2472,8 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) if (new_primary_key) { - /* - Primary key value changed. This is essentially a DELETE + INSERT. + /* + Primary key value changed. This is essentially a DELETE + INSERT. Add a DELETE operation into the batch */ Column_name_enumerator_impl name_enumerator(this); @@ -2606,7 +2606,7 @@ int ha_cassandra::external_lock(THD *thd, int lock_type) int ha_cassandra::delete_table(const char *name) { DBUG_ENTER("ha_cassandra::delete_table"); - /* + /* Cassandra table is just a view. Dropping it doesn't affect the underlying column family. */ @@ -2640,7 +2640,7 @@ bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) { - cassandra_counters_copy= cassandra_counters; + cassandra_counters_copy= cassandra_counters; var->type= SHOW_ARRAY; var->value= (char *) &cassandra_status_variables; diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index f32151849e5..947834685fd 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -106,7 +106,7 @@ class ha_cassandra: public handler /* Used to produce 'wrong column %s at row %lu' warnings */ ha_rows insert_lineno; - void print_conversion_error(const char *field_name, + void print_conversion_error(const char *field_name, char *cass_value, int cass_value_len); int connect_and_check_options(TABLE *table_arg); public: @@ -144,12 +144,12 @@ public: We are saying that this engine is just statement capable to have an engine that can only handle statement-based logging. This is used in testing. - HA_REC_NOT_IN_SEQ - If we don't set it, filesort crashes, because it assumes rowids are - 1..8 byte numbers + HA_REC_NOT_IN_SEQ + If we don't set it, filesort crashes, because it assumes rowids are + 1..8 byte numbers */ - return HA_BINLOG_STMT_CAPABLE | - HA_REC_NOT_IN_SEQ; + return HA_BINLOG_STMT_CAPABLE | + HA_REC_NOT_IN_SEQ; } @@ -191,7 +191,7 @@ public: support indexes. */ uint max_supported_key_length() const { return 16*1024; /* just to return something*/ } - + int index_init(uint idx, bool sorted); int index_read_map(uchar * buf, const uchar * key, @@ -211,19 +211,19 @@ public: virtual void start_bulk_insert(ha_rows rows); virtual int end_bulk_insert(); - + virtual int reset(); - + int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint mode, HANDLER_BUFFER *buf); int multi_range_read_next(range_id_t *range_info); ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, - void *seq_init_param, + void *seq_init_param, uint n_ranges, uint *bufsz, uint *flags, COST_VECT *cost); ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, - uint key_parts, uint *bufsz, + uint key_parts, uint *bufsz, uint *flags, COST_VECT *cost); int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size); -- cgit v1.2.1 From 40d62823cdd635d3aa11e7677faf6ccf2f11633b Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 28 Sep 2012 14:01:52 +0400 Subject: Fix compile warnings --- storage/cassandra/ha_cassandra.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index d77a89bded3..3b0db24cff0 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -160,8 +160,8 @@ cassandra_default_thrift_host_update(THD *thd, if (new_host) { - strncpy(cassandra_default_host_buf, new_host, max_len); - cassandra_default_host_buf[max_len]= 0; + strncpy(cassandra_default_host_buf, new_host, max_len-1); + cassandra_default_host_buf[max_len-1]= 0; cassandra_default_thrift_host= cassandra_default_host_buf; } else @@ -539,10 +539,8 @@ int ha_cassandra::check_table_options(ha_table_option_struct *options) int ha_cassandra::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { - ha_table_option_struct *options= table_arg->s->option_struct; int res; DBUG_ENTER("ha_cassandra::create"); - DBUG_ASSERT(options); Field **pfield= table_arg->s->field; if (!((*pfield)->flags & NOT_NULL_FLAG)) -- cgit v1.2.1 From aec2c55ac23bbbe32dd669eb291cb3d490795104 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 28 Sep 2012 14:02:59 +0400 Subject: Fix compile: expect Thrift where it is at buildbot. --- storage/cassandra/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt index f11dfaf4a29..d5f63229512 100644 --- a/storage/cassandra/CMakeLists.txt +++ b/storage/cassandra/CMakeLists.txt @@ -12,7 +12,8 @@ SET(cassandra_sources gen-cpp/Cassandra.h) #INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) +INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/) + # STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -- cgit v1.2.1 From 703d82c4ca62081cf1b890e56f6eac342b565b4c Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 28 Sep 2012 15:29:59 +0400 Subject: Include cassandra storage engine in tarballs --- cmake/build_configurations/mysql_release.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 5b2596491ad..1387eea4dcc 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -46,6 +46,8 @@ SET(FEATURE_SET_large 5) SET(FEATURE_SET_xlarge 6) SET(FEATURE_SET_community 7) +SET(WITH_CASSANDRA_STORAGE_ENGINE ON) + IF(FEATURE_SET) STRING(TOLOWER ${FEATURE_SET} feature_set) SET(num ${FEATURE_SET_${feature_set}}) -- cgit v1.2.1 From ce8484548b2a1e55bb6e1f798732f7d3a0e0c30d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Sep 2012 16:01:24 +0300 Subject: Fix of MDEV-565: Server crashes in ha_cassandra::write_row on inserting NULL into a dynamic column Fixed incorrect initialization of variable which caused freeing memory by random address in case of error. --- mysql-test/r/cassandra.result | 9 +++++++++ mysql-test/t/cassandra.test | 10 ++++++++++ storage/cassandra/CMakeLists.txt | 2 ++ storage/cassandra/ha_cassandra.cc | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 3cf286013b8..f6703580b7b 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -546,3 +546,12 @@ insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); ERROR HY000: Encountered illegal format of dynamic column string delete from t1; DROP TABLE t1; +# +# MDEV-565: Server crashes in ha_cassandra::write_row on +# inserting NULL into a dynamic column +# +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +insert into t1 values (1, NULL); +delete from t1; +DROP TABLE t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index b0b29c52f21..9ddd6e23d55 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -634,6 +634,16 @@ insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a'); delete from t1; DROP TABLE t1; +--echo # +--echo # MDEV-565: Server crashes in ha_cassandra::write_row on +--echo # inserting NULL into a dynamic column +--echo # +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +insert into t1 values (1, NULL); +delete from t1; +DROP TABLE t1; + ############################################################################ ## Cassandra cleanup diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt index d5f63229512..990012760e3 100644 --- a/storage/cassandra/CMakeLists.txt +++ b/storage/cassandra/CMakeLists.txt @@ -12,6 +12,8 @@ SET(cassandra_sources gen-cpp/Cassandra.h) #INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) + +#INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/) # diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 3b0db24cff0..3b0772fc3e1 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1978,7 +1978,7 @@ int ha_cassandra::write_row(uchar *buf) { String valcol; DYNAMIC_ARRAY vals, names; - char *free_names; + char *free_names= NULL; int rc; DBUG_ASSERT(field_converters[i] == NULL); if (!(rc= read_dyncol(&vals, &names, &valcol, &free_names))) -- cgit v1.2.1 From 665c93f8a79a835f3eea642a90cce752ec123bdf Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Sep 2012 07:58:01 +0300 Subject: Check of deleting whole dynamic columns. --- mysql-test/t/cassandra.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 9ddd6e23d55..cf0783a0ac8 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -644,6 +644,23 @@ insert into t1 values (1, NULL); delete from t1; DROP TABLE t1; +--echo # +--echo # strange side effect of Cassandra - remiving all columns of primary +--echo # key removes all row. +--echo # +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +INSERT INTO t1 VALUES(2,column_create("ab","ab")); +select rowkey, column_json(dyn) from t1; +UPDATE t1 set dyn=NULL; +select rowkey, column_json(dyn) from t1; +INSERT INTO t1 VALUES(2,column_create("ab","ab")); +select rowkey, column_json(dyn) from t1; +UPDATE t1 set dyn=""; +select rowkey, column_json(dyn) from t1; +delete from t1; +DROP TABLE t1; + ############################################################################ ## Cassandra cleanup -- cgit v1.2.1 From 7e5ef4077918841e24fb5309a90bbaebbc530ebe Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 20 Dec 2012 13:10:09 +0400 Subject: Cassandra Storage Engine: - Partially address review feedback. - Update cassandra.test result result - make cassandra.test timezone-agnostic --- mysql-test/r/cassandra.result | 31 ++++++++++++-- mysql-test/t/cassandra.test | 7 ++- storage/cassandra/CMakeLists.txt | 3 +- storage/cassandra/cassandra_se.cc | 9 ---- storage/cassandra/ha_cassandra.cc | 90 ++++++++------------------------------- storage/cassandra/ha_cassandra.h | 75 ++++---------------------------- 6 files changed, 61 insertions(+), 154 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index f6703580b7b..4eae1983bf3 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -1,7 +1,7 @@ drop table if exists t0, t1; create table t1 (a int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; -ERROR 42000: Incorrect column name 'First column must be NOT NULL' +ERROR 42000: This table type requires a primary key create table t1 (a int primary key, b int) engine=cassandra thrift_host='localhost' keyspace='foo' column_family='colfam'; ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace foo does not exist] @@ -356,6 +356,8 @@ drop table t2; # # Mapping TIMESTAMP -> int64 # +set @save_tz= @@time_zone; +set time_zone='UTC'; CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; insert into t2 values (1, '2012-08-29 01:23:45'); @@ -365,10 +367,11 @@ CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; select * from t2; rowkey datecol -1 1346192625000 -10 1346192626000 +1 1346203425000 +10 1346203426000 delete from t2; drop table t2; +set time_zone=@save_tz; # # Check whether changing parameters with ALTER TABLE works. # @@ -555,3 +558,25 @@ ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = insert into t1 values (1, NULL); delete from t1; DROP TABLE t1; +# +# strange side effect of Cassandra - remiving all columns of primary +# key removes all row. +# +CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) +ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; +INSERT INTO t1 VALUES(2,column_create("ab","ab")); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +2 [{"ab":"ab"}] +UPDATE t1 set dyn=NULL; +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +INSERT INTO t1 VALUES(2,column_create("ab","ab")); +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +2 [{"ab":"ab"}] +UPDATE t1 set dyn=""; +select rowkey, column_json(dyn) from t1; +rowkey column_json(dyn) +delete from t1; +DROP TABLE t1; diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index cf0783a0ac8..542987a869a 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -8,9 +8,9 @@ drop table if exists t0, t1; --enable_warnings # Test various errors on table creation. ---error ER_WRONG_COLUMN_NAME +--error ER_REQUIRES_PRIMARY_KEY create table t1 (a int) engine=cassandra - thrift_host='localhost' keyspace='foo' column_family='colfam'; + thrift_host='localhost' keyspace='foo' column_family='colfam'; --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE create table t1 (a int primary key, b int) engine=cassandra @@ -466,6 +466,8 @@ drop table t2; --echo # --echo # Mapping TIMESTAMP -> int64 --echo # +set @save_tz= @@time_zone; +set time_zone='UTC'; CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol timestamp) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4'; insert into t2 values (1, '2012-08-29 01:23:45'); @@ -477,6 +479,7 @@ CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA select * from t2; delete from t2; drop table t2; +set time_zone=@save_tz; --echo # --echo # Check whether changing parameters with ALTER TABLE works. diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt index 990012760e3..7e92d3cc0bd 100644 --- a/storage/cassandra/CMakeLists.txt +++ b/storage/cassandra/CMakeLists.txt @@ -14,7 +14,8 @@ SET(cassandra_sources #INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) #INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) -INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/) +#INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/) +INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/) # STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/storage/cassandra/cassandra_se.cc b/storage/cassandra/cassandra_se.cc index 9e2b815c488..0d62c5af7a6 100644 --- a/storage/cassandra/cassandra_se.cc +++ b/storage/cassandra/cassandra_se.cc @@ -30,15 +30,6 @@ using namespace apache::thrift::protocol; using namespace org::apache::cassandra; -void Cassandra_se_interface::print_error(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - // it's not a problem if output was truncated - vsnprintf(err_buffer, sizeof(err_buffer), format, ap); - va_end(ap); -} - /* Implementation of connection to one Cassandra column family (ie., table) */ diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 3b0772fc3e1..5aa3226c9b4 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -542,13 +542,6 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, int res; DBUG_ENTER("ha_cassandra::create"); - Field **pfield= table_arg->s->field; - if (!((*pfield)->flags & NOT_NULL_FLAG)) - { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL"); - DBUG_RETURN(HA_WRONG_CREATE_OPTION); - } - if (table_arg->s->keys != 1 || table_arg->s->primary_key !=0 || table_arg->key_info[0].key_parts != 1 || table_arg->key_info[0].key_part[0].fieldnr != 1) @@ -1680,7 +1673,7 @@ void ha_cassandra::print_conversion_error(const char *field_name, char buf[32]; char *p= cass_value; size_t i= 0; - for (; (i < (int)sizeof(buf)-1) && (p < cass_value + cass_value_len); p++) + for (; (i < sizeof(buf)-1) && (p < cass_value + cass_value_len); p++) { buf[i++]= map2number[(*p >> 4) & 0xF]; buf[i++]= map2number[*p & 0xF]; @@ -2163,7 +2156,7 @@ int ha_cassandra::info(uint flag) if (flag & HA_STATUS_VARIABLE) { stats.records= 1000; - //TODO: any other stats? + stats.deleted= 0; } if (flag & HA_STATUS_CONST) { @@ -2346,55 +2339,6 @@ int ha_cassandra::multi_range_read_explain_info(uint mrr_mode, char *str, size_t } -///////////////////////////////////////////////////////////////////////////// -// Dummy implementations start -///////////////////////////////////////////////////////////////////////////// - - -int ha_cassandra::index_next(uchar *buf) -{ - int rc; - DBUG_ENTER("ha_cassandra::index_next"); - rc= HA_ERR_WRONG_COMMAND; - DBUG_RETURN(rc); -} - - -int ha_cassandra::index_prev(uchar *buf) -{ - int rc; - DBUG_ENTER("ha_cassandra::index_prev"); - rc= HA_ERR_WRONG_COMMAND; - DBUG_RETURN(rc); -} - - -int ha_cassandra::index_first(uchar *buf) -{ - int rc; - DBUG_ENTER("ha_cassandra::index_first"); - rc= HA_ERR_WRONG_COMMAND; - DBUG_RETURN(rc); -} - -int ha_cassandra::index_last(uchar *buf) -{ - int rc; - DBUG_ENTER("ha_cassandra::index_last"); - rc= HA_ERR_WRONG_COMMAND; - DBUG_RETURN(rc); -} - - -ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, - key_range *max_key) -{ - DBUG_ENTER("ha_cassandra::records_in_range"); - //DBUG_RETURN(10); // low number to force index usage - DBUG_RETURN(HA_POS_ERROR); -} - - class Column_name_enumerator_impl : public Column_name_enumerator { ha_cassandra *obj; @@ -2550,13 +2494,6 @@ err: } -int ha_cassandra::extra(enum ha_extra_function operation) -{ - DBUG_ENTER("ha_cassandra::extra"); - DBUG_RETURN(0); -} - - /* The following function was copied from ha_blackhole::store_lock: */ THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, THR_LOCK_DATA **to, @@ -2595,18 +2532,20 @@ THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, } -int ha_cassandra::external_lock(THD *thd, int lock_type) +ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - DBUG_ENTER("ha_cassandra::external_lock"); - DBUG_RETURN(0); + DBUG_ENTER("ha_cassandra::records_in_range"); + DBUG_RETURN(HA_POS_ERROR); /* Range scans are not supported */ } + int ha_cassandra::delete_table(const char *name) { DBUG_ENTER("ha_cassandra::delete_table"); /* Cassandra table is just a view. Dropping it doesn't affect the underlying - column family. + column family, so we do nothing here. */ DBUG_RETURN(0); } @@ -2632,9 +2571,15 @@ bool ha_cassandra::check_if_incompatible_data(HA_CREATE_INFO *info, } -///////////////////////////////////////////////////////////////////////////// -// Dummy implementations end -///////////////////////////////////////////////////////////////////////////// +void Cassandra_se_interface::print_error(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + // it's not a problem if output was truncated + my_vsnprintf(err_buffer, sizeof(err_buffer), format, ap); + va_end(ap); +} + static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) { @@ -2655,6 +2600,7 @@ static struct st_mysql_show_var func_status[]= {0,0,SHOW_UNDEF} }; + maria_declare_plugin(cassandra) { MYSQL_STORAGE_ENGINE_PLUGIN, diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 947834685fd..3954c7850ef 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -139,18 +139,13 @@ public: */ ulonglong table_flags() const { - /* - HA_BINLOG_STMT_CAPABLE - We are saying that this engine is just statement capable to have - an engine that can only handle statement-based logging. This is - used in testing. - HA_REC_NOT_IN_SEQ - If we don't set it, filesort crashes, because it assumes rowids are - 1..8 byte numbers - */ return HA_BINLOG_STMT_CAPABLE | - HA_REC_NOT_IN_SEQ; - + HA_REC_NOT_IN_SEQ | + HA_NO_TRANSACTIONS | + HA_REQUIRE_PRIMARY_KEY | + HA_PRIMARY_KEY_IN_READ_INDEX | + HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | + HA_NO_AUTO_INCREMENT; } /** @brief @@ -239,65 +234,13 @@ private: CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name, int cass_name_length); public: + int open(const char *name, int mode, uint test_if_locked); + int close(void); - /* - Everything below are methods that we implement in ha_example.cc. - - Most of these methods are not obligatory, skip them and - MySQL will treat them as not implemented - */ - /** @brief - We implement this in ha_example.cc; it's a required method. - */ - int open(const char *name, int mode, uint test_if_locked); // required - - /** @brief - We implement this in ha_example.cc; it's a required method. - */ - int close(void); // required - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ int write_row(uchar *buf); - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ int update_row(const uchar *old_data, uchar *new_data); - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ int delete_row(const uchar *buf); - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_next(uchar *buf); - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_prev(uchar *buf); - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_first(uchar *buf); - - /** @brief - We implement this in ha_example.cc. It's not an obligatory method; - skip it and and MySQL will treat it as not implemented. - */ - int index_last(uchar *buf); - /** @brief Unlike index_init(), rnd_init() can be called two consecutive times without rnd_end() in between (it only makes sense if scan=1). In this @@ -312,8 +255,6 @@ public: int rnd_pos(uchar *buf, uchar *pos); ///< required void position(const uchar *record); ///< required int info(uint); ///< required - int extra(enum ha_extra_function operation); - int external_lock(THD *thd, int lock_type); ///< required int delete_all_rows(void); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); -- cgit v1.2.1 From 6b47b2fe986f22cc3db4c3b8727783a4b392909e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 20 Dec 2012 14:15:56 +0400 Subject: Cassandra Storage Engine: Address review feedback part # 2 - Register counters directly in the array passed to maria_declare_plugin. As a consequence, FLUSH TABLES will reset the counters. - Update test results accordingly. --- mysql-test/r/cassandra.result | 14 ++++----- storage/cassandra/ha_cassandra.cc | 62 ++++++++++++++------------------------- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 4eae1983bf3..55607726458 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -74,8 +74,8 @@ Variable_name Value cassandra_insert_batch_size 100 show status like 'cassandra_row_insert%'; Variable_name Value -Cassandra_row_inserts 8 Cassandra_row_insert_batches 7 +Cassandra_row_inserts 8 CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; delete from t1; @@ -84,14 +84,14 @@ DELETE FROM t1 ORDER BY a LIMIT 1; DROP TABLE t1; show status like 'cassandra_row_insert%'; Variable_name Value -Cassandra_row_inserts 10 Cassandra_row_insert_batches 8 +Cassandra_row_inserts 10 # FLUSH STATUS doesn't work for our variables, just like with InnoDB. flush status; show status like 'cassandra_row_insert%'; Variable_name Value -Cassandra_row_inserts 10 -Cassandra_row_insert_batches 8 +Cassandra_row_insert_batches 0 +Cassandra_row_inserts 0 # # Batched Key Access # @@ -102,8 +102,8 @@ cassandra_multiget_batch_size 100 # MRR-related status variables: show status like 'cassandra_multi%'; Variable_name Value -Cassandra_multiget_reads 0 Cassandra_multiget_keys_scanned 0 +Cassandra_multiget_reads 0 Cassandra_multiget_rows_read 0 CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, a BIGINT) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2'; @@ -129,8 +129,8 @@ rowkey a rowkey a 9 9 9 9 show status like 'cassandra_multi%'; Variable_name Value -Cassandra_multiget_reads 1 Cassandra_multiget_keys_scanned 10 +Cassandra_multiget_reads 1 Cassandra_multiget_rows_read 10 insert into t1 values(1, 8); insert into t1 values(3, 8); @@ -150,8 +150,8 @@ rowkey a rowkey a 9 9 9 9 show status like 'cassandra_multi%'; Variable_name Value -Cassandra_multiget_reads 2 Cassandra_multiget_keys_scanned 16 +Cassandra_multiget_reads 2 Cassandra_multiget_rows_read 16 delete from t1; drop table t1; diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 5aa3226c9b4..d85fa942029 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -195,31 +195,7 @@ static struct st_mysql_sys_var* cassandra_system_variables[]= { NULL }; - -static SHOW_VAR cassandra_status_variables[]= { - {"row_inserts", - (char*) &cassandra_counters.row_inserts, SHOW_LONG}, - {"row_insert_batches", - (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, - - {"multiget_reads", - (char*) &cassandra_counters.multiget_reads, SHOW_LONG}, - {"multiget_keys_scanned", - (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, - {"multiget_rows_read", - (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, - - {"timeout_exceptions", - (char*) &cassandra_counters.timeout_exceptions, SHOW_LONG}, - {"unavailable_exceptions", - (char*) &cassandra_counters.unavailable_exceptions, SHOW_LONG}, - {NullS, NullS, SHOW_LONG} -}; - - Cassandra_status_vars cassandra_counters; -Cassandra_status_vars cassandra_counters_copy; - /** @brief @@ -2581,26 +2557,32 @@ void Cassandra_se_interface::print_error(const char *format, ...) } -static int show_cassandra_vars(THD *thd, SHOW_VAR *var, char *buff) -{ - cassandra_counters_copy= cassandra_counters; - - var->type= SHOW_ARRAY; - var->value= (char *) &cassandra_status_variables; - return 0; -} - - struct st_mysql_storage_engine cassandra_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; -static struct st_mysql_show_var func_status[]= -{ - {"Cassandra", (char *)show_cassandra_vars, SHOW_FUNC}, - {0,0,SHOW_UNDEF} +static SHOW_VAR cassandra_status_variables[]= { + {"Cassandra_row_inserts", + (char*) &cassandra_counters.row_inserts, SHOW_LONG}, + {"Cassandra_row_insert_batches", + (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, + + {"Cassandra_multiget_keys_scanned", + (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, + {"Cassandra_multiget_reads", + (char*) &cassandra_counters.multiget_reads, SHOW_LONG}, + {"Cassandra_multiget_rows_read", + (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, + + {"Cassandra_timeout_exceptions", + (char*) &cassandra_counters.timeout_exceptions, SHOW_LONG}, + {"Cassandra_unavailable_exceptions", + (char*) &cassandra_counters.unavailable_exceptions, SHOW_LONG}, + {NullS, NullS, SHOW_LONG} }; + + maria_declare_plugin(cassandra) { MYSQL_STORAGE_ENGINE_PLUGIN, @@ -2611,8 +2593,8 @@ maria_declare_plugin(cassandra) PLUGIN_LICENSE_GPL, cassandra_init_func, /* Plugin Init */ cassandra_done_func, /* Plugin Deinit */ - 0x0001, /* version number (0.1) */ - func_status, /* status variables */ + 0x0001, /* version number (0.1) */ + cassandra_status_variables, /* status variables */ cassandra_system_variables, /* system variables */ "0.1", /* string version */ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */ -- cgit v1.2.1 From 28c9e1a550bc9f2c2dbb28304d22552ea944cf07 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 20 Dec 2012 14:30:09 +0400 Subject: Cassandra Storage Engine: Address review feedback part #3 - Cleanup ha_cassandra::store_lock() - Remove dummy ha_cassandra::delete_table() - Add HA_TABLE_SCAN_ON_INDEX to table_flags() --- storage/cassandra/ha_cassandra.cc | 47 ++++++++++++++------------------------- storage/cassandra/ha_cassandra.h | 4 ++-- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index d85fa942029..a54190e080c 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -1605,7 +1605,10 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key, DBUG_ENTER("ha_cassandra::index_read_map"); if (find_flag != HA_READ_KEY_EXACT) + { + DBUG_ASSERT(0); /* Non-equality lookups should never be done */ DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } uint key_len= calculate_key_len(table, active_index, key, keypart_map); store_key_image_to_rec(table->field[0], (uchar*)key, key_len); @@ -2470,7 +2473,16 @@ err: } -/* The following function was copied from ha_blackhole::store_lock: */ +/* + We can't really have any locks for Cassandra Storage Engine. We're reading + from Cassandra cluster, and other clients can asynchronously modify the data. + + We can enforce locking within this process, but this will not be useful. + + Thus, store_lock() should express that: + - Writes do not block other writes + - Reads should not block anything either, including INSERTs. +*/ THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) @@ -2478,27 +2490,13 @@ THR_LOCK_DATA **ha_cassandra::store_lock(THD *thd, DBUG_ENTER("ha_cassandra::store_lock"); if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { - /* - Here is where we get into the guts of a row level lock. - If TL_UNLOCK is set - If we are not doing a LOCK TABLE or DISCARD/IMPORT - TABLESPACE, then allow multiple writers - */ - + /* Writes allow other writes */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && - lock_type <= TL_WRITE) && !thd_in_lock_tables(thd) - && !thd_tablespace_op(thd)) + lock_type <= TL_WRITE)) lock_type = TL_WRITE_ALLOW_WRITE; - /* - In queries of type INSERT INTO t1 SELECT ... FROM t2 ... - MySQL would use the lock TL_READ_NO_INSERT on t2, and that - would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts - to t2. Convert the lock to a normal read lock to allow - concurrent inserts to t2. - */ - - if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd)) + /* Reads allow everything, including INSERTs */ + if (lock_type == TL_READ_NO_INSERT) lock_type = TL_READ; lock.type= lock_type; @@ -2516,17 +2514,6 @@ ha_rows ha_cassandra::records_in_range(uint inx, key_range *min_key, } -int ha_cassandra::delete_table(const char *name) -{ - DBUG_ENTER("ha_cassandra::delete_table"); - /* - Cassandra table is just a view. Dropping it doesn't affect the underlying - column family, so we do nothing here. - */ - DBUG_RETURN(0); -} - - /** check_if_incompatible_data() called if ALTER TABLE can't detect otherwise if new and old definition are compatible diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index 3954c7850ef..be8a49af493 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -145,7 +145,8 @@ public: HA_REQUIRE_PRIMARY_KEY | HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | - HA_NO_AUTO_INCREMENT; + HA_NO_AUTO_INCREMENT | + HA_TABLE_SCAN_ON_INDEX; } /** @brief @@ -258,7 +259,6 @@ public: int delete_all_rows(void); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); - int delete_table(const char *from); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); ///< required bool check_if_incompatible_data(HA_CREATE_INFO *info, -- cgit v1.2.1 From 40ae63dd65fb9e812f29d3520acb0ba6b64d3005 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Dec 2012 20:57:54 +0200 Subject: backport to 5.5 dyncol changes and names support --- include/ma_dyncol.h | 110 +-- include/my_sys.h | 7 +- mysql-test/r/cassandra.result | 2 +- mysql-test/r/dyncol.result | 116 ++- mysql-test/t/cassandra.test | 2 +- mysql-test/t/dyncol.test | 43 +- mysys/ma_dyncol.c | 1421 ++++++++++++++++++++++++------------- mysys/string.c | 10 +- sql/item_cmpfunc.cc | 7 +- sql/item_create.cc | 89 ++- sql/item_func.h | 2 +- sql/item_strfunc.cc | 154 ++-- sql/item_strfunc.h | 6 +- sql/lex.h | 3 - sql/sql_join_cache.cc | 4 +- sql/sql_yacc.yy | 27 - storage/cassandra/CMakeLists.txt | 4 +- storage/cassandra/ha_cassandra.cc | 227 +++--- storage/cassandra/ha_cassandra.h | 18 +- 19 files changed, 1449 insertions(+), 803 deletions(-) diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h index 2264ec6f53f..78d3f15978c 100644 --- a/include/ma_dyncol.h +++ b/include/ma_dyncol.h @@ -38,12 +38,13 @@ how the offset are stored. */ #define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL +#define MAX_DYNAMIC_COLUMN_LENGTH_NM 0XFFFFFFFFFL /* Limits of implementation */ -#define MAX_NAME_LENGTH 255 #define MAX_TOTAL_NAME_LENGTH 65535 +#define MAX_NAME_LENGTH (MAX_TOTAL_NAME_LENGTH/4) /* NO and OK is the same used just to show semantics */ #define ER_DYNCOL_NO ER_DYNCOL_OK @@ -72,7 +73,8 @@ enum enum_dynamic_column_type DYN_COL_DECIMAL, DYN_COL_DATETIME, DYN_COL_DATE, - DYN_COL_TIME + DYN_COL_TIME, + DYN_COL_DYNCOL }; typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE; @@ -88,7 +90,6 @@ struct st_dynamic_column_value struct { LEX_STRING value; CHARSET_INFO *charset; - my_bool nonfreeable; } string; struct { decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; @@ -100,6 +101,8 @@ struct st_dynamic_column_value typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; +/* old functions (deprecated) */ +#ifdef MADYNCOL_DEPRECATED enum enum_dyncol_func_result dynamic_column_create(DYNAMIC_COLUMN *str, uint column_nr, DYNAMIC_COLUMN_VALUE *value); @@ -109,21 +112,6 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str, uint column_count, uint *column_numbers, DYNAMIC_COLUMN_VALUE *values); - -enum enum_dyncol_func_result -dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str, - uint column_count, - uchar *column_keys, - DYNAMIC_COLUMN_VALUE *values, - my_bool names); -enum enum_dyncol_func_result -dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str, - uint column_count, - void *column_keys, - DYNAMIC_COLUMN_VALUE *values, - my_bool new_str, - my_bool string_keys); - enum enum_dyncol_func_result dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, DYNAMIC_COLUMN_VALUE *value); @@ -133,73 +121,105 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, uint *column_numbers, DYNAMIC_COLUMN_VALUE *values); enum enum_dyncol_func_result -dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, - uint add_column_count, - void *column_keys, - DYNAMIC_COLUMN_VALUE *values, - my_bool string_keys); - -enum enum_dyncol_func_result dynamic_column_delete(DYNAMIC_COLUMN *org, uint column_nr); enum enum_dyncol_func_result dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr); + enum enum_dyncol_func_result -dynamic_column_exists_str(DYNAMIC_COLUMN *str, LEX_STRING *name); +dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); + enum enum_dyncol_func_result -dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_keys); +dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, + DYNAMIC_COLUMN_VALUE *store_it_here); +#endif -/* List of not NULL columns */ +/* new functions */ enum enum_dyncol_func_result -dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); +mariadb_dyncol_create_many(DYNAMIC_COLUMN *str, + uint column_count, + uint *column_numbers, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_string); enum enum_dyncol_func_result -dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr); +mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str, + uint column_count, + LEX_STRING *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_string); + + +enum enum_dyncol_func_result +mariadb_dyncol_update_many(DYNAMIC_COLUMN *str, + uint add_column_count, + uint *column_keys, + DYNAMIC_COLUMN_VALUE *values); +enum enum_dyncol_func_result +mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str, + uint add_column_count, + LEX_STRING *column_keys, + DYNAMIC_COLUMN_VALUE *values); + + +enum enum_dyncol_func_result +mariadb_dyncol_exists(DYNAMIC_COLUMN *org, uint column_nr); enum enum_dyncol_func_result -dynamic_column_list_fmt(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array, my_bool string_keys); +mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, LEX_STRING *name); + +/* List of not NULL columns */ +enum enum_dyncol_func_result +mariadb_dyncol_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); +enum enum_dyncol_func_result +mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, LEX_STRING **names); /* if the column do not exists it is NULL */ enum enum_dyncol_func_result -dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, +mariadb_dyncol_get(DYNAMIC_COLUMN *org, uint column_nr, DYNAMIC_COLUMN_VALUE *store_it_here); enum enum_dyncol_func_result -dynamic_column_get_str(DYNAMIC_COLUMN *str, LEX_STRING *name, - DYNAMIC_COLUMN_VALUE *store_it_here); +mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, LEX_STRING *name, + DYNAMIC_COLUMN_VALUE *store_it_here); -my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str); +my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str); enum enum_dyncol_func_result -dynamic_column_check(DYNAMIC_COLUMN *str); +mariadb_dyncol_check(DYNAMIC_COLUMN *str); enum enum_dyncol_func_result -dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); +mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); #define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A))) #define dynamic_column_column_free(V) dynstr_free(V) /* conversion of values to 3 base types */ enum enum_dyncol_func_result -dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, +mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, CHARSET_INFO *cs, my_bool quote); enum enum_dyncol_func_result -dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); +mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); +enum enum_dyncol_func_result +mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val); + + enum enum_dyncol_func_result -dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val); +mariadb_dyncol_unpack(DYNAMIC_COLUMN *str, + uint *count, + LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals); +int mariadb_dyncol_column_cmp_named(const LEX_STRING *s1, const LEX_STRING *s2); enum enum_dyncol_func_result -dynamic_column_vals(DYNAMIC_COLUMN *str, - DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals, - char **free_names); +mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count); /*************************************************************************** Internal functions, don't use if you don't know what you are doing... ***************************************************************************/ -#define dynamic_column_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A)) +#define mariadb_dyncol_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A)) -#define dynamic_column_value_init(V) (V)->type= DYN_COL_NULL +#define dyncol_value_init(V) (V)->type= DYN_COL_NULL /* Prepare value for using as decimal diff --git a/include/my_sys.h b/include/my_sys.h index 58a343bb789..f56c29afeae 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -794,11 +794,16 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append, extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...); extern my_bool dynstr_append_quoted(DYNAMIC_STRING *str, - const char *append, size_t len); + const char *append, size_t len, + char quote); extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str); extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size); extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n); extern void dynstr_free(DYNAMIC_STRING *str); +extern uint32 copy_and_convert_extended(char *to, uint32 to_length, + CHARSET_INFO *to_cs, + const char *from, uint32 from_length, + CHARSET_INFO *from_cs, uint *errors); extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length, size_t *alloc_length); extern uint32 copy_and_convert_extended(char *to, uint32 to_length, diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index 55607726458..b5ff3194480 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -532,7 +532,7 @@ delete from t1; drop table t1; CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1'; select * from t1; -ERROR HY000: Internal error: 'Unable to convert value for field `dyn` from Cassandra's data format. Name length exceed limit of 255: 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_ver' +ERROR HY000: Internal error: 'Unable to convert value for field `dyn` from Cassandra's data format. Name length exceed limit of 16383: 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_v' drop table t1; CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2'; diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index 2e9a8462eee..c8d23d75d6c 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1342,22 +1342,22 @@ hex(COLUMN_CREATE(0, 0.0 as decimal)) set names utf8; select hex(column_create("адын", 1212)); hex(column_create("адын", 1212)) -040100080008000000D0B0D0B4D18BD0BD7809 +040100080000000000D0B0D0B4D18BD0BD7809 select hex(column_create("1212", 1212)); hex(column_create("1212", 1212)) -040100040004000000313231327809 +040100040000000000313231327809 select hex(column_create(1212, 2, "www", 3)); hex(column_create(1212, 2, "www", 3)) -04020007000300000004030008777777313231320604 +04020007000000000003001000777777313231320604 select hex(column_create("1212", 2, "www", 3)); hex(column_create("1212", 2, "www", 3)) -04020007000300000004030008777777313231320604 +04020007000000000003001000777777313231320604 select hex(column_create("1212", 2, 3, 3)); hex(column_create("1212", 2, 3, 3)) -0402000500010000000401000833313231320604 +0402000500000000000100100033313231320604 select hex(column_create("1212", 2, "адын", 1, 3, 3)); hex(column_create("1212", 2, "адын", 1, 3, 3)) -0403000D000100000004010008080500103331323132D0B0D0B4D18BD0BD060402 +0403000D000000000001001000050020003331323132D0B0D0B4D18BD0BD060402 set names default; # fetching column test (names) set names utf8; @@ -1413,10 +1413,10 @@ set names default; # column changing test (names) select hex(column_add(column_create(1, "AAA"), "b", "BBB")); hex(column_add(column_create(1, "AAA"), "b", "BBB")) -0402000200010000030101002331620841414108424242 +0402000200000003000100430031620841414108424242 select hex(column_add(column_create("1", "AAA"), "b", "BBB")); hex(column_add(column_create("1", "AAA"), "b", "BBB")) -0402000200010000030101002331620841414108424242 +0402000200000003000100430031620841414108424242 select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char); column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char) AAA @@ -1425,25 +1425,25 @@ column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char) BBB select hex(column_add(column_create("a", "AAA"), 1, "BBB")); hex(column_add(column_create("a", "AAA"), 1, "BBB")) -0402000200010000030101002331610842424208414141 +0402000200000003000100430031610842424208414141 select hex(column_add(column_create("a", "AAA"), "1", "BBB")); hex(column_add(column_create("a", "AAA"), "1", "BBB")) -0402000200010000030101002331610842424208414141 +0402000200000003000100430031610842424208414141 select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)); hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer)) -04020002000100000001010010616278097809 +04020002000000000001002000616278097809 select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)); hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer)) -040100010001000000617809 +040100010000000000617809 select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)); hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer)) 0400000000 select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)); hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer)) -040100010001000000617809 +040100010000000000617809 select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)); hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer)) -040200020001000000010100086162167809 +040200020000000000010010006162167809 select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer); column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer) 11 @@ -1452,13 +1452,13 @@ column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, 1212 select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)); hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer)) -040200020001000000010100106162780916 +040200020000000000010020006162780916 select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)); hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer)) -040200020001000000010100106162780916 +040200020000000000010020006162780916 select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)); hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer)) -040200020001000000010100086162167809 +040200020000000000010010006162167809 select hex(column_add(column_create("a", 1), "a", null)); hex(column_add(column_create("a", 1), "a", null)) 0400000000 @@ -1470,29 +1470,29 @@ column_list(column_add(column_create("a", 1), "a", "")) `a` select hex(column_add("", "a", 1)); hex(column_add("", "a", 1)) -0401000100010000006102 +0401000100000000006102 # column delete (names) select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")); hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a")) -040100010001000000627809 +040100010000000000627809 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b")) -0402000200010000000101000861630206 +0402000200000000000100100061630206 select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)); hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer)) -0403000300010000000101000801020010616263020406 +0403000300000000000100100002002000616263020406 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c")) -0402000200010000000101000861620204 +0402000200000000000100100061620204 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d")) -0403000300010000000101000801020010616263020406 +0403000300000000000100100002002000616263020406 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a")) -0401000100010000006306 +0401000100000000006306 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c")) -0401000100010000006102 +0401000100000000006102 select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")); hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c")) 0400000000 @@ -1517,11 +1517,21 @@ ERROR 42S22: Unknown column 'color' in 'field list' # CREATE TABLE t1 (f1 tinyblob); INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30))); +select column_check(f1) from t1; +column_check(f1) +1 UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' ); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 +select column_check(f1) from t1; +column_check(f1) +0 UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' ); -ERROR HY000: Encountered illegal format of dynamic column string +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 +select column_check(f1) from t1; +column_check(f1) +0 drop table t1; # # MDEV-490/MDEV-491 null as arguments @@ -1550,8 +1560,8 @@ NULL # SELECT hex(COLUMN_CREATE(REPEAT('a',255),1)); hex(COLUMN_CREATE(REPEAT('a',255),1)) -040100FF00FF00000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102 -SELECT hex(COLUMN_CREATE(REPEAT('a',256),1)); +040100FF000000000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102 +SELECT hex(COLUMN_CREATE(REPEAT('a',65536),1)); ERROR 22007: Illegal value used as argument of dynamic column function # # JSON conversion @@ -1577,3 +1587,53 @@ COLUMN_CHECK('') SELECT COLUMN_CHECK(NULL); COLUMN_CHECK(NULL) NULL +# +# escaping check +# +select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_create("string", "'\"/\\`.,whatever")); +column_json(column_create("string", "'\"/\\`.,whatever")) hex(column_create("string", "'\"/\\`.,whatever")) +[{"string":"'\"/\\`.,whatever"}] 040100060000000300737472696E670827222F5C602E2C7768617465766572 +# +# embedding test +# +select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))); +column_json(column_create("val", "val", "emb", column_create("val2", "val2"))) +[{"emb":[{"val2":"val2"}],{"val":"val"}] +select column_json(column_create(1, "val", 2, column_create(3, "val2"))); +column_json(column_create(1, "val", 2, column_create(3, "val2"))) +[{"1":"val"},{"2":[{"3":"val2"}]] +# +# Time encoding +# +select hex(column_create("t", "800:46:06.23434" AS time)) as hex, +column_json(column_create("t", "800:46:06.23434" AS time)) as json; +hex json +04010001000000070074649363B82003 [{"t":"800:46:06.234340"}] +select hex(column_create(1, "800:46:06.23434" AS time)) as hex, +column_json(column_create(1, "800:46:06.23434" AS time)) as json; +hex json +000100010007649363B82003 [{"1":"800:46:06.234340"}] +select hex(column_create("t", "800:46:06" AS time)) as hex, +column_json(column_create("t", "800:46:06" AS time)) as json; +hex json +04010001000000070074860B32 [{"t":"800:46:06"}] +select hex(column_create(1, "800:46:06" AS time)) as hex, +column_json(column_create(1, "800:46:06" AS time)) as json; +hex json +000100010007000060B82003 [{"1":"800:46:06"}] +select hex(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as hex, +column_json(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as json; +hex json +0401000100000005007495B90F649363B80A00 [{"t":"2012-12-21 10:46:06.234340"}] +select hex(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as hex, +column_json(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as json; +hex json +00010001000595B90F649363B80A00 [{"1":"2012-12-21 10:46:06.234340"}] +select hex(column_create("t", "2012-12-21 10:46:06" AS datetime)) as hex, +column_json(column_create("t", "2012-12-21 10:46:06" AS datetime)) as json; +hex json +0401000100000005007495B90F86AB00 [{"t":"2012-12-21 10:46:06"}] +select hex(column_create(1, "2012-12-21 10:46:06" AS datetime)) as hex, +column_json(column_create(1, "2012-12-21 10:46:06" AS datetime)) as json; +hex json +00010001000595B90F000060B80A00 [{"1":"2012-12-21 10:46:06"}] diff --git a/mysql-test/t/cassandra.test b/mysql-test/t/cassandra.test index 542987a869a..93c81086de8 100644 --- a/mysql-test/t/cassandra.test +++ b/mysql-test/t/cassandra.test @@ -99,7 +99,7 @@ CREATE COLUMN FAMILY cfd1 WITH comparator = UTF8Type AND key_validation_class=UTF8Type AND default_validation_class = UTF8Type; -SET cfd1['1']['very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_name']='1'; +SET cfd1['1']['very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_name']='1'; CREATE COLUMN FAMILY cfd2 WITH comparator = UTF8Type diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 143a833fe8d..de30cac610a 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -636,9 +636,14 @@ select COLUMN_CREATE(color, "black"); CREATE TABLE t1 (f1 tinyblob); INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30))); +select column_check(f1) from t1; UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' ); ---error ER_DYN_COL_WRONG_FORMAT +# we can't detect last string cut with 100% probability, +# because we detect it by string end +select column_check(f1) from t1; UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' ); +select column_check(f1) from t1; + drop table t1; --echo # @@ -657,7 +662,7 @@ SELECT COLUMN_ADD( NULL, 'val', 'col'); --echo # SELECT hex(COLUMN_CREATE(REPEAT('a',255),1)); --error ER_DYN_COL_DATA -SELECT hex(COLUMN_CREATE(REPEAT('a',256),1)); +SELECT hex(COLUMN_CREATE(REPEAT('a',65536),1)); --echo # --echo # JSON conversion @@ -672,3 +677,37 @@ SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a')); SELECT COLUMN_CHECK('abracadabra'); SELECT COLUMN_CHECK(''); SELECT COLUMN_CHECK(NULL); + +--echo # +--echo # escaping check +--echo # +select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_create("string", "'\"/\\`.,whatever")); + +--echo # +--echo # embedding test +--echo # +select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))); +select column_json(column_create(1, "val", 2, column_create(3, "val2"))); + +--echo # +--echo # Time encoding +--echo # +select hex(column_create("t", "800:46:06.23434" AS time)) as hex, + column_json(column_create("t", "800:46:06.23434" AS time)) as json; +select hex(column_create(1, "800:46:06.23434" AS time)) as hex, + column_json(column_create(1, "800:46:06.23434" AS time)) as json; + +select hex(column_create("t", "800:46:06" AS time)) as hex, + column_json(column_create("t", "800:46:06" AS time)) as json; +select hex(column_create(1, "800:46:06" AS time)) as hex, + column_json(column_create(1, "800:46:06" AS time)) as json; + +select hex(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as hex, + column_json(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as json; +select hex(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as hex, + column_json(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as json; + +select hex(column_create("t", "2012-12-21 10:46:06" AS datetime)) as hex, + column_json(column_create("t", "2012-12-21 10:46:06" AS datetime)) as json; +select hex(column_create(1, "2012-12-21 10:46:06" AS datetime)) as hex, + column_json(column_create(1, "2012-12-21 10:46:06" AS datetime)) as json; diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index e7c9b835454..34bb8b9de3d 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2011, Monty Program Ab - Copyright (c) 2011, Oleksandr Byelkin +/* Copyright (c) 2011,2012 Monty Program Ab; + Copyright (c) 2011,2012 Oleksandr Byelkin Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -26,6 +26,40 @@ SUCH DAMAGE. */ +/* + Numeric format: + =============== + * Fixed header part + 1 byte flags: + 0,1 bits - - 1 + 2-7 bits - 0 + 2 bytes column counter + * Columns directory sorted by column number, each entry contains of: + 2 bytes column number + bytes (1-4) combined offset from beginning of + the data segment + 3 bit type + * Data of above columns size of data and length depend on type + + Columns with names: + =================== + * Fixed header part + 1 byte flags: + 0,1 bits - - 2 + 2 bit - 1 (means format with names) + 3,4 bits - 00 (means - 2, + now 2 is the only supported size) + 5-7 bits - 0 + 2 bytes column counter + * Variable header part (now it is actually fixed part) + (2) bytes size of stored names pool + * Column directory sorted by names, each consists of + (2) bytes offset of name + bytes (2-5)bytes combined offset from beginning of + the data segment + 4 bit type + * Names stored one after another + * Data of above columns size of data and length depend on type +*/ + #include "mysys_priv.h" #include #include @@ -40,14 +74,22 @@ uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, 2 bits which determinate size of offset in the header -1 */ /* mask to get above bits */ -#define DYNCOL_FLG_OFFSET 3 -#define DYNCOL_FLG_NAMES 4 -/* All known flags mask */ -#define DYNCOL_FLG_KNOWN 7 +#define DYNCOL_FLG_OFFSET (1|2) +#define DYNCOL_FLG_NAMES 4 +#define DYNCOL_FLG_NMOFFSET (8|16) +/** + All known flags mask that could be set. + + @note DYNCOL_FLG_NMOFFSET should be 0 for now. +*/ +#define DYNCOL_FLG_KNOWN (1|2|4) /* formats */ -#define DYNCOL_FMT_NUM 0 -#define DYNCOL_FMT_STR 1 +enum enum_dyncol_format +{ + dyncol_fmt_num= 0, + dyncol_fmt_str= 1 +}; /* dynamic column size reserve */ #define DYNCOL_SYZERESERVE 80 @@ -63,14 +105,15 @@ uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, #define FIXED_HEADER_SIZE_NM 5 #define COLUMN_NUMBER_SIZE 2 -/* 1 byte name length + 2 bytes offset from the name pool */ -#define COLUMN_NAMEPTR_SIZE 3 +/* 2 bytes offset from the name pool */ +#define COLUMN_NAMEPTR_SIZE 2 -#define MAX_OFFSET_LENGTH 5 +#define MAX_OFFSET_LENGTH 4 +#define MAX_OFFSET_LENGTH_NM 5 #define DYNCOL_NUM_CHAR 6 -my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str) +my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str) { if (str->length < 1) return FALSE; @@ -79,7 +122,7 @@ my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str) static enum enum_dyncol_func_result dynamic_column_time_store(DYNAMIC_COLUMN *str, - MYSQL_TIME *value); + MYSQL_TIME *value, enum enum_dyncol_format format); static enum enum_dyncol_func_result dynamic_column_date_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value); @@ -96,14 +139,14 @@ dynamic_column_get_internal(DYNAMIC_COLUMN *str, static enum enum_dyncol_func_result dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, LEX_STRING *str_key); -enum enum_dyncol_func_result +static enum enum_dyncol_func_result dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, uint add_column_count, void *column_keys, DYNAMIC_COLUMN_VALUE *values, my_bool string_keys); static int plan_sort_num(const void *a, const void *b); -static int plan_sort_str(const void *a, const void *b); +static int plan_sort_named(const void *a, const void *b); /* Structure to hold information about dynamic columns record and @@ -118,8 +161,8 @@ struct st_dyn_header size_t header_size; size_t nmpool_size; size_t data_size; - /* DYNCOL_FMT_NUM - numeric columns, DYNCOL_FMT_STR - column names */ - uint format; + /* dyncol_fmt_num - numeric columns, dyncol_fmt_str - column names */ + enum enum_dyncol_format format; uint column_count; uchar *entry, *data, *name; @@ -135,9 +178,6 @@ static inline my_bool read_fixed_header(DYN_HEADER *hdr, static void set_fixed_header(DYNAMIC_COLUMN *str, uint offset_size, uint column_count); -static my_bool type_and_offset_store(uchar *place, size_t offset_size, - DYNAMIC_COLUMN_TYPE type, - size_t offset); /* Calculate entry size (E) and header size (H) by offset size (O) and column @@ -154,8 +194,8 @@ static my_bool type_and_offset_store(uchar *place, size_t offset_size, Name pool size functions, for numeric format it is 0 */ -size_t name_size_num(void *keys __attribute__((unused)), - uint i __attribute__((unused))) +static size_t name_size_num(void *keys __attribute__((unused)), + uint i __attribute__((unused))) { return 0; } @@ -164,7 +204,7 @@ size_t name_size_num(void *keys __attribute__((unused)), /** Name pool size functions. */ -size_t name_size_str(void *keys, uint i) +static size_t name_size_named(void *keys, uint i) { return ((LEX_STRING *) keys)[i].length; } @@ -180,23 +220,33 @@ static int column_sort_num(const void *a, const void *b) return **((uint **)a) - **((uint **)b); } - /** Comparator function for references on column numbers for qsort (names format) */ -static int column_sort_str(const void *a, const void *b) +int mariadb_dyncol_column_cmp_named(const LEX_STRING *s1, const LEX_STRING *s2) { - LEX_STRING *s1= *((LEX_STRING **)a); - LEX_STRING *s2= *((LEX_STRING **)b); int rc= s1->length - s2->length; if (rc == 0) - rc= memcmp((void *)s1->str, (void *)s2->str, (size_t) s1->length); + rc= memcmp((void *)s1->str, (void *)s2->str, + (size_t) s1->length); return rc; } +/** + Comparator function for references on column numbers for qsort + (names format) +*/ + +static int column_sort_named(const void *a, const void *b) +{ + return mariadb_dyncol_column_cmp_named(*((LEX_STRING **)a), + *((LEX_STRING **)b)); +} + + /** Check limit function (numeric format) */ @@ -211,7 +261,7 @@ static my_bool check_limit_num(const void *val) Check limit function (names format) */ -static my_bool check_limit_str(const void *val) +static my_bool check_limit_named(const void *val) { return (*((LEX_STRING **)val))->length > MAX_NAME_LENGTH; } @@ -221,7 +271,7 @@ static my_bool check_limit_str(const void *val) Write numeric format static header part. */ -void set_fixed_header_num(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) +static void set_fixed_header_num(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) { set_fixed_header(str, hdr->offset_size, hdr->column_count); hdr->header= (uchar *)str->str + FIXED_HEADER_SIZE; @@ -233,10 +283,14 @@ void set_fixed_header_num(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) Write names format static header part. */ -void set_fixed_header_str(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) +static void set_fixed_header_named(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) { - set_fixed_header(str, hdr->offset_size, hdr->column_count); - str->str[0]|= DYNCOL_FLG_NAMES; + DBUG_ASSERT(hdr->column_count <= 0xffff); + DBUG_ASSERT(hdr->offset_size <= MAX_OFFSET_LENGTH_NM); + /* size of data offset, named format flag, size of names offset (0 means 2) */ + str->str[0]= ((str->str[0] & ~(DYNCOL_FLG_OFFSET | DYNCOL_FLG_NMOFFSET)) | + (hdr->offset_size - 2) | DYNCOL_FLG_NAMES); + int2store(str->str + 1, hdr->column_count); /* columns number */ int2store(str->str + 3, hdr->nmpool_size); hdr->header= (uchar *)str->str + FIXED_HEADER_SIZE_NM; hdr->nmpool= hdr->header + hdr->header_size; @@ -244,6 +298,94 @@ void set_fixed_header_str(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) } +/** + Store offset and type information in the given place + + @param place Beginning of the index entry + @param offset_size Size of offset field in bytes + @param type Type to be written + @param offset Offset to be written +*/ + +static my_bool type_and_offset_store_num(uchar *place, size_t offset_size, + DYNAMIC_COLUMN_TYPE type, + size_t offset) +{ + ulong val = (((ulong) offset) << 3) | (type - 1); + DBUG_ASSERT(type != DYN_COL_NULL); + DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */ + DBUG_ASSERT(offset_size >= 1 && offset_size <= 4); + + /* Index entry starts with column number; jump over it */ + place+= COLUMN_NUMBER_SIZE; + + switch (offset_size) { + case 1: + if (offset >= 0x1f) /* all 1 value is reserved */ + return TRUE; + place[0]= (uchar)val; + break; + case 2: + if (offset >= 0x1fff) /* all 1 value is reserved */ + return TRUE; + int2store(place, val); + break; + case 3: + if (offset >= 0x1fffff) /* all 1 value is reserved */ + return TRUE; + int3store(place, val); + break; + case 4: + if (offset >= 0x1fffffff) /* all 1 value is reserved */ + return TRUE; + int4store(place, val); + break; + default: + return TRUE; + } + return FALSE; +} + + +static my_bool type_and_offset_store_named(uchar *place, size_t offset_size, + DYNAMIC_COLUMN_TYPE type, + size_t offset) +{ + ulong val = (((ulong) offset) << 4) | (type - 1); + DBUG_ASSERT(type != DYN_COL_NULL); + DBUG_ASSERT(((type - 1) & (~0xf)) == 0); /* fit in 4 bits */ + DBUG_ASSERT(offset_size >= 2 && offset_size <= 5); + + /* Index entry starts with name offset; jump over it */ + place+= COLUMN_NAMEPTR_SIZE; + switch (offset_size) { + case 2: + if (offset >= 0xfff) /* all 1 value is reserved */ + return TRUE; + int2store(place, val); + break; + case 3: + if (offset >= 0xfffff) /* all 1 value is reserved */ + return TRUE; + int3store(place, val); + break; + case 4: + if (offset >= 0xfffffff) /* all 1 value is reserved */ + return TRUE; + int4store(place, val); + break; + case 5: + if (offset >= 0xfffffffff) /* all 1 value is reserved */ + return TRUE; + int5store(place, val); + break; + case 1: + default: + return TRUE; + } + return FALSE; +} + /** Write numeric format header entry 2 bytes - column number @@ -255,17 +397,17 @@ void set_fixed_header_str(DYNAMIC_COLUMN *str, DYN_HEADER *hdr) @param offset offset of the data */ -my_bool put_header_entry_num(DYN_HEADER *hdr, - void *column_key, - DYNAMIC_COLUMN_VALUE *value, - size_t offset) +static my_bool put_header_entry_num(DYN_HEADER *hdr, + void *column_key, + DYNAMIC_COLUMN_VALUE *value, + size_t offset) { uint *column_number= (uint *)column_key; int2store(hdr->entry, *column_number); DBUG_ASSERT(hdr->nmpool_size == 0); - if (type_and_offset_store(hdr->entry, hdr->offset_size, - value->type, - offset)) + if (type_and_offset_store_num(hdr->entry, hdr->offset_size, + value->type, + offset)) return TRUE; hdr->entry= hdr->entry + hdr->entry_size; return FALSE; @@ -284,21 +426,20 @@ my_bool put_header_entry_num(DYN_HEADER *hdr, @param offset offset of the data */ -my_bool put_header_entry_str(DYN_HEADER *hdr, - void *column_key, - DYNAMIC_COLUMN_VALUE *value, - size_t offset) +static my_bool put_header_entry_named(DYN_HEADER *hdr, + void *column_key, + DYNAMIC_COLUMN_VALUE *value, + size_t offset) { LEX_STRING *column_name= (LEX_STRING *)column_key; DBUG_ASSERT(column_name->length <= MAX_NAME_LENGTH); - hdr->entry[0]= column_name->length; DBUG_ASSERT(hdr->name - hdr->nmpool < (long) 0x10000L); - int2store(hdr->entry + 1, hdr->name - hdr->nmpool); + int2store(hdr->entry, hdr->name - hdr->nmpool); memcpy(hdr->name, column_name->str, column_name->length); DBUG_ASSERT(hdr->nmpool_size != 0 || column_name->length == 0); - if (type_and_offset_store(hdr->entry + 1, hdr->offset_size, - value->type, - offset)) + if (type_and_offset_store_named(hdr->entry, hdr->offset_size, + value->type, + offset)) return TRUE; hdr->entry+= hdr->entry_size; hdr->name+= column_name->length; @@ -306,6 +447,119 @@ my_bool put_header_entry_str(DYN_HEADER *hdr, } +/** + Calculate length of offset field for given data length + + @param data_length Length of the data segment + + @return number of bytes +*/ + +static size_t dynamic_column_offset_bytes_num(size_t data_length) +{ + if (data_length < 0x1f) /* all 1 value is reserved */ + return 1; + if (data_length < 0x1fff) /* all 1 value is reserved */ + return 2; + if (data_length < 0x1fffff) /* all 1 value is reserved */ + return 3; + if (data_length < 0x1fffffff) /* all 1 value is reserved */ + return 4; + return MAX_OFFSET_LENGTH + 1; /* For an error generation*/ +} + +static size_t dynamic_column_offset_bytes_named(size_t data_length) +{ + if (data_length < 0xfff) /* all 1 value is reserved */ + return 2; + if (data_length < 0xfffff) /* all 1 value is reserved */ + return 3; + if (data_length < 0xfffffff) /* all 1 value is reserved */ + return 4; + if (data_length < 0xfffffffff) /* all 1 value is reserved */ + return 5; + return MAX_OFFSET_LENGTH_NM + 1; /* For an error generation */ +} + +/** + Read offset and type information from index entry + + @param type Where to put type info + @param offset Where to put offset info + @param place beginning of the type and offset + @param offset_size Size of offset field in bytes +*/ + +static my_bool type_and_offset_read_num(DYNAMIC_COLUMN_TYPE *type, + size_t *offset, + uchar *place, size_t offset_size) +{ + ulong UNINIT_VAR(val); + ulong UNINIT_VAR(lim); + + DBUG_ASSERT(offset_size >= 1 && offset_size <= 4); + + switch (offset_size) { + case 1: + val= (ulong)place[0]; + lim= 0x1f; + break; + case 2: + val= uint2korr(place); + lim= 0x1fff; + break; + case 3: + val= uint3korr(place); + lim= 0x1fffff; + break; + case 4: + val= uint4korr(place); + lim= 0x1fffffff; + break; + default: + DBUG_ASSERT(0); /* impossible */ + return 1; + } + *type= (val & 0x7) + 1; + *offset= val >> 3; + return (*offset >= lim); +} + +static my_bool type_and_offset_read_named(DYNAMIC_COLUMN_TYPE *type, + size_t *offset, + uchar *place, size_t offset_size) +{ + ulong UNINIT_VAR(val); + ulong UNINIT_VAR(lim); + DBUG_ASSERT(offset_size >= 2 && offset_size <= 5); + + switch (offset_size) { + case 2: + val= uint2korr(place); + lim= 0xfff; + break; + case 3: + val= uint3korr(place); + lim= 0xfffff; + break; + case 4: + val= uint4korr(place); + lim= 0xfffffff; + break; + case 5: + val= uint5korr(place); + lim= 0xfffffffff; + break; + case 1: + default: + DBUG_ASSERT(0); /* impossible */ + return 1; + } + *type= (val & 0xf) + 1; + *offset= val >> 4; + return (*offset >= lim); +} + /** Format descriptor, contain constants and function references for format processing @@ -321,6 +575,9 @@ struct st_service_funcs /*size of array element which stores keys */ uint key_size_in_array; + /* Maximum data offset size in bytes */ + size_t max_offset_size; + size_t (*name_size) (void *, uint); int (*column_sort) @@ -334,6 +591,11 @@ struct st_service_funcs DYNAMIC_COLUMN_VALUE *value, size_t offset); int (*plan_sort)(const void *a, const void *b); + size_t (*dynamic_column_offset_bytes)(size_t data_length); + my_bool (*type_and_offset_read)(DYNAMIC_COLUMN_TYPE *type, + size_t *offset, + uchar *place, size_t offset_size); + }; @@ -347,23 +609,29 @@ static struct st_service_funcs fmt_data[2]= FIXED_HEADER_SIZE, COLUMN_NUMBER_SIZE, sizeof(uint), + MAX_OFFSET_LENGTH, &name_size_num, &column_sort_num, &check_limit_num, &set_fixed_header_num, &put_header_entry_num, - &plan_sort_num + &plan_sort_num, + &dynamic_column_offset_bytes_num, + &type_and_offset_read_num }, { FIXED_HEADER_SIZE_NM, COLUMN_NAMEPTR_SIZE, sizeof(LEX_STRING), - &name_size_str, - &column_sort_str, - &check_limit_str, - &set_fixed_header_str, - &put_header_entry_str, - &plan_sort_str + MAX_OFFSET_LENGTH_NM, + &name_size_named, + &column_sort_named, + &check_limit_named, + &set_fixed_header_named, + &put_header_entry_named, + &plan_sort_named, + &dynamic_column_offset_bytes_named, + &type_and_offset_read_named } }; @@ -377,7 +645,7 @@ static struct st_service_funcs fmt_data[2]= @return ER_DYNCOL_* return code */ -enum enum_dyncol_func_result +static enum enum_dyncol_func_result init_read_hdr(DYN_HEADER *hdr, DYNAMIC_COLUMN *str) { if (read_fixed_header(hdr, str)) @@ -405,7 +673,7 @@ init_read_hdr(DYN_HEADER *hdr, DYNAMIC_COLUMN *str) @retval TRUE error */ -static my_bool dynamic_column_init_str(DYNAMIC_COLUMN *str, size_t size) +static my_bool dynamic_column_init_named(DYNAMIC_COLUMN *str, size_t size) { DBUG_ASSERT(size != 0); @@ -647,7 +915,8 @@ dynamic_column_sint_read(DYNAMIC_COLUMN_VALUE *store_it_here, */ static size_t -dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value) +dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value, + enum enum_dyncol_format format) { switch (value->type) { case DYN_COL_NULL: @@ -689,14 +958,22 @@ dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value) decimal_bin_size(precision, scale)); } case DYN_COL_DATETIME: - /* date+time in bits: 14 + 4 + 5 + 10 + 6 + 6 + 20 + 1 66bits ~= 9 bytes */ - return 9; + if (format == dyncol_fmt_num || value->x.time_value.second_part) + /* date+time in bits: 14 + 4 + 5 + 10 + 6 + 6 + 20 + 1 66bits ~= 9 bytes*/ + return 9; + else + return 6; case DYN_COL_DATE: /* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/ return 3; case DYN_COL_TIME: - /* time in bits: 10 + 6 + 6 + 20 + 1 = 43bits ~= 6bytes*/ - return 6; + if (format == dyncol_fmt_num || value->x.time_value.second_part) + /* time in bits: 10 + 6 + 6 + 20 + 1 = 43bits ~= 6bytes*/ + return 6; + else + return 3; + case DYN_COL_DYNCOL: + return value->x.string.value.length; } DBUG_ASSERT(0); return 0; @@ -765,6 +1042,22 @@ dynamic_column_string_store(DYNAMIC_COLUMN *str, LEX_STRING *string, return ER_DYNCOL_OK; } +/** + Append the string with given string value. + + @param str the string where to put the value + @param val the value to put in the string + + @return ER_DYNCOL_* return code +*/ + +static enum enum_dyncol_func_result +dynamic_column_dyncol_store(DYNAMIC_COLUMN *str, LEX_STRING *string) +{ + if (dynstr_append_mem(str, string->str, string->length)) + return ER_DYNCOL_RESOURCE; + return ER_DYNCOL_OK; +} /** Read string value of given length from the packed string @@ -793,6 +1086,26 @@ dynamic_column_string_read(DYNAMIC_COLUMN_VALUE *store_it_here, return ER_DYNCOL_OK; } +/** + Read Dynamic columns packet string value of given length + from the packed string + + @param store_it_here The structure to store the value + @param data The packed string which should be read + @param length The length (in bytes) of the value in nthe string + + @return ER_DYNCOL_* return code +*/ + +static enum enum_dyncol_func_result +dynamic_column_dyncol_read(DYNAMIC_COLUMN_VALUE *store_it_here, + uchar *data, size_t length) +{ + store_it_here->x.string.charset= &my_charset_bin; + store_it_here->x.string.value.length= length; + store_it_here->x.string.value.str= (char*) data; + return ER_DYNCOL_OK; +} /** Append the string with given decimal value. @@ -835,7 +1148,7 @@ dynamic_column_decimal_store(DYNAMIC_COLUMN *str, @param value The value structure which sould be setup. */ -void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value) +void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value) { value->x.decimal.value.buf= value->x.decimal.buffer; value->x.decimal.value.len= DECIMAL_BUFF_LENGTH; @@ -844,6 +1157,12 @@ void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value) decimal_make_zero(&value->x.decimal.value); } +void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value) +{ + mariadb_dyncol_prepare_decimal(value); +} + + /** Read decimal value of given length from the string @@ -899,7 +1218,8 @@ dynamic_column_decimal_read(DYNAMIC_COLUMN_VALUE *store_it_here, */ static enum enum_dyncol_func_result -dynamic_column_date_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value) +dynamic_column_date_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value, + enum enum_dyncol_format format) { enum enum_dyncol_func_result rc; /* @@ -908,7 +1228,7 @@ dynamic_column_date_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value) <123456><123456><123456><123456><123456><123456><123456><123456><123456> */ if ((rc= dynamic_column_date_store(str, value)) || - (rc= dynamic_column_time_store(str, value))) + (rc= dynamic_column_time_store(str, value, format))) return rc; return ER_DYNCOL_OK; } @@ -934,11 +1254,12 @@ dynamic_column_date_time_read(DYNAMIC_COLUMN_VALUE *store_it_here, 12345678901234123412345 1123456789012345612345612345678901234567890 <123456><123456><123456><123456><123456><123456><123456><123456><123456> */ - if (length != 9) + if (length != 9 && length != 6) goto err; store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME; if ((rc= dynamic_column_date_read_internal(store_it_here, data, 3)) || - (rc= dynamic_column_time_read_internal(store_it_here, data + 3, 6))) + (rc= dynamic_column_time_read_internal(store_it_here, data + 3, + length - 3))) goto err; return ER_DYNCOL_OK; @@ -958,7 +1279,8 @@ err: */ static enum enum_dyncol_func_result -dynamic_column_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value) +dynamic_column_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value, + enum enum_dyncol_format format) { uchar *buf; if (dynstr_realloc(str, 6)) @@ -980,19 +1302,35 @@ dynamic_column_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value) DBUG_ASSERT(value->minute <= 59); DBUG_ASSERT(value->second <= 59); DBUG_ASSERT(value->second_part <= 999999); + if (format == dyncol_fmt_num || value->second_part) + { /* 00000!<-hours--><---microseconds---> 1123456789012345612345612345678901234567890 <123456><123456><123456><123456><123456><123456> */ - buf[0]= (value->second_part & 0xff); - buf[1]= ((value->second_part & 0xff00) >> 8); - buf[2]= (uchar)(((value->second & 0xf) << 4) | - ((value->second_part & 0xf0000) >> 16)); - buf[3]= ((value->minute << 2) | ((value->second & 0x30) >> 4)); - buf[4]= (value->hour & 0xff); - buf[5]= ((value->neg ? 0x4 : 0) | (value->hour >> 8)); - str->length+= 6; + buf[0]= (value->second_part & 0xff); + buf[1]= ((value->second_part & 0xff00) >> 8); + buf[2]= (uchar)(((value->second & 0xf) << 4) | + ((value->second_part & 0xf0000) >> 16)); + buf[3]= ((value->minute << 2) | ((value->second & 0x30) >> 4)); + buf[4]= (value->hour & 0xff); + buf[5]= ((value->neg ? 0x4 : 0) | (value->hour >> 8)); + str->length+= 6; + } + else + { + /* + !<-hours--> + 11234567890123456123456 + <123456><123456><123456> + */ + buf[0]= (value->second) | ((value->minute & 0x3) << 6); + buf[1]= (value->minute >> 2) | ((value->hour & 0xf) << 4); + buf[2]= (value->hour >> 4) | (value->neg ? 0x80 : 0); + str->length+= 3; + } + return ER_DYNCOL_OK; } @@ -1031,21 +1369,37 @@ static enum enum_dyncol_func_result dynamic_column_time_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here, uchar *data, size_t length) { - if (length != 6) + if (length != 6 && length != 3) goto err; - /* - 00000!<-hours--><---microseconds---> - 1123456789012345612345612345678901234567890 - <123456><123456><123456><123456><123456><123456> - */ - store_it_here->x.time_value.second_part= (data[0] | - (data[1] << 8) | - ((data[2] & 0xf) << 16)); - store_it_here->x.time_value.second= ((data[2] >> 4) | - ((data[3] & 0x3) << 4)); - store_it_here->x.time_value.minute= (data[3] >> 2); - store_it_here->x.time_value.hour= (((((uint)data[5]) & 0x3 ) << 8) | data[4]); - store_it_here->x.time_value.neg= ((data[5] & 0x4) ? 1 : 0); + if (length == 6) + { + /* + 00000!<-hours--><---microseconds---> + 1123456789012345612345612345678901234567890 + <123456><123456><123456><123456><123456><123456> + */ + store_it_here->x.time_value.second_part= (data[0] | + (data[1] << 8) | + ((data[2] & 0xf) << 16)); + store_it_here->x.time_value.second= ((data[2] >> 4) | + ((data[3] & 0x3) << 4)); + store_it_here->x.time_value.minute= (data[3] >> 2); + store_it_here->x.time_value.hour= (((((uint)data[5]) & 0x3 ) << 8) | data[4]); + store_it_here->x.time_value.neg= ((data[5] & 0x4) ? 1 : 0); + } + else + { + /* + !<-hours--> + 11234567890123456123456 + <123456><123456><123456> + */ + store_it_here->x.time_value.second_part= 0; + store_it_here->x.time_value.second= (data[0] & 0x3f); + store_it_here->x.time_value.minute= (data[0] >> 6) | ((data[1] & 0xf) << 2); + store_it_here->x.time_value.hour= (data[1] >> 4) | ((data[2] & 0x3f) << 4); + store_it_here->x.time_value.neg= ((data[2] & 0x80) ? 1 : 0); + } if (store_it_here->x.time_value.second > 59 || store_it_here->x.time_value.minute > 59 || store_it_here->x.time_value.hour > 838 || @@ -1169,146 +1523,38 @@ err: @return ER_DYNCOL_* return code */ -static enum enum_dyncol_func_result -data_store(DYNAMIC_COLUMN *str, DYNAMIC_COLUMN_VALUE *value) -{ - switch (value->type) { - case DYN_COL_INT: - return dynamic_column_sint_store(str, value->x.long_value); - case DYN_COL_UINT: - return dynamic_column_uint_store(str, value->x.ulong_value); - case DYN_COL_DOUBLE: - return dynamic_column_double_store(str, value->x.double_value); - case DYN_COL_STRING: - return dynamic_column_string_store(str, &value->x.string.value, - value->x.string.charset); - case DYN_COL_DECIMAL: - return dynamic_column_decimal_store(str, &value->x.decimal.value); - case DYN_COL_DATETIME: - /* date+time in bits: 14 + 4 + 5 + 5 + 6 + 6 40bits = 5 bytes */ - return dynamic_column_date_time_store(str, &value->x.time_value); - case DYN_COL_DATE: - /* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/ - return dynamic_column_date_store(str, &value->x.time_value); - case DYN_COL_TIME: - /* time in bits: 5 + 6 + 6 = 17bits ~= 3bytes*/ - return dynamic_column_time_store(str, &value->x.time_value); - case DYN_COL_NULL: - break; /* Impossible */ - } - DBUG_ASSERT(0); - return ER_DYNCOL_OK; /* Impossible */ -} - - -/** - Calculate length of offset field for given data length - - @param data_length Length of the data segment - - @return number of bytes -*/ - -static size_t dynamic_column_offset_bytes(size_t data_length) -{ - if (data_length < 0x1f) /* all 1 value is reserved */ - return 1; - if (data_length < 0x1fff) /* all 1 value is reserved */ - return 2; - if (data_length < 0x1fffff) /* all 1 value is reserved */ - return 3; - if (data_length < 0x1fffffff) /* all 1 value is reserved */ - return 4; - return MAX_OFFSET_LENGTH; /* For future */ -} - -/** - Store offset and type information in the given place - - @param place Beginning of the index entry - @param offset_size Size of offset field in bytes - @param type Type to be written - @param offset Offset to be written -*/ - -static my_bool type_and_offset_store(uchar *place, size_t offset_size, - DYNAMIC_COLUMN_TYPE type, - size_t offset) -{ - ulong val = (((ulong) offset) << 3) | (type - 1); - DBUG_ASSERT(type != DYN_COL_NULL); - DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */ - - /* Index entry starts with column number; Jump over it */ - place+= COLUMN_NUMBER_SIZE; - - switch (offset_size) { - case 1: - if (offset >= 0x1f) /* all 1 value is reserved */ - return TRUE; - place[0]= (uchar)val; - break; - case 2: - if (offset >= 0x1fff) /* all 1 value is reserved */ - return TRUE; - int2store(place, val); - break; - case 3: - if (offset >= 0x1fffff) /* all 1 value is reserved */ - return TRUE; - int3store(place, val); - break; - case 4: - if (offset >= 0x1fffffff) /* all 1 value is reserved */ - return TRUE; - int4store(place, val); - break; - default: - return TRUE; - } - return FALSE; -} - - -/** - Read offset and type information from index entry - - @param type Where to put type info - @param offset Where to put offset info - @param place beginning of the type and offset - @param offset_size Size of offset field in bytes -*/ - -static my_bool type_and_offset_read(DYNAMIC_COLUMN_TYPE *type, - size_t *offset, - uchar *place, size_t offset_size) -{ - ulong UNINIT_VAR(val); - ulong UNINIT_VAR(lim); - - switch (offset_size) { - case 1: - val= (ulong)place[0]; - lim= 0x1f; - break; - case 2: - val= uint2korr(place); - lim= 0x1fff; - break; - case 3: - val= uint3korr(place); - lim= 0x1fffff; - break; - case 4: - val= uint4korr(place); - lim= 0x1fffffff; - break; - default: - DBUG_ASSERT(0); /* impossible */ +static enum enum_dyncol_func_result +data_store(DYNAMIC_COLUMN *str, DYNAMIC_COLUMN_VALUE *value, + enum enum_dyncol_format format) +{ + switch (value->type) { + case DYN_COL_INT: + return dynamic_column_sint_store(str, value->x.long_value); + case DYN_COL_UINT: + return dynamic_column_uint_store(str, value->x.ulong_value); + case DYN_COL_DOUBLE: + return dynamic_column_double_store(str, value->x.double_value); + case DYN_COL_STRING: + return dynamic_column_string_store(str, &value->x.string.value, + value->x.string.charset); + case DYN_COL_DECIMAL: + return dynamic_column_decimal_store(str, &value->x.decimal.value); + case DYN_COL_DATETIME: + /* date+time in bits: 14 + 4 + 5 + 5 + 6 + 6 40bits = 5 bytes */ + return dynamic_column_date_time_store(str, &value->x.time_value, format); + case DYN_COL_DATE: + /* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/ + return dynamic_column_date_store(str, &value->x.time_value); + case DYN_COL_TIME: + /* time in bits: 5 + 6 + 6 = 17bits ~= 3bytes*/ + return dynamic_column_time_store(str, &value->x.time_value, format); + case DYN_COL_DYNCOL: + return dynamic_column_dyncol_store(str, &value->x.string.value); + case DYN_COL_NULL: + break; /* Impossible */ } - *type= (val & 0x7) + 1; - *offset= val >> 3; - return (*offset >= lim); + DBUG_ASSERT(0); + return ER_DYNCOL_OK; /* Impossible */ } @@ -1325,7 +1571,7 @@ static void set_fixed_header(DYNAMIC_COLUMN *str, uint column_count) { DBUG_ASSERT(column_count <= 0xffff); - DBUG_ASSERT(offset_size <= 4); + DBUG_ASSERT(offset_size <= MAX_OFFSET_LENGTH); str->str[0]= ((str->str[0] & ~DYNCOL_FLG_OFFSET) | (offset_size - 1)); /* size of offset */ int2store(str->str + 1, column_count); /* columns number */ @@ -1364,12 +1610,12 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str, return ER_DYNCOL_RESOURCE; if (new_str) { - if (dynamic_column_init_str(str, - fmt->fixed_hdr + - hdr->header_size + - hdr->nmpool_size + - hdr->data_size + - DYNCOL_SYZERESERVE)) + if (dynamic_column_init_named(str, + fmt->fixed_hdr + + hdr->header_size + + hdr->nmpool_size + + hdr->data_size + + DYNCOL_SYZERESERVE)) goto err; } else @@ -1438,7 +1684,7 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str, } /* Store value in 'str + str->length' and increase str->length */ - if ((rc= data_store(str, values + ord))) + if ((rc= data_store(str, values + ord, hdr->format))) goto err; } } @@ -1476,15 +1722,19 @@ calc_var_sizes(DYN_HEADER *hdr, { size_t tmp; hdr->column_count++; - hdr->data_size+= (tmp= dynamic_column_value_len(values + i)); + hdr->data_size+= (tmp= dynamic_column_value_len(values + i, + hdr->format)); if (tmp == (size_t) ~0) return ER_DYNCOL_DATA; hdr->nmpool_size+= (*fmt->name_size)(column_keys, i); } } - /* We can handle data up to 1fffffff = 536870911 bytes now */ - if ((hdr->offset_size= dynamic_column_offset_bytes(hdr->data_size)) >= - MAX_OFFSET_LENGTH) + /* + We can handle data up to 0x1fffffff (old format) and + 0xfffffffff (new format) bytes now. + */ + if ((hdr->offset_size= fmt->dynamic_column_offset_bytes(hdr->data_size)) >= + fmt->max_offset_size) return ER_DYNCOL_LIMIT; /* header entry is column number or string pointer + offset & type */ @@ -1506,7 +1756,7 @@ calc_var_sizes(DYN_HEADER *hdr, @return ER_DYNCOL_* return code */ -enum enum_dyncol_func_result +static enum enum_dyncol_func_result dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str, uint column_count, void *column_keys, @@ -1558,6 +1808,31 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str, TRUE, FALSE)); } +/** + Create packed string which contains given columns + + @param str String where to write the data + @param column_count Number of columns in the arrays + @param column_numbers Array of columns numbers + @param values Array of columns values + @param new_string True if we need allocate new string + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +mariadb_dyncol_create_many(DYNAMIC_COLUMN *str, + uint column_count, + uint *column_numbers, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_string) +{ + DBUG_ENTER("mariadb_dyncol_create_many"); + DBUG_RETURN(dynamic_column_create_many_internal_fmt(str, column_count, + column_numbers, values, + new_string, FALSE)); +} + /** Create packed string which contains given columns @@ -1565,22 +1840,22 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str, @param column_count Number of columns in the arrays @param column_keys Array of columns keys @param values Array of columns value - @param names use string names as keys + @param new_string True if we need allocate new string @return ER_DYNCOL_* return code */ enum enum_dyncol_func_result -dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str, - uint column_count, - uchar *column_keys, - DYNAMIC_COLUMN_VALUE *values, - my_bool names) +mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str, + uint column_count, + LEX_STRING *column_keys, + DYNAMIC_COLUMN_VALUE *values, + my_bool new_string) { - DBUG_ENTER("dynamic_column_create_many"); + DBUG_ENTER("mariadb_dyncol_create_many_named"); DBUG_RETURN(dynamic_column_create_many_internal_fmt(str, column_count, column_keys, values, - TRUE, names)); + new_string, TRUE)); } /** @@ -1622,13 +1897,13 @@ static size_t get_length_interval(uchar *entry, uchar *entry_next, DYNAMIC_COLUMN_TYPE type, type_next; DBUG_ASSERT(entry < entry_next); - if (type_and_offset_read(&type, &offset, entry + COLUMN_NUMBER_SIZE, - offset_size)) + if (type_and_offset_read_num(&type, &offset, entry + COLUMN_NUMBER_SIZE, + offset_size)) return DYNCOL_OFFSET_ERROR; if (entry_next >= header_end) return (last_offset - offset); - if (type_and_offset_read(&type_next, &offset_next, - entry_next + COLUMN_NUMBER_SIZE, offset_size)) + if (type_and_offset_read_num(&type_next, &offset_next, + entry_next + COLUMN_NUMBER_SIZE, offset_size)) return DYNCOL_OFFSET_ERROR; return (offset_next - offset); } @@ -1653,13 +1928,15 @@ static size_t hdr_interval_length(DYN_HEADER *hdr, uchar *next_entry) DBUG_ASSERT(hdr->entry >= hdr->header); DBUG_ASSERT(next_entry <= hdr->header + hdr->header_size); - if (type_and_offset_read(&hdr->type, &hdr->offset, - hdr->entry + fmt->fixed_hdr_entry, hdr->offset_size)) + if ((*fmt->type_and_offset_read)(&hdr->type, &hdr->offset, + hdr->entry + fmt->fixed_hdr_entry, + hdr->offset_size)) return DYNCOL_OFFSET_ERROR; if (next_entry == hdr->header + hdr->header_size) return hdr->data_size - hdr->offset; - if (type_and_offset_read(&next_entry_type, &next_entry_offset, - next_entry + fmt->fixed_hdr_entry, hdr->offset_size)) + if ((*fmt->type_and_offset_read)(&next_entry_type, &next_entry_offset, + next_entry + fmt->fixed_hdr_entry, + hdr->offset_size)) return DYNCOL_OFFSET_ERROR; return (next_entry_offset - hdr->offset); } @@ -1688,7 +1965,7 @@ static int header_compar_num(const void *a, const void *b) static uchar *find_entry_num(DYN_HEADER *hdr, uint key) { uchar header_entry[2+4]; - DBUG_ASSERT(hdr->format == DYNCOL_FMT_NUM); + DBUG_ASSERT(hdr->format == dyncol_fmt_num); int2store(header_entry, key); return hdr->entry= bsearch(header_entry, hdr->header, (size_t)hdr->column_count, @@ -1696,6 +1973,39 @@ static uchar *find_entry_num(DYN_HEADER *hdr, uint key) } +/** + Read name from header entry + + @param hdr descriptor of dynamic column record + @param entry pointer to the header entry + @param name where to put name + + @return 0 ok + @return 1 error in data +*/ + +static my_bool read_name(DYN_HEADER *hdr, uchar *entry, LEX_STRING *name) +{ + size_t nmoffset= uint2korr(entry); + uchar *next_entry= entry + hdr->entry_size; + + if (nmoffset > hdr->nmpool_size) + return 1; + + name->str= (char *)hdr->nmpool + nmoffset; + if (next_entry == hdr->header + hdr->header_size) + name->length= hdr->nmpool_size - nmoffset; + else + { + size_t next_nmoffset= uint2korr(next_entry); + if (next_nmoffset > hdr->nmpool_size) + return 1; + name->length= next_nmoffset - nmoffset; + } + return 0; +} + + /** Find entry in the names format header by the column number @@ -1704,22 +2014,24 @@ static uchar *find_entry_num(DYN_HEADER *hdr, uint key) @return pointer to the entry or NULL */ -static uchar *find_entry_str(DYN_HEADER *hdr, LEX_STRING *key) +static uchar *find_entry_named(DYN_HEADER *hdr, LEX_STRING *key) { uchar *min= hdr->header; uchar *max= hdr->header + (hdr->column_count - 1) * hdr->entry_size; uchar *mid; - DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); + DBUG_ASSERT(hdr->format == dyncol_fmt_str); DBUG_ASSERT(hdr->nmpool != NULL); while (max >= min) { - uint len; + LEX_STRING name; int cmp; - mid= hdr->header + ((min - hdr->header) + (max - hdr->header)) / 2 / hdr->entry_size * hdr->entry_size; - len= mid[0]; - cmp= len - key->length; - if (cmp == 0) - cmp= memcmp(hdr->nmpool + uint2korr(mid + 1), key->str, len); + mid= hdr->header + ((min - hdr->header) + + (max - hdr->header)) / + 2 / + hdr->entry_size * hdr->entry_size; + if (read_name(hdr, mid, &name)) + return NULL; + cmp= mariadb_dyncol_column_cmp_named(&name, key); if (cmp < 0) min= mid + hdr->entry_size; else if (cmp > 0) @@ -1773,7 +2085,7 @@ find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey) return TRUE; /* fix key */ - if (hdr->format == DYNCOL_FMT_NUM && strkey != NULL) + if (hdr->format == dyncol_fmt_num && strkey != NULL) { char *end; numkey= (uint) strtoul(strkey->str, &end, 10); @@ -1784,16 +2096,16 @@ find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey) return 0; } } - else if (hdr->format == DYNCOL_FMT_STR && strkey == NULL) + else if (hdr->format == dyncol_fmt_str && strkey == NULL) { nmkey.str= backwritenum(nmkeybuff + sizeof(nmkeybuff), numkey); nmkey.length= (nmkeybuff + sizeof(nmkeybuff)) - nmkey.str; strkey= &nmkey; } - if (hdr->format == DYNCOL_FMT_NUM) + if (hdr->format == dyncol_fmt_num) hdr->entry= find_entry_num(hdr, numkey); else - hdr->entry= find_entry_str(hdr, strkey); + hdr->entry= find_entry_named(hdr, strkey); if (!hdr->entry) { @@ -1837,14 +2149,15 @@ static inline my_bool read_fixed_header(DYN_HEADER *hdr, (str->str[0] & (~DYNCOL_FLG_KNOWN))) return 1; hdr->format= ((str->str[0] & DYNCOL_FLG_NAMES) ? - DYNCOL_FMT_STR: - DYNCOL_FMT_NUM); + dyncol_fmt_str: + dyncol_fmt_num); if ((str->length < fmt_data[hdr->format].fixed_hdr)) return 1; /* Wrong header */ - hdr->offset_size= (str->str[0] & DYNCOL_FLG_OFFSET) + 1; + hdr->offset_size= (str->str[0] & DYNCOL_FLG_OFFSET) + 1 + + (hdr->format == dyncol_fmt_str ? 1 : 0); hdr->column_count= uint2korr(str->str + 1); - if (hdr->format == DYNCOL_FMT_STR) - hdr->nmpool_size= uint2korr(str->str + 3); + if (hdr->format == dyncol_fmt_str) + hdr->nmpool_size= uint2korr(str->str + 3); // only 2 bytes supported for now else hdr->nmpool_size= 0; return 0; @@ -1868,6 +2181,13 @@ dynamic_column_get(DYNAMIC_COLUMN *str, uint column_nr, return dynamic_column_get_internal(str, store_it_here, column_nr, NULL); } +enum enum_dyncol_func_result +mariadb_dyncol_get(DYNAMIC_COLUMN *str, uint column_nr, + DYNAMIC_COLUMN_VALUE *store_it_here) +{ + return dynamic_column_get_internal(str, store_it_here, column_nr, NULL); +} + /** Get dynamic column value by name @@ -1880,39 +2200,14 @@ dynamic_column_get(DYNAMIC_COLUMN *str, uint column_nr, */ enum enum_dyncol_func_result -dynamic_column_get_str(DYNAMIC_COLUMN *str, LEX_STRING *name, - DYNAMIC_COLUMN_VALUE *store_it_here) +mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, LEX_STRING *name, + DYNAMIC_COLUMN_VALUE *store_it_here) { DBUG_ASSERT(name != NULL); return dynamic_column_get_internal(str, store_it_here, 0, name); } -/** - Get dynamic column value by number or name - - @param str The packed string to extract the column - @param key Name or number of column to fetch - (depends on string_key) - @param store_it_here Where to store the extracted value - @param string_key True if we gave pointer to LEX_STRING. - - @return ER_DYNCOL_* return code -*/ - -enum enum_dyncol_func_result -dynamic_column_get_fmt(DYNAMIC_COLUMN *str, void *key, - DYNAMIC_COLUMN_VALUE *store_it_here, - my_bool string_key) -{ - DBUG_ASSERT(key != NULL); - if (string_key) - return dynamic_column_get_internal(str, store_it_here, - 0, (LEX_STRING *)key); - return dynamic_column_get_internal(str, store_it_here, - *((uint *)key), NULL); -} - static enum enum_dyncol_func_result dynamic_column_get_value(DYN_HEADER *hdr, DYNAMIC_COLUMN_VALUE *store_it_here) { @@ -1946,6 +2241,9 @@ dynamic_column_get_value(DYN_HEADER *hdr, DYNAMIC_COLUMN_VALUE *store_it_here) case DYN_COL_NULL: rc= ER_DYNCOL_OK; break; + case DYN_COL_DYNCOL: + rc= dynamic_column_dyncol_read(store_it_here, hdr->data, hdr->length); + break; default: rc= ER_DYNCOL_FORMAT; store_it_here->type= DYN_COL_NULL; @@ -2012,6 +2310,11 @@ dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr) return dynamic_column_exists_internal(str, column_nr, NULL); } +enum enum_dyncol_func_result +mariadb_dyncol_exists(DYNAMIC_COLUMN *str, uint column_nr) +{ + return dynamic_column_exists_internal(str, column_nr, NULL); +} /** Check existence of the column in the packed string (by name) @@ -2023,34 +2326,13 @@ dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr) */ enum enum_dyncol_func_result -dynamic_column_exists_str(DYNAMIC_COLUMN *str, LEX_STRING *name) +mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, LEX_STRING *name) { DBUG_ASSERT(name != NULL); return dynamic_column_exists_internal(str, 0, name); } -/** - Check existence of the column in the packed string (by name of number) - - @param str The packed string to check the column - @param key Name or number of column to fetch - (depends on string_key) - @param string_key True if we gave pointer to LEX_STRING. - - @return ER_DYNCOL_* return code -*/ - -enum enum_dyncol_func_result -dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_key) -{ - DBUG_ASSERT(key != NULL); - if (string_key) - return dynamic_column_exists_internal(str, 0, (LEX_STRING *) key); - return dynamic_column_exists_internal(str, *((uint *)key), NULL); -} - - /** Check existence of the column in the packed string (by name of number) @@ -2093,9 +2375,14 @@ dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, @return ER_DYNCOL_* return code */ - enum enum_dyncol_func_result dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) +{ + return mariadb_dyncol_list(str, array_of_uint); +} + +enum enum_dyncol_func_result +mariadb_dyncol_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) { DYN_HEADER header; uchar *read; @@ -2109,7 +2396,7 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) if ((rc= init_read_hdr(&header, str)) < 0) return rc; - if (header.format != DYNCOL_FMT_NUM) + if (header.format != dyncol_fmt_num) return ER_DYNCOL_FORMAT; if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > @@ -2135,21 +2422,24 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) List not-null columns in the packed string (any format) @param str The packed string - @param array_of_lexstr Where to put reference on created array + @param count Number of names in the list + @param names Where to put names list (should be freed) @return ER_DYNCOL_* return code */ enum enum_dyncol_func_result -dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr) +mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, LEX_STRING **names) { DYN_HEADER header; uchar *read; + char *pool; struct st_service_funcs *fmt; uint i; enum enum_dyncol_func_result rc; - bzero(array_of_lexstr, sizeof(*array_of_lexstr)); /* In case of errors */ + (*names)= 0; (*count)= 0; + if (str->length == 0) return ER_DYNCOL_OK; /* no columns */ @@ -2162,36 +2452,41 @@ dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr) str->length) return ER_DYNCOL_FORMAT; - if (init_dynamic_array(array_of_lexstr, sizeof(LEX_STRING), - header.column_count, 0)) + if (header.format == dyncol_fmt_num) + *names= my_malloc(sizeof(LEX_STRING) * header.column_count + + DYNCOL_NUM_CHAR * header.column_count, MYF(0)); + else + *names= my_malloc(sizeof(LEX_STRING) * header.column_count + + header.nmpool_size + header.column_count, MYF(0)); + if (!(*names)) return ER_DYNCOL_RESOURCE; + pool= ((char *)(*names)) + sizeof(LEX_STRING) * header.column_count; for (i= 0, read= header.header; i < header.column_count; i++, read+= header.entry_size) { - LEX_STRING tmp; - if (header.format == DYNCOL_FMT_NUM) + if (header.format == dyncol_fmt_num) { uint nm= uint2korr(read); - tmp.str= my_malloc(DYNCOL_NUM_CHAR, MYF(0)); - if (!tmp.str) - return ER_DYNCOL_RESOURCE; - tmp.length= snprintf(tmp.str, DYNCOL_NUM_CHAR, "%u", nm); + (*names)[i].str= pool; + pool+= DYNCOL_NUM_CHAR; + (*names)[i].length= + longlong2str(nm, (*names)[i].str, 10) - (*names)[i].str; } else { - tmp.length= read[0]; - tmp.str= my_malloc(tmp.length + 1, MYF(0)); - if(!tmp.str) - return ER_DYNCOL_RESOURCE; - memcpy(tmp.str, (const void *)header.nmpool + uint2korr(read + 1), - tmp.length); - tmp.str[tmp.length]= '\0'; // just for safety + LEX_STRING tmp; + if (read_name(&header, read, &tmp)) + return ER_DYNCOL_FORMAT; + (*names)[i].length= tmp.length; + (*names)[i].str= pool; + pool+= tmp.length + 1; + memcpy((*names)[i].str, (const void *)tmp.str, tmp.length); + (*names)[i].str[tmp.length]= '\0'; // just for safety } - /* Insert can't never fail as it's pre-allocated above */ - (void) insert_dynamic(array_of_lexstr, (uchar *)&tmp); } + (*count)= header.column_count; return ER_DYNCOL_OK; } @@ -2211,15 +2506,14 @@ static my_bool find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) { uint mid, start, end, val; - int flag; + int UNINIT_VAR(flag); LEX_STRING str; char buff[DYNCOL_NUM_CHAR]; - my_bool need_conversion= ((string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM) != + my_bool need_conversion= ((string_keys ? dyncol_fmt_str : dyncol_fmt_num) != hdr->format); - LINT_INIT(flag); /* 100 % safe */ /* new format can't be numeric if the old one is names */ DBUG_ASSERT(string_keys || - hdr->format == DYNCOL_FMT_NUM); + hdr->format == dyncol_fmt_num); start= 0; end= hdr->column_count -1; @@ -2243,13 +2537,11 @@ find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) } else { - DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); - str.length= hdr->entry[0]; - str.str= (char *)hdr->nmpool + uint2korr(hdr->entry + 1); + DBUG_ASSERT(hdr->format == dyncol_fmt_str); + if (read_name(hdr, hdr->entry, &str)) + return 0; } - flag= ((LEX_STRING *) key)->length - str.length; - if (flag == 0) - flag= memcmp(((LEX_STRING *) key)->str, str.str, str.length); + flag= mariadb_dyncol_column_cmp_named((LEX_STRING *)key, &str); } if (flag <= 0) end= mid; @@ -2273,13 +2565,11 @@ find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) } else { - DBUG_ASSERT(hdr->format == DYNCOL_FMT_STR); - str.length= hdr->entry[0]; - str.str= (char*) hdr->nmpool + uint2korr(hdr->entry + 1); + DBUG_ASSERT(hdr->format == dyncol_fmt_str); + if (read_name(hdr, hdr->entry, &str)) + return 0; } - flag= ((LEX_STRING *) key)->length - str.length; - if (flag == 0) - flag= memcmp(((LEX_STRING *) key)->str, str.str, str.length); + flag= mariadb_dyncol_column_cmp_named((LEX_STRING *)key, &str); } } if (flag > 0) @@ -2289,7 +2579,7 @@ find_place(DYN_HEADER *hdr, void *key, my_bool string_keys) /* - It is internal structure which describes plan of chenging the record + It is internal structure which describes a plan of changing the record of dynamic columns */ @@ -2321,15 +2611,10 @@ static int plan_sort_num(const void *a, const void *b) Sort function for plan by column name */ -static int plan_sort_str(const void *a, const void *b) +static int plan_sort_named(const void *a, const void *b) { - int res= (((LEX_STRING *)((PLAN *)a)->key)->length - - ((LEX_STRING *)((PLAN *)b)->key)->length); - if (res == 0) - res= memcmp(((LEX_STRING *)((PLAN *)a)->key)->str, - ((LEX_STRING *)((PLAN *)b)->key)->str, - ((LEX_STRING *)((PLAN *)a)->key)->length); - return res; + return mariadb_dyncol_column_cmp_named((LEX_STRING *)((PLAN *)a)->key, + (LEX_STRING *)((PLAN *)b)->key); } #define DELTA_CHECK(S, D, C) \ @@ -2354,7 +2639,7 @@ static int plan_sort_str(const void *a, const void *b) @return ER_DYNCOL_* return code */ -enum enum_dyncol_func_result +static enum enum_dyncol_func_result dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, uint add_column_count, DYN_HEADER *hdr, DYN_HEADER *new_hdr, @@ -2366,7 +2651,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, uint i, j, k; size_t all_headers_size; - if (dynamic_column_init_str(&tmp, + if (dynamic_column_init_named(&tmp, (new_fmt->fixed_hdr + new_hdr->header_size + new_hdr->nmpool_size + new_hdr->data_size + DYNCOL_SYZERESERVE))) @@ -2432,7 +2717,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, DYNAMIC_COLUMN_TYPE tp; char buff[DYNCOL_NUM_CHAR]; - if (hdr->format == DYNCOL_FMT_NUM) + if (hdr->format == dyncol_fmt_num) { if (convert) { @@ -2448,12 +2733,13 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, } else { - name.length= read[0]; - name.str= (char *) hdr->nmpool + uint2korr(read + 1); + if (read_name(hdr, read, &name)) + goto err; key= &name; } - if (type_and_offset_read(&tp, &offs, - read + fmt->fixed_hdr_entry, hdr->offset_size)) + if (fmt->type_and_offset_read(&tp, &offs, + read + fmt->fixed_hdr_entry, + hdr->offset_size)) goto err; if (k == start) first_offset= offs; @@ -2496,7 +2782,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, plan[i].val, tmp.length - all_headers_size)) goto err; - data_store(&tmp, plan[i].val); /* Append new data */ + data_store(&tmp, plan[i].val, new_hdr->format); /* Append new data */ } } } @@ -2508,7 +2794,7 @@ err: return ER_DYNCOL_FORMAT; } -enum enum_dyncol_func_result +static enum enum_dyncol_func_result dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, size_t offset_size, size_t entry_size, @@ -2570,9 +2856,9 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, { DYNAMIC_COLUMN_TYPE tp; - if (type_and_offset_read(&tp, &first_offset, - header_base + start * entry_size + - COLUMN_NUMBER_SIZE, offset_size)) + if (type_and_offset_read_num(&tp, &first_offset, + header_base + start * entry_size + + COLUMN_NUMBER_SIZE, offset_size)) return ER_DYNCOL_FORMAT; } /* find data to be moved */ @@ -2617,8 +2903,8 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, DYNAMIC_COLUMN_TYPE tp; nm= uint2korr(read); /* Column nummber */ - if (type_and_offset_read(&tp, &offs, read + COLUMN_NUMBER_SIZE, - offset_size)) + if (type_and_offset_read_num(&tp, &offs, read + COLUMN_NUMBER_SIZE, + offset_size)) return ER_DYNCOL_FORMAT; if (k > start && offs < first_offset) @@ -2630,7 +2916,7 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, offs+= plan[i].ddelta; int2store(write, nm); /* write rest of data at write + COLUMN_NUMBER_SIZE */ - type_and_offset_store(write, new_offset_size, tp, offs); + type_and_offset_store_num(write, new_offset_size, tp, offs); write+= new_entry_size; } } @@ -2641,9 +2927,9 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) { int2store(write, *((uint *)plan[i].key)); - type_and_offset_store(write, new_offset_size, - plan[i].val[0].type, - curr_offset); + type_and_offset_store_num(write, new_offset_size, + plan[i].val[0].type, + curr_offset); write+= new_entry_size; curr_offset+= plan[i].length; } @@ -2690,14 +2976,15 @@ dynamic_column_update_move_left(DYNAMIC_COLUMN *str, PLAN *plan, { if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) { - data_store(str, plan[i].val); /* Append new data */ + data_store(str, plan[i].val, dyncol_fmt_num);/* Append new data */ } } } return ER_DYNCOL_OK; } -enum enum_dyncol_func_result +#ifdef UNUSED +static enum enum_dyncol_func_result dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, size_t offset_size, size_t entry_size, @@ -2759,8 +3046,10 @@ dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, { DYNAMIC_COLUMN_TYPE tp; - type_and_offset_read(&tp, &first_offset, - header_base + start * entry_size + COLUMN_NUMBER_SIZE, offset_size); + type_and_offset_read_num(&tp, &first_offset, + header_base + + start * entry_size + COLUMN_NUMBER_SIZE, + offset_size); } /* find data to be moved */ if (start < end) @@ -2804,7 +3093,8 @@ dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, DYNAMIC_COLUMN_TYPE tp; nm= uint2korr(read); /* Column nummber */ - type_and_offset_read(&tp, &offs, read + COLUMN_NUMBER_SIZE, offset_size); + type_and_offset_read_num(&tp, &offs, read + COLUMN_NUMBER_SIZE, + offset_size); if (k > start && offs < first_offset) { str->length= 0; // just something valid @@ -2814,7 +3104,7 @@ dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, offs+= plan[i].ddelta; int2store(write, nm); /* write rest of data at write + COLUMN_NUMBER_SIZE */ - if (type_and_offset_store(write, new_offset_size, tp, offs)) + if (type_and_offset_store_num(write, new_offset_size, tp, offs)) { str->length= 0; // just something valid return ER_DYNCOL_FORMAT; @@ -2829,9 +3119,9 @@ dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) { int2store(write, *((uint *)plan[i].key)); - if (type_and_offset_store(write, new_offset_size, - plan[i].val[0].type, - curr_offset)) + if (type_and_offset_store_num(write, new_offset_size, + plan[i].val[0].type, + curr_offset)) { str->length= 0; // just something valid return ER_DYNCOL_FORMAT; @@ -2882,13 +3172,13 @@ dynamic_column_update_move_right(DYNAMIC_COLUMN *str, PLAN *plan, { if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE) { - data_store(str, plan[i].val); /* Append new data */ + data_store(str, plan[i].val, dyncol_fmt_num); /* Append new data */ } } } return ER_DYNCOL_OK; } - +#endif /** Update the packed string with the given columns @@ -2913,7 +3203,27 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str, values, FALSE); } -uint numlen(uint val) +enum enum_dyncol_func_result +mariadb_dyncol_update_many(DYNAMIC_COLUMN *str, + uint add_column_count, + uint *column_numbers, + DYNAMIC_COLUMN_VALUE *values) +{ + return dynamic_column_update_many_fmt(str, add_column_count, column_numbers, + values, FALSE); +} + +enum enum_dyncol_func_result +mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str, + uint add_column_count, + LEX_STRING *column_names, + DYNAMIC_COLUMN_VALUE *values) +{ + return dynamic_column_update_many_fmt(str, add_column_count, column_names, + values, TRUE); +} + +static uint numlen(uint val) { uint res; if (val == 0) @@ -2927,7 +3237,7 @@ uint numlen(uint val) return res; } -enum enum_dyncol_func_result +static enum enum_dyncol_func_result dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, uint add_column_count, void *column_keys, @@ -2952,7 +3262,7 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, bzero(&header, sizeof(header)); bzero(&new_header, sizeof(new_header)); - new_header.format= (string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM); + new_header.format= (string_keys ? dyncol_fmt_str : dyncol_fmt_num); new_fmt= fmt_data + new_header.format; /* @@ -2997,8 +3307,8 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, goto end; fmt= fmt_data + header.format; /* new format can't be numeric if the old one is names */ - DBUG_ASSERT(new_header.format == DYNCOL_FMT_STR || - header.format == DYNCOL_FMT_NUM); + DBUG_ASSERT(new_header.format == dyncol_fmt_str || + header.format == dyncol_fmt_num); if (header.column_count == 0) goto create_new_string; @@ -3006,8 +3316,8 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, new_header.column_count= header.column_count; new_header.nmpool_size= header.nmpool_size; - if ((convert= (new_header.format == DYNCOL_FMT_STR && - header.format == DYNCOL_FMT_NUM))) + if ((convert= (new_header.format == dyncol_fmt_str && + header.format == dyncol_fmt_num))) { DBUG_ASSERT(new_header.nmpool_size == 0); for(i= 0, header.entry= header.header; @@ -3064,12 +3374,18 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, goto end; } - //get_length(header.entry, header.dtpool, header.offset_size, - //header.data_size); - if (new_header.format == DYNCOL_FMT_STR) + if (new_header.format == dyncol_fmt_str) { - if (header.format == DYNCOL_FMT_STR) - entry_name_size= header.entry[0]; + if (header.format == dyncol_fmt_str) + { + LEX_STRING name; + if (read_name(&header, header.entry, &name)) + { + rc= ER_DYNCOL_FORMAT; + goto end; + } + entry_name_size= name.length; + } else entry_name_size= numlen(uint2korr(header.entry)); } @@ -3089,14 +3405,15 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, plan[i].act= PLAN_REPLACE; /* get data delta in bytes */ - if ((plan[i].length= dynamic_column_value_len(plan[i].val)) == + if ((plan[i].length= dynamic_column_value_len(plan[i].val, + new_header.format)) == (size_t) ~0) { rc= ER_DYNCOL_DATA; goto end; } data_delta+= plan[i].length - entry_data_size; - if (new_header.format == DYNCOL_FMT_STR) + if (new_header.format == dyncol_fmt_str) { name_delta+= ((LEX_STRING *)(plan[i].key))->length - entry_name_size; } @@ -3117,14 +3434,15 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, plan[i].act= PLAN_ADD; header_delta++; /* One more row in header */ /* get data delta in bytes */ - if ((plan[i].length= dynamic_column_value_len(plan[i].val)) == + if ((plan[i].length= dynamic_column_value_len(plan[i].val, + new_header.format)) == (size_t) ~0) { rc= ER_DYNCOL_DATA; goto end; } data_delta+= plan[i].length; - if (new_header.format == DYNCOL_FMT_STR) + if (new_header.format == dyncol_fmt_str) name_delta+= ((LEX_STRING *)plan[i].key)->length; } } @@ -3143,18 +3461,18 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, */ new_header.data_size= header.data_size + data_delta; new_header.nmpool_size= new_header.nmpool_size + name_delta; - DBUG_ASSERT(new_header.format != DYNCOL_FMT_NUM || + DBUG_ASSERT(new_header.format != dyncol_fmt_num || new_header.nmpool_size == 0); if ((new_header.offset_size= - dynamic_column_offset_bytes(new_header.data_size)) >= - MAX_OFFSET_LENGTH) + new_fmt->dynamic_column_offset_bytes(new_header.data_size)) >= + new_fmt->max_offset_size) { rc= ER_DYNCOL_LIMIT; goto end; } copy= ((header.format != new_header.format) || - (new_header.format == DYNCOL_FMT_STR)); + (new_header.format == dyncol_fmt_str)); /* if (new_header.offset_size!=offset_size) then we have to rewrite header */ header_delta_sign= ((int)new_header.offset_size + new_fmt->fixed_hdr_entry) - @@ -3173,14 +3491,14 @@ dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str, /* Need copy because: - 1. Header/data parts moved in different directions. + 1, Header/data parts moved in different directions. 2. There is no enough allocated space in the string. 3. Header and data moved in different directions. */ - if (copy || /*1*/ - str->max_length < str->length + header_delta + data_delta || /*2*/ + if (copy || /*1.*/ + str->max_length < str->length + header_delta + data_delta || /*2.*/ ((header_delta_sign < 0 && data_delta_sign > 0) || - (header_delta_sign > 0 && data_delta_sign < 0))) /*3*/ + (header_delta_sign > 0 && data_delta_sign < 0))) /*3.*/ rc= dynamic_column_update_copy(str, plan, add_column_count, &header, &new_header, convert); @@ -3246,7 +3564,7 @@ int dynamic_column_update(DYNAMIC_COLUMN *str, uint column_nr, enum enum_dyncol_func_result -dynamic_column_check(DYNAMIC_COLUMN *str) +mariadb_dyncol_check(DYNAMIC_COLUMN *str) { struct st_service_funcs *fmt; enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT; @@ -3297,7 +3615,7 @@ dynamic_column_check(DYNAMIC_COLUMN *str) header.header_size - header.nmpool_size; /* read and check headers */ - if (header.format == DYNCOL_FMT_NUM) + if (header.format == dyncol_fmt_num) { key= # prev_key= &prev_num; @@ -3312,20 +3630,28 @@ dynamic_column_check(DYNAMIC_COLUMN *str) i++, header.entry+= header.entry_size) { - if (header.format == DYNCOL_FMT_NUM) + if (header.format == dyncol_fmt_num) { num= uint2korr(header.entry); } else { - DBUG_ASSERT(header.format == DYNCOL_FMT_STR); - name.length= header.entry[0]; - name_offset= uint2korr(header.entry + 1); - name.str= (char *)header.nmpool + name_offset; + DBUG_ASSERT(header.format == dyncol_fmt_str); + if (read_name(&header, header.entry, &name)) + { + DBUG_PRINT("info", ("Reading name failed: Field order: %u" + " Name offset: %u" + " Name pool size: %u", + (uint) i, + uint2korr(header.entry), + (uint)header.nmpool_size)); + goto end; + } + name_offset= name.str - (char *)header.nmpool; } - if (type_and_offset_read(&type, &data_offset, - header.entry + fmt->fixed_hdr_entry, - header.offset_size)) + if ((*fmt->type_and_offset_read)(&type, &data_offset, + header.entry + fmt->fixed_hdr_entry, + header.offset_size)) goto end; DBUG_ASSERT(type != DYN_COL_NULL); @@ -3334,17 +3660,8 @@ dynamic_column_check(DYNAMIC_COLUMN *str) DBUG_PRINT("info", ("Field order: %u Data offset: %u" " > Data pool size: %u", (uint)i, - (uint)name_offset, - (uint)header.nmpool_size)); - goto end; - } - if (name_offset > header.nmpool_size) - { - DBUG_PRINT("info", ("Field order: %u Name offset: %u" - " > Name pool size: %u", - (uint)i, - (uint)name_offset, - (uint)header.nmpool_size)); + (uint)data_offset, + (uint)header.data_size)); goto end; } if (prev_type != DYN_COL_NULL) @@ -3389,9 +3706,9 @@ dynamic_column_check(DYNAMIC_COLUMN *str) { DYNAMIC_COLUMN_VALUE store; // already checked by previouse pass - type_and_offset_read(&header.type, &header.offset, - header.entry + fmt->fixed_hdr_entry, - header.offset_size); + (*fmt->type_and_offset_read)(&header.type, &header.offset, + header.entry + fmt->fixed_hdr_entry, + header.offset_size); header.length= hdr_interval_length(&header, header.entry + header.entry_size); header.data= header.dtpool + header.offset; @@ -3421,6 +3738,9 @@ dynamic_column_check(DYNAMIC_COLUMN *str) case DYN_COL_TIME: rc= dynamic_column_time_read(&store, header.data, header.length); break; + case DYN_COL_DYNCOL: + rc= dynamic_column_dyncol_read(&store, header.data, header.length); + break; case DYN_COL_NULL: default: rc= ER_DYNCOL_FORMAT; @@ -3442,13 +3762,13 @@ end: enum enum_dyncol_func_result -dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, - CHARSET_INFO *cs, my_bool quote) +mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, + CHARSET_INFO *cs, char quote) { char buff[40]; int len; switch (val->type) { - case DYN_COL_INT: + case DYN_COL_INT: len= snprintf(buff, sizeof(buff), "%lld", val->x.long_value); if (dynstr_append_mem(str, buff, len)) return ER_DYNCOL_RESOURCE; @@ -3463,11 +3783,12 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, if (dynstr_realloc(str, len + (quote ? 2 : 0))) return ER_DYNCOL_RESOURCE; if (quote) - str->str[str->length++]= '"'; + str->str[str->length++]= quote; dynstr_append_mem(str, buff, len); if (quote) - str->str[str->length++]= '"'; + str->str[str->length++]= quote; break; + case DYN_COL_DYNCOL: case DYN_COL_STRING: { char *alloc= NULL; @@ -3506,7 +3827,7 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, return ER_DYNCOL_RESOURCE; } if (quote) - rc= dynstr_append_quoted(str, from, len); + rc= dynstr_append_quoted(str, from, len, quote); else rc= dynstr_append_mem(str, from, len); if (alloc) @@ -3547,7 +3868,7 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, enum enum_dyncol_func_result -dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) +mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) { enum enum_dyncol_func_result rc= ER_DYNCOL_OK; *ll= 0; @@ -3619,6 +3940,7 @@ dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) val->x.time_value.second) * (val->x.time_value.neg ? -1 : 1); break; + case DYN_COL_DYNCOL: case DYN_COL_NULL: rc= ER_DYNCOL_TRUNCATED; break; @@ -3630,7 +3952,7 @@ dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) enum enum_dyncol_func_result -dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val) +mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val) { enum enum_dyncol_func_result rc= ER_DYNCOL_OK; *dbl= 0; @@ -3684,6 +4006,7 @@ dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val) val->x.time_value.second) * (val->x.time_value.neg ? -1 : 1); break; + case DYN_COL_DYNCOL: case DYN_COL_NULL: rc= ER_DYNCOL_TRUNCATED; break; @@ -3703,30 +4026,40 @@ dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val) @return ER_DYNCOL_* return code */ -enum enum_dyncol_func_result -dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) +#define JSON_STACK_PROTECTION 10 + +static enum enum_dyncol_func_result +mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, + uint lvl) { DYN_HEADER header; uint i; enum enum_dyncol_func_result rc; - bzero(json, sizeof(DYNAMIC_STRING)); /* In case of errors */ + if (lvl >= JSON_STACK_PROTECTION) + { + rc= ER_DYNCOL_RESOURCE; + goto err; + } + + if (str->length == 0) return ER_DYNCOL_OK; /* no columns */ if ((rc= init_read_hdr(&header, str)) < 0) - return rc; + goto err; if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > str->length) - return ER_DYNCOL_FORMAT; + { + rc= ER_DYNCOL_FORMAT; + goto err; + } - if (init_dynamic_string(json, NULL, str->length * 2, 100)) - return ER_DYNCOL_RESOURCE; + rc= ER_DYNCOL_RESOURCE; if (dynstr_append_mem(json, "[", 1)) - return ER_DYNCOL_RESOURCE; - rc= ER_DYNCOL_RESOURCE; + goto err; for (i= 0, header.entry= header.header; i < header.column_count; i++, header.entry+= header.entry_size) @@ -3750,7 +4083,7 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) if ((rc= dynamic_column_get_value(&header, &val)) < 0 || dynstr_append_mem(json, "{", 1)) goto err; - if (header.format == DYNCOL_FMT_NUM) + if (header.format == dyncol_fmt_num) { uint nm= uint2korr(header.entry); if (dynstr_realloc(json, DYNCOL_NUM_CHAR + 3)) @@ -3761,23 +4094,47 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) } else { - uint len= header.entry[0]; - if (dynstr_realloc(json, len + 3)) + LEX_STRING name; + if (read_name(&header, header.entry, &name)) + { + rc= ER_DYNCOL_FORMAT; + goto err; + } + if (dynstr_realloc(json, name.length + 3)) goto err; json->str[json->length++]= '"'; - memcpy(json->str + json->length, (const void *)header.nmpool + - uint2korr(header.entry + 1), len); - json->length+= len; + memcpy(json->str + json->length, name.str, name.length); + json->length+= name.length; } json->str[json->length++]= '"'; json->str[json->length++]= ':'; - if ((rc= dynamic_column_val_str(json, &val, - &my_charset_utf8_general_ci, TRUE)) < 0 || - dynstr_append_mem(json, "}", 1)) - goto err; + if (val.type == DYN_COL_DYNCOL) + { + /* here we use it only for read so can cheat a bit */ + DYNAMIC_COLUMN dc; + bzero(&dc, sizeof(dc)); + dc.str= val.x.string.value.str; + dc.length= val.x.string.value.length; + if (mariadb_dyncol_json_internal(&dc, json, lvl + 1) < 0) + { + dc.str= NULL; dc.length= 0; + goto err; + } + dc.str= NULL; dc.length= 0; + } + else + { + if ((rc= mariadb_dyncol_val_str(json, &val, + &my_charset_utf8_general_ci, '"')) < 0 || + dynstr_append_mem(json, "}", 1)) + goto err; + } } if (dynstr_append_mem(json, "]", 1)) - return ER_DYNCOL_RESOURCE; + { + rc= ER_DYNCOL_RESOURCE; + goto err; + } return ER_DYNCOL_OK; err: @@ -3785,59 +4142,73 @@ err: return rc; } +enum enum_dyncol_func_result +mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json) +{ + + if (init_dynamic_string(json, NULL, str->length * 2, 100)) + return ER_DYNCOL_RESOURCE; + + return mariadb_dyncol_json_internal(str, json, 1); +} + /** Convert to DYNAMIC_COLUMN_VALUE values and names (LEX_STING) dynamic array @param str The packed string - @param names Where to put names - @param vals Where to put values - @param free_names pointer to free names buffer if there is it. + @param count number of elements in the arrays + @param names Where to put names (should be free by user) + @param vals Where to put values (should be free by user) @return ER_DYNCOL_* return code */ enum enum_dyncol_func_result -dynamic_column_vals(DYNAMIC_COLUMN *str, - DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals, - char **free_names) +mariadb_dyncol_unpack(DYNAMIC_COLUMN *str, + uint *count, + LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals) { DYN_HEADER header; char *nm; uint i; enum enum_dyncol_func_result rc; - *free_names= 0; - bzero(names, sizeof(DYNAMIC_ARRAY)); /* In case of errors */ - bzero(vals, sizeof(DYNAMIC_ARRAY)); /* In case of errors */ + *count= 0; *names= 0; *vals= 0; + if (str->length == 0) return ER_DYNCOL_OK; /* no columns */ if ((rc= init_read_hdr(&header, str)) < 0) return rc; + if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > str->length) return ER_DYNCOL_FORMAT; - if (init_dynamic_array(names, sizeof(LEX_STRING), - header.column_count, 0) || - init_dynamic_array(vals, sizeof(DYNAMIC_COLUMN_VALUE), - header.column_count, 0) || - (header.format == DYNCOL_FMT_NUM && - !(*free_names= (char *)malloc(DYNCOL_NUM_CHAR * header.column_count)))) + *vals= my_malloc(sizeof(DYNAMIC_COLUMN_VALUE)* header.column_count, MYF(0)); + if (header.format == dyncol_fmt_num) + { + *names= my_malloc(sizeof(LEX_STRING) * header.column_count + + DYNCOL_NUM_CHAR * header.column_count, MYF(0)); + nm= (char *)(names + sizeof(LEX_STRING) * header.column_count); + } + else + { + *names= my_malloc(sizeof(LEX_STRING) * header.column_count, MYF(0)); + nm= 0; + } + if (!(*vals) || !(*names)) { rc= ER_DYNCOL_RESOURCE; goto err; } - nm= *free_names; for (i= 0, header.entry= header.header; i < header.column_count; i++, header.entry+= header.entry_size) { - DYNAMIC_COLUMN_VALUE val; - LEX_STRING name; header.length= hdr_interval_length(&header, header.entry + header.entry_size); header.data= header.dtpool + header.offset; @@ -3851,32 +4222,60 @@ dynamic_column_vals(DYNAMIC_COLUMN *str, rc= ER_DYNCOL_FORMAT; goto err; } - if ((rc= dynamic_column_get_value(&header, &val)) < 0) + if ((rc= dynamic_column_get_value(&header, (*vals) + i)) < 0) goto err; - if (header.format == DYNCOL_FMT_NUM) + if (header.format == dyncol_fmt_num) { uint num= uint2korr(header.entry); - name.str= nm; - name.length= snprintf(nm, DYNCOL_NUM_CHAR, "%u", num); - nm+= name.length + 1; + (*names)[i].str= nm; + (*names)[i].length= snprintf(nm, DYNCOL_NUM_CHAR, "%u", num); + nm+= (*names)[i].length + 1; } else { - name.length= header.entry[0]; - name.str= (char *)header.nmpool + uint2korr(header.entry + 1); + if (read_name(&header, header.entry, (*names) + i)) + { + rc= ER_DYNCOL_FORMAT; + goto err; + } } - /* following is preallocated and so do not fail */ - (void) insert_dynamic(names, (uchar *)&name); - (void) insert_dynamic(vals, (uchar *)&val); } + + *count= header.column_count; return ER_DYNCOL_OK; err: - delete_dynamic(names); - delete_dynamic(vals); - if (*free_names) - my_free(*free_names); - *free_names= 0; + if (*vals) + { + my_free(*vals); + *vals= 0; + } + if (*names) + { + my_free(*names); + *names= 0; + } + return rc; +} + +/** + Get not NULL column count + + @param str The packed string + @param column_count Where to put column count + + @return ER_DYNCOL_* return code +*/ + +enum enum_dyncol_func_result +mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count) +{ + DYN_HEADER header; + enum enum_dyncol_func_result rc; + + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; + *column_count= header.column_count; return rc; } diff --git a/mysys/string.c b/mysys/string.c index 0cf8f939260..1263e7824f9 100644 --- a/mysys/string.c +++ b/mysys/string.c @@ -176,18 +176,19 @@ my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...) } my_bool dynstr_append_quoted(DYNAMIC_STRING *str, - const char *append, size_t len) + const char *append, size_t len, + char quote) { uint additional= (str->alloc_increment ? str->alloc_increment : 10); uint lim= additional; uint i; if (dynstr_realloc(str, len + additional + 2)) return TRUE; - str->str[str->length++]= '"'; + str->str[str->length++]= quote; for (i= 0; i < len; i++) { register char c= append[i]; - if (c == '"' || c == '\\') + if (c == quote || c == '\\') { if (!lim) { @@ -200,10 +201,11 @@ my_bool dynstr_append_quoted(DYNAMIC_STRING *str, } str->str[str->length++]= c; } - str->str[str->length++]= '"'; + str->str[str->length++]= quote; return FALSE; } + void dynstr_free(DYNAMIC_STRING *str) { my_free(str->str); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 72d28bb2e7e..ad01f9f83fc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -6048,6 +6048,7 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) return NULL; } + longlong Item_func_dyncol_check::val_int() { char buff[STRING_BUFFER_USUAL_SIZE]; @@ -6062,7 +6063,7 @@ longlong Item_func_dyncol_check::val_int() col.length= str->length(); /* We do not change the string, so could do this trick */ col.str= (char *)str->ptr(); - rc= dynamic_column_check(&col); + rc= mariadb_dyncol_check(&col); if (rc < 0 && rc != ER_DYNCOL_FORMAT) { dynamic_column_error_message(rc); @@ -6127,8 +6128,8 @@ longlong Item_func_dyncol_exists::val_int() /* We do not change the string, so could do this trick */ col.str= (char *)str->ptr(); rc= ((name == NULL) ? - dynamic_column_exists(&col, (uint) num) : - dynamic_column_exists_str(&col, name)); + mariadb_dyncol_exists(&col, (uint) num) : + mariadb_dyncol_exists_named(&col, name)); if (rc < 0) { dynamic_column_error_message(rc); diff --git a/sql/item_create.cc b/sql/item_create.cc index f886b3d598b..bc449b0aaf2 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -526,6 +526,54 @@ protected: virtual ~Create_func_coercibility() {} }; +class Create_func_dyncol_check : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_dyncol_check s_singleton; + +protected: + Create_func_dyncol_check() {} + virtual ~Create_func_dyncol_check() {} +}; + +class Create_func_dyncol_exists : public Create_func_arg2 +{ +public: + virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); + + static Create_func_dyncol_exists s_singleton; + +protected: + Create_func_dyncol_exists() {} + virtual ~Create_func_dyncol_exists() {} +}; + +class Create_func_dyncol_list : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_dyncol_list s_singleton; + +protected: + Create_func_dyncol_list() {} + virtual ~Create_func_dyncol_list() {} +}; + +class Create_func_dyncol_json : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_dyncol_json s_singleton; + +protected: + Create_func_dyncol_json() {} + virtual ~Create_func_dyncol_json() {} +}; + class Create_func_compress : public Create_func_arg1 { @@ -3108,6 +3156,38 @@ Create_func_coercibility::create_1_arg(THD *thd, Item *arg1) } +Create_func_dyncol_check Create_func_dyncol_check::s_singleton; + +Item* +Create_func_dyncol_check::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_dyncol_check(arg1); +} + +Create_func_dyncol_exists Create_func_dyncol_exists::s_singleton; + +Item* +Create_func_dyncol_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_dyncol_exists(arg1, arg2); +} + +Create_func_dyncol_list Create_func_dyncol_list::s_singleton; + +Item* +Create_func_dyncol_list::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_dyncol_list(arg1); +} + +Create_func_dyncol_json Create_func_dyncol_json::s_singleton; + +Item* +Create_func_dyncol_json::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_dyncol_json(arg1); +} + Create_func_concat Create_func_concat::s_singleton; Item* @@ -5245,6 +5325,10 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)}, { { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)}, { { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)}, + { { C_STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)}, + { { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)}, + { { C_STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)}, + { { C_STRING_WITH_LEN("COLUMN_JSON") }, BUILDER(Create_func_dyncol_json)}, { { C_STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)}, { { C_STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)}, { { C_STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)}, @@ -5720,11 +5804,6 @@ Item *create_func_dyncol_create(THD *thd, List &list) return new (thd->mem_root) Item_func_dyncol_create(*args, dfs); } -Item *create_func_dyncol_json(THD *thd, Item *str) -{ - return new (thd->mem_root) Item_func_dyncol_json(str); -} - Item *create_func_dyncol_add(THD *thd, Item *str, List &list) { diff --git a/sql/item_func.h b/sql/item_func.h index cb9c1929d7d..ccb86fd03e5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -58,7 +58,7 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC, GSYSVAR_FUNC }; + NEG_FUNC, GSYSVAR_FUNC, DYNCOL }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index ca6a6b2cea3..706fbbff94d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3760,8 +3760,8 @@ String *Item_func_uuid::val_str(String *str) Item_func_dyncol_create::Item_func_dyncol_create(List &args, DYNCALL_CREATE_DEF *dfs) - : Item_str_func(args), defs(dfs), vals(0), keys(NULL), names(FALSE), - force_names(FALSE) + : Item_str_func(args), defs(dfs), vals(0), keys_num(NULL), keys_str(NULL), + names(FALSE), force_names(FALSE) { DBUG_ASSERT((args.elements & 0x1) == 0); // even number of arguments } @@ -3782,13 +3782,15 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref) names= TRUE; } - keys= (uchar *) alloc_root(thd->mem_root, + keys_num= (uint *) alloc_root(thd->mem_root, (sizeof(LEX_STRING) > sizeof(uint) ? sizeof(LEX_STRING) : sizeof(uint)) * (arg_count / 2)); + keys_str= (LEX_STRING *) keys_num; + //status_var_increment(thd->status_var.feature_dynamic_columns); } - return res || vals == 0 || keys == 0; + return res || vals == 0 || keys_num == 0; } @@ -3808,6 +3810,41 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) my_decimal dtmp, *dres; force_names= force_names_arg; + if (!(names || force_names)) + { + for (i= 0; i < column_count; i++) + { + uint valpos= i * 2 + 1; + DYNAMIC_COLUMN_TYPE type= defs[i].type; + if (type == DYN_COL_NULL) + switch (args[valpos]->field_type()) + { + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_GEOMETRY: + type= DYN_COL_STRING; + break; + default: + break; + } + + if (type == DYN_COL_STRING && + args[valpos]->type() == Item::FUNC_ITEM && + ((Item_func *)args[valpos])->functype() == DYNCOL) + { + force_names= 1; + break; + } + } + } + /* get values */ for (i= 0; i < column_count; i++) { @@ -3865,6 +3902,13 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) break; } } + if (type == DYN_COL_STRING && + args[valpos]->type() == Item::FUNC_ITEM && + ((Item_func *)args[valpos])->functype() == DYNCOL) + { + DBUG_ASSERT(names || force_names); + type= DYN_COL_DYNCOL; + } if (names || force_names) { res= args[i * 2]->val_str(&tmp); @@ -3873,10 +3917,8 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) // guaranty UTF-8 string for names if (my_charset_same(res->charset(), &my_charset_utf8_general_ci)) { - ((LEX_STRING *)keys)[i].length= res->length(); - if (!(((LEX_STRING *)keys)[i].str= - (char *)sql_memdup(res->ptr(), res->length()))) - ((LEX_STRING *)keys)[i].length= 0; + keys_str[i].length= res->length(); + keys_str[i].str= sql_strmake(res->ptr(), res->length()); } else { @@ -3887,25 +3929,25 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) my_charset_utf8_general_ci.mbmaxlen + 1)); if (str) { - ((LEX_STRING *)keys)[i].length= + keys_str[i].length= copy_and_convert(str, strlen, &my_charset_utf8_general_ci, res->ptr(), res->length(), res->charset(), &dummy_errors); - ((LEX_STRING *)keys)[i].str= str; + keys_str[i].str= str; } else - ((LEX_STRING *)keys)[i].length= 0; + keys_str[i].length= 0; } } else { - ((LEX_STRING *)keys)[i].length= 0; - ((LEX_STRING *)keys)[i].str= NULL; + keys_str[i].length= 0; + keys_str[i].str= NULL; } } else - ((uint *)keys)[i]= (uint) args[i * 2]->val_int(); + keys_num[i]= (uint) args[i * 2]->val_int(); if (args[i * 2]->null_value) { /* to make cleanup possible */ @@ -3927,11 +3969,11 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) case DYN_COL_DOUBLE: vals[i].x.double_value= args[valpos]->val_real(); break; + case DYN_COL_DYNCOL: case DYN_COL_STRING: res= args[valpos]->val_str(&tmp); if (res && - (vals[i].x.string.value.str= my_strndup(res->ptr(), res->length(), - MYF(MY_WME)))) + (vals[i].x.string.value.str= sql_strmake(res->ptr(), res->length()))) { vals[i].x.string.value.length= res->length(); vals[i].x.string.charset= res->charset(); @@ -3975,26 +4017,12 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) } if (vals[i].type != DYN_COL_NULL && args[valpos]->null_value) { - if (vals[i].type == DYN_COL_STRING) - my_free(vals[i].x.string.value.str); vals[i].type= DYN_COL_NULL; } } return FALSE; } -void Item_func_dyncol_create::cleanup_arguments() -{ - uint column_count= (arg_count / 2); - uint i; - - for (i= 0; i < column_count; i++) - { - if (vals[i].type == DYN_COL_STRING) - my_free(vals[i].x.string.value.str); - } - force_names= FALSE; -} String *Item_func_dyncol_create::val_str(String *str) { @@ -4011,8 +4039,11 @@ String *Item_func_dyncol_create::val_str(String *str) } else { - if ((rc= dynamic_column_create_many_fmt(&col, column_count, keys, - vals, names || force_names))) + if ((rc= ((names || force_names) ? + mariadb_dyncol_create_many_named(&col, column_count, keys_str, + vals, TRUE) : + mariadb_dyncol_create_many(&col, column_count, keys_num, + vals, TRUE)))) { dynamic_column_error_message(rc); dynamic_column_column_free(&col); @@ -4024,7 +4055,7 @@ String *Item_func_dyncol_create::val_str(String *str) /* Move result from DYNAMIC_COLUMN to str_value */ char *ptr; size_t length, alloc_length; - dynamic_column_reassociate(&col, &ptr, &length, &alloc_length); + mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length); str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length, &my_charset_bin); res= &str_value; @@ -4032,9 +4063,6 @@ String *Item_func_dyncol_create::val_str(String *str) } } - /* cleanup */ - cleanup_arguments(); - return res; } @@ -4060,6 +4088,7 @@ void Item_func_dyncol_create::print_arguments(String *str, case DYN_COL_DOUBLE: str->append(STRING_WITH_LEN(" AS double")); break; + case DYN_COL_DYNCOL: case DYN_COL_STRING: str->append(STRING_WITH_LEN(" AS char")); if (defs[i].cs) @@ -4109,7 +4138,7 @@ String *Item_func_dyncol_json::val_str(String *str) col.str= (char *)res->ptr(); col.length= res->length(); - if ((rc= dynamic_column_json(&col, &json))) + if ((rc= mariadb_dyncol_json(&col, &json))) { dynamic_column_error_message(rc); goto null; @@ -4150,15 +4179,17 @@ String *Item_func_dyncol_add::val_str(String *str) col.length= res->length(); memcpy(col.str, res->ptr(), col.length); - if (prepare_arguments(dynamic_column_has_names(&col))) + if (prepare_arguments(mariadb_dyncol_has_names(&col))) goto null; - if ((rc= dynamic_column_update_many_fmt(&col, column_count, keys, - vals, names || force_names))) + if ((rc= ((names || force_names) ? + mariadb_dyncol_update_many_named(&col, column_count, + keys_str, vals) : + mariadb_dyncol_update_many(&col, column_count, + keys_num, vals)))) { dynamic_column_error_message(rc); dynamic_column_column_free(&col); - cleanup_arguments(); goto null; } @@ -4166,15 +4197,12 @@ String *Item_func_dyncol_add::val_str(String *str) /* Move result from DYNAMIC_COLUMN to str */ char *ptr; size_t length, alloc_length; - dynamic_column_reassociate(&col, &ptr, &length, &alloc_length); + mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length); str->reassociate(ptr, (uint32) length, (uint32) alloc_length, &my_charset_bin); null_value= FALSE; } - /* cleanup */ - cleanup_arguments(); - return str; null: @@ -4264,8 +4292,8 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) dyn_str.str= (char*) res->ptr(); dyn_str.length= res->length(); if ((rc= ((name == NULL) ? - dynamic_column_get(&dyn_str, (uint) num, val) : - dynamic_column_get_str(&dyn_str, name, val)))) + mariadb_dyncol_get(&dyn_str, (uint) num, val) : + mariadb_dyncol_get_named(&dyn_str, name, val)))) { dynamic_column_error_message(rc); null_value= 1; @@ -4297,6 +4325,7 @@ String *Item_dyncol_get::val_str(String *str_result) case DYN_COL_DOUBLE: str_result->set_real(val.x.double_value, NOT_FIXED_DEC, &my_charset_latin1); break; + case DYN_COL_DYNCOL: case DYN_COL_STRING: if ((char*) tmp.ptr() <= val.x.string.value.str && (char*) tmp.ptr() + tmp.length() >= val.x.string.value.str) @@ -4373,6 +4402,7 @@ longlong Item_dyncol_get::val_int() return 0; switch (val.type) { + case DYN_COL_DYNCOL: case DYN_COL_NULL: goto null; case DYN_COL_UINT: @@ -4453,6 +4483,7 @@ double Item_dyncol_get::val_real() return 0.0; switch (val.type) { + case DYN_COL_DYNCOL: case DYN_COL_NULL: goto null; case DYN_COL_UINT: @@ -4510,6 +4541,7 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value) return NULL; switch (val.type) { + case DYN_COL_DYNCOL: case DYN_COL_NULL: goto null; case DYN_COL_UINT: @@ -4569,6 +4601,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) return 1; // Error switch (val.type) { + case DYN_COL_DYNCOL: case DYN_COL_NULL: goto null; case DYN_COL_INT: @@ -4631,7 +4664,8 @@ String *Item_func_dyncol_list::val_str(String *str) { uint i; enum enum_dyncol_func_result rc; - DYNAMIC_ARRAY arr; + LEX_STRING *names= 0; + uint count; DYNAMIC_COLUMN col; String *res= args[0]->val_str(str); @@ -4640,37 +4674,37 @@ String *Item_func_dyncol_list::val_str(String *str) col.length= res->length(); /* We do not change the string, so could do this trick */ col.str= (char *)res->ptr(); - if ((rc= dynamic_column_list_str(&col, &arr))) + if ((rc= mariadb_dyncol_list_named(&col, &count, &names))) { + bzero(&col, sizeof(col)); dynamic_column_error_message(rc); - for (i= 0; i < arr.elements; i++) - my_free(dynamic_element(&arr, i, LEX_STRING*)->str); - delete_dynamic(&arr); goto null; } + bzero(&col, sizeof(col)); /* We estimate average name length as 10 */ - if (str->alloc(arr.elements * 13)) + if (str->alloc(count * 13)) goto null; str->length(0); str->set_charset(&my_charset_utf8_general_ci); - for (i= 0; i < arr.elements; i++) + for (i= 0; i < count; i++) { - LEX_STRING *name= dynamic_element(&arr, i, LEX_STRING *); - append_identifier(current_thd, str, name->str, name->length); - if (i < arr.elements - 1) + append_identifier(current_thd, str, names[i].str, names[i].length); + if (i < count - 1) str->qs_append(','); - my_free(name->str); } - null_value= FALSE; - delete_dynamic(&arr); + if (names) + my_free(names); return str; null: null_value= TRUE; + if (names) + my_free(names); return NULL; } + diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e6a7e1291b8..8ef67654b35 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1001,10 +1001,10 @@ class Item_func_dyncol_create: public Item_str_func protected: DYNCALL_CREATE_DEF *defs; DYNAMIC_COLUMN_VALUE *vals; - uchar *keys; + uint *keys_num; + LEX_STRING *keys_str; bool names, force_names; bool prepare_arguments(bool force_names); - void cleanup_arguments(); void print_arguments(String *str, enum_query_type query_type); public: Item_func_dyncol_create(List &args, DYNCALL_CREATE_DEF *dfs); @@ -1013,6 +1013,7 @@ public: const char *func_name() const{ return "column_create"; } String *val_str(String *); virtual void print(String *str, enum_query_type query_type); + virtual enum Functype functype() const { return DYNCOL; } }; @@ -1081,3 +1082,4 @@ public: extern String my_empty_string; #endif /* ITEM_STRFUNC_INCLUDED */ + diff --git a/sql/lex.h b/sql/lex.h index ea68ea0972a..34eda613e71 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -126,10 +126,7 @@ static SYMBOL symbols[] = { { "COLUMN_CHECK", SYM(COLUMN_CHECK_SYM)}, { "COLUMN_CREATE", SYM(COLUMN_CREATE_SYM)}, { "COLUMN_DELETE", SYM(COLUMN_DELETE_SYM)}, - { "COLUMN_EXISTS", SYM(COLUMN_EXISTS_SYM)}, { "COLUMN_GET", SYM(COLUMN_GET_SYM)}, - { "COLUMN_JSON", SYM(COLUMN_JSON_SYM)}, - { "COLUMN_LIST", SYM(COLUMN_LIST_SYM)}, { "COMMENT", SYM(COMMENT_SYM)}, { "COMMIT", SYM(COMMIT_SYM)}, { "COMMITTED", SYM(COMMITTED_SYM)}, diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index d785366ae69..14d4d5fca6c 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -3872,10 +3872,10 @@ int JOIN_TAB_SCAN_MRR::next() int rc= join_tab->table->file->multi_range_read_next((range_id_t*)ptr) ? -1 : 0; if (!rc) { - /* + /* If a record in in an incremental cache contains no fields then the association for the last record in cache will be equal to cache->end_pos - */ + */ /* psergey: this makes no sense where HA_MRR_NO_ASSOC is used. DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) && diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 48dd47bccea..87a7df34986 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -885,10 +885,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COLUMN_CHECK_SYM %token COLUMN_CREATE_SYM %token COLUMN_DELETE_SYM -%token COLUMN_EXISTS_SYM %token COLUMN_GET_SYM -%token COLUMN_JSON_SYM -%token COLUMN_LIST_SYM %token COLUMN_SYM /* SQL-2003-R */ %token COLUMN_NAME_SYM /* SQL-2003-N */ %token COMMENT_SYM @@ -8807,20 +8804,6 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } - | - COLUMN_EXISTS_SYM '(' expr ',' expr ')' - { - $$= new (YYTHD->mem_root) Item_func_dyncol_exists($3, $5); - if ($$ == NULL) - MYSQL_YYABORT; - } - | - COLUMN_LIST_SYM '(' expr ')' - { - $$= new (YYTHD->mem_root) Item_func_dyncol_list($3); - if ($$ == NULL) - MYSQL_YYABORT; - } | COLUMN_CREATE_SYM '(' dyncall_create_list ')' { @@ -8828,13 +8811,6 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } - | - COLUMN_JSON_SYM '(' expr ')' - { - $$= create_func_dyncol_json(YYTHD, $3); - if ($$ == NULL) - MYSQL_YYABORT; - } | COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { @@ -12927,10 +12903,7 @@ keyword: | COLUMN_CHECK_SYM {} | COLUMN_CREATE_SYM {} | COLUMN_DELETE_SYM {} - | COLUMN_EXISTS_SYM {} | COLUMN_GET_SYM {} - | COLUMN_JSON_SYM {} - | COLUMN_LIST_SYM {} | COMMENT_SYM {} | COMMIT_SYM {} | CONTAINS_SYM {} diff --git a/storage/cassandra/CMakeLists.txt b/storage/cassandra/CMakeLists.txt index 7e92d3cc0bd..7852177b9b3 100644 --- a/storage/cassandra/CMakeLists.txt +++ b/storage/cassandra/CMakeLists.txt @@ -13,9 +13,9 @@ SET(cassandra_sources #INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) -#INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) +INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift) #INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/) -INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/) +#INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/) # STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index a54190e080c..75eff80a3cf 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -89,7 +89,7 @@ ha_create_table_option cassandra_field_option_list[]= /* Collect all other columns as dynamic here, the valid values are YES/NO, ON/OFF, 1/0. - The default is 0, that is true, yes, on. + The default is 0, that is false, no, off. */ HA_FOPTION_BOOL("DYNAMIC_COLUMN_STORAGE", dyncol_field, 0), HA_FOPTION_END @@ -862,9 +862,37 @@ public: /** Converting dynamic columns types to/from casandra types */ + + +/** + Check and initialize (if it is needed) string MEM_ROOT +*/ +static void alloc_strings_memroot(MEM_ROOT *mem_root) +{ + if (!alloc_root_inited(mem_root)) + { + /* + The mem_root used to allocate UUID (of length 36 + \0) so make + appropriate allocated size + */ + init_alloc_root(mem_root, + (36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 + + ALLOC_ROOT_MIN_BLOCK_SIZE, + (36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 + + ALLOC_ROOT_MIN_BLOCK_SIZE); + } +} + +static void free_strings_memroot(MEM_ROOT *mem_root) +{ + if (alloc_root_inited(mem_root)) + free_root(mem_root, MYF(0)); +} + bool cassandra_to_dyncol_intLong(const char *cass_data, int cass_data_len __attribute__((unused)), - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { value->type= DYN_COL_INT; #ifdef WORDS_BIGENDIAN @@ -881,7 +909,7 @@ bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value, { longlong *tmp= (longlong *) buff; enum enum_dyncol_func_result rc= - dynamic_column_val_long(tmp, value); + mariadb_dyncol_val_long(tmp, value); if (rc < 0) return true; *cass_data_len= sizeof(longlong); @@ -897,7 +925,8 @@ bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_intInt32(const char *cass_data, int cass_data_len __attribute__((unused)), - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { int32 tmp; value->type= DYN_COL_INT; @@ -917,7 +946,7 @@ bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value, { longlong *tmp= (longlong *) ((char *)buff + sizeof(longlong)); enum enum_dyncol_func_result rc= - dynamic_column_val_long(tmp, value); + mariadb_dyncol_val_long(tmp, value); if (rc < 0) return true; *cass_data_len= sizeof(int32); @@ -937,7 +966,8 @@ bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_intCounter(const char *cass_data, int cass_data_len __attribute__((unused)), - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { value->type= DYN_COL_INT; value->x.long_value= *((longlong *)cass_data); @@ -951,7 +981,7 @@ bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value, { longlong *tmp= (longlong *)buff; enum enum_dyncol_func_result rc= - dynamic_column_val_long(tmp, value); + mariadb_dyncol_val_long(tmp, value); if (rc < 0) return true; *cass_data_len= sizeof(longlong); @@ -962,7 +992,8 @@ bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_doubleFloat(const char *cass_data, int cass_data_len __attribute__((unused)), - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { value->type= DYN_COL_DOUBLE; value->x.double_value= *((float *)cass_data); @@ -975,7 +1006,7 @@ bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value, { double tmp; enum enum_dyncol_func_result rc= - dynamic_column_val_double(&tmp, value); + mariadb_dyncol_val_double(&tmp, value); if (rc < 0) return true; *((float *)buff)= (float) tmp; @@ -987,7 +1018,9 @@ bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_doubleDouble(const char *cass_data, int cass_data_len __attribute__((unused)), - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root + __attribute__((unused))) { value->type= DYN_COL_DOUBLE; value->x.double_value= *((double *)cass_data); @@ -1000,7 +1033,7 @@ bool dyncol_to_cassandraDouble(DYNAMIC_COLUMN_VALUE *value, { double *tmp= (double *)buff; enum enum_dyncol_func_result rc= - dynamic_column_val_double(tmp, value); + mariadb_dyncol_val_double(tmp, value); if (rc < 0) return true; *cass_data_len= sizeof(double); @@ -1018,7 +1051,6 @@ bool cassandra_to_dyncol_strStr(const char *cass_data, value->x.string.charset= cs; value->x.string.value.str= (char *)cass_data; value->x.string.value.length= cass_data_len; - value->x.string.nonfreeable= TRUE; // do not try to free return 0; } @@ -1030,7 +1062,7 @@ bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value, if (init_dynamic_string(&tmp, NULL, 1024, 1024)) return 1; enum enum_dyncol_func_result rc= - dynamic_column_val_str(&tmp, value, cs, FALSE); + mariadb_dyncol_val_str(&tmp, value, cs, '\0'); if (rc < 0) { dynstr_free(&tmp); @@ -1044,7 +1076,8 @@ bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_strBytes(const char *cass_data, int cass_data_len, - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, &my_charset_bin); @@ -1060,7 +1093,8 @@ bool dyncol_to_cassandraBytes(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_strAscii(const char *cass_data, int cass_data_len, - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, &my_charset_latin1_bin); @@ -1076,7 +1110,8 @@ bool dyncol_to_cassandraAscii(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_strUTF8(const char *cass_data, int cass_data_len, - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value, &my_charset_utf8_unicode_ci); @@ -1092,20 +1127,20 @@ bool dyncol_to_cassandraUTF8(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_strUUID(const char *cass_data, int cass_data_len, - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root) { value->type= DYN_COL_STRING; value->x.string.charset= &my_charset_bin; - value->x.string.value.str= (char *)my_malloc(37, MYF(0)); + alloc_strings_memroot(mem_root); + value->x.string.value.str= (char *)alloc_root(mem_root, 37); if (!value->x.string.value.str) { value->x.string.value.length= 0; - value->x.string.nonfreeable= TRUE; return 1; } convert_uuid2string(value->x.string.value.str, cass_data); value->x.string.value.length= 36; - value->x.string.nonfreeable= FALSE; return 0; } @@ -1117,7 +1152,7 @@ bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value, if (init_dynamic_string(&tmp, NULL, 1024, 1024)) return true; enum enum_dyncol_func_result rc= - dynamic_column_val_str(&tmp, value, &my_charset_latin1_bin, FALSE); + mariadb_dyncol_val_str(&tmp, value, &my_charset_latin1_bin, '\0'); if (rc < 0 || tmp.length != 36 || convert_string2uuid((char *)buff, tmp.str)) { dynstr_free(&tmp); @@ -1132,7 +1167,8 @@ bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value, bool cassandra_to_dyncol_intBool(const char *cass_data, int cass_data_len, - DYNAMIC_COLUMN_VALUE *value) + DYNAMIC_COLUMN_VALUE *value, + MEM_ROOT *mem_root __attribute__((unused))) { value->type= DYN_COL_INT; value->x.long_value= (cass_data[0] ? 1 : 0); @@ -1145,7 +1181,7 @@ bool dyncol_to_cassandraBool(DYNAMIC_COLUMN_VALUE *value, { longlong tmp; enum enum_dyncol_func_result rc= - dynamic_column_val_long(&tmp, value); + mariadb_dyncol_val_long(&tmp, value); if (rc < 0) return true; ((char *)buff)[0]= (tmp ? 1 : 0); @@ -1430,10 +1466,7 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) (CASSANDRA_TYPE_DEF *)(field_converters + n_fields); special_type_field_names= ((LEX_STRING*)(special_type_field_converters + max_non_default_fields)); - } - if (dyncol_set) - { if (init_dynamic_array(&dynamic_values, sizeof(DYNAMIC_COLUMN_VALUE), DYNCOL_USUAL, DYNCOL_DELTA)) @@ -1667,14 +1700,6 @@ void ha_cassandra::print_conversion_error(const char *field_name, } -void free_strings(DYNAMIC_COLUMN_VALUE *vals, uint num) -{ - for (uint i= 0; i < num; i++) - if (vals[i].type == DYN_COL_STRING && - !vals[i].x.string.nonfreeable) - my_free(vals[i].x.string.value.str); -} - CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name, int cass_name_len) @@ -1695,6 +1720,7 @@ CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name, int ha_cassandra::read_cassandra_columns(bool unpack_pk) { + MEM_ROOT strings_root; char *cass_name; char *cass_value; int cass_value_len, cass_name_len; @@ -1702,6 +1728,7 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) int res= 0; ulong total_name_len= 0; + clear_alloc_root(&strings_root); /* cassandra_to_mariadb() calls will use field->store(...) methods, which require that the column is in the table->write_set @@ -1770,7 +1797,8 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) } if ((res= (*(type->cassandra_to_dynamic))(cass_value, - cass_value_len, &val)) || + cass_value_len, &val, + &strings_root)) || insert_dynamic(&dynamic_names, (uchar *) &nm) || insert_dynamic(&dynamic_values, (uchar *) &val)) { @@ -1778,10 +1806,9 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) { print_conversion_error(cass_name, cass_value, cass_value_len); } - free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer, - dynamic_values.elements); + free_strings_memroot(&strings_root); // EOM shouldm be already reported if happened - res=1; + res= 1; goto err; } } @@ -1790,21 +1817,17 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk) dynamic_rec.length= 0; if (dyncol_set) { - if (dynamic_column_create_many_internal_fmt(&dynamic_rec, - dynamic_names.elements, - dynamic_names.buffer, - (DYNAMIC_COLUMN_VALUE *) - dynamic_values.buffer, - FALSE, - TRUE) < 0) + if (mariadb_dyncol_create_many_named(&dynamic_rec, + dynamic_names.elements, + (LEX_STRING *)dynamic_names.buffer, + (DYNAMIC_COLUMN_VALUE *) + dynamic_values.buffer, + FALSE) < 0) dynamic_rec.length= 0; - free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer, - dynamic_values.elements); + free_strings_memroot(&strings_root); dynamic_values.elements= dynamic_names.elements= 0; - } - if (dyncol_set) - { + if (dynamic_rec.length == 0) table->field[dyncol_field]->set_null(); else @@ -1836,11 +1859,14 @@ err: return res; } -int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, - String *valcol, char **freenames) +int ha_cassandra::read_dyncol(uint *count, + DYNAMIC_COLUMN_VALUE **vals, + LEX_STRING **names, + String *valcol) { String *strcol; DYNAMIC_COLUMN col; + enum enum_dyncol_func_result rc; DBUG_ENTER("ha_cassandra::read_dyncol"); @@ -1850,8 +1876,9 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, strcol= field->val_str(NULL, valcol); if (field->is_null()) { - bzero(vals, sizeof(DYNAMIC_ARRAY)); - bzero(names, sizeof(DYNAMIC_ARRAY)); + *count= 0; + *names= 0; + *vals= 0; DBUG_RETURN(0); // nothing to write } /* @@ -1861,7 +1888,7 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, bzero(&col, sizeof(col)); col.str= (char *)strcol->ptr(); col.length= strcol->length(); - if ((rc= dynamic_column_vals(&col, names, vals, freenames)) < 0) + if ((rc= mariadb_dyncol_unpack(&col, count, names, vals)) < 0) { dynamic_column_error_message(rc); DBUG_RETURN(HA_ERR_INTERNAL_ERROR); @@ -1869,34 +1896,33 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, DBUG_RETURN(0); } -int ha_cassandra::write_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names) +int ha_cassandra::write_dynamic_row(uint count, + DYNAMIC_COLUMN_VALUE *vals, + LEX_STRING *names) { uint i; DBUG_ENTER("ha_cassandra::write_dynamic_row"); DBUG_ASSERT(dyncol_set); - DBUG_ASSERT(names->elements == vals->elements); - for (i= 0; i < names->elements; i++) + for (i= 0; i < count; i++) { char buff[16]; CASSANDRA_TYPE_DEF *type; void *freemem= NULL; char *cass_data; int cass_data_len; - LEX_STRING *name= dynamic_element(names, i, LEX_STRING*); - DYNAMIC_COLUMN_VALUE *val= dynamic_element(vals, i, DYNAMIC_COLUMN_VALUE*); - DBUG_PRINT("info", ("field %*s", (int)name->length, name->str)); - type= get_cassandra_field_def(name->str, (int) name->length); - if ((*type->dynamic_to_cassandra)(val, &cass_data, &cass_data_len, + DBUG_PRINT("info", ("field %*s", (int)names[i].length, names[i].str)); + type= get_cassandra_field_def(names[i].str, (int) names[i].length); + if ((*type->dynamic_to_cassandra)(vals +i, &cass_data, &cass_data_len, buff, &freemem)) { my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0), - name->str, insert_lineno); - DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + names[i].str, insert_lineno); + DBUG_RETURN(HA_ERR_GENERIC); } - se->add_insert_column(name->str, name->length, + se->add_insert_column(names[i].str, names[i].length, cass_data, cass_data_len); if (freemem) my_free(freemem); @@ -1904,13 +1930,19 @@ int ha_cassandra::write_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names) DBUG_RETURN(0); } -void ha_cassandra::free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, - char *free_names) +void ha_cassandra::free_dynamic_row(DYNAMIC_COLUMN_VALUE **vals, + LEX_STRING **names) { - delete_dynamic(names); - delete_dynamic(vals); - if (free_names) - my_free(free_names); + if (*vals) + { + my_free(*vals); + *vals= 0; + } + if (*names) + { + my_free(*names); + *names= 0; + } } int ha_cassandra::write_row(uchar *buf) @@ -1949,13 +1981,14 @@ int ha_cassandra::write_row(uchar *buf) if (dyncol_set && dyncol_field == i) { String valcol; - DYNAMIC_ARRAY vals, names; - char *free_names= NULL; + DYNAMIC_COLUMN_VALUE *vals; + LEX_STRING *names; + uint count; int rc; DBUG_ASSERT(field_converters[i] == NULL); - if (!(rc= read_dyncol(&vals, &names, &valcol, &free_names))) - rc= write_dynamic_row(&vals, &names); - free_dynamic_row(&vals, &names, free_names); + if (!(rc= read_dyncol(&count, &vals, &names, &valcol))) + rc= write_dynamic_row(count, vals, names); + free_dynamic_row(&vals, &names); if (rc) { dbug_tmp_restore_column_map(table->read_set, old_map); @@ -2336,9 +2369,10 @@ public: int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) { - DYNAMIC_ARRAY oldvals, oldnames, vals, names; + DYNAMIC_COLUMN_VALUE *oldvals, *vals; + LEX_STRING *oldnames, *names; + uint oldcount, count; String oldvalcol, valcol; - char *oldfree_names= NULL, *free_names= NULL; my_bitmap_map *old_map; int res; DBUG_ENTER("ha_cassandra::update_row"); @@ -2381,12 +2415,12 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) my_ptrdiff_t diff; diff= (my_ptrdiff_t) (old_data - new_data); field->move_field_offset(diff); // Points now at old_data - if ((res= read_dyncol(&oldvals, &oldnames, &oldvalcol, &oldfree_names))) + if ((res= read_dyncol(&oldcount, &oldvals, &oldnames, &oldvalcol))) DBUG_RETURN(res); field->move_field_offset(-diff); // back to new_data - if ((res= read_dyncol(&vals, &names, &valcol, &free_names))) + if ((res= read_dyncol(&count, &vals, &names, &valcol))) { - free_dynamic_row(&oldnames, &oldvals, oldfree_names); + free_dynamic_row(&oldvals, &oldnames); DBUG_RETURN(res); } } @@ -2399,9 +2433,9 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) */ Column_name_enumerator_impl name_enumerator(this); se->add_row_deletion(old_key, old_key_len, &name_enumerator, - (LEX_STRING *)oldnames.buffer, - (dyncol_set ? oldnames.elements : 0)); - oldnames.elements= oldvals.elements= 0; // they will be deleted + oldnames, + (dyncol_set ? oldcount : 0)); + oldcount= 0; // they will be deleted } se->start_row_insert(new_key, new_key_len); @@ -2414,7 +2448,7 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) if (dyncol_set && dyncol_field == i) { DBUG_ASSERT(field_converters[i] == NULL); - if ((res= write_dynamic_row(&vals, &names))) + if ((res= write_dynamic_row(count, vals, names))) goto err; } else @@ -2434,24 +2468,19 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) { /* find removed fields */ uint i= 0, j= 0; - LEX_STRING *onames= (LEX_STRING *)oldnames.buffer; - LEX_STRING *nnames= (LEX_STRING *)names.buffer; /* both array are sorted */ - for(; i < oldnames.elements; i++) + for(; i < oldcount; i++) { int scmp= 0; - while (j < names.elements && - (nnames[j].length < onames[i].length || - (nnames[j].length == onames[i].length && - (scmp= memcmp(nnames[j].str, onames[i].str, - onames[i].length)) < 0))) + while (j < count && + (scmp = mariadb_dyncol_column_cmp_named(names + j, + oldnames + i)) < 0) j++; - if (j < names.elements && - nnames[j].length == onames[i].length && + if (j < count && scmp == 0) j++; else - se->add_insert_delete_column(onames[i].str, onames[i].length); + se->add_insert_delete_column(oldnames[i].str, oldnames[i].length); } } @@ -2465,8 +2494,8 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data) err: if (dyncol_set) { - free_dynamic_row(&oldnames, &oldvals, oldfree_names); - free_dynamic_row(&names, &vals, free_names); + free_dynamic_row(&oldvals, &oldnames); + free_dynamic_row(&vals, &names); } DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0); diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index be8a49af493..ecd8bdb57e3 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -37,6 +37,8 @@ typedef struct st_cassandra_share { } CASSANDRA_SHARE; class ColumnDataConverter; +struct st_dynamic_column_value; +typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; struct ha_table_option_struct; @@ -45,7 +47,8 @@ struct st_dynamic_column_value; typedef bool (* CAS2DYN_CONVERTER)(const char *cass_data, int cass_data_len, - struct st_dynamic_column_value *value); + struct st_dynamic_column_value *value, + MEM_ROOT *mem_root); typedef bool (* DYN2CAS_CONVERTER)(struct st_dynamic_column_value *value, char **cass_data, int *cass_data_len, @@ -227,11 +230,14 @@ private: bool source_exhausted; bool mrr_start_read(); int check_field_options(Field **fields); - int read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, - String *valcol, char **freenames); - int write_dynamic_row(DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals); - void static free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names, - char *free_names); + int read_dyncol(uint *count, + DYNAMIC_COLUMN_VALUE **vals, LEX_STRING **names, + String *valcol); + int write_dynamic_row(uint count, + DYNAMIC_COLUMN_VALUE *vals, + LEX_STRING *names); + void static free_dynamic_row(DYNAMIC_COLUMN_VALUE **vals, + LEX_STRING **names); CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name, int cass_name_length); public: -- cgit v1.2.1 From 082ff5931770ed70df0ec1e85f81fa880a4d9e62 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Dec 2012 22:17:22 +0200 Subject: Post-post review fixes. --- include/ma_dyncol.h | 20 +++------------ mysql-test/r/cassandra.result | 54 +++++++++++++++++++------------------- mysql-test/r/dyncol.result | 26 +++++++++---------- mysys/ma_dyncol.c | 60 +++++++++++++++++++++++++++++++++---------- sql/item_func.h | 2 +- sql/item_strfunc.cc | 12 ++++----- sql/item_strfunc.h | 8 +++--- 7 files changed, 100 insertions(+), 82 deletions(-) diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h index 78d3f15978c..7f888759207 100644 --- a/include/ma_dyncol.h +++ b/include/ma_dyncol.h @@ -33,13 +33,6 @@ #include #include -/* - Max length for data in a dynamic colums. This comes from how the - how the offset are stored. -*/ -#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL -#define MAX_DYNAMIC_COLUMN_LENGTH_NM 0XFFFFFFFFFL - /* Limits of implementation */ @@ -101,7 +94,6 @@ struct st_dynamic_column_value typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; -/* old functions (deprecated) */ #ifdef MADYNCOL_DEPRECATED enum enum_dyncol_func_result dynamic_column_create(DYNAMIC_COLUMN *str, @@ -168,7 +160,7 @@ mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, LEX_STRING *name); /* List of not NULL columns */ enum enum_dyncol_func_result -mariadb_dyncol_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); +mariadb_dyncol_list(DYNAMIC_COLUMN *str, uint *count, uint **nums); enum enum_dyncol_func_result mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, LEX_STRING **names); @@ -213,17 +205,11 @@ int mariadb_dyncol_column_cmp_named(const LEX_STRING *s1, const LEX_STRING *s2); enum enum_dyncol_func_result mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count); -/*************************************************************************** - Internal functions, don't use if you don't know what you are doing... -***************************************************************************/ - -#define mariadb_dyncol_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A)) - -#define dyncol_value_init(V) (V)->type= DYN_COL_NULL +#define mariadb_dyncol_value_init(V) (V)->type= DYN_COL_NULL /* Prepare value for using as decimal */ -void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value); +void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value); #endif diff --git a/mysql-test/r/cassandra.result b/mysql-test/r/cassandra.result index b5ff3194480..d11e2f66729 100644 --- a/mysql-test/r/cassandra.result +++ b/mysql-test/r/cassandra.result @@ -448,7 +448,7 @@ CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) insert into t2 values (1, column_create("dyn1", 1, "dyn2", "two")); select rowkey, column_json(dyn) from t2; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn2":"two"}] +1 {"dyn1":"1","dyn2":"two"} delete from t2; drop table t2; # bigint @@ -457,8 +457,8 @@ insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'a', 254324)); insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'a', 2543)); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":254324},{"dyn1":"1"},{"dyn2":"two"}] -2 [{"a":2543},{"dyn1":"1"},{"dyn2":"two"}] +1 {"a":254324,"dyn1":"1","dyn2":"two"} +2 {"a":2543,"dyn1":"1","dyn2":"two"} delete from t1; drop table t1; # int @@ -467,8 +467,8 @@ insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543 insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543)); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":254324}] -2 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":2543}] +1 {"dyn1":"1","dyn2":"two","intcol":254324} +2 {"dyn1":"1","dyn2":"two","intcol":2543} delete from t1; drop table t1; # timestamp @@ -477,8 +477,8 @@ insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'datecol', 254 insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'datecol', 2543)); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":254324}] -2 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":2543}] +1 {"dyn1":"1","dyn2":"two","datecol":254324} +2 {"dyn1":"1","dyn2":"two","datecol":2543} delete from t1; drop table t1; # boolean @@ -487,47 +487,47 @@ insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 254 insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 0)); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}] -2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}] +1 {"dyn1":"1","dyn2":"two","boolcol":1} +2 {"dyn1":"1","dyn2":"two","boolcol":0} select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}] -2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}] +1 {"dyn1":"1","dyn2":"two","boolcol":1} +2 {"dyn1":"1","dyn2":"two","boolcol":0} update t1 set dyn=column_add(dyn, "dyn2", null, "dyn3", "3"); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":1}] -2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}] +1 {"dyn1":"1","dyn3":"3","boolcol":1} +2 {"dyn1":"1","dyn3":"3","boolcol":0} update t1 set dyn=column_add(dyn, "dyn1", null) where rowkey= 1; select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"dyn3":"3"},{"boolcol":1}] -2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}] +1 {"dyn3":"3","boolcol":1} +2 {"dyn1":"1","dyn3":"3","boolcol":0} update t1 set dyn=column_add(dyn, "dyn3", null, "a", "ddd"); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":"ddd"},{"boolcol":1}] -2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}] +1 {"a":"ddd","boolcol":1} +2 {"a":"ddd","dyn1":"1","boolcol":0} update t1 set dyn=column_add(dyn, "12345678901234", "ddd"); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":"ddd"},{"boolcol":1},{"12345678901234":"ddd"}] -2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0},{"12345678901234":"ddd"}] +1 {"a":"ddd","boolcol":1,"12345678901234":"ddd"} +2 {"a":"ddd","dyn1":"1","boolcol":0,"12345678901234":"ddd"} update t1 set dyn=column_add(dyn, "12345678901234", null); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":"ddd"},{"boolcol":1}] -2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}] +1 {"a":"ddd","boolcol":1} +2 {"a":"ddd","dyn1":"1","boolcol":0} update t1 set dyn=column_add(dyn, 'boolcol', null) where rowkey= 2; select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":"ddd"},{"boolcol":1}] -2 [{"a":"ddd"},{"dyn1":"1"}] +1 {"a":"ddd","boolcol":1} +2 {"a":"ddd","dyn1":"1"} update t1 set rowkey= 3, dyn=column_add(dyn, "dyn1", null, 'boolcol', 0) where rowkey= 2; select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -1 [{"a":"ddd"},{"boolcol":1}] -3 [{"a":"ddd"},{"boolcol":0}] +1 {"a":"ddd","boolcol":1} +3 {"a":"ddd","boolcol":0} delete from t1; drop table t1; CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1'; @@ -567,14 +567,14 @@ ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = INSERT INTO t1 VALUES(2,column_create("ab","ab")); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -2 [{"ab":"ab"}] +2 {"ab":"ab"} UPDATE t1 set dyn=NULL; select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) INSERT INTO t1 VALUES(2,column_create("ab","ab")); select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) -2 [{"ab":"ab"}] +2 {"ab":"ab"} UPDATE t1 set dyn=""; select rowkey, column_json(dyn) from t1; rowkey column_json(dyn) diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index c8d23d75d6c..d50a5c0a27d 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1568,10 +1568,10 @@ ERROR 22007: Illegal value used as argument of dynamic column function # select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date)); column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" -[{"int":-1212},{"date":"2011-04-05"},{"time":"00:45:49.000001"},{"uint":12334},{"double":"1.23444e+50"},{"string":"gdgd\\dhdjh\"dhdhd"},{"decimal":23.344},{"datetime":"2011-04-05 00:45:49.000001"}] +{"int":-1212,"date":"2011-04-05","time":"00:45:49.000001","uint":12334,"double":"1.23444e+50","string":"gdgd\\dhdjh\"dhdhd","decimal":23.344,"datetime":"2011-04-05 00:45:49.000001"} select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)); column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date)) -[{"1":-1212},{"2":12334},{"3":23.344},{"4":"1.23444e+50"},{"5":"gdgd\\dhdjh\"dhdhd"},{"6":"00:45:49.000001"},{"7":"2011-04-05 00:45:49.000001"},{"8":"2011-04-05"}] +{"1":-1212,"2":12334,"3":23.344,"4":"1.23444e+50","5":"gdgd\\dhdjh\"dhdhd","6":"00:45:49.000001","7":"2011-04-05 00:45:49.000001","8":"2011-04-05"} # # CHECK test # @@ -1592,48 +1592,48 @@ NULL # select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_create("string", "'\"/\\`.,whatever")); column_json(column_create("string", "'\"/\\`.,whatever")) hex(column_create("string", "'\"/\\`.,whatever")) -[{"string":"'\"/\\`.,whatever"}] 040100060000000300737472696E670827222F5C602E2C7768617465766572 +{"string":"'\"/\\`.,whatever"} 040100060000000300737472696E670827222F5C602E2C7768617465766572 # # embedding test # select column_json(column_create("val", "val", "emb", column_create("val2", "val2"))); column_json(column_create("val", "val", "emb", column_create("val2", "val2"))) -[{"emb":[{"val2":"val2"}],{"val":"val"}] +{"emb":{"val2":"val2"},"val":"val"} select column_json(column_create(1, "val", 2, column_create(3, "val2"))); column_json(column_create(1, "val", 2, column_create(3, "val2"))) -[{"1":"val"},{"2":[{"3":"val2"}]] +{"1":"val","2":{"3":"val2"}} # # Time encoding # select hex(column_create("t", "800:46:06.23434" AS time)) as hex, column_json(column_create("t", "800:46:06.23434" AS time)) as json; hex json -04010001000000070074649363B82003 [{"t":"800:46:06.234340"}] +04010001000000070074649363B82003 {"t":"800:46:06.234340"} select hex(column_create(1, "800:46:06.23434" AS time)) as hex, column_json(column_create(1, "800:46:06.23434" AS time)) as json; hex json -000100010007649363B82003 [{"1":"800:46:06.234340"}] +000100010007649363B82003 {"1":"800:46:06.234340"} select hex(column_create("t", "800:46:06" AS time)) as hex, column_json(column_create("t", "800:46:06" AS time)) as json; hex json -04010001000000070074860B32 [{"t":"800:46:06"}] +04010001000000070074860B32 {"t":"800:46:06"} select hex(column_create(1, "800:46:06" AS time)) as hex, column_json(column_create(1, "800:46:06" AS time)) as json; hex json -000100010007000060B82003 [{"1":"800:46:06"}] +000100010007000060B82003 {"1":"800:46:06"} select hex(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as hex, column_json(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as json; hex json -0401000100000005007495B90F649363B80A00 [{"t":"2012-12-21 10:46:06.234340"}] +0401000100000005007495B90F649363B80A00 {"t":"2012-12-21 10:46:06.234340"} select hex(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as hex, column_json(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as json; hex json -00010001000595B90F649363B80A00 [{"1":"2012-12-21 10:46:06.234340"}] +00010001000595B90F649363B80A00 {"1":"2012-12-21 10:46:06.234340"} select hex(column_create("t", "2012-12-21 10:46:06" AS datetime)) as hex, column_json(column_create("t", "2012-12-21 10:46:06" AS datetime)) as json; hex json -0401000100000005007495B90F86AB00 [{"t":"2012-12-21 10:46:06"}] +0401000100000005007495B90F86AB00 {"t":"2012-12-21 10:46:06"} select hex(column_create(1, "2012-12-21 10:46:06" AS datetime)) as hex, column_json(column_create(1, "2012-12-21 10:46:06" AS datetime)) as json; hex json -00010001000595B90F000060B80A00 [{"1":"2012-12-21 10:46:06"}] +00010001000595B90F000060B80A00 {"1":"2012-12-21 10:46:06"} diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 34bb8b9de3d..575c2eceb11 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -2368,7 +2368,7 @@ dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, /** - List not-null columns in the packed string (only numeric foemat) + List not-null columns in the packed string (only numeric format) @param str The packed string @param array_of_uint Where to put reference on created array @@ -2377,12 +2377,6 @@ dynamic_column_exists_internal(DYNAMIC_COLUMN *str, uint num_key, */ enum enum_dyncol_func_result dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) -{ - return mariadb_dyncol_list(str, array_of_uint); -} - -enum enum_dyncol_func_result -mariadb_dyncol_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) { DYN_HEADER header; uchar *read; @@ -2417,6 +2411,48 @@ mariadb_dyncol_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) return ER_DYNCOL_OK; } +/** + List not-null columns in the packed string (only numeric format) + + @param str The packed string + @param array_of_uint Where to put reference on created array + + @return ER_DYNCOL_* return code +*/ +enum enum_dyncol_func_result +mariadb_dyncol_list(DYNAMIC_COLUMN *str, uint *count, uint **nums) +{ + DYN_HEADER header; + uchar *read; + uint i; + enum enum_dyncol_func_result rc; + + (*nums)= 0; /* In case of errors */ + if (str->length == 0) + return ER_DYNCOL_OK; /* no columns */ + + if ((rc= init_read_hdr(&header, str)) < 0) + return rc; + + if (header.format != dyncol_fmt_num) + return ER_DYNCOL_FORMAT; + + if (header.entry_size * header.column_count + FIXED_HEADER_SIZE > + str->length) + return ER_DYNCOL_FORMAT; + + if (!((*nums)= my_malloc(sizeof(uint) * header.column_count, MYF(0)))) + return ER_DYNCOL_RESOURCE; + + for (i= 0, read= header.header; + i < header.column_count; + i++, read+= header.entry_size) + { + (*nums)[i]= uint2korr(read); + } + (*count)= header.column_count; + return ER_DYNCOL_OK; +} /** List not-null columns in the packed string (any format) @@ -4058,7 +4094,7 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, rc= ER_DYNCOL_RESOURCE; - if (dynstr_append_mem(json, "[", 1)) + if (dynstr_append_mem(json, "{", 1)) goto err; for (i= 0, header.entry= header.header; i < header.column_count; @@ -4080,8 +4116,7 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, rc= ER_DYNCOL_FORMAT; goto err; } - if ((rc= dynamic_column_get_value(&header, &val)) < 0 || - dynstr_append_mem(json, "{", 1)) + if ((rc= dynamic_column_get_value(&header, &val)) < 0) goto err; if (header.format == dyncol_fmt_num) { @@ -4125,12 +4160,11 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, else { if ((rc= mariadb_dyncol_val_str(json, &val, - &my_charset_utf8_general_ci, '"')) < 0 || - dynstr_append_mem(json, "}", 1)) + &my_charset_utf8_general_ci, '"')) < 0) goto err; } } - if (dynstr_append_mem(json, "]", 1)) + if (dynstr_append_mem(json, "}", 1)) { rc= ER_DYNCOL_RESOURCE; goto err; diff --git a/sql/item_func.h b/sql/item_func.h index ccb86fd03e5..e13fa0834f0 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -58,7 +58,7 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC, GSYSVAR_FUNC, DYNCOL }; + NEG_FUNC, GSYSVAR_FUNC, DYNCOL_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 706fbbff94d..5559ffa6c20 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3837,7 +3837,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) if (type == DYN_COL_STRING && args[valpos]->type() == Item::FUNC_ITEM && - ((Item_func *)args[valpos])->functype() == DYNCOL) + ((Item_func *)args[valpos])->functype() == DYNCOL_FUNC) { force_names= 1; break; @@ -3904,7 +3904,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) } if (type == DYN_COL_STRING && args[valpos]->type() == Item::FUNC_ITEM && - ((Item_func *)args[valpos])->functype() == DYNCOL) + ((Item_func *)args[valpos])->functype() == DYNCOL_FUNC) { DBUG_ASSERT(names || force_names); type= DYN_COL_DYNCOL; @@ -3988,7 +3988,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) case DYN_COL_DECIMAL: if ((dres= args[valpos]->val_decimal(&dtmp))) { - dynamic_column_prepare_decimal(&vals[i]); + mariadb_dyncol_prepare_decimal(&vals[i]); DBUG_ASSERT(vals[i].x.decimal.value.len == dres->len); vals[i].x.decimal.value.intg= dres->intg; vals[i].x.decimal.value.frac= dres->frac; @@ -3998,7 +3998,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) } else { - dynamic_column_prepare_decimal(&vals[i]); // just to be safe + mariadb_dyncol_prepare_decimal(&vals[i]); // just to be safe DBUG_ASSERT(args[valpos]->null_value); } break; @@ -4055,7 +4055,7 @@ String *Item_func_dyncol_create::val_str(String *str) /* Move result from DYNAMIC_COLUMN to str_value */ char *ptr; size_t length, alloc_length; - mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length); + dynstr_reassociate(&col, &ptr, &length, &alloc_length); str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length, &my_charset_bin); res= &str_value; @@ -4197,7 +4197,7 @@ String *Item_func_dyncol_add::val_str(String *str) /* Move result from DYNAMIC_COLUMN to str */ char *ptr; size_t length, alloc_length; - mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length); + dynstr_reassociate(&col, &ptr, &length, &alloc_length); str->reassociate(ptr, (uint32) length, (uint32) alloc_length, &my_charset_bin); null_value= FALSE; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 8ef67654b35..d21c938f378 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1013,7 +1013,7 @@ public: const char *func_name() const{ return "column_create"; } String *val_str(String *); virtual void print(String *str, enum_query_type query_type); - virtual enum Functype functype() const { return DYNCOL; } + virtual enum Functype functype() const { return DYNCOL_FUNC; } }; @@ -1051,11 +1051,9 @@ class Item_dyncol_get: public Item_str_func public: Item_dyncol_get(Item *str, Item *num) :Item_str_func(str, num) - { - max_length= MAX_DYNAMIC_COLUMN_LENGTH; - } + {} void fix_length_and_dec() - { maybe_null= 1; } + { maybe_null= 1; max_length= MAX_BLOB_WIDTH; } /* Mark that collation can change between calls */ bool dynamic_result() { return 1; } -- cgit v1.2.1