Hi,

I did not find a solution, I just stopped using prepared statements
altogether. But I tried to isolate the problem just now, and found somehow
that I cannot use FLOAT in prepared statement somehow (when I tried INT
columns it even segfaults). Below the source code of a mini-module to
illustrate this. This is the table I created in MySQL:

CREATE TABLE simple_table (duration FLOAT NOT NULL) ENGINE=INNODEDB;

And this is what appears in the MySQL log:

Prepare    INSERT INTO simple_table (duration) VALUES (?)
Execute    INSERT INTO simple_table (duration) VALUES ('')

If you want to reproduce it, dont forget to put this in httpd.conf:
LoadModule prep_stmt_module   modules/mod_prep_stmt.so
PrepStmt on


-----------------  Complete mini-module -------------------------



#include <httpd.h>
#include <http_config.h>
#include <http_core.h>
#include <http_log.h>
#include <http_protocol.h>
#include <http_connection.h>
#include <apr_file_info.h>
#include <apr_file_io.h>
#include <apr_dbd.h>
#include <mod_dbd.h>

module AP_MODULE_DECLARE_DATA prep_stmt_module;

static int prep_stmt_write(request_rec *r);

typedef struct prep_stmt_config
{
  int prep_stmt_on;
} prep_stmt_config;

static const char * prep_stmt_config_set_prep_stmt_on(cmd_parms *cmd, void
*dummy, int flag)
{
    ap_dbd_prepare(cmd->server, "INSERT INTO simple_table (duration) VALUES
(%f)", "insert_row");

  prep_stmt_config *cfg = ap_get_module_config(cmd->server->module_config,
&prep_stmt_module);
  cfg->prep_stmt_on = flag;
  return NULL;
}

static int prep_stmt_write(request_rec *r)
{
    prep_stmt_config *cfg = ap_get_module_config(r->server->module_config,
&prep_stmt_module);
    if (!cfg->prep_stmt_on)
        return DECLINED;

    ap_dbd_t * dbd = ap_dbd_acquire(r);

    apr_dbd_prepared_t *prepared = apr_hash_get(dbd->prepared, "insert_row",
APR_HASH_KEY_STRING);
    if (!prepared) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                "DBD Log: Failed to get prepared statement:
update_request");
        return DECLINED;
    }

    int rv, nrows;
    if (rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows,
prepared, 10.2, NULL)) {
        const char *errmsg = apr_dbd_error(dbd->driver, dbd->handle, rv);
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                "DBD Log: Failed to execute prepared statement:
insert_row");
        return DECLINED;
    }
}

static const command_rec prep_stmt_cmds[] = {
    AP_INIT_FLAG("PrepStmt", prep_stmt_config_set_prep_stmt_on,
            NULL, RSRC_CONF, "Enable DBD Log"),
    { NULL }
};

static void prep_stmt_register_hooks(apr_pool_t *p)
{
    ap_hook_log_transaction(prep_stmt_write, NULL, NULL, APR_HOOK_MIDDLE);
}

static void * prep_stmt_create_config(apr_pool_t *pool, server_rec *s)
{
  prep_stmt_config *cfg = apr_pcalloc(pool, sizeof(prep_stmt_config));
  return cfg;
}

module AP_MODULE_DECLARE_DATA prep_stmt_module =
{
    STANDARD20_MODULE_STUFF,    /* stuff that needs to be declared in every
2.0 mod */
    NULL,           /* create per-directory config structure            */
    NULL,                       /* merge per-directory config
structures            */
    prep_stmt_create_config,                       /* create per-server
config structure               */
    NULL,                       /* merge per-server config
structures               */
    prep_stmt_cmds,                       /* command
apr_table_t                              */
    prep_stmt_register_hooks      /* register
hooks                                   */
};

Reply via email to