Allocate SQL functions on heap, not end of struct.

Allocating the functions hash_t struct as an extension to the dbsql_db_t struct
was foolish.  Allocate it on the heap, remember to free it when we close the
database.
This commit is contained in:
Gregory Burd 2007-10-21 01:24:20 +01:00
parent 89646d2c84
commit ed5cf2a8d3
3 changed files with 20 additions and 15 deletions

View file

@ -414,7 +414,7 @@ __api_open(dbp, filename, mode, err_msgs)
dbp->nDb = 2; dbp->nDb = 2;
if (__dbsql_calloc(dbp, 2, sizeof(dbsql_db_t), &dbp->aDb) == ENOMEM) if (__dbsql_calloc(dbp, 2, sizeof(dbsql_db_t), &dbp->aDb) == ENOMEM)
goto no_mem_on_open; goto no_mem_on_open1;
if (filename[0] == ':' && strcmp(filename, ":memory:") == 0) if (filename[0] == ':' && strcmp(filename, ":memory:") == 0)
mem = 1; mem = 1;
@ -435,13 +435,15 @@ __api_open(dbp, filename, mode, err_msgs)
dbp->aDb[1].zName = "temp"; dbp->aDb[1].zName = "temp";
/* Attempt to read the schema. */ /* Attempt to read the schema. */
__hash_init((hash_t*)dbp->aFunc, DBSQL_HASH_STRING, 1); if (__dbsql_calloc(dbp, 1, sizeof(hash_t), &dbp->fns) == ENOMEM)
goto no_mem_on_open2;
__hash_init((hash_t*)dbp->fns, DBSQL_HASH_STRING, 1);
__register_builtin_funcs(dbp); __register_builtin_funcs(dbp);
rc = __init_databases(dbp, err_msgs); rc = __init_databases(dbp, err_msgs);
dbp->magic = DBSQL_STATUS_OPEN; dbp->magic = DBSQL_STATUS_OPEN;
if (rc == ENOMEM) { if (rc == ENOMEM) {
dbp->close(dbp); dbp->close(dbp);
goto no_mem_on_open; goto no_mem_on_open2;
} else if (rc != DBSQL_SUCCESS && rc != DBSQL_BUSY) { } else if (rc != DBSQL_SUCCESS && rc != DBSQL_BUSY) {
dbp->close(dbp); dbp->close(dbp);
__str_urealloc(err_msgs); __str_urealloc(err_msgs);
@ -454,7 +456,9 @@ __api_open(dbp, filename, mode, err_msgs)
/* Return a pointer to the newly opened database structure */ /* Return a pointer to the newly opened database structure */
return DBSQL_SUCCESS; return DBSQL_SUCCESS;
no_mem_on_open: no_mem_on_open2:
__dbsql_free(NULL, dbp);
no_mem_on_open1:
__str_append(err_msgs, "out of memory", (char*)0); __str_append(err_msgs, "out of memory", (char*)0);
__str_urealloc(err_msgs); __str_urealloc(err_msgs);
return DBSQL_NOMEM; return DBSQL_NOMEM;
@ -531,7 +535,7 @@ __api_close(dbp)
} }
__reset_internal_schema(dbp, 0); __reset_internal_schema(dbp, 0);
DBSQL_ASSERT(dbp->nDb <= 2); DBSQL_ASSERT(dbp->nDb <= 2);
for (i = __hash_first((hash_t*)dbp->aFunc); i; i = __hash_next(i)){ for (i = __hash_first((hash_t*)dbp->fns); i; i = __hash_next(i)){
func_def_t *func, *next; func_def_t *func, *next;
for (func = (func_def_t*)__hash_data(i); func; func = next){ for (func = (func_def_t*)__hash_data(i); func; func = next){
next = func->pNext; next = func->pNext;
@ -541,8 +545,9 @@ __api_close(dbp)
if (dbp->dbsql_errpfx) if (dbp->dbsql_errpfx)
__dbsql_free(dbp, dbp->dbsql_errpfx); __dbsql_free(dbp, dbp->dbsql_errpfx);
__dbsql_free(dbp, dbp->aDb); __dbsql_free(dbp, dbp->aDb);
__hash_clear((hash_t*)dbp->aFunc); __hash_clear((hash_t*)dbp->fns);
__dbsql_free(dbp, dbp); __dbsql_free(dbp, dbp->fns);
__dbsql_free(NULL, dbp);
return DBSQL_SUCCESS; return DBSQL_SUCCESS;
} }
@ -1161,7 +1166,7 @@ __api_func_return_type(dbp, name, data_type)
const char *name; const char *name;
int data_type; int data_type;
{ {
func_def_t *p = (func_def_t*)__hash_find((hash_t*)dbp->aFunc, name, func_def_t *p = (func_def_t*)__hash_find((hash_t*)dbp->fns, name,
strlen(name)); strlen(name));
while(p) { while(p) {
p->dataType = data_type; p->dataType = data_type;
@ -1438,12 +1443,9 @@ dbsql_create(dbpp, dbenv, flags)
DBSQL_GLOBAL(encoding) = "iso8859"; DBSQL_GLOBAL(encoding) = "iso8859";
#endif #endif
if (__dbsql_calloc(NULL, 1, sizeof(DBSQL) + sizeof(hash_t), &dbp) if (__dbsql_calloc(NULL, 1, sizeof(DBSQL), &dbp) == ENOMEM)
== ENOMEM)
return DBSQL_NOMEM; return DBSQL_NOMEM;
dbp->aFunc = dbp + sizeof(DBSQL);
if (LF_ISSET(DBSQL_THREAD)) if (LF_ISSET(DBSQL_THREAD))
F_SET(dbp, DBSQL_Threaded); F_SET(dbp, DBSQL_Threaded);
if (LF_ISSET(DBSQL_DURABLE_TEMP)) if (LF_ISSET(DBSQL_DURABLE_TEMP))

View file

@ -1949,7 +1949,10 @@ __find_function(dbp, name, len, nargs, create)
int create; int create;
{ {
func_def_t *first, *p, *maybe; func_def_t *first, *p, *maybe;
first = p = (func_def_t *)__hash_find((hash_t*)dbp->aFunc, name, len);
DBSQL_ASSERT(dbp->fns != 0);
p = (func_def_t *)__hash_find((hash_t*)dbp->fns, name, len);
first = p;
if (p && !create && nargs < 0) { if (p && !create && nargs < 0) {
while (p && p->xFunc==0 && p->xStep == 0) { while (p && p->xFunc==0 && p->xStep == 0) {
p = p->pNext; p = p->pNext;
@ -1974,7 +1977,7 @@ __find_function(dbp, name, len, nargs, create)
p->nArg = nargs; p->nArg = nargs;
p->pNext = first; p->pNext = first;
p->dataType = first ? first->dataType : DBSQL_NUMERIC; p->dataType = first ? first->dataType : DBSQL_NUMERIC;
__hash_insert((hash_t*)dbp->aFunc, name, len, (void*)p); __hash_insert((hash_t*)dbp->fns, name, len, (void*)p);
} }
return p; return p;
} }

View file

@ -353,7 +353,7 @@ struct __dbsql {
int (*xBusyCallback)(DBSQL *, void *, const char*, int); int (*xBusyCallback)(DBSQL *, void *, const char*, int);
void *pCommitArg; /* Argument to xCommitCallback() */ void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*);/* Invoked at every commit. */ int (*xCommitCallback)(void*);/* Invoked at every commit. */
void *aFunc; /* All functions that can be in SQL exprs */ void *fns; /* All functions that can be in SQL exprs */
int lastRowid; /* ROWID of most recent insert */ int lastRowid; /* ROWID of most recent insert */
int priorNewRowid; /* Last generated ROWID */ int priorNewRowid; /* Last generated ROWID */
int onError; /* Default conflict algorithm */ int onError; /* Default conflict algorithm */