Beispiel #1
0
/*
 * must be called after an execute
 */
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
    int i;
    int d;

    SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1];
    SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
    SQLINTEGER sqlcode;
    SQLSMALLINT length;

    SQLRETURN rc = SQL_SUCCESS;
 
    if (!statement->resultset || !statement->bind) {
	lua_pushnil(L);
	return 1;
    }

    /* fetch each row, and display */
    rc = SQLFetch(statement->stmt);
    if (rc == SQL_NO_DATA_FOUND) {
        SQLFreeStmt(statement->stmt, SQL_RESET_PARAMS);
	lua_pushnil(L);
	return 1;
    }

    if (rc != SQL_SUCCESS) {
        SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length);

        luaL_error(L, DBI_ERR_FETCH_FAILED, message);
    }

    d = 1; 
    lua_newtable(L);
    for (i = 0; i < statement->num_result_columns; i++) {
	lua_push_type_t lua_push = db2_to_lua_push(statement->resultset[i].type, statement->bind[i].len);
	const char *name = strlower(statement->resultset[i].name);
	double val;
	char *value = (char *)statement->bind[i].buffer;

	switch (lua_push) {
	case LUA_PUSH_NIL:
	    if (named_columns) {
		LUA_PUSH_ATTRIB_NIL(name);
	    } else {
		LUA_PUSH_ARRAY_NIL(d);
	    }
	    break;
	case LUA_PUSH_INTEGER:
            if (named_columns) {
                LUA_PUSH_ATTRIB_INT(name, atoi(value));
            } else {
                LUA_PUSH_ARRAY_INT(d, atoi(value));
            }
	    break;
	case LUA_PUSH_NUMBER:
	    val = strtod(value, NULL);

            if (named_columns) {
		LUA_PUSH_ATTRIB_FLOAT(name, val);
            } else {
		LUA_PUSH_ARRAY_FLOAT(d, val);
            }
	    break;
	case LUA_PUSH_BOOLEAN:
            if (named_columns) {
                LUA_PUSH_ATTRIB_BOOL(name, atoi(value));
            } else {
                LUA_PUSH_ARRAY_BOOL(d, atoi(value));
            }
            break;	    
	case LUA_PUSH_STRING:
	    if (named_columns) {
		LUA_PUSH_ATTRIB_STRING(name, value);
	    } else {
		LUA_PUSH_ARRAY_STRING(d, value);
	    }    
	    break;
	default:
	    luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
	}
    }

    return 1;    
}
Beispiel #2
0
/*
 * must be called after an execute
 */
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
    int rc;
    sword status;
    int i;
    bindparams_t *bind;

    char errbuf[100];
    int errcode;

    if (!statement->stmt) {
	luaL_error(L, DBI_ERR_FETCH_INVALID);
	return 0;
    }

    statement_fetch_metadata(L, statement);    
    bind = statement->bind;

    status = OCIStmtFetch(statement->stmt, statement->conn->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);

    if (status == OCI_NO_DATA) {
	/* No more rows */
        lua_pushnil(L);
        return 1;
    } else if (status != OCI_SUCCESS) {
	OCIErrorGet((dvoid *)statement->conn->err, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
	luaL_error(L, DBI_ERR_FETCH_FAILED, errbuf);
    }

    if (statement->num_columns) {
	int i;
	int d = 1;

	lua_newtable(L);

	for (i = 0; i < statement->num_columns; i++) {
	    lua_push_type_t lua_push = oracle_to_lua_push(bind[i].data_type, bind[i].null);
	    const char *name = strlower(bind[i].name);
	    const char *data = bind[i].data;

	    if (lua_push == LUA_PUSH_NIL) {
                if (named_columns) {
                    LUA_PUSH_ATTRIB_NIL(name);
                } else {
                    LUA_PUSH_ARRAY_NIL(d);
                }
            } else if (lua_push == LUA_PUSH_INTEGER) {
		int val = atoi(data);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_INT(name, val);
                } else {
                    LUA_PUSH_ARRAY_INT(d, val);
                }
            } else if (lua_push == LUA_PUSH_NUMBER) {
		double val = strtod(data, NULL);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_FLOAT(name, val);
                } else {
                    LUA_PUSH_ARRAY_FLOAT(d, val);
                }
            } else if (lua_push == LUA_PUSH_STRING) {
                if (named_columns) {
                    LUA_PUSH_ATTRIB_STRING(name, data);
                } else {
                    LUA_PUSH_ARRAY_STRING(d, data);
                }
            } else if (lua_push == LUA_PUSH_BOOLEAN) {
		int val = atoi(data);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_BOOL(name, val);
                } else {
                    LUA_PUSH_ARRAY_BOOL(d, val);
                }
            } else {
                luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
            }
	}
    } else {
	/* 
         * no columns returned by statement?
         */ 
	lua_pushnil(L);
    }

    return 1;    
}
Beispiel #3
0
static int
statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */
		      int named_columns)
{
  int column_count, fetch_result_ok;
  MYSQL_BIND *bind = NULL;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

  if (!statement->stmt)
    {
      luaL_error (L, DBI_ERR_FETCH_INVALID);
      return 0;
    }

  if (!statement->metadata)
    {
      luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE);
      return 0;
    }

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;
      MYSQL_FIELD *fields;

      real_length = calloc (column_count, sizeof (unsigned long));

      bind = malloc (sizeof (MYSQL_BIND) * column_count);
      memset (bind, 0, sizeof (MYSQL_BIND) * column_count);

      fields = mysql_fetch_fields (statement->metadata);

      for (i = 0; i < column_count; i++)
	{
	  unsigned int length = mysql_buffer_size (&fields[i]);
	  if (length > sizeof (MYSQL_TIME))
	    {
	      bind[i].buffer = NULL;
	      bind[i].buffer_length = 0;
	    }
	  else
	    {
	      char *buffer = (char *) malloc (length);
	      memset (buffer, 0, length);

	      bind[i].buffer = buffer;
	      bind[i].buffer_length = length;
	    }

	  bind[i].buffer_type = fields[i].type;
	  bind[i].length = &real_length[i];
	}

      if (mysql_stmt_bind_result (statement->stmt, bind))
	{
	  error_message = DBI_ERR_BINDING_RESULTS;
	  goto cleanup;
	}

      fetch_result_ok = mysql_stmt_fetch (statement->stmt);
      if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED)
	{
	  int d = 1;

	  lua_newtable (L);
	  for (i = 0; i < column_count; i++)
	    {
	      lua_push_type_t lua_push = mysql_to_lua_push (fields[i].type);
	      const char *name = fields[i].name;

	      if (bind[i].buffer == NULL)
		{
		  char *buffer =
		    (char *) calloc (real_length[i] + 1, sizeof (char));
		  bind[i].buffer = buffer;
		  bind[i].buffer_length = real_length[i];
		  mysql_stmt_fetch_column (statement->stmt, &bind[i], i, 0);
		}

	      if (lua_push == LUA_PUSH_NIL)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_NIL (name);
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_NIL (d);
		    }
		}
	      else if (lua_push == LUA_PUSH_INTEGER)
		{
		  if (fields[i].type == MYSQL_TYPE_YEAR
		      || fields[i].type == MYSQL_TYPE_SHORT)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(short *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(short *) (bind[i].buffer));
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TINY)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       (int) *(char
						       *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      (int) *(char
						      *) (bind[i].buffer));
			}
		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(int *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(int *) (bind[i].buffer));
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_NUMBER)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_FLOAT (name,
					     *(double *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_FLOAT (d, *(double *) (bind[i].buffer));
		    }
		}
	      else if (lua_push == LUA_PUSH_STRING)
		{

		  if (fields[i].type == MYSQL_TYPE_TIMESTAMP
		      || fields[i].type == MYSQL_TYPE_DATETIME)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d",
				t->year, t->month, t->day, t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TIME)
		    {
		      char str[9];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 9, "%02d:%02d:%02d", t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_DATE)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 11, "%d-%02d-%02d", t->year,
				t->month, t->day);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}

		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, bind[i].buffer);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, bind[i].buffer);
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_BOOLEAN)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_BOOL (name, *(int *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_BOOL (d, *(int *) (bind[i].buffer));
		    }
		}
	      else
		{
		  luaL_error (L, DBI_ERR_UNKNOWN_PUSH);
		}
	    }
	}
      else
	{
	  lua_pushnil (L);
	}
    }

cleanup:
  free (real_length);

  if (bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (bind[i].buffer);
	}

      free (bind);
    }

  if (error_message)
    {
      luaL_error (L, error_message, mysql_stmt_error (statement->stmt));
      return 0;
    }

  return 1;
} /* }}} */
Beispiel #4
0
static int
statement_fetch_impl_cont (lua_State * L, statement_t * statement, /* {{{ */
			   int event, int named_columns)
{
  int column_count;
  unsigned long *real_length = NULL;
  int values = 0;

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;

      real_length = calloc (column_count, sizeof (unsigned long));

      statement->event =
	mysql_stmt_fetch_cont (&(statement->ret), statement->stmt, event);

      if (statement->event & MYSQL_WAIT_EXCEPT)
	{
	  lua_pushnil (L);
	  lua_pushfstring (L, mysql_stmt_error (statement->stmt));
	  values = 2;
	}

      if (statement->event & MYSQL_WAIT_TIMEOUT)
	{
	  statement->timeout =
	    1000 * mysql_get_timeout_value_ms (statement->mysql);
	}
      /* Pretty sure statement->ret should be the return value, but it seems to return 1 */
      /* using mysql_stmt_errno instead */
      if (mysql_stmt_errno (statement->stmt) != 0)
	{
	  lua_pushnil (L);
	  lua_pushstring (L, mysql_stmt_error (statement->stmt));
	  values = 2;
	}
      if (statement->event > 0)
	{
	  lua_pushboolean (L, 0);
	  lua_pushnumber (L, convert_mysql_to_ev (statement->event));
	  values = 2;
	}

      if (mysql_stmt_errno (statement->stmt) == 0
	  || statement->ret == MYSQL_DATA_TRUNCATED)
	{
	  int d = 1;

	  lua_pushboolean (L, 1);
	  lua_newtable (L);
	  values = 2;
	  for (i = 0; i < column_count; i++)
	    {
	      lua_push_type_t lua_push =
		mysql_to_lua_push (statement->fields[i].type);
	      const char *name = statement->fields[i].name;

	      if (statement->bind[i].buffer == NULL)
		{
		  char *buffer =
		    (char *) calloc (real_length[i] + 1, sizeof (char));
		  statement->bind[i].buffer = buffer;
		  statement->bind[i].buffer_length = real_length[i];
		  mysql_stmt_fetch_column (statement->stmt,
					   &(statement->bind[i]), i, 0);
		}

	      if (lua_push == LUA_PUSH_NIL)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_NIL (name);
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_NIL (d);
		    }
		}
	      else if (lua_push == LUA_PUSH_INTEGER)
		{
		  if (statement->fields[i].type == MYSQL_TYPE_YEAR
		      || statement->fields[i].type == MYSQL_TYPE_SHORT)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(short
						 *) (statement->
						     bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      *(short
						*) (statement->
						    bind[i].buffer));
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_TINY)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       (int) *(char
						       *) (statement->bind
							   [i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      (int) *(char
						      *) (statement->bind
							  [i].buffer));
			}
		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(int
						 *) (statement->
						     bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      *(int
						*) (statement->
						    bind[i].buffer));
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_NUMBER)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_FLOAT (name,
					     *(double
					       *) (statement->
						   bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_FLOAT (d,
					    *(double
					      *) (statement->bind[i].buffer));
		    }
		}
	      else if (lua_push == LUA_PUSH_STRING)
		{

		  if (statement->fields[i].type == MYSQL_TYPE_TIMESTAMP
		      || statement->fields[i].type == MYSQL_TYPE_DATETIME)
		    {
		      char str[20];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d",
				t->year, t->month, t->day, t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_TIME)
		    {
		      char str[9];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 9, "%02d:%02d:%02d", t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (statement->fields[i].type == MYSQL_TYPE_DATE)
		    {
		      char str[20];
		      struct st_mysql_time *t = statement->bind[i].buffer;

		      snprintf (str, 11, "%d-%02d-%02d", t->year,
				t->month, t->day);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}

		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name,
						  statement->bind[i].buffer);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d,
						 statement->bind[i].buffer);
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_BOOLEAN)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_BOOL (name,
					    *(int *) (statement->
						      bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_BOOL (d,
					   *(int *) (statement->
						     bind[i].buffer));
		    }
		}
	      else
		{
		  luaL_error (L, DBI_ERR_UNKNOWN_PUSH);
		  values = 1;
		}
	    }
	}
      else
	{
	  lua_pushnil (L);
	  values = 1;
	}
    }

  if (statement->bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (statement->bind[i].buffer);
	}

      free (statement->bind);
    }
  return values;

} /* }}} */
Beispiel #5
0
/*
 * must be called after an execute
 */
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
    int num_columns;

    if (!statement->stmt) {
	luaL_error(L, DBI_ERR_FETCH_INVALID);
	return 0;
    }

    if (!statement->more_data) {
	/* 
         * Result set is empty, or not result set returned
         */
  
	lua_pushnil(L);
	return 1;
    }

    num_columns = sqlite3_column_count(statement->stmt);

    if (num_columns) {
	int i;
	int d = 1;

	lua_newtable(L);

	for (i = 0; i < num_columns; i++) {
	    lua_push_type_t lua_push = sqlite_to_lua_push(sqlite3_column_type(statement->stmt, i));
	    const char *name = sqlite3_column_name(statement->stmt, i);

	    if (lua_push == LUA_PUSH_NIL) {
                if (named_columns) {
                    LUA_PUSH_ATTRIB_NIL(name);
                } else {
                    LUA_PUSH_ARRAY_NIL(d);
                }
            } else if (lua_push == LUA_PUSH_INTEGER) {
		int val = sqlite3_column_int(statement->stmt, i);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_INT(name, val);
                } else {
                    LUA_PUSH_ARRAY_INT(d, val);
                }
            } else if (lua_push == LUA_PUSH_NUMBER) {
		double val = sqlite3_column_double(statement->stmt, i);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_FLOAT(name, val);
                } else {
                    LUA_PUSH_ARRAY_FLOAT(d, val);
                }
            } else if (lua_push == LUA_PUSH_STRING) {
		const char *val = (const char *)sqlite3_column_text(statement->stmt, i);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_STRING(name, val);
                } else {
                    LUA_PUSH_ARRAY_STRING(d, val);
                }
            } else if (lua_push == LUA_PUSH_BOOLEAN) {
		int val = sqlite3_column_int(statement->stmt, i);

                if (named_columns) {
                    LUA_PUSH_ATTRIB_BOOL(name, val);
                } else {
                    LUA_PUSH_ARRAY_BOOL(d, val);
                }
            } else {
                luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
            }
	}
    } else {
	/* 
         * no columns returned by statement?
         */ 
	lua_pushnil(L);
    }

    if (step(statement) == 0) {
	if (sqlite3_reset(statement->stmt) != SQLITE_OK) {
	    /* 
	     * reset needs to be called to retrieve the 'real' error message
	     */
	    luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite));
	}
    }

    return 1;    
}
Beispiel #6
0
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
    int column_count;
    MYSQL_BIND *bind = NULL;
    const char *error_message = NULL;

    if (!statement->stmt) {
		luaL_error(L, DBI_ERR_FETCH_INVALID);
		return 0;
    }

    if (!statement->metadata) {
		luaL_error(L, DBI_ERR_FETCH_NO_EXECUTE);
		return 0;
    }

    column_count = mysql_num_fields(statement->metadata);

    if (column_count > 0) {
		int i;
		MYSQL_FIELD *fields;

        bind = malloc(sizeof(MYSQL_BIND) * column_count);
        memset(bind, 0, sizeof(MYSQL_BIND) * column_count);

		fields = mysql_fetch_fields(statement->metadata);

		for (i = 0; i < column_count; i++) {
			unsigned int length = mysql_buffer_size(&fields[i]);
			char *buffer = (char *) malloc(length);
			memset(buffer, 0, length);

			bind[i].buffer_type = fields[i].type; 
			bind[i].buffer = buffer;
			bind[i].buffer_length = length;
		}

		if (mysql_stmt_bind_result(statement->stmt, bind)) {
			error_message = DBI_ERR_BINDING_RESULTS;
			goto cleanup;
		}

		if (!mysql_stmt_fetch(statement->stmt)) {
			int d = 1;

			lua_newtable(L);
			for (i = 0; i < column_count; i++) {
				lua_push_type_t lua_push = mysql_to_lua_push(fields[i].type);
				const char *name = fields[i].name;

				if (lua_push == LUA_PUSH_NIL) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_NIL(name);
					} else {
						LUA_PUSH_ARRAY_NIL(d);
					}
				} else if (lua_push == LUA_PUSH_INTEGER) {
					if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, *(short *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, *(short *)(bind[i].buffer)); 
						}
					} else if (fields[i].type == MYSQL_TYPE_TINY) {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, (int)*(char *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, (int)*(char *)(bind[i].buffer)); 
						}
					} else {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, *(int *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, *(int *)(bind[i].buffer)); 
						}
					}
				} else if (lua_push == LUA_PUSH_NUMBER) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer));
					} else {
						LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer));
					}
				} else if (lua_push == LUA_PUSH_STRING) {
					if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) {
						char str[20];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
					} else if (fields[i].type == MYSQL_TYPE_TIME) {
						char str[9];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
						} else if (fields[i].type == MYSQL_TYPE_DATE) {
						char str[20];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 11, "%d-%02d-%02d", t->year, t->month, t->day);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
					} else {
						size_t length = bind[i].buffer_length;
						//
						//  hack for strings. have no idea what 8 means but it is different from value for binary blobs, which is good enough
						//
						if (fields[i].charsetnr == 8) {
							length = min(bind[i].buffer_length, strlen(bind[i].buffer));
						}
						if (named_columns) {
							LUA_PUSH_ATTRIB_LSTRING(name, bind[i].buffer, length);
						} else {
							LUA_PUSH_ARRAY_LSTRING(d, bind[i].buffer, length);
						}
					}
				} else if (lua_push == LUA_PUSH_BOOLEAN) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_BOOL(name, *(int *)(bind[i].buffer));
					} else {
						LUA_PUSH_ARRAY_BOOL(d, *(int *)(bind[i].buffer));
					}
				} else {
					luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
				}
			}
		} else {
			lua_pushnil(L);	    
		}
    }

cleanup:
    if (bind) {
	int i;

	for (i = 0; i < column_count; i++) {
	    free(bind[i].buffer);
	}

	free(bind);
    }

    if (error_message) {
        luaL_error(L, error_message, mysql_stmt_error(statement->stmt));
        return 0;
    }

    return 1;    
}