← Back to team overview

sysbench-developers team mailing list archive

[Merge] lp:~linuxjedi/sysbench/add-attachsql-driver into lp:sysbench

 

Andrew Hutchings has proposed merging lp:~linuxjedi/sysbench/add-attachsql-driver into lp:sysbench.

Requested reviews:
  sysbench-developers (sysbench-developers)

For more details, see:
https://code.launchpad.net/~linuxjedi/sysbench/add-attachsql-driver/+merge/238541

This adds a sysbench driver so that libAttachSQL can be used to talk to MySQL servers.
-- 
https://code.launchpad.net/~linuxjedi/sysbench/add-attachsql-driver/+merge/238541
Your team sysbench-developers is requested to review the proposed merge of lp:~linuxjedi/sysbench/add-attachsql-driver into lp:sysbench.
=== modified file 'configure.ac'
--- configure.ac	2012-09-23 13:09:08 +0000
+++ configure.ac	2014-10-16 09:41:21 +0000
@@ -107,6 +107,14 @@
 )
 AC_CACHE_CHECK([whether to compile with Drizzle support], [ac_cv_use_drizzle], [ac_cv_use_drizzle=no])
 
+# Check if we should compile with libattachsql support
+AC_ARG_WITH([attachsql], 
+            AS_HELP_STRING([--with-attachsql],[compile with libattachsql support (default is enabled)]),
+            [ac_cv_use_attachsql=$withval], [ac_cv_use_attachsql=yes]
+)
+AC_CACHE_CHECK([whether to compile with libattachsql support], [ac_cv_use_attachsql], [ac_cv_use_attachsql=no])
+
+
 # Check if we should compile with Oracle support
 AC_ARG_WITH([oracle],
             AS_HELP_STRING([--with-oracle],[compile with Oracle support (default is disabled)]),
@@ -188,6 +196,20 @@
 fi
 AM_CONDITIONAL(USE_DRIZZLE, test x$ac_cv_libdrizzle = xyes)
 
+if test x$ac_cv_use_attachsql != xno; then
+  AC_LIB_HAVE_LINKFLAGS(attachsql,,
+    [#include <libattachsql-1.0/attachsql.h>],
+    [
+     const char *version= attachsql_get_library_version();
+    ])
+fi
+if test "x$ac_cv_libattachsql" = "xyes"
+then
+    AC_DEFINE(USE_ATTACHSQL,1,[Define to 1 if you want to compile with libattachsql support])
+fi
+AM_CONDITIONAL(USE_ATTACHSQL, test x$ac_cv_libattachsql = xyes)
+
+
 AM_CONDITIONAL(USE_ORACLE, test x$ac_cv_use_oracle != xno)
 if test x$ac_cv_use_oracle != xno; then
     AC_DEFINE(USE_ORACLE,1,[Define to 1 if you want to compile with Oracle support])
@@ -428,6 +450,7 @@
 sysbench/drivers/drizzle/Makefile
 sysbench/drivers/oracle/Makefile
 sysbench/drivers/pgsql/Makefile
+sysbench/drivers/attachsql/Makefile
 sysbench/tests/Makefile
 sysbench/tests/cpu/Makefile
 sysbench/tests/fileio/Makefile

=== modified file 'sysbench/Makefile.am'
--- sysbench/Makefile.am	2012-08-30 17:59:06 +0000
+++ sysbench/Makefile.am	2014-10-16 09:41:21 +0000
@@ -29,6 +29,10 @@
 drizzle_ldadd = drivers/drizzle/libsbdrizzle.a $(LIBDRIZZLE)
 endif
 
+if USE_ATTACHSQL
+attachsql_ldadd = drivers/attachsql/libsbattachsql.a $(LIBATTACHSQL)
+endif
+
 if USE_ORACLE
 ora_ldadd = drivers/oracle/libsboracle.a $(ORA_LIBS)
 endif
@@ -49,7 +53,7 @@
 sysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \
     tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \
     tests/mutex/libsbmutex.a scripting/libsbscript.a \
-    $(mysql_ldadd) $(drizzle_ldadd) $(pgsql_ldadd) $(ora_ldadd) $(lua_ldadd)
+    $(mysql_ldadd) $(drizzle_ldadd) $(attachsql_ldadd) $(pgsql_ldadd) $(ora_ldadd) $(lua_ldadd)
 
-sysbench_LDFLAGS = $(EXTRA_LDFLAGS) $(mysql_ldflags) $(pgsql_ldflags) $(ora_ldflags) $(lua_ldflags)
+sysbench_LDFLAGS = $(EXTRA_LDFLAGS) $(mysql_ldflags) $(attachsql_ldflags) $(pgsql_ldflags) $(ora_ldflags) $(lua_ldflags)
 

=== modified file 'sysbench/db_driver.c'
--- sysbench/db_driver.c	2012-08-30 08:43:42 +0000
+++ sysbench/db_driver.c	2014-10-16 09:41:21 +0000
@@ -114,6 +114,9 @@
 #ifdef USE_DRIZZLE
   register_driver_drizzle(&drivers);
 #endif
+#ifdef USE_ATTACHSQL
+  register_driver_attachsql(&drivers);
+#endif
 #ifdef USE_DRIZZLECLIENT
   register_driver_drizzleclient(&drivers);
 #endif

=== modified file 'sysbench/db_driver.h'
--- sysbench/db_driver.h	2011-07-19 14:49:27 +0000
+++ sysbench/db_driver.h	2014-10-16 09:41:21 +0000
@@ -309,6 +309,10 @@
 int register_driver_drizzle(sb_list_t *);
 #endif
 
+#ifdef USE_ATTACHSQL
+int register_driver_attachsql(sb_list_t *);
+#endif
+
 #ifdef USE_DRIZZLECLIENT
 int register_driver_drizzleclient(sb_list_t *);
 #endif

=== modified file 'sysbench/drivers/Makefile.am'
--- sysbench/drivers/Makefile.am	2009-06-10 23:43:32 +0000
+++ sysbench/drivers/Makefile.am	2014-10-16 09:41:21 +0000
@@ -22,6 +22,10 @@
 DRIZZLE_DIR = drizzle
 endif
 
+if USE_ATTACHSQL
+ATTACHSQL_DIR = attachsql
+endif
+
 if USE_ORACLE
 ORACLE_DIR = oracle
 endif
@@ -30,4 +34,4 @@
 PGSQL_DIR = pgsql
 endif
 
-SUBDIRS = $(MYSQL_DIR) $(ORACLE_DIR) $(PGSQL_DIR) $(DRIZZLE_DIR)
+SUBDIRS = $(MYSQL_DIR) $(ORACLE_DIR) $(PGSQL_DIR) $(DRIZZLE_DIR) $(ATTACHSQL_DIR)

=== added directory 'sysbench/drivers/attachsql'
=== added file 'sysbench/drivers/attachsql/Makefile.am'
--- sysbench/drivers/attachsql/Makefile.am	1970-01-01 00:00:00 +0000
+++ sysbench/drivers/attachsql/Makefile.am	2014-10-16 09:41:21 +0000
@@ -0,0 +1,19 @@
+# Copyright (C) 2009 Sun Microsystems, Inc.
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# 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
+
+noinst_LIBRARIES = libsbattachsql.a
+
+libsbattachsql_a_SOURCES = drv_attachsql.c

=== added file 'sysbench/drivers/attachsql/drv_attachsql.c'
--- sysbench/drivers/attachsql/drv_attachsql.c	1970-01-01 00:00:00 +0000
+++ sysbench/drivers/attachsql/drv_attachsql.c	2014-10-16 09:41:21 +0000
@@ -0,0 +1,632 @@
+/* Copyright 2014 Hewlett-Packard Development Company, L.P.
+   based on the Drizzle driver:
+   Copyright (C) 2009 Sun Microsystems, Inc.
+
+   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; either version 2 of the License, or
+   (at your option) any later version.
+
+   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 HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#include <stdio.h>
+
+#include <stdint.h>
+#include <libattachsql-1.0/attachsql.h>
+
+#include "sb_options.h"
+
+#include "db_driver.h"
+
+#define DEBUG(format, ...) do { if (db_globals.debug) log_text(LOG_DEBUG, format, __VA_ARGS__); } while (0)
+
+/* Drizzle driver arguments */
+
+static sb_arg_t attachsql_drv_args[] =
+{
+  {"attachsql-host", "libAttachSQL server host", SB_ARG_TYPE_LIST, "localhost"},
+  {"attachsql-port", "libAttachSQL server port", SB_ARG_TYPE_INT, "4427"},
+  {"attachsql-socket", "libAttachSQL socket", SB_ARG_TYPE_STRING, NULL},
+  {"attachsql-user", "libAttachSQL user", SB_ARG_TYPE_STRING, ""},
+  {"attachsql-password", "libAttachSQL password", SB_ARG_TYPE_STRING, ""},
+  {"attachsql-db", "libAttachSQL database name", SB_ARG_TYPE_STRING, "sbtest"},
+  {NULL, NULL, SB_ARG_TYPE_NULL, NULL}
+};
+
+typedef struct
+{
+  sb_list_t          *hosts;
+  unsigned int       port;
+  char               *socket;
+  char               *user;
+  char               *password;
+  char               *db;
+} attachsql_drv_args_t;
+
+/* AttachSQL driver capabilities
+ * At a later date we will add prepared statements to this
+ */
+
+static drv_caps_t attachsql_drv_caps =
+{
+  .multi_rows_insert = 1,
+  .prepared_statements = 1,
+  .auto_increment = 1,
+  .serial = 0,
+  .unsigned_int = 0,
+};
+
+static attachsql_drv_args_t args;          /* driver args */
+
+static sb_list_item_t *hosts_pos;
+
+static pthread_mutex_t hosts_mutex;
+
+/* libAttachSQL driver operations */
+
+static int attachsql_drv_init(void);
+static int attachsql_drv_describe(drv_caps_t *);
+static int attachsql_drv_connect(db_conn_t *);
+static int attachsql_drv_disconnect(db_conn_t *);
+static int attachsql_drv_prepare(db_stmt_t *, const char *);
+static int attachsql_drv_bind_param(db_stmt_t *, db_bind_t *, unsigned int);
+static int attachsql_drv_bind_result(db_stmt_t *, db_bind_t *, unsigned int);
+static int attachsql_drv_execute(db_stmt_t *, db_result_set_t *);
+static int attachsql_drv_fetch(db_result_set_t *);
+static int attachsql_drv_fetch_row(db_result_set_t *, db_row_t *);
+static unsigned long long attachsql_drv_num_rows(db_result_set_t *);
+static int attachsql_drv_query(db_conn_t *, const char *, db_result_set_t *);
+static int attachsql_drv_free_results(db_result_set_t *);
+static int attachsql_drv_close(db_stmt_t *);
+static int attachsql_drv_store_results(db_result_set_t *);
+static int attachsql_drv_done(void);
+
+/* libAttachSQL driver definition */
+
+static db_driver_t attachsql_driver =
+{
+  .sname = "attachsql",
+  .lname = "libAttachSQL driver",
+  .args = attachsql_drv_args,
+  .ops =
+  {
+    attachsql_drv_init,
+    attachsql_drv_describe,
+    attachsql_drv_connect,
+    attachsql_drv_disconnect,
+    attachsql_drv_prepare,
+    attachsql_drv_bind_param,
+    attachsql_drv_bind_result,
+    attachsql_drv_execute,
+    attachsql_drv_fetch,
+    attachsql_drv_fetch_row,
+    attachsql_drv_num_rows,
+    attachsql_drv_free_results,
+    attachsql_drv_close,
+    attachsql_drv_query,
+    attachsql_drv_store_results,
+    attachsql_drv_done
+  },
+  .listitem = {NULL, NULL}
+};
+
+
+/* Local functions */
+
+/* Register libAttachSQL driver */
+
+
+int register_driver_attachsql(sb_list_t *drivers)
+{
+  SB_LIST_ADD_TAIL(&attachsql_driver.listitem, drivers);
+
+  return 0;
+}
+
+
+/* libAttachSQL driver initialization */
+
+
+int attachsql_drv_init(void)
+{
+  args.hosts = sb_get_value_list("attachsql-host");
+  if (SB_LIST_IS_EMPTY(args.hosts))
+  {
+    log_text(LOG_FATAL, "No libAttachSQL hosts specified, aborting");
+    return 1;
+  }
+  hosts_pos = args.hosts;
+  pthread_mutex_init(&hosts_mutex, NULL);
+  
+  args.port = (unsigned int)sb_get_value_int("attachsql-port");
+  args.socket = sb_get_value_string("attachsql-socket");
+  args.user = sb_get_value_string("attachsql-user");
+  args.password = sb_get_value_string("attachsql-password");
+  args.db = sb_get_value_string("attachsql-db");
+  attachsql_library_init();
+  return 0;
+}
+
+
+/* Describe database capabilities (possibly depending on table type) */
+
+
+int attachsql_drv_describe(drv_caps_t *caps )
+{
+  *caps = attachsql_drv_caps;
+  
+  return 0;
+}
+
+
+/* Connect to libAttachSQL database */
+
+
+int attachsql_drv_connect(db_conn_t *sb_conn)
+{
+  attachsql_connect_t     *con= NULL;
+  const char              *host;
+  attachsql_error_t      *error= NULL;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+
+  if (args.socket)
+  {
+    DEBUG("attachsql_connect_create(\"%s\", \"%s\", \"%s\", \"%s\")",
+      args.socket,
+      args.user,
+      args.password,
+      args.db);
+    con= attachsql_connect_create(args.socket,
+                             0,
+                             args.user,
+                             args.password,
+                             args.db,
+                             &error);
+  } else {
+
+    pthread_mutex_lock(&hosts_mutex);
+    hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
+    if (hosts_pos == args.hosts)
+      hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
+    host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data;
+    pthread_mutex_unlock(&hosts_mutex);
+
+    DEBUG("attachsql_connect_create(\"%s\", %u, \"%s\", \"%s\", \"%s\")",
+          host,
+          args.port,
+          args.user,
+          args.password,
+          args.db);
+    con= attachsql_connect_create(host,
+                             args.port,
+                             args.user,
+                             args.password,
+                             args.db,
+                             &error);
+  }
+  if (con == NULL)
+  {
+    log_text(LOG_FATAL, "unable to Add libAttachSQL Connection, aborting...");
+    log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
+    attachsql_error_free(error);
+    return 1;
+  }
+  attachsql_connect_set_option(con, ATTACHSQL_OPTION_SEMI_BLOCKING, NULL);
+
+  if (!attachsql_connect(con, &error))
+  {
+    log_text(LOG_FATAL, "unable to connect to libAttachSQL server");
+    log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
+    attachsql_error_free(error);
+    attachsql_connect_destroy(con);
+    return 1;
+
+  }
+
+  while (aret != ATTACHSQL_RETURN_IDLE)
+  {
+    aret = attachsql_connect_poll(con, &error);
+
+    if (error)
+    {
+      log_text(LOG_FATAL, "unable to connect to libAttachSQL server");
+      log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      attachsql_connect_destroy(con);
+      return 1;
+    }
+  }
+
+  sb_conn->ptr = con;
+
+  return 0;
+}
+
+
+/* Disconnect from libAttachSQL database */
+
+
+int attachsql_drv_disconnect(db_conn_t *sb_conn)
+{
+  attachsql_connect_t *con = (attachsql_connect_t *)sb_conn->ptr;
+
+  if (con != NULL)
+  {
+    DEBUG("attachsql_connect_destroy(%p)", con);
+    attachsql_connect_destroy(con);
+  }
+  return 0;
+}
+
+
+/* Prepare statement */
+
+
+int attachsql_drv_prepare(db_stmt_t *stmt, const char *query)
+{
+  attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
+  attachsql_error_t *error= NULL;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+  attachsql_statement_prepare(con, strlen(query), query, &error);
+  while(aret != ATTACHSQL_RETURN_EOF)
+  {
+    aret= attachsql_connect_poll(con, &error);
+    if (error)
+    {
+      log_text(LOG_ALERT, "libAttachSQL Prepare Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      return SB_DB_ERROR_FAILED;
+    }
+  }
+
+  return 0;
+}
+
+
+/* Bind parameters for prepared statement */
+int attachsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, unsigned int len)
+{
+  /* libAttachSQL doesn't do this, you do this during execute
+   * this is because sysbench doesn't set the values until that time
+   */
+
+  if (stmt->bound_param != NULL)
+    free(stmt->bound_param);
+  stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));
+  if (stmt->bound_param == NULL)
+    return 1;
+  memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));
+  stmt->bound_param_len = len;
+
+  return 0;
+
+}
+
+
+/* Bind results for prepared statement */
+int attachsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, unsigned int len)
+{
+  (void)stmt;
+  (void)params;
+  (void)len;
+  /* libAttachSQL doesn't do this, you get after execute */
+  return 0;
+}
+
+
+/* Execute prepared statement */
+
+
+int attachsql_drv_execute(db_stmt_t *stmt, db_result_set_t *rs)
+{
+  (void) rs;
+  attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+  attachsql_error_t *error= NULL;
+
+  uint16_t i;
+  int8_t tinyint;
+  int16_t smallint;
+  int32_t normalint;
+  int64_t bigint;
+  float float_type;
+  double double_type;
+  db_time_t *time_data;
+  if (con == NULL)
+    return 1;
+
+  for (i= 0; i < stmt->bound_param_len; i++)
+  {
+    db_bind_t *param= &stmt->bound_param[i];
+    switch(param->type)
+    {
+      case DB_TYPE_TINYINT:
+        tinyint= *(int8_t*)param->buffer;
+        attachsql_statement_set_int(con, i, tinyint, NULL);
+        break;
+      case DB_TYPE_SMALLINT:
+        smallint= *(int16_t*)param->buffer;
+        attachsql_statement_set_int(con, i, smallint, NULL);
+        break;
+      case DB_TYPE_INT:
+        normalint= *(int32_t*)param->buffer;
+        attachsql_statement_set_int(con, i, normalint, NULL);
+        break;
+      case DB_TYPE_BIGINT:
+        bigint= *(int64_t*)param->buffer;
+        attachsql_statement_set_bigint(con, i, bigint, NULL);
+        break;
+      case DB_TYPE_FLOAT:
+        float_type= *(float*)param->buffer;
+        attachsql_statement_set_float(con, i, float_type, NULL);
+        break;
+      case DB_TYPE_DOUBLE:
+        double_type= *(double*)param->buffer;
+        attachsql_statement_set_double(con, i, double_type, NULL);
+        break;
+      case DB_TYPE_TIME:
+        time_data= (db_time_t*)param->buffer;
+        attachsql_statement_set_time(con, i, time_data->hour, time_data->minute, time_data->second, 0, false, NULL);
+        break;
+      case DB_TYPE_DATE:
+      case DB_TYPE_DATETIME:
+      case DB_TYPE_TIMESTAMP:
+        time_data= (db_time_t*)param->buffer;
+        attachsql_statement_set_datetime(con, i, time_data->year, time_data->month, time_data->day, time_data->hour, time_data->minute, time_data->second, 0, NULL);
+        break;
+      case DB_TYPE_CHAR:
+      case DB_TYPE_VARCHAR:
+        attachsql_statement_set_string(con, i, param->max_len, param->buffer, NULL);
+      case DB_TYPE_NONE:
+      default:
+        attachsql_statement_set_null(con, i, NULL);
+        /* Not supported */
+    }
+  }
+
+  attachsql_statement_execute(con, &error);
+
+  while(aret != ATTACHSQL_RETURN_EOF)
+  {
+    aret= attachsql_connect_poll(con, &error);
+    if (aret == ATTACHSQL_RETURN_ROW_READY)
+    {
+      return 0;
+    }
+    if (error)
+    {
+      log_text(LOG_ALERT, "libAttachSQL Execute Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      return SB_DB_ERROR_FAILED;
+    }
+  }
+
+  return SB_DB_ERROR_NONE;
+}
+
+
+/* Execute SQL query */
+
+
+int attachsql_drv_query(db_conn_t *sb_conn, const char *query,
+                      db_result_set_t *rs)
+{
+  (void) rs;
+  attachsql_connect_t *con = sb_conn->ptr;
+  unsigned int rc;
+  attachsql_error_t *error= NULL;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+
+  /* Close any previous query */
+  attachsql_query_close(con);
+
+  DEBUG("attachsql_query(%p, \"%s\", %u)",
+        con,
+        query,
+        strlen(query));
+  attachsql_query(con, strlen(query), query, 0, NULL, &error);
+
+  while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
+  {
+    aret= attachsql_connect_poll(con, &error);
+
+    if (error)
+    {
+      rc= attachsql_error_code(error);
+      if (rc == 1213 || rc == 1205 || rc == 1020)
+      {
+        attachsql_error_free(error);
+        return SB_DB_ERROR_DEADLOCK;
+      }
+      log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      return SB_DB_ERROR_FAILED;
+    }
+  }
+  //rs->connection->ptr= con;
+  DEBUG("attachsql_query \"%s\" returned %d", query, aret);
+
+  return SB_DB_ERROR_NONE;
+}
+
+
+/* Fetch row from result set of a prepared statement */
+
+
+int attachsql_drv_fetch(db_result_set_t *rs)
+{
+  /* NYI */
+  attachsql_connect_t *con = rs->connection->ptr;
+  size_t tmp_len;
+  uint16_t columns, col;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+  attachsql_error_t *error= NULL;
+
+  while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
+  {
+    aret= attachsql_connect_poll(con, &error);
+
+    if (error)
+    {
+      log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      return 1;
+    }
+  }
+  if (aret == ATTACHSQL_RETURN_EOF)
+  {
+    return 1;
+  }
+  attachsql_statement_row_get(con, NULL);
+  columns= attachsql_query_column_count(con);
+  for (col= 0; col < columns; col++)
+  {
+    switch (attachsql_statement_get_column_type(con, col))
+    {
+      case ATTACHSQL_COLUMN_TYPE_TINY:
+      case ATTACHSQL_COLUMN_TYPE_SHORT:
+      case ATTACHSQL_COLUMN_TYPE_LONG:
+      case ATTACHSQL_COLUMN_TYPE_YEAR:
+      case ATTACHSQL_COLUMN_TYPE_INT24:
+        attachsql_statement_get_int(con, col, &error);
+        break;
+      case ATTACHSQL_COLUMN_TYPE_LONGLONG:
+        attachsql_statement_get_bigint(con, col, &error);
+        break;
+      case ATTACHSQL_COLUMN_TYPE_FLOAT:
+        attachsql_statement_get_float(con, col, &error);
+        break;
+      case ATTACHSQL_COLUMN_TYPE_DOUBLE:
+        attachsql_statement_get_double(con, col, &error);
+        break;
+      default:
+        attachsql_statement_get_char(con, col, &tmp_len, &error);
+        break;
+    }
+  }
+  attachsql_query_row_next(con);
+
+  return 0;
+}
+
+
+/* Fetch row from result set of a query */
+
+
+int attachsql_drv_fetch_row(db_result_set_t *rs, db_row_t *row)
+{
+  attachsql_error_t *error= NULL;
+  attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
+
+  /* NYI */
+
+  attachsql_connect_t *con = rs->connection->ptr;
+
+  while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
+  {
+    aret= attachsql_connect_poll(con, &error);
+
+    if (error)
+    {
+      log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
+      attachsql_error_free(error);
+      return 1;
+    }
+  }
+  if (aret == ATTACHSQL_RETURN_EOF)
+  {
+    return 1;
+  }
+  row->ptr= attachsql_query_row_get(con, NULL);
+  attachsql_query_row_next(con);
+
+  return 0;
+}
+
+
+/* Return the number of rows in a result set */
+
+
+unsigned long long attachsql_drv_num_rows(db_result_set_t *rs)
+{
+  return rs->nrows;
+}
+
+
+/* Store results from the last query */
+
+
+int attachsql_drv_store_results(db_result_set_t *rs)
+{
+  int ret= 0;
+  db_row_t row;
+  /* libAttachSQL can't do things in this order */
+  while (ret == 0)
+  {
+    if (rs->statement != NULL)
+    {
+      ret= attachsql_drv_fetch(rs);
+    }
+    else
+    {
+      ret= attachsql_drv_fetch_row(rs, &row);
+    }
+  }
+
+  return SB_DB_ERROR_NONE;
+}
+
+
+/* Free result set */
+
+
+int attachsql_drv_free_results(db_result_set_t *rs)
+{
+
+  if (rs->connection->ptr != NULL)
+  {
+    DEBUG("attachsql_query_close(%p)", rs->connection->ptr);
+    attachsql_query_close(rs->connection->ptr);
+    return 0;
+  }
+
+  return 1;
+}
+
+
+/* Close prepared statement */
+
+
+int attachsql_drv_close(db_stmt_t *stmt)
+{
+  attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
+  attachsql_statement_close(con);
+
+  return 0;
+}
+
+
+/* Uninitialize driver */
+int attachsql_drv_done(void)
+{
+  return 0;
+}
+

=== modified file 'sysbench/tests/db/common.lua'
--- sysbench/tests/db/common.lua	2011-12-01 19:43:29 +0000
+++ sysbench/tests/db/common.lua	2014-10-16 09:41:21 +0000
@@ -20,7 +20,7 @@
    i = table_id
 
    print("Creating table 'sbtest" .. i .. "'...")
-   if (db_driver == "mysql") then
+   if ((db_driver == "mysql") or (db_driver == "attachsql")) then
       query = [[
 CREATE TABLE sbtest]] .. i .. [[ (
 id INTEGER UNSIGNED NOT NULL ]] ..

=== modified file 'sysbench/tests/db/oltp.lua'
--- sysbench/tests/db/oltp.lua	2011-12-01 19:43:29 +0000
+++ sysbench/tests/db/oltp.lua	2014-10-16 09:41:21 +0000
@@ -5,7 +5,7 @@
 function thread_init(thread_id)
    set_vars()
 
-   if (db_driver == "mysql" and mysql_table_engine == "myisam") then
+   if (((db_driver == "mysql") or (db_driver == "attachsql")) and mysql_table_engine == "myisam") then
       begin_query = "LOCK TABLES sbtest WRITE"
       commit_query = "UNLOCK TABLES"
    else

=== modified file 'sysbench/tests/db/select_random_points.lua'
--- sysbench/tests/db/select_random_points.lua	2010-10-29 02:15:54 +0000
+++ sysbench/tests/db/select_random_points.lua	2014-10-16 09:41:21 +0000
@@ -14,7 +14,7 @@
 
    print("Creating table 'sbtest'...")
 
-   if (db_driver == "mysql") then
+   if ((db_driver == "mysql") or (db_driver == "attachsql")) then
       query = [[
         CREATE TABLE sbtest (
           id INTEGER UNSIGNED NOT NULL ]] .. ((oltp_auto_inc and "AUTO_INCREMENT") or "") .. [[,

=== modified file 'sysbench/tests/db/select_random_ranges.lua'
--- sysbench/tests/db/select_random_ranges.lua	2010-10-29 02:15:54 +0000
+++ sysbench/tests/db/select_random_ranges.lua	2014-10-16 09:41:21 +0000
@@ -14,7 +14,7 @@
 
    print("Creating table 'sbtest'...")
 
-   if (db_driver == "mysql") then
+   if ((db_driver == "mysql") or (db_driver == "attachsql")) then
       query = [[
         CREATE TABLE sbtest (
           id INTEGER UNSIGNED NOT NULL ]] .. ((oltp_auto_inc and "AUTO_INCREMENT") or "") .. [[,


Follow ups