numerous fixes

This commit is contained in:
Gregory Burd 2023-10-21 13:06:35 -04:00
parent 8f5855b6b6
commit bdd732cef7
23 changed files with 305 additions and 158 deletions

2
.gitignore vendored
View file

@ -8,4 +8,4 @@ dist/config.hin
dist/configure
src/py/setup.py
test/scr050/Makefile
result-bin

2
README
View file

@ -1,4 +1,4 @@
DBSQL 0.3.1: (October 19, 2023)
DBSQL 0.3.1: (October 21, 2023)
This is version 0.3.1 of DBSQL.

17
dist/Makefile.in vendored
View file

@ -125,8 +125,8 @@ C_FILES=\
$(srcdir)/os/os_jtime.c $(srcdir)/clib/memcmp.c \
$(srcdir)/clib/strcasecmp.c $(srcdir)/os/dbsql_alloc.c \
$(srcdir)/common/str.c $(srcdir)/common/dbsql_atoi.c \
$(srcdir)/common/dbsql_atof.c $(srcdir)/safety.c \
$(srcdir)/clib/strdup.c
$(srcdir)/common/dbsql_atof.c $(srcdir)/common/dbsql_fop.c \
$(srcdir)/safety.c $(srcdir)/clib/strdup.c
##################################################
# Object and utility lists.
@ -137,9 +137,10 @@ C_OBJS= cg_attach@o@ cg_insert@o@ sql_tokenize@o@ cg_auth@o@ \
cg_pragma@o@ cg_where@o@ cg_trigger@o@ cg_build@o@ \
sql_fns@o@ random@o@ cg_update@o@ cg_delete@o@ hash@o@ \
cg_expr@o@ opcodes@o@ sql_parser@o@ cg_vacuum@o@ \
vdbe@o@ vdbe_method@o@ sm@o@ snprintf@o@ dbsql_err@o@ cg_select@o@ \
os_jtime@o@ memcmp@o@ dbsql_atof@o@ safety@o@ dbsql_atoi@o@ \
strcasecmp@o@ strdup@o@ dbsql_alloc@o@ str@o@
vdbe@o@ vdbe_method@o@ sm@o@ snprintf@o@ dbsql_err@o@ \
dbsql_fop@o@ cg_select@o@ os_jtime@o@ memcmp@o@ \
dbsql_atof@o@ safety@o@ dbsql_atoi@o@ strcasecmp@o@ \
strdup@o@ dbsql_alloc@o@ str@o@
LEMON_OBJS=\
lemon@o@
@ -187,12 +188,12 @@ $(libdbsql): $(DEF_LIB)
$(ln) -s $(libdbsql_version) $@)
# Real static C library.
$(libdbsql_version): dbsql_int.h sql_parser.h opcodes.h $(C_OBJS)
$(libdbsql_version): dbsql_int.h db_int.h sql_parser.h opcodes.h $(C_OBJS)
$(ar) cr $@ $(C_OBJS)
test ! -f $(ranlib) || $(ranlib) $@
# Shared C library.
$(libso_target): dbsql_int.h sql_parser.h opcodes.h $(C_OBJS)
$(libso_target): dbsql_int.h db_int.h sql_parser.h opcodes.h $(C_OBJS)
$(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(LIBSO_LIBS)
##################################################
@ -396,6 +397,8 @@ dbsql_atoi@o@: $(srcdir)/common/dbsql_atoi.c
$(CC) $(CFLAGS) $?
dbsql_err@o@: $(srcdir)/common/dbsql_err.c
$(CC) $(CFLAGS) $?
dbsql_fop@o@: $(srcdir)/common/dbsql_fop.c
$(CC) $(CFLAGS) $?
str@o@: $(srcdir)/common/str.c
$(CC) $(CFLAGS) $?
hash@o@: $(srcdir)/common/hash.c

20
dist/sqlconf vendored
View file

@ -28,10 +28,19 @@ args="--enable-test $args"
args="--enable-tcl $args"
#args="--enable-sqlite-compat $args"
args="--enable-soundex-sqlfn $args"
args="--with-tcl=/nix/store/aqlscqccxp85w5zxrcmim7qf1i88xyli-tcl-8.5.19/lib $args"
args="--with-berkeleydb=/nix/store/mlhib3c2ra8bj36vhxmwqhyxph8a8sgf-db-4.8.30 $args"
#args="--with-tcl=/usr/lib/tcl-8.5.19/lib $args"
#args="--with-berkeleydb=/usr/local/db-4.8.30 $args"
#args="--with-db-uniquename=FOO $args"
#args="LD_TWOLEVEL_NAMESPACE=1 LIBTSO_LIBS=-ltcl8.4 $args" # Mac OS/X
# Mac OS/X enable:
#args="LD_TWOLEVEL_NAMESPACE=1 LIBTSO_LIBS=-ltcl8.4 $args"
# On NixOS enable:
CFLAGS=${NIX_CFLAGS_COMPILE}
LDLAGS=${NIX_LDFLAGS}
#args="--with-berkeleydb=$(pkg-config --variable=prefix db) $args"
args="--with-berkeleydb=/nix/store/mlhib3c2ra8bj36vhxmwqhyxph8a8sgf-db-4.8.30 $args"
args="--with-tcl=$(pkg-config --variable=libdir tcl) $args"
echo "env $cppflags $ldflags $libs ../dist/configure $args"
env $cppflags $ldflags $libs sh ../dist/configure -C $args
@ -57,3 +66,8 @@ rm -f tags
ln -s ../dist/tags tags
mkdir -p .libs && true
exit 0
nix-build -E 'with import <nixpkgs> {}; enableDebugging db4'
gdb -ix .gdbinit --tui build_unix/.libs/dbsql
r --init ../tests/smoke.sql /tmp/dbsql

View file

@ -49,6 +49,12 @@
configureFlags = [
"--host ${system}"
];
buildInputs = [
(enableDebuging db4)
glibc.out
glibc.static
tcl-8_5
];
nativeBuildInputs = [ autoreconfHook ];
meta = {
changelog = "https://git.burd.me/greg/dbsql/raw/branch/main/ChangeLog";

View file

@ -1,25 +1,26 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# nativeBuildInputs is usually what you want -- tools you need to run
nativeBuildInputs = with pkgs.buildPackages; [
act
autoconf
db4
ed
gcc
gdb
gettext
libtool
m4
pkg-config
perl
ripgrep
tcl-8_5
];
buildInputs = with pkgs; [
# (enableDebuging db4)
db4
glibc.out
glibc.static
tcl-8_5
];
DOCKER_BUILDKIT = 1;

View file

@ -1360,20 +1360,21 @@ dbsql_create_env(dbpp, dir, crypt, mode, flags)
return DBSQL_CANTOPEN;
}
} else {
if (__os_exists(dbenv, dir, &dir_p) == 0) {
if (__dbsql_exists(NULL, dir, &dir_p) == 0) {
if (dir_p) {
char buf[1024];
snprintf(buf, 1024, "%s%s%s", dir,
PATH_SEPARATOR, dir);
if (__os_exists(dbenv, buf, &dir_p) == 0)
if (__dbsql_exists(NULL, buf, &dir_p) == 0)
env_open_flags = DB_JOINENV;
} else {
__dbsql_err(NULL,
"Environment must be a directory.");
return DBSQL_INVALID_NAME;
}
} else { /* TODO __db_omode("rwxrwxrwx"):mode) != 0) */
if (mkdir(dir, mode == 0 ? 0777 : mode) != 0)
} else {
mode = mode == 0 ? __dbsql_omode(NULL, "rwxrwxrwx") : mode;
if (__dbsql_mkdir(NULL, dir, mode) != 0)
return errno;
}
}

View file

@ -1045,7 +1045,8 @@ __add_collate_type(parser, type)
*
* PUBLIC: void __change_schema_signature __P((DBSQL *, vdbe_t *));
*/
void __change_schema_signature(dbp, v)
void
__change_schema_signature(dbp, v)
DBSQL *dbp;
vdbe_t *v;
{
@ -1929,7 +1930,7 @@ __defer_foreign_key(parser, deferred)
}
/*
* __creat_index --
* __create_index --
* Create a new index for an SQL table. 'index' is the name of the
* index and pTable is the name of the table that is to be indexed.
* Both will be NULL for a primary key or an index that is created
@ -1954,7 +1955,8 @@ __defer_foreign_key(parser, deferred)
* statement.
* end The ")" that closes the CREATE INDEX statement.
*/
void __create_index(parser, token, sltable, list, on_error, start, end)
void
__create_index(parser, token, sltable, list, on_error, start, end)
parser_t *parser;
token_t *token;
src_list_t *sltable;
@ -2281,7 +2283,7 @@ exit_create_index:
* This routine will drop an existing named index. This routine
* implements the DROP INDEX statement.
*
* PUBILC: __drop_index __P((parser_t *, src_list_t *));
* PUBLIC: void __drop_index __P((parser_t *, src_list_t *));
*/
void
__drop_index(parser, name)
@ -2494,7 +2496,7 @@ __src_list_append(list, table, database)
* __src_list_assign_cursors --
* Assign cursors to all tables in a src_list_t.
*
* __src_list_assign_cursors __P((parser_t *, src_list_t *));
* PUBLIC: void __src_list_assign_cursors __P((parser_t *, src_list_t *));
*/
void
__src_list_assign_cursors(parser, list)

View file

@ -869,7 +869,7 @@ __code_trigger_program(parser, steplist, orconfin)
* pointing at a row containing values to be substituted for old.*
* expressions in the trigger program(s).
*
* PUBlIC: int __code_row_trigger __P(());
* PUBLIC: int __code_row_trigger __P(());
*
* parser Parser context
* op One of TK_UPDATE, TK_INSERT, TK_DELETE

View file

@ -18,8 +18,12 @@
* General Public License for more details.
*/
#include "dbsql.h"
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "db_int.h"
#include <string.h>
/*
* __dbsql_umalloc --

View file

@ -21,6 +21,8 @@
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
/*
* __dbsql_atof --
* The string z[] is an ascii representation of a real number.

View file

@ -21,6 +21,8 @@
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
/*
* __dbsql_atoi --
* Return TRUE if 'str' is a 32-bit signed integer and write

View file

@ -280,8 +280,8 @@ __dbsql_errcall(dbp, error, error_set, fmt, ap)
* are pretty rare anymore.
*/
if ((size_t)(p - errbuf) > sizeof(errbuf)) {
write(
STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1);
IGNORE_RESULT(write(
STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1));
abort();
/* NOTREACHED */
}

101
src/common/dbsql_fop.c Normal file
View file

@ -0,0 +1,101 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "db_int.h"
#include <sys/stat.h>
/*
* __dbsql_exists --
* Returns if file exists using the __os_exists call of DB.
*
* PUBLIC: int __dbsql_exists __P((DBSQL *, const char *, int *));
*/
int
__dbsql_exists(dbp, path, isdirp)
DBSQL *dbp;
const char *path;
int *isdirp;
{
return (__os_exists((dbp ? dbp->dbenv : NULL), path, isdirp));
}
/*
* __dbsql_mkdir --
* Create a directory using the __os_mkdir call of DB.
*
* PUBLIC: int __dbsql_mkdir __P((DBSQL *, const char *, int));
*/
int
__dbsql_mkdir(dbp, path, mode)
DBSQL *dbp;
const char *path;
int mode;
{
return (__os_mkdir((dbp ? dbp->dbenv : NULL), path, mode));
}
/*
* __dbsql_omode --
* Convert a file mode from a string to an int.
*
* PUBLIC: int __dbsql_omode __P((DBSQL *, const char *));
*/
int
__dbsql_omode(dbp, mode)
DBSQL *dbp;
const char *mode;
{
u_int t;
int ret;
#define __SETMODE(offset, valid_ch, mask) { \
if (mode[offset] == (valid_ch)) \
t |= (mask); \
else if (mode[offset] != '-') \
goto format_err; \
}
t = 0;
__SETMODE(0, 'r', S_IRUSR);
__SETMODE(1, 'w', S_IWUSR);
__SETMODE(2, 'x', S_IXUSR);
__SETMODE(3, 'r', S_IRGRP);
__SETMODE(4, 'w', S_IWGRP);
__SETMODE(5, 'x', S_IXGRP);
__SETMODE(6, 'r', S_IROTH);
__SETMODE(7, 'w', S_IWOTH);
__SETMODE(8, 'x', S_IXOTH);
if (mode[9] != '\0' || t == 0) {
/*
* We disallow modes of 0 -- we use 0 to decide the application
* never configured intermediate directory permissions, and we
* shouldn't create intermediate directories. Besides, setting
* the permissions to 0 makes no sense.
*/
format_err: __dbsql_err(dbp, "illegal mode \"%s\"", mode);
return (EINVAL);
}
return t;
}

View file

@ -95,6 +95,9 @@
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
unsigned char __str_upper_to_lower[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
@ -273,7 +276,7 @@ __str_urealloc(pz)
char *new;
if (pz == 0 || *pz == NULL)
return;
return rc;
if (__dbsql_umalloc(NULL, strlen(*pz) + 1, &new) == ENOMEM) {
rc = ENOMEM;

View file

@ -30,6 +30,7 @@
#include <ctype.h>
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "dbsql.h"
#if !defined(_WIN32) && !defined(WIN32)
@ -222,11 +223,6 @@ char *modeDescr[MODE_NUM_OF] = {
"insert"
};
/*
* Number of elements in an array
*/
#define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
/*
* Output the given string as a quoted string using SQL quoting conventions.
*/

View file

@ -23,7 +23,6 @@
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "tcl.h"

View file

@ -26,6 +26,9 @@ void __dbsql_err __P((const DBSQL *, const char *, ...)) __attribute__ ((__forma
void __dbsql_errcall __P((const DBSQL *, int, int, const char *, va_list));
void __dbsql_errfile __P((const DBSQL *, int, int, const char *, va_list));
void __error_msg __P((parser_t *, const char *, ...));
int __dbsql_exists __P((DBSQL *, const char *, int *));
int __dbsql_mkdir __P((DBSQL *, const char *, int));
int __dbsql_omode __P((DBSQL *, const char *));
void __hash_init __P((hash_t *, int, int));
void __hash_clear __P((hash_t *));
void *__hash_find __P((const hash_t *, const void *, int));

View file

@ -32,21 +32,22 @@
extern "C" {
#endif
extern void *__ua_memcpy__DB_UNIQUE_NAME__ __P((void *, const void *, size_t));
extern int __db_omode__DB_UNIQUE_NAME__ __P((const char *));
extern int __os_calloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, size_t, void *));
extern int __os_exists__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, int *));
extern int __os_get_errno__DB_UNIQUE_NAME__ __P((void));
extern int __os_id__DB_UNIQUE_NAME__ __P((DB_ENV *, pid_t *, db_threadid_t*));
extern int __os_malloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_mkdir__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, int));
extern int __os_realloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_strdup__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, void *));
extern int __os_umalloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_urealloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern void *__ua_memcpy__DB_UNIQUE_NAME__ __P((void *, const void *, size_t));
extern void __os_free__DB_UNIQUE_NAME__ __P((DB_ENV *, void *));
extern void __os_set_errno__DB_UNIQUE_NAME__ __P((int));
extern void __os_sleep__DB_UNIQUE_NAME__ __P((DB_ENV *, u_long, u_long));
extern void __os_free__DB_UNIQUE_NAME__ __P((DB_ENV *, void *));
extern int __os_realloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_malloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_calloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, size_t, void *));
extern int __os_strdup__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, void *));
extern void __os_ufree__DB_UNIQUE_NAME__ __P((DB_ENV *, void *));
extern int __os_urealloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_umalloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_exists__DB_UNIQUE_NAME__ __P((const char *, int *));
extern int __db_omode__DB_UNIQUE_NAME__ __P((const char *));
extern int __os_id__DB_UNIQUE_NAME__ __P((DB_ENV *, pid_t *, db_threadid_t*));
#if defined(__cplusplus)
}

View file

@ -54,8 +54,10 @@ void __add_idx_key_type __P((vdbe_t *, index_t *));
void __create_foreign_key __P((parser_t *, id_list_t *, token_t *, id_list_t *, int));
void __defer_foreign_key __P((parser_t *, int));
void __create_index __P((parser_t *, token_t *, src_list_t *, id_list_t *, int, token_t *, token_t *));
void __drop_index __P((parser_t *, src_list_t *));
id_list_t *__id_list_append __P((id_list_t *, token_t *));
src_list_t *__src_list_append __P((src_list_t *, token_t *, token_t *));
void __src_list_assign_cursors __P((parser_t *, src_list_t *));
void __src_list_add_alias __P((src_list_t *, token_t *));
void __id_list_delete __P((id_list_t *));
int __id_list_index __P((id_list_t *, const char *));
@ -119,6 +121,7 @@ void __vdbe_delete_trigger __P((trigger_t *));
void __drop_trigger __P((parser_t *, src_list_t *));
void __drop_trigger_ptr __P((parser_t *, trigger_t *, int));
int __triggers_exist __P((parser_t *, trigger_t *, int, int, int, expr_list_t *));
int __code_row_trigger __P(());
void __update __P((parser_t *, src_list_t *, expr_list_t *, expr_t *, int));
void __vacuum __P((parser_t *, token_t *));
int __execute_vacuum __P((char **, DBSQL *));
@ -160,7 +163,7 @@ int __sm_get_format_version __P((sm_t *, u_int32_t *));
int __sm_set_schema_sig __P((sm_t *, u_int32_t));
int __sm_get_schema_sig __P((sm_t *, u_int32_t *));
void __register_builtin_funcs __P((DBSQL *));
int get_keyword_code __P((const char *, int));
int __get_keyword_code __P((const char *, int));
int __run_sql_parser __P((parser_t *, const char *, char **));
int __api_step __P((dbsql_stmt_t *, int *, const char ***, const char ***));
int __vdbe_exec __P((vdbe_t *));

View file

@ -37,10 +37,16 @@ extern "C" {
#define DBSQL_ASSERT(e)
#endif
/*
* Purposly ignore return value.
*/
#define IGNORE_RESULT(x) \
(void)!(x)
/*
* "Shut that bloody compiler up!"
*
* Unused, or not-used-yet variable. We need to write and then read the
* Unused, or not-usedyet variable. We need to write and then read the
* variable, some compilers are too bloody clever by half.
*/
#define COMPQUIET(n, v) \

View file

@ -167,7 +167,7 @@ static u_int8_t ai_table[KEY_HASH_SIZE];
* keyword. If it is a keyword, the token code of that keyword is
* returned. If the input is not a keyword, TK_ID is returned.
*
* PUBLIC: int get_keyword_code __P((const char *, int));
* PUBLIC: int __get_keyword_code __P((const char *, int));
*/
int
__get_keyword_code(z, n)