sql_printf.c:

- Solucionado bug de "Segmentation fault".
Debian:
	- Añadida dependencia con MariaDB.
This commit is contained in:
Juan Ferrer Toribio 2014-07-30 14:18:03 +02:00
parent d390a0ff15
commit f127871a21
2 changed files with 63 additions and 57 deletions

4
debian/control vendored
View File

@ -8,7 +8,7 @@ Homepage: http://www.verdnatura.es
Package: vn-mysql Package: vn-mysql
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, mysql-server (>= 5.5.27) Depends: ${shlibs:Depends}, ${misc:Depends}, mysql-server (>= 5.5.27) | mariadb-galera-server (>= 5.5.27) | mariadb-server (>= 5.5.27)
Description: Verdnatura MySQL plugins Description: MySQL plugins
This package contains some useful MySQL plugins This package contains some useful MySQL plugins
developed by Verdnatura. developed by Verdnatura.

View File

@ -4,83 +4,93 @@
#include <mysql/mysql.h> #include <mysql/mysql.h>
#define NAME "multimax" #define NAME "multimax"
#define PARAMC 1 #define NPARAMS 1
#define BLOCK_SIZE 1024 #define BLOCK_SIZE 1024
typedef struct typedef struct
{ {
int * org_type; int * org_type;
char * data; char * data;
size_t len; unsigned long len;
size_t allocated; unsigned long alloc;
} }
Buffer; Buffer;
static void buffer_append (Buffer *buffer, char *string, size_t len) static void buffer_append (Buffer *buffer, char *string, unsigned long len)
{ {
if (!string) if (!string)
return; return;
unsigned long new_len = buffer->len + len;
if ((buffer->len + len) > buffer->allocated) if (new_len > buffer->alloc)
{ {
size_t allocate = buffer->allocated + (len > BLOCK_SIZE ? len : BLOCK_SIZE); buffer->alloc = new_len + BLOCK_SIZE - (new_len % BLOCK_SIZE);
buffer->data = realloc (buffer->data, allocate); buffer->data = realloc (buffer->data, sizeof (char) * buffer->alloc);
buffer->allocated = allocate;
} }
strncpy (&buffer->data[buffer->len], string, len); strncpy (&buffer->data[buffer->len], string, len);
buffer->len += len; buffer->len = new_len;
} }
char * sql_printf (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error) char * sql_printf (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
{ {
int n = 1; int i = 1;
size_t len; unsigned long j = 0;
char *arg;
char *aux;
char delimiter;
Buffer *buffer = (Buffer *) initid->ptr; Buffer *buffer = (Buffer *) initid->ptr;
char *string = args->args[0]; char *format = args->args[0];
if (!string) if (!format)
{ {
*is_null = 1; *is_null = 1;
return NULL; return NULL;
} }
buffer->len = 0; while (1)
string[args->lengths[0]] = '\0';
while ((aux = strchr (string, '%')))
{ {
buffer_append (buffer, string, aux - string); char *delimiter = NULL;
string = aux + 1; unsigned long aux = j;
switch (*string) while (j < args->lengths[0] && format[j] != '%')
j++;
buffer_append (buffer, &format[aux], j - aux);
if (j == args->lengths[0])
break;
char c = format[j+1];
j += 2;
switch (c)
{ {
case 'v':
if (buffer->org_type[n] == STRING_RESULT)
delimiter = "'";
else
delimiter = NULL;
break;
case 't': case 't':
delimiter = "`"; delimiter = "`";
break; break;
case 's': case 'v':
delimiter = NULL; if (buffer->org_type[i] == STRING_RESULT)
delimiter = "'";
break; break;
default: case 's':
string--; break;
case '%':
buffer_append (buffer, "%", 1);
continue; continue;
default:
*error = 1;
return NULL;
}
if (i >= args->arg_count)
{
*error = 1;
return NULL;
} }
if (arg) char *arg = args->args[i];
{ unsigned long len = args->lengths[i];
arg = args->args[n];
len = args->lengths[n]; if (!arg)
}
else
{ {
arg = "NULL"; arg = "NULL";
len = strlen (arg); len = strlen (arg);
@ -90,32 +100,28 @@ char * sql_printf (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
buffer_append (buffer, delimiter, 1); buffer_append (buffer, delimiter, 1);
buffer_append (buffer, arg, len); buffer_append (buffer, arg, len);
buffer_append (buffer, delimiter, 1); buffer_append (buffer, delimiter, 1);
i++;
string++;
n++;
} }
buffer_append (buffer, string, strlen (string) + 1); *length = buffer->len;
*length = buffer->len - 1;
return buffer->data; return buffer->data;
} }
my_bool sql_printf_init (UDF_INIT *initid, UDF_ARGS *args, char *message) my_bool sql_printf_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
{ {
int count = args->arg_count; if (args->arg_count >= NPARAMS)
if (count >= PARAMC)
{ {
int n; int i;
Buffer *buffer = malloc (sizeof (Buffer)); Buffer *buffer = malloc (sizeof (Buffer));
buffer->org_type = malloc (sizeof (int) * count); buffer->org_type = malloc (sizeof (int) * args->arg_count);
buffer->data = malloc (sizeof (char) * BLOCK_SIZE); buffer->alloc = BLOCK_SIZE;
buffer->allocated = BLOCK_SIZE; buffer->data = malloc (sizeof (char) * buffer->alloc);
buffer->len = 0;
for (n = 0; n < count; n++) for (i = 0; i < args->arg_count; i++)
{ {
buffer->org_type[n] = args->arg_type[n]; buffer->org_type[i] = args->arg_type[i];
args->arg_type[n] = STRING_RESULT; args->arg_type[i] = STRING_RESULT;
} }
initid->ptr = (void *) buffer; initid->ptr = (void *) buffer;
@ -125,7 +131,7 @@ my_bool sql_printf_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
} }
else else
{ {
sprintf (message, "%s must have at least %d parameters", NAME, PARAMC); sprintf (message, "%s must have at least %d parameters", NAME, NPARAMS);
return 1; return 1;
} }
} }