2
0
Эх сурвалжийг харах

core, srdb1, modules/db_*, modules_k/db_*: Added support for configuring SQL buffer size and mediumblob/mediumtext in MySQL

- Currently the SQL buffer size is hard-coded to 64k.  This isn't
  enough in some cases.  For example, it is easily possible for
  resource lists (which can be Network Address Books) to be larger
  than 64k.
- The default buffer size is still 64k, but this can be overriden
  with the new "sql_buffer_size" configuration option.
- Support added for mediumblob/mediumtext in MySQL as the blob/text
  types that are currently supported are limited to 64k.
- Feature added by Andrew Miller at Crocodile RCS
pd 14 жил өмнө
parent
commit
5cd87175fa

+ 2 - 0
cfg.lex

@@ -383,6 +383,7 @@ DST_BLST_SCTP_IMASK	dst_blacklist_sctp_imask
 PORT	port
 STAT	statistics
 MAXBUFFER maxbuffer
+SQL_BUFFER_SIZE sql_buffer_size
 CHILDREN children
 CHECK_VIA	check_via
 PHONE2TEL	phone2tel
@@ -765,6 +766,7 @@ IMPORTFILE      "import_file"
 <INITIAL>{PORT}	{ count(); yylval.strval=yytext; return PORT; }
 <INITIAL>{STAT}	{ count(); yylval.strval=yytext; return STAT; }
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
+<INITIAL>{SQL_BUFFER_SIZE}	{ count(); yylval.strval=yytext; return SQL_BUFFER_SIZE; }
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
 <INITIAL>{PHONE2TEL}	{ count(); yylval.strval=yytext; return PHONE2TEL; }

+ 3 - 0
cfg.y

@@ -447,6 +447,7 @@ extern char *finame;
 %token LOADPATH
 %token MODPARAM
 %token MAXBUFFER
+%token SQL_BUFFER_SIZE
 %token USER
 %token GROUP
 %token CHROOT
@@ -914,6 +915,8 @@ assign_stm:
 	}
 	| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
 	| MAXBUFFER EQUAL error { yyerror("number expected"); }
+    | SQL_BUFFER_SIZE EQUAL NUMBER { sql_buffer_size=$3; }
+	| SQL_BUFFER_SIZE EQUAL error { yyerror("number expected"); }
 	| PORT EQUAL error    { yyerror("number expected"); }
 	| CHILDREN EQUAL NUMBER { children_no=$3; }
 	| CHILDREN EQUAL error { yyerror("number expected"); }

+ 12 - 0
doc/cfg_list/docbook/cfg_core.xml

@@ -520,4 +520,16 @@
     </para>
 </section>
 
+<section id="coresql_buffer_size">
+    <title>core.sql_buffer_size</title>
+    <para>
+        Size for the SQL buffer.
+        This will limit the size of objects that can be stored in an SQL database.
+    </para>
+    <para>Default value: 65535.</para>
+    <para>Type: integer.</para>
+    <para>
+    </para>
+</section>
+
 </chapter>

+ 3 - 1
doc/stylesheets/dbschema_k/xsl/db_berkeley.xsl

@@ -166,7 +166,9 @@
 	    </xsl:when>
 	    <xsl:when test="$type='string' or
 						$type='text' or
-						$type='binary'">
+						$type='binary' or 
+                        $type='largetext' or
+						$type='largebinary'">
 		<xsl:text>str</xsl:text>
 	    </xsl:when>
 	    <xsl:otherwise>

+ 4 - 2
doc/stylesheets/dbschema_k/xsl/db_sqlite.xsl

@@ -85,12 +85,14 @@
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='binary'">
+	    <xsl:when test="$type='binary' or
+						$type='largebinary'">
 		<xsl:text>BYTEA</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='text'">
+	    <xsl:when test="$type='text'or
+						$type='largetext'">
 		<xsl:text>TEXT</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>

+ 3 - 1
doc/stylesheets/dbschema_k/xsl/dbtext.xsl

@@ -90,7 +90,9 @@
 	    </xsl:when>
 	    <xsl:when test="$type='string' or
 						$type='text' or
-						$type='binary'">
+						$type='binary' or 
+                        $type='largetext' or
+						$type='largebinary'">
 		<xsl:text>string</xsl:text>
 	    </xsl:when>
 	    <xsl:otherwise>

+ 12 - 0
doc/stylesheets/dbschema_k/xsl/mysql.xsl

@@ -103,11 +103,23 @@
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
+        <xsl:when test="$type='largebinary'">
+        <!-- In MySQL  MEDIUMBLOB <= 16MB -->
+		<xsl:text>MEDIUMBLOB</xsl:text>
+		<xsl:call-template name="column.size"/>
+		<xsl:call-template name="column.trailing"/>
+	    </xsl:when>
 	    <xsl:when test="$type='text'">
 		<xsl:text>TEXT</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
+	    <xsl:when test="$type='largetext'">
+        <!-- In MySQL  MEDIUMTEXT <= 16MB -->
+		<xsl:text>MEDIUMTEXT</xsl:text>
+		<xsl:call-template name="column.size"/>
+		<xsl:call-template name="column.trailing"/>
+	    </xsl:when>
 	    <xsl:otherwise>
 		<xsl:call-template name="type-error"/>
 	    </xsl:otherwise>

+ 4 - 2
doc/stylesheets/dbschema_k/xsl/oracle.xsl

@@ -114,12 +114,14 @@
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='binary'">
+	    <xsl:when test="$type='binary' or 
+						$type='largebinary'">
 		<xsl:text>BLOB</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='text'">
+	    <xsl:when test="$type='text' or 
+                        $type='largetext'">
 		<xsl:text>CLOB</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>

+ 4 - 2
doc/stylesheets/dbschema_k/xsl/postgres.xsl

@@ -87,12 +87,14 @@
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='binary'">
+	    <xsl:when test="$type='binary' or 
+						$type='largebinary'">
 		<xsl:text>BYTEA</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>
 	    </xsl:when>
-	    <xsl:when test="$type='text'">
+	    <xsl:when test="$type='text' or 
+                        $type='largetext'">
 		<xsl:text>TEXT</xsl:text>
 		<xsl:call-template name="column.size"/>
 		<xsl:call-template name="column.trailing"/>

+ 1 - 0
globals.h

@@ -86,6 +86,7 @@ extern struct socket_info* sendipv6_sctp; /* same as above for ipv6 */
 #endif
 
 extern unsigned int maxbuffer;
+extern unsigned int sql_buffer_size;
 extern int children_no;
 #ifdef USE_TCP
 extern int tcp_main_pid;

+ 60 - 42
lib/srdb1/db_query.c

@@ -36,9 +36,10 @@
 #include "../../dprint.h"
 #include "db_ut.h"
 #include "db_query.h"
+#include "../../globals.h"
 
 static str  sql_str;
-static char sql_buf[SQL_BUF_LEN];
+static char *sql_buf = NULL;
 
 int db_do_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
 	const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
@@ -54,35 +55,35 @@ int db_do_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
 	}
 
 	if (!_c) {
-		ret = snprintf(sql_buf, SQL_BUF_LEN, "select * from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+		ret = snprintf(sql_buf, sql_buffer_size, "select * from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+		if (ret < 0 || ret >= sql_buffer_size) goto error;
 		off = ret;
 	} else {
-		ret = snprintf(sql_buf, SQL_BUF_LEN, "select ");
-		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+		ret = snprintf(sql_buf, sql_buffer_size, "select ");
+		if (ret < 0 || ret >= sql_buffer_size) goto error;
 		off = ret;
 
-		ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _c, _nc);
+		ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _c, _nc);
 		if (ret < 0) return -1;
 		off += ret;
 
-		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		ret = snprintf(sql_buf + off, sql_buffer_size - off, "from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+		if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 		off += ret;
 	}
 	if (_n) {
-		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "where ");
-		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		ret = snprintf(sql_buf + off, sql_buffer_size - off, "where ");
+		if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 		off += ret;
 
 		ret = db_print_where(_h, sql_buf + off,
-				SQL_BUF_LEN - off, _k, _op, _v, _n, val2str);
+				sql_buffer_size - off, _k, _op, _v, _n, val2str);
 		if (ret < 0) return -1;;
 		off += ret;
 	}
 	if (_o) {
-		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " order by %.*s", _o->len, _o->s);
-		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		ret = snprintf(sql_buf + off, sql_buffer_size - off, " order by %.*s", _o->len, _o->s);
+		if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 		off += ret;
 	}
 	/*
@@ -90,9 +91,9 @@ int db_do_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
 	 * don't support a length parameter, so they need this for the correct
 	 * function of strlen. This zero is not included in the 'str' length.
 	 * We need to check the length here, otherwise we could overwrite the buffer
-	 * boundaries if off is equal to SQL_BUF_LEN.
+	 * boundaries if off is equal to sql_buffer_size.
 	 */
-	if (off + 1 >= SQL_BUF_LEN) goto error;
+	if (off + 1 >= sql_buffer_size) goto error;
 	sql_buf[off + 1] = '\0';
 	sql_str.s = sql_buf;
 	sql_str.len = off;
@@ -153,23 +154,23 @@ int db_do_insert(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
 		return -1;
 	}
 
-	ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	ret = snprintf(sql_buf, sql_buffer_size, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+	if (ret < 0 || ret >= sql_buffer_size) goto error;
 	off = ret;
 
-	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
+	ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _k, _n);
 	if (ret < 0) return -1;
 	off += ret;
 
-	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
-	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	ret = snprintf(sql_buf + off, sql_buffer_size - off, ") values (");
+	if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 	off += ret;
 
-	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n, val2str);
+	ret = db_print_values(_h, sql_buf + off, sql_buffer_size - off, _v, _n, val2str);
 	if (ret < 0) return -1;
 	off += ret;
 
-	if (off + 2 > SQL_BUF_LEN) goto error;
+	if (off + 2 > sql_buffer_size) goto error;
 	sql_buf[off++] = ')';
 	sql_buf[off] = '\0';
 	sql_str.s = sql_buf;
@@ -199,21 +200,21 @@ int db_do_delete(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
 		return -1;
 	}
 
-	ret = snprintf(sql_buf, SQL_BUF_LEN, "delete from %.*s", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	ret = snprintf(sql_buf, sql_buffer_size, "delete from %.*s", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+	if (ret < 0 || ret >= sql_buffer_size) goto error;
 	off = ret;
 
 	if (_n) {
-		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
-		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		ret = snprintf(sql_buf + off, sql_buffer_size - off, " where ");
+		if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 		off += ret;
 
 		ret = db_print_where(_h, sql_buf + off,
-				SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
+				sql_buffer_size - off, _k, _o, _v, _n, val2str);
 		if (ret < 0) return -1;
 		off += ret;
 	}
-	if (off + 1 > SQL_BUF_LEN) goto error;
+	if (off + 1 > sql_buffer_size) goto error;
 	sql_buf[off] = '\0';
 	sql_str.s = sql_buf;
 	sql_str.len = off;
@@ -242,24 +243,24 @@ int db_do_update(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
 		return -1;
 	}
 
-	ret = snprintf(sql_buf, SQL_BUF_LEN, "update %.*s set ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	ret = snprintf(sql_buf, sql_buffer_size, "update %.*s set ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+	if (ret < 0 || ret >= sql_buffer_size) goto error;
 	off = ret;
 
-	ret = db_print_set(_h, sql_buf + off, SQL_BUF_LEN - off, _uk, _uv, _un, val2str);
+	ret = db_print_set(_h, sql_buf + off, sql_buffer_size - off, _uk, _uv, _un, val2str);
 	if (ret < 0) return -1;
 	off += ret;
 
 	if (_n) {
-		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
-		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		ret = snprintf(sql_buf + off, sql_buffer_size - off, " where ");
+		if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 		off += ret;
 
-		ret = db_print_where(_h, sql_buf + off, SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
+		ret = db_print_where(_h, sql_buf + off, sql_buffer_size - off, _k, _o, _v, _n, val2str);
 		if (ret < 0) return -1;
 		off += ret;
 	}
-	if (off + 1 > SQL_BUF_LEN) goto error;
+	if (off + 1 > sql_buffer_size) goto error;
 	sql_buf[off] = '\0';
 	sql_str.s = sql_buf;
 	sql_str.len = off;
@@ -287,24 +288,24 @@ int db_do_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
 		return -1;
 	}
 
-	ret = snprintf(sql_buf, SQL_BUF_LEN, "replace %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	ret = snprintf(sql_buf, sql_buffer_size, "replace %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+	if (ret < 0 || ret >= sql_buffer_size) goto error;
 	off = ret;
 
-	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
+	ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _k, _n);
 	if (ret < 0) return -1;
 	off += ret;
 
-	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
-	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	ret = snprintf(sql_buf + off, sql_buffer_size - off, ") values (");
+	if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 	off += ret;
 
-	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n,
+	ret = db_print_values(_h, sql_buf + off, sql_buffer_size - off, _v, _n,
 	val2str);
 	if (ret < 0) return -1;
 	off += ret;
 
-	if (off + 2 > SQL_BUF_LEN) goto error;
+	if (off + 2 > sql_buffer_size) goto error;
 	sql_buf[off++] = ')';
 	sql_buf[off] = '\0';
 	sql_str.s = sql_buf;
@@ -320,3 +321,20 @@ int db_do_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
 	LM_ERR("error while preparing replace operation\n");
 	return -1;
 }
+
+int db_query_init(void)
+{
+    if (sql_buf != NULL)
+    {
+        LM_DBG("sql_buf not NULL on init\n");
+        return 0;
+    }
+    LM_DBG("About to allocate sql_buf size = %d\n", sql_buffer_size);
+    sql_buf = (char*)malloc(sql_buffer_size);
+    if (sql_buf == NULL)
+    {
+        LM_ERR("failed to allocate sql_buf\n");
+        return -1;
+    }
+    return 0;
+}

+ 9 - 0
lib/srdb1/db_query.h

@@ -184,4 +184,13 @@ int db_do_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
 	int*), int (*submit_query)(const db1_con_t* _h, const str* _c));
 
 
+/**
+ * \brief Initialisation function - should be called from db.c at start-up
+ *
+ * This initialises the db_query module, and should be called before any functions in db_query are called.
+ *
+ * \return zero on success, negative on errors
+ */
+int db_query_init(void);
+    
 #endif

+ 0 - 5
lib/srdb1/db_ut.h

@@ -33,11 +33,6 @@
 #ifndef DB1_UT_H
 #define DB1_UT_H
 
-/**
- * maximal SQL buffer length for database drivers
- */
-#define SQL_BUF_LEN 65536
-
 /**
  * make strptime available
  * use 600 for 'Single UNIX Specification, Version 3'

+ 2 - 0
main.c

@@ -311,6 +311,8 @@ unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
 												  not want to exceed during the
 												  auto-probing procedure; may
 												  be re-configured */
+unsigned int sql_buffer_size = 65535; /* Size for the SQL buffer. Defaults to 64k. 
+                                         This may be re-configured */
 int children_no = 0;			/* number of children processing requests */
 #ifdef USE_TCP
 int tcp_children_no = 0;

+ 2 - 1
modules/db_berkeley/km_db_berkeley.c

@@ -46,6 +46,7 @@
 #include "../../sr_module.h"
 #include "../../lib/srdb1/db_res.h"
 #include "../../lib/srdb1/db.h"
+#include "../../lib/srdb1/db_query.h"
 #include "km_db_berkeley.h"
 #include "km_bdb_lib.h"
 #include "km_bdb_res.h"
@@ -128,7 +129,7 @@ int km_mod_init(void)
 	if(km_bdblib_init(&p))
 		return -1;
 
-	return 0;
+	return db_query_init();
 }
 
 void km_destroy(void)

+ 1 - 1
modules/db_mysql/km_db_mysql.c

@@ -90,7 +90,7 @@ struct kam_module_exports kam_exports = {
 int kam_mysql_mod_init(void)
 {
 	LM_DBG("MySQL client version is %s\n", mysql_get_client_info());
-	return 0;
+	return db_mysql_alloc_buffer();
 }
 
 int db_mysql_bind_api(db_func_t *dbb)

+ 32 - 10
modules/db_mysql/km_dbase.c

@@ -50,6 +50,8 @@
 #include "km_db_mysql.h"
 #include "km_dbase.h"
 
+static char *sql_buf;
+
 
 /**
  * \brief Send a SQL query to the server.
@@ -490,35 +492,34 @@ int db_last_inserted_id(const db1_con_t* _h)
  {
 	int off, ret;
 	static str  sql_str;
-	static char sql_buf[SQL_BUF_LEN];
  
 	if ((!_h) || (!_k) || (!_v) || (!_n)) {
 		LM_ERR("invalid parameter value\n");
 		return -1;
 	}
  
-	ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
-	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	ret = snprintf(sql_buf, sql_buffer_size, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+	if (ret < 0 || ret >= sql_buffer_size) goto error;
 	off = ret;
 
-	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
+	ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _k, _n);
 	if (ret < 0) return -1;
 	off += ret;
 
-	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
-	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	ret = snprintf(sql_buf + off, sql_buffer_size - off, ") values (");
+	if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 	off += ret;
-	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n, db_mysql_val2str);
+	ret = db_print_values(_h, sql_buf + off, sql_buffer_size - off, _v, _n, db_mysql_val2str);
 	if (ret < 0) return -1;
 	off += ret;
 
 	*(sql_buf + off++) = ')';
 	
-	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " on duplicate key update ");
-	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	ret = snprintf(sql_buf + off, sql_buffer_size - off, " on duplicate key update ");
+	if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
 	off += ret;
 	
-	ret = db_print_set(_h, sql_buf + off, SQL_BUF_LEN - off, _k, _v, _n, db_mysql_val2str);
+	ret = db_print_set(_h, sql_buf + off, sql_buffer_size - off, _k, _v, _n, db_mysql_val2str);
 	if (ret < 0) return -1;
 	off += ret;
 	
@@ -547,3 +548,24 @@ int db_mysql_use_table(db1_con_t* _h, const str* _t)
 {
 	return db_use_table(_h, _t);
 }
+
+
+/**
+ * Allocate a buffer for database module
+ * No function should be called before this
+ * \return zero on success, negative value on failure
+ */
+int db_mysql_alloc_buffer(void)
+{
+    if (db_query_init())
+    {
+        LM_ERR("Failed to initialise db_query\n");
+		return -1;
+    }
+
+    sql_buf = (char*)malloc(sql_buffer_size);
+    if (sql_buf == NULL)
+        return -1;
+    else
+        return 0;
+}

+ 2 - 1
modules/db_postgres/km_db_postgres.c

@@ -37,6 +37,7 @@
 #include "../../sr_module.h"
 #include "../../lib/srdb1/db_con.h"
 #include "../../lib/srdb1/db.h"
+#include "../../lib/srdb1/db_query.h"
 #include "km_dbase.h"
 #include "km_db_postgres.h"
 
@@ -72,7 +73,7 @@ struct kam_module_exports kam_exports = {
 
 int km_postgres_mod_init(void)
 {
-	return 0;
+	return db_query_init();
 }
 
 int db_postgres_bind_api(db_func_t *dbb)

+ 2 - 1
modules_k/db_oracle/db_oracle.c

@@ -30,6 +30,7 @@
 #include <oci.h>
 #include "../../sr_module.h"
 #include "../../lib/srdb1/db.h"
+#include "../../lib/srdb1/db_query.h"
 #include "dbase.h"
 #include "asynch.h"
 
@@ -82,7 +83,7 @@ static int oracle_mod_init(void)
 	OCIClientVersion(&major, &minor, &update, &patch, &port);
 	LM_DBG("Oracle client version is %d.%d.%d.%d.%d\n",
 		major, minor, update, patch, port);
-	return 0;
+	return db_query_init();
 }
 
 

+ 1 - 1
modules_k/db_sqlite/db_sqlite.c

@@ -63,7 +63,7 @@ static int sqlite_mod_init(void)
 	LM_INFO("SQlite library version %s (compiled using %s)\n",
 		sqlite3_libversion(),
 		SQLITE_VERSION);
-	return 0;
+	return db_query_init();
 }
 
 

+ 16 - 9
modules_k/db_unixodbc/db_unixodbc.c

@@ -30,6 +30,7 @@
 
 #include "../../sr_module.h"
 #include "../../lib/srdb1/db.h"
+#include "../../lib/srdb1/db_query.h"
 #include "dbase.h"
 #include "db_unixodbc.h"
 
@@ -40,6 +41,7 @@ int use_escape_common = 0;  /* Enable common escaping */
 MODULE_VERSION
 
 int db_unixodbc_bind_api(db_func_t *dbb);
+int unixodbc_mod_init(void);
 
 /*
  * MySQL database module interface
@@ -65,15 +67,15 @@ struct module_exports exports = {
 	"db_unixodbc",
 	DEFAULT_DLFLAGS, /* dlopen flags */
 	cmds,
-	params,     /*  module parameters */
-	0,          /* exported statistics */
-	0,          /* exported MI functions */
-	0,          /* exported pseudo-variables */
-	0,          /* extra processes */
-	0,          /* module initialization function */
-	0,          /* response function*/
-	0,          /* destroy function */
-	0           /* per-child init function */
+	params,             /*  module parameters */
+	0,                  /* exported statistics */
+	0,                  /* exported MI functions */
+	0,                  /* exported pseudo-variables */
+	0,                  /* extra processes */
+	unixodbc_mod_init,  /* module initialization function */
+	0,                  /* response function*/
+	0,                  /* destroy function */
+	0                   /* per-child init function */
 };
 
 int db_unixodbc_bind_api(db_func_t *dbb)
@@ -98,3 +100,8 @@ int db_unixodbc_bind_api(db_func_t *dbb)
 	return 0;
 }
 
+int unixodbc_mod_init(void)
+{
+	return db_query_init();
+}
+