changeset 22615:ac7bd203229d

cassandra: Fix using bigint types with unprepared statements This reverts the code to not using the statements with binding at all. Alternative fix would be to start using explicit int32 or int64 parameter types, but that breaks backwards compatibility a bit.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 16 Oct 2017 14:49:56 +0300
parents cf66220d281e
children 629f44740f50
files src/lib-sql/driver-cassandra.c
diffstat 1 files changed, 27 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-sql/driver-cassandra.c	Sat Oct 14 12:54:18 2017 +0300
+++ b/src/lib-sql/driver-cassandra.c	Mon Oct 16 14:49:56 2017 +0300
@@ -1648,14 +1648,11 @@
 	const CassDataType *data_type;
 	CassValueType value_type;
 
-	if (stmt->prep == NULL) {
-		value_type = value >= -2147483648 && value <= 2147483647 ?
-			CASS_VALUE_TYPE_INT : CASS_VALUE_TYPE_BIGINT;
-	} else {
-		/* prepared statements require exactly correct value type */
-		data_type = cass_prepared_parameter_data_type(stmt->prep->prepared, column_idx);
-		value_type = cass_data_type_type(data_type);
-	}
+	i_assert(stmt->prep != NULL);
+
+	/* statements require exactly correct value type */
+	data_type = cass_prepared_parameter_data_type(stmt->prep->prepared, column_idx);
+	value_type = cass_data_type_type(data_type);
 
 	switch (value_type) {
 	case CASS_VALUE_TYPE_INT:
@@ -1826,24 +1823,12 @@
 
 static struct sql_statement *
 driver_cassandra_statement_init(struct sql_db *db ATTR_UNUSED,
-				const char *query_template)
+				const char *query_template ATTR_UNUSED)
 {
 	pool_t pool = pool_alloconly_create("cassandra sql statement", 1024);
 	struct cassandra_sql_statement *stmt =
 		p_new(pool, struct cassandra_sql_statement, 1);
-
-	/* Count the number of parameters in the query. We'll assume that all
-	   the changing parameters are bound, so there shouldn't be any
-	   quoted strings with '?' in them. */
-	const char *p = query_template;
-	size_t param_count = 0;
-	while ((p = strchr(p, '?')) != NULL) {
-		param_count++;
-		p++;
-	}
-
 	stmt->stmt.pool = pool;
-	stmt->cass_stmt = cass_statement_new(query_template, param_count);
 	return &stmt->stmt;
 }
 
@@ -1921,7 +1906,7 @@
 		(struct cassandra_sql_statement *)_stmt;
 	if (stmt->cass_stmt != NULL)
 		cass_statement_bind_string(stmt->cass_stmt, column_idx, value);
-	else {
+	else if (stmt->prep != NULL) {
 		struct cassandra_sql_arg *arg =
 			driver_cassandra_add_pending_arg(stmt, column_idx);
 		arg->value_str = p_strdup(_stmt->pool, value);
@@ -1939,7 +1924,7 @@
 	if (stmt->cass_stmt != NULL) {
 		cass_statement_bind_bytes(stmt->cass_stmt, column_idx,
 					  value, value_size);
-	} else {
+	} else if (stmt->prep != NULL) {
 		struct cassandra_sql_arg *arg =
 			driver_cassandra_add_pending_arg(stmt, column_idx);
 		arg->value_binary = p_memdup(_stmt->pool, value, value_size);
@@ -1956,7 +1941,7 @@
 
 	if (stmt->cass_stmt != NULL)
 		driver_cassandra_bind_int(stmt, column_idx, value);
-	else {
+	else if (stmt->prep != NULL) {
 		struct cassandra_sql_arg *arg =
 			driver_cassandra_add_pending_arg(stmt, column_idx);
 		arg->value_int64 = value;
@@ -1970,17 +1955,25 @@
 	struct cassandra_sql_statement *stmt =
 		(struct cassandra_sql_statement *)_stmt;
 	struct cassandra_db *db = (struct cassandra_db *)_stmt->db;
+	const char *query = sql_statement_get_query(_stmt);
 
-	stmt->result = driver_cassandra_query_init(db, sql_statement_get_query(_stmt),
+	stmt->result = driver_cassandra_query_init(db, query,
 						   CASSANDRA_QUERY_TYPE_READ,
 						   callback, context);
-	if (stmt->cass_stmt == NULL) {
-		/* wait for prepare to finish */
-	} else {
+	if (stmt->cass_stmt != NULL) {
 		stmt->result->statement = stmt->cass_stmt;
-		(void)driver_cassandra_send_query(stmt->result);
-		pool_unref(&_stmt->pool);
+	} else if (stmt->prep != NULL) {
+		/* wait for prepare to finish */
+		return;
+	} else {
+		stmt->result->statement = cass_statement_new(query, 0);
+		if (stmt->pending_timestamp != 0) {
+			cass_statement_set_timestamp(stmt->result->statement,
+						     stmt->pending_timestamp);
+		}
 	}
+	(void)driver_cassandra_send_query(stmt->result);
+	pool_unref(&_stmt->pool);
 }
 
 static struct sql_result *
@@ -2005,7 +1998,10 @@
 		transaction_set_failed(ctx, "Multiple changes in transaction not supported");
 		return;
 	}
-	ctx->stmt = stmt;
+	if (stmt->prep != NULL)
+		ctx->stmt = stmt;
+	else
+		ctx->query = i_strdup(sql_statement_get_query(_stmt));
 }
 
 const struct sql_db driver_cassandra_db = {