diff --git a/.gitignore b/.gitignore index c9918cc..4fe4e16 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ dist/config.hin dist/configure src/py/setup.py test/scr050/Makefile - +result-bin diff --git a/README b/README index d6abf69..1dba120 100644 --- a/README +++ b/README @@ -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. diff --git a/dist/Makefile.in b/dist/Makefile.in index 3c70523..0228192 100644 --- a/dist/Makefile.in +++ b/dist/Makefile.in @@ -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 diff --git a/dist/sqlconf b/dist/sqlconf index 2a3a7bb..f51f288 100644 --- a/dist/sqlconf +++ b/dist/sqlconf @@ -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 {}; enableDebugging db4' +gdb -ix .gdbinit --tui build_unix/.libs/dbsql +r --init ../tests/smoke.sql /tmp/dbsql diff --git a/flake.nix b/flake.nix index 96f9089..cec5b0a 100644 --- a/flake.nix +++ b/flake.nix @@ -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"; diff --git a/shell.nix b/shell.nix index edf2961..7e122d8 100644 --- a/shell.nix +++ b/shell.nix @@ -1,25 +1,26 @@ { pkgs ? import {} }: - 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; diff --git a/src/api.c b/src/api.c index b1e168f..1e51572 100644 --- a/src/api.c +++ b/src/api.c @@ -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; } } diff --git a/src/cg_build.c b/src/cg_build.c index a4990ad..69bbacb 100644 --- a/src/cg_build.c +++ b/src/cg_build.c @@ -100,7 +100,7 @@ __null_callback(not_used, n, a, b) /* * __parse_exec -- * This routine is called after a single SQL statement has been - * parsed and we want to execute the VDBE code to implement + * parsed and we want to execute the VDBE code to implement * that statement. Prior action routines should have already * constructed VDBE code to do the work of the SQL statement. * This routine just has to execute the VDBE code. @@ -163,7 +163,7 @@ __parse_exec(parser) /* * __find_table -- - * Locate the in-memory structure that describes + * Locate the in-memory structure that describes * a particular database table given the name * of that table and (optionally) the name of the database * containing the table. Return NULL if not found. @@ -199,7 +199,7 @@ __find_table(dbp, name, database) /* * __locate_table -- - * Locate the in-memory structure that describes + * Locate the in-memory structure that describes * a particular database table given the name * of that table and (optionally) the name of the database * containing the table. Return NULL if not found. @@ -236,7 +236,7 @@ __locate_table(parser, name, database) /* * __find_index -- - * Locate the in-memory structure that describes + * Locate the in-memory structure that describes * a particular index given the name of that index * and the name of the database that contains the index. * Return NULL if not found. @@ -433,7 +433,7 @@ __commit_internal_changes(dbp) * This routine just deletes the data structure. It does not unlink * the table data structure from the hash table. Nor does it remove * foreign keys from the aFKey hash table. But it does destroy - * memory structures of the indices and foreign keys associated with + * memory structures of the indices and foreign keys associated with * the table. * Indices associated with the table are unlinked from the "db" * data structure if db!=NULL. If db==NULL, indices attached to @@ -466,7 +466,7 @@ __vdbe_delete_table(dbp, table) /* * Delete all foreign keys associated with this table. The keys - * should have already been unlinked from the dbp->aFKey hash table + * should have already been unlinked from the dbp->aFKey hash table */ for (fkey = table->pFKey; fkey; fkey = next_fkey) { next_fkey = fkey->pNextFrom; @@ -548,7 +548,7 @@ __table_name_from_token(name) /* * __open_master_table -- * Generate code to open the appropriate master table. The table - * opened will be DBSQL_MASTER for persistent tables and + * opened will be DBSQL_MASTER for persistent tables and * DBSQL_TEMP_MASTER for temporary tables. The table is opened * on cursor 0. * @@ -636,9 +636,9 @@ void __start_table(parser, start, name, temp, view) } } #endif - - /* + + /* * Before trying to create a temporary table, make sure the DB for * holding temporary tables is open. */ @@ -687,7 +687,7 @@ void __start_table(parser, start, name, temp, view) if ((idx = __find_index(dbp, n, 0)) != 0 && (idx->iDb == 0 || !parser->initFlag)) { __str_append(&parser->zErrMsg, - "there is already an index named ", + "there is already an index named ", n, (char*)0); __dbsql_free(dbp, n); parser->nErr++; @@ -813,7 +813,7 @@ __add_not_null(parser, on_error) * in 'type'. * * PUBLIC: void __add_column_type __P((parser_t *, token_t *, token_t *)); - */ + */ void __add_column_type(parser, first, last) parser_t *parser; @@ -884,7 +884,7 @@ __add_default_value(parser, val, minus) /* * __add_primary_key -- * - * Designate the PRIMARY KEY for the table. 'list' is a list of names + * Designate the PRIMARY KEY for the table. 'list' is a list of names * of columns that form the primary key. If 'list' is NULL, then the * most recently added column of the table is the primary key. * A table can have at most one primary key. If the table already has @@ -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; { @@ -1184,7 +1185,7 @@ __gen_create_table_stmt(table) * recently changed, so the entry for this table already exists in * the master table. We do not want to create it again. * If the 'select' argument is not NULL, it means that this routine - * was called to create a table generated from a + * was called to create a table generated from a * "CREATE TABLE ... AS SELECT ..." statement. The column names of * the new table will match the result set of the SELECT. * @@ -1246,7 +1247,7 @@ __ending_create_table_paren(parser, end, select) if (!parser->initFlag) { int n; vdbe_t *v; - + v = __parser_get_vdbe(parser); if (v == 0) return; @@ -1305,8 +1306,8 @@ __ending_create_table_paren(parser, end, select) if (parser->explain == 0 && parser->nErr == 0) { table_t *old; foreign_key_t *fkey; - old = __hash_insert(&dbp->aDb[table->iDb].tblHash, - table->zName, strlen(table->zName) + 1, table); + old = __hash_insert(&dbp->aDb[table->iDb].tblHash, + table->zName, strlen(table->zName) + 1, table); if (old) { /* Malloc must have failed inside __hash_insert() */ DBSQL_ASSERT(table == old); @@ -1450,7 +1451,7 @@ __view_get_column_names(parser, table) /* * If we get this far, it means we need to compute the table names. */ - /* If nCol == 0, then 'table' must be a VIEW */ + /* If nCol == 0, then 'table' must be a VIEW */ DBSQL_ASSERT(table->pSelect); sel = table->pSelect; @@ -1483,7 +1484,7 @@ __view_get_column_names(parser, table) __select_unbind(sel); __expr_list_delete(sel->pEList); sel->pEList = elist; - return nerr; + return nerr; } /* @@ -1627,7 +1628,7 @@ __drop_table(parser, name, view) } #endif if (table->readOnly) { - __str_append(&parser->zErrMsg, "table ", table->zName, + __str_append(&parser->zErrMsg, "table ", table->zName, " may not be dropped", (char*)0); parser->nErr++; return; @@ -1819,7 +1820,7 @@ void __create_foreign_key(parser, from_col, to, to_col, flags) if (to_col && to_col->nId!=1 ){ __str_nappend(&parser->zErrMsg, "foreign key on ", -1, - table->aCol[col].zName, -1, + table->aCol[col].zName, -1, " should reference only one column " "of table ", -1, to->z, to->n, NULL); parser->nErr++; @@ -1827,7 +1828,7 @@ void __create_foreign_key(parser, from_col, to, to_col, flags) } ncol = 1; } else if (to_col && to_col->nId != from_col->nId) { - __str_append(&parser->zErrMsg, + __str_append(&parser->zErrMsg, "number of columns in foreign key does not " "match the number of columns in the referenced " "table", (char*)0); @@ -1870,7 +1871,7 @@ void __create_foreign_key(parser, from_col, to, to_col, flags) } if (j >= table->nCol) { __str_append(&parser->zErrMsg, - "unknown column \"", + "unknown column \"", from_col->a[i].zName, "\" in foreign key definition", (char*)0); @@ -1929,8 +1930,8 @@ __defer_foreign_key(parser, deferred) } /* - * __creat_index -- - * Create a new index for an SQL table. 'index' is the name of the + * __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 * to satisfy a UNIQUE constraint. If pTable and pIndex are NULL, @@ -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; @@ -1969,7 +1971,7 @@ void __create_index(parser, token, sltable, list, on_error, start, end) int i, j; token_t null_id; /* Fake token for an empty ID list */ ref_normalizer_ctx_t normctx; /* For assigning database - names to sltable */ + names to sltable */ int temp; /* True for a temporary index */ DBSQL *dbp = parser->db; @@ -2002,7 +2004,7 @@ void __create_index(parser, token, sltable, list, on_error, start, end) goto exit_create_index; } if (table->iDb >= 2 && parser->initFlag == 0) { - __str_append(&parser->zErrMsg, "table ", table->zName, + __str_append(&parser->zErrMsg, "table ", table->zName, " may not have indices added", (char*)0); parser->nErr++; goto exit_create_index; @@ -2017,7 +2019,7 @@ void __create_index(parser, token, sltable, list, on_error, start, end) /* * Find the name of the index. Make sure there is not already another - * index or table with the same name. + * index or table with the same name. * * Exception: If we are reading the names of permanent indices from * the master table (because some other process changed the schema) and @@ -2034,7 +2036,7 @@ void __create_index(parser, token, sltable, list, on_error, start, end) if (name == 0) goto exit_create_index; if ((idx_same_name = __find_index(dbp, name, 0)) != 0) { - __str_append(&parser->zErrMsg, "index ", name, + __str_append(&parser->zErrMsg, "index ", name, " already exists", (char*)0); parser->nErr++; goto exit_create_index; @@ -2098,8 +2100,8 @@ void __create_index(parser, token, sltable, list, on_error, start, end) goto exit_create_index; } - /* - * Allocate the index structure. + /* + * Allocate the index structure. */ if (__dbsql_calloc(dbp, 1, sizeof(index_t) + (strlen(name) + 1) + (sizeof(int) * list->nId), &index) == ENOMEM) @@ -2136,16 +2138,16 @@ void __create_index(parser, token, sltable, list, on_error, start, end) index->aiColumn[i] = j; } - /* + /* * Link the new index_t structure to its table and to the other - * in-memory database structures. + * in-memory database structures. */ if (!parser->explain) { index_t *rindex; - rindex = __hash_insert(&dbp->aDb[index->iDb].idxHash, - index->zName, strlen(index->zName) + 1, index); + rindex = __hash_insert(&dbp->aDb[index->iDb].idxHash, + index->zName, strlen(index->zName) + 1, index); if (rindex) { - /* Malloc must have failed */ + /* Malloc must have failed */ DBSQL_ASSERT(rindex == index); __dbsql_free(dbp, index); goto exit_create_index; @@ -2186,8 +2188,8 @@ void __create_index(parser, token, sltable, list, on_error, start, end) * involves writing the index into the master table and * filling in the index with the current table contents. * - * The initFlag is 0 when the user first enters a CREATE INDEX - * command. The initFlag is 1 when a database is opened and + * The initFlag is 0 when the user first enters a CREATE INDEX + * command. The initFlag is 1 when a database is opened and * CREATE INDEX statements are read out of the master table. * In the latter case the index already exists on disk, which * is why we don't want to recreate it. @@ -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) @@ -2335,7 +2337,7 @@ __drop_index(parser, name) v = __parser_get_vdbe(parser); if( v ){ static vdbe_op_t drop_index[] = { - { OP_Rewind, 0, ADDR(9), 0}, + { OP_Rewind, 0, ADDR(9), 0}, { OP_String, 0, 0, 0}, /* 1 */ { OP_MemStore, 1, 1, 0}, { OP_MemLoad, 1, 0, 0}, /* 3 */ @@ -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) @@ -2685,7 +2687,7 @@ __dbsql_txn_abort(parser) if ((dbp->flags & DBSQL_InTrans) == 0) { __error_msg(parser, "cannot rollback - no transaction is active"); - return; + return; } v = __parser_get_vdbe(parser); if (v) { @@ -2771,7 +2773,7 @@ __vdbe_prepare_write(parser, checkpoint, idb) * the database. If a statement transaction was started, then emit * an OP_Commit that will cause the changes to be committed to disk. * Note that checkpoints are automatically committed at the end of - * a statement. Note also that there can be multiple calls to + * a statement. Note also that there can be multiple calls to * __vdbe_prepare_write() but there should only be a single * call to __vdbe_conclude_write() at the conclusion of the statement. * @@ -2789,7 +2791,7 @@ __vdbe_conclude_write(parser) if (v == 0) return; if (dbp->flags & DBSQL_InTrans) { - /* + /* * A BEGIN has executed. Do not commit until we see an * explicit COMMIT statement. */ diff --git a/src/cg_trigger.c b/src/cg_trigger.c index c45f505..b29cf28 100644 --- a/src/cg_trigger.c +++ b/src/cg_trigger.c @@ -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 diff --git a/src/common/dbsql_alloc.c b/src/common/dbsql_alloc.c index efcf645..1f36145 100644 --- a/src/common/dbsql_alloc.c +++ b/src/common/dbsql_alloc.c @@ -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 + /* * __dbsql_umalloc -- diff --git a/src/common/dbsql_atof.c b/src/common/dbsql_atof.c index 4049687..0126819 100644 --- a/src/common/dbsql_atof.c +++ b/src/common/dbsql_atof.c @@ -21,6 +21,8 @@ #include "dbsql_config.h" #include "dbsql_int.h" +#include + /* * __dbsql_atof -- * The string z[] is an ascii representation of a real number. diff --git a/src/common/dbsql_atoi.c b/src/common/dbsql_atoi.c index 6a466a1..5568312 100644 --- a/src/common/dbsql_atoi.c +++ b/src/common/dbsql_atoi.c @@ -21,6 +21,8 @@ #include "dbsql_config.h" #include "dbsql_int.h" +#include + /* * __dbsql_atoi -- * Return TRUE if 'str' is a 32-bit signed integer and write diff --git a/src/common/dbsql_err.c b/src/common/dbsql_err.c index d9dd148..b684a13 100644 --- a/src/common/dbsql_err.c +++ b/src/common/dbsql_err.c @@ -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 */ } diff --git a/src/common/dbsql_fop.c b/src/common/dbsql_fop.c new file mode 100644 index 0000000..dc72c21 --- /dev/null +++ b/src/common/dbsql_fop.c @@ -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 + +/* + * __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; +} diff --git a/src/common/str.c b/src/common/str.c index 1badda7..9ad7740 100644 --- a/src/common/str.c +++ b/src/common/str.c @@ -95,6 +95,9 @@ #include "dbsql_config.h" #include "dbsql_int.h" +#include + + 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, @@ -164,9 +167,9 @@ __str_append(result, fmt, va_alist) /* * __str_nappend -- * Works like __str_append, but each string is now followed by - * a length integer which specifies how much of the source string - * to copy (in bytes). -1 means use the whole string. The 1st - * argument must either be NULL or point to memory obtained from + * a length integer which specifies how much of the source string + * to copy (in bytes). -1 means use the whole string. The 1st + * argument must either be NULL or point to memory obtained from * __dbsql_calloc(). * * PUBLIC: void __str_nappend __P((char **, ...)); @@ -273,8 +276,8 @@ __str_urealloc(pz) char *new; if (pz == 0 || *pz == NULL) - return; - + return rc; + if (__dbsql_umalloc(NULL, strlen(*pz) + 1, &new) == ENOMEM) { rc = ENOMEM; __dbsql_free(NULL, *pz); @@ -394,7 +397,7 @@ static int __utf8_to_int(const unsigned char *z) { * '?' Matches exactly one character. * * [...] Matches one character from the enclosed list of - * characters. + * characters. * * [^...] Matches one character not in the enclosed list. * @@ -408,12 +411,12 @@ static int __utf8_to_int(const unsigned char *z) { * * Hints: to match '*' or '?', put them in "[]". Like this: * - * abc[*]xyz Matches "abc*xyz" only + * abc[*]xyz Matches "abc*xyz" only * * PUBLIC: int __str_glob_cmp __P((const unsigned char *, * PUBLIC: const unsigned char *)); */ -int +int __str_glob_cmp(pattern, string) const unsigned char *pattern; const unsigned char *string; @@ -526,7 +529,7 @@ __str_glob_cmp(pattern, string) * PUBLIC: int __str_like_cmp __P((const unsigned char *, * PUBLIC: const unsigned char *)); */ -int +int __str_like_cmp(pattern, string) const unsigned char *pattern; const unsigned char *string; @@ -588,10 +591,10 @@ __str_like_cmp(pattern, string) * do not necessarily contain numbers. They could contain text. * * If the input strings both look like actual numbers then they - * compare in numerical order. Numerical strings are always less + * compare in numerical order. Numerical strings are always less * than non-numeric strings so if one input string looks like a * number and the other does not, then the one that looks like - * a number is the smaller. Non-numeric strings compare in + * a number is the smaller. Non-numeric strings compare in * lexigraphical order (the same order as strcmp()). * * PUBLIC: int __str_numeric_cmp __P((const char *, const char *)); @@ -631,7 +634,7 @@ __str_numeric_cmp(left, right) } else { result = strcmp(left, right); } - return result; + return result; } /* @@ -704,7 +707,7 @@ __str_real_as_sortable(r, z) * The digits must be chosen such at their ASCII codes are increasing. * This means we can not use the traditional base-64 digit set. */ - static const char digit[] = + static const char digit[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" diff --git a/src/dbsql/dbsql.c b/src/dbsql/dbsql.c index faaf31c..bc75a96 100644 --- a/src/dbsql/dbsql.c +++ b/src/dbsql/dbsql.c @@ -30,6 +30,7 @@ #include #include "dbsql_config.h" +#include "dbsql_int.h" #include "dbsql.h" #if !defined(_WIN32) && !defined(WIN32) @@ -51,29 +52,29 @@ #endif struct globals { - /* The Berkeley DBSQL database manager. */ + /* The Berkeley DBSQL database manager. */ DBSQL *dbp; - /* The Berkeley DB database environment. */ + /* The Berkeley DB database environment. */ DB_ENV *dbenv; - /* Non-zero if an interrupt (Control-C) has been received. */ + /* Non-zero if an interrupt (Control-C) has been received. */ int interrupted_p; - /* - * This is the name of our program. It is set in main(), used - * in a number of other places, mostly for error messages. - */ + /* + * This is the name of our program. It is set in main(), used + * in a number of other places, mostly for error messages. + */ char *progname; /* An output stream for error messages, normally stdout. */ FILE *errfp; - /* - * Prompt strings. Initialized in main. Settable using the - * '.prompt [main] [continuation]' command. - */ - char prompt[20]; /* First line prompt. default: "SQL> "*/ + /* + * Prompt strings. Initialized in main. Settable using the + * '.prompt [main] [continuation]' command. + */ + char prompt[20]; /* First line prompt. default: "SQL> "*/ char prompt2[20]; /* Continuation prompt. default: "...> " */ }; @@ -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. */ @@ -326,7 +322,7 @@ callback(arg, num_args, args, cols) if (p->cnt++ > 0) fprintf(p->out, "\n"); for (i = 0; i < num_args; i++) { - fprintf(p->out, "%*s = %s\n", w, cols[i], + fprintf(p->out, "%*s = %s\n", w, cols[i], (args[i] ? args[i] : p->nullvalue)); } break; @@ -368,7 +364,7 @@ callback(arg, num_args, args, cols) w = 10; } fprintf(p->out, "%-*.*s%s", w, w, - "----------------------------------------------------------" + "----------------------------------------------------------" "-----------------------------------", (i == num_args - 1) ? "\n" : " "); @@ -696,7 +692,7 @@ do_meta_command(line, p) p->db->exec_printf(p->db, "SELECT name, type, sql FROM " MASTER_NAME " " "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL " - "ORDER BY substr(type,2,1), name", + "ORDER BY substr(type,2,1), name", dump_callback, p, &err_msgs, args[i]); } @@ -1490,26 +1486,26 @@ main(argc, argv) int version_check() { - int v_major, v_minor, v_patch; + int v_major, v_minor, v_patch; - /* Make sure we're loaded with the right version of the DB library. */ - (void)dbsql_version(&v_major, &v_minor, &v_patch); - if (v_major != DBSQL_VERSION_MAJOR || v_minor != DBSQL_VERSION_MINOR) { - fprintf(stderr, + /* Make sure we're loaded with the right version of the DB library. */ + (void)dbsql_version(&v_major, &v_minor, &v_patch); + if (v_major != DBSQL_VERSION_MAJOR || v_minor != DBSQL_VERSION_MINOR) { + fprintf(stderr, "%s: version %d.%d doesn't match library version %d.%d\n", g.progname, DBSQL_VERSION_MAJOR, DBSQL_VERSION_MINOR, v_major, v_minor); - return (EXIT_FAILURE); - } + return (EXIT_FAILURE); + } - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, "%s: version %d.%d doesn't match library version %d.%d\n", g.progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); + return (EXIT_FAILURE); + } + return (0); } diff --git a/src/dbsql_tclsh.c b/src/dbsql_tclsh.c index 8d3b593..d48a6c4 100644 --- a/src/dbsql_tclsh.c +++ b/src/dbsql_tclsh.c @@ -23,7 +23,6 @@ */ #include "dbsql_config.h" - #include "dbsql_int.h" #include "tcl.h" @@ -42,9 +41,9 @@ static char main_loop[] = "append line [gets stdin]\n" "if {[info complete $line]} {\n" "if {[catch {uplevel #0 $line} result]} {\n" - "puts stderr \"Error: $result\"\n" + "puts stderr \"Error: $result\"\n" "} elseif {$result!=\"\"} {\n" - "puts $result\n" + "puts $result\n" "}\n" "set line {}\n" "} else {\n" diff --git a/src/inc/common_ext.h b/src/inc/common_ext.h index 4e4795e..a90435e 100644 --- a/src/inc/common_ext.h +++ b/src/inc/common_ext.h @@ -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)); diff --git a/src/inc/db_int.h b/src/inc/db_int.h index c48f34e..5c6f13d 100644 --- a/src/inc/db_int.h +++ b/src/inc/db_int.h @@ -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) } diff --git a/src/inc/dbsql_ext.h b/src/inc/dbsql_ext.h index 0dc2f7b..f8f59b8 100644 --- a/src/inc/dbsql_ext.h +++ b/src/inc/dbsql_ext.h @@ -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 *)); diff --git a/src/inc/dbsql_int.in b/src/inc/dbsql_int.in index 6b17a7c..f1fc0de 100644 --- a/src/inc/dbsql_int.in +++ b/src/inc/dbsql_int.in @@ -202,7 +202,7 @@ struct __dbsql_db { * Similarly, the DBSQL_COOKIE flag is set when the OP_VerifyCookie opcode * is emitted, and prevents duplicate OP_VerifyCookies from taking up space * and slowing down execution. TODO: do we need this? - * + * * The DBSQL_SCHEMA_LOADED flag is set after the database schema has been * read into internal hash tables. * @@ -447,7 +447,7 @@ struct foreign_key { * key is set to NULL. CASCADE means that a DELETE or UPDATE of the * referenced table row is propagated into the row that holds the * foreign key. - * + * * The following symbolic values are used to record which type * of action to take. */ @@ -479,7 +479,7 @@ struct foreign_key { * In the table_t structure describing Ex1, nCol==3 because there are * three columns in the table. In the index_t structure describing * Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. - * The value of aiColumn is {2, 0}. aiColumn[0]==2 because the + * The value of aiColumn is {2, 0}. aiColumn[0]==2 because the * first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. * The second column to be indexed (c1) has an index of 0 in * Ex1.aCol[], hence Ex2.aiColumn[1]==0. @@ -587,7 +587,7 @@ struct expr { }; /* - * These macros can be used to test, set, or clear bits in the + * These macros can be used to test, set, or clear bits in the * expr_t.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) @@ -862,10 +862,10 @@ struct auth_context { /* * Each trigger present in the database schema is stored as an instance of - * struct trigger. + * struct trigger. * * Pointers to instances of struct trigger are stored in two ways. - * 1. In the "trigHash" hash table (part of the DBSQL* that represents the + * 1. In the "trigHash" hash table (part of the DBSQL* that represents the * database). This allows trigger_t structures to be retrieved by name. * 2. All triggers associated with a single table form a linked list, using the * pNext member of struct trigger. A pointer to the first element of the @@ -897,15 +897,15 @@ struct trigger { /* * An instance of struct trigger_step_t is used to store a single SQL statement - * that is a part of a trigger-program. + * that is a part of a trigger-program. * * Instances of struct trigger_step_t are stored in a singly linked list * (linked using the "pNext" member) referenced by the "step_list" member of * the associated struct trigger instance. The first element of the linked * list is the first step of the trigger-program. - * + * * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or - * "SELECT" statement. The meanings of the other members is determined by the + * "SELECT" statement. The meanings of the other members is determined by the * value of "op" as follows: * * (op == TK_INSERT) @@ -915,7 +915,7 @@ struct trigger { * target -> A token holding the name of the table to insert into. * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then * this stores values to be inserted. Otherwise NULL. - * pIdList -> If this is an INSERT INTO ... () VALUES ... + * pIdList -> If this is an INSERT INTO ... () VALUES ... * statement, then this stores the column-names to be * inserted into. * @@ -923,7 +923,7 @@ struct trigger { * target -> A token holding the name of the table to delete from. * pWhere -> The WHERE clause of the DELETE statement if one is specified. * Otherwise NULL. - * + * * (op == TK_UPDATE) * target -> A token holding the name of the table to update rows of. * pWhere -> The WHERE clause of the UPDATE statement if one is specified. @@ -931,18 +931,18 @@ struct trigger { * pExprList -> A list of the columns to update and the expressions to update * them to. See __update() documentation of "pChanges" * argument. - * + * */ struct trigger_step { int op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ int orconf; /* OE_Rollback etc. */ trigger_t *pTrig; /* The trigger that this step is a part of */ - select_t *pSelect; /* Valid for SELECT and sometimes + select_t *pSelect; /* Valid for SELECT and sometimes INSERT steps (when pExprList == 0) */ token_t target; /* Valid for DELETE, UPDATE, INSERT steps */ expr_t *pWhere; /* Valid for DELETE, UPDATE steps */ - expr_list_t *pExprList; /* Valid for UPDATE statements and sometimes + expr_list_t *pExprList; /* Valid for UPDATE statements and sometimes INSERT steps (when pSelect == 0) */ id_list_t *pIdList; /* Valid for INSERT statements only */ trigger_step_t * pNext; /* Next in the link-list */ @@ -954,15 +954,15 @@ struct trigger_step { * being coded, its associated trigger_stack_t instance is pointed to by the * "pTriggerStack" member of the Parse structure. * - * The pTab member points to the table that triggers are being coded on. The + * The pTab member points to the table that triggers are being coded on. The * newIdx member contains the index of the vdbe cursor that points at the temp * table that stores the new.* references. If new.* references are not valid * for the trigger being coded (for example an ON DELETE trigger), then newIdx * is set to -1. The oldIdx member is analogous to newIdx, for old.* * references. * - * The ON CONFLICT policy to be used for the trigger program steps is stored - * as the orconf member. If this is OE_Default, then the ON CONFLICT clause + * The ON CONFLICT policy to be used for the trigger program steps is stored + * as the orconf member. If this is OE_Default, then the ON CONFLICT clause * specified for individual triggers steps is used. * * struct trigger_stack_t has a "pNext" member, to allow linked lists to be @@ -972,7 +972,7 @@ struct trigger_step { * restored to the pTriggerStack member of the Parse stucture and coding of * the parent trigger continues. * - * Before a nested trigger is coded, the linked list pointed to by the + * Before a nested trigger is coded, the linked list pointed to by the * pTriggerStack is scanned to ensure that the trigger is not about to be coded * recursively. If this condition is detected, the nested trigger is not coded. */ @@ -990,7 +990,7 @@ struct trigger_stack { /* * The following structure contains information used by the __ref_normalizeXXX * routines as they walk the parse tree to make database references - * explicit. + * explicit. */ typedef struct ref_normalizer_ctx ref_normalizer_ctx_t; struct ref_normalizer_ctx { diff --git a/src/inc/debug.h b/src/inc/debug.h index f7052cc..4dbb36a 100644 --- a/src/inc/debug.h +++ b/src/inc/debug.h @@ -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) \ diff --git a/src/sql_tokenize.c b/src/sql_tokenize.c index d1262a2..c5d6de6 100644 --- a/src/sql_tokenize.c +++ b/src/sql_tokenize.c @@ -45,7 +45,7 @@ struct keyword { u_int8_t token_type; /* token_t value for this keyword */ u_int8_t len; /* Length of this keyword */ u_int8_t inext; /* Index in sql_tokens_table[] of next with - same hash */ + same hash */ }; /* @@ -164,10 +164,10 @@ static u_int8_t ai_table[KEY_HASH_SIZE]; /* * __get_keyword_code -- * This function looks up an identifier to determine if it is a - * keyword. If it is a keyword, the token code of that keyword is + * 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) @@ -234,7 +234,7 @@ static const char id_char_p[] = { /* * __get_token -- - * Return the length of the token that begins at z[0]. + * Return the length of the token that begins at z[0]. * Store the token type in *token_type before returning. * * STATIC: static int __get_token __P((const unsigned char *, int *)); @@ -459,7 +459,7 @@ __get_token(z, token_type) * PUBLIC: int __run_sql_parser __P((parser_t *, const char *, char **)); */ /*TODO: REMOVE THIS If an error occurs - * and pzErrMsg!=NULL then an error message might be written into + * and pzErrMsg!=NULL then an error message might be written into * memory obtained from malloc() and *pzErrMsg made to point to that * error message. Or maybe not. */ @@ -598,7 +598,7 @@ __run_sql_parser(parser, sql, err_msgs) * returns 1 if it ends in the START state and 0 if it ends * in any other state. * - * (1) EXPLAIN The keyword EXPLAIN has been seen at the beginning of + * (1) EXPLAIN The keyword EXPLAIN has been seen at the beginning of * a statement. * * (2) CREATE The keyword CREATE has been seen at the beginning of a @@ -649,7 +649,7 @@ dbsql_complete_stmt(sql) * returns the next state. */ static const u_int8_t trans[7][8] = { - /* Token: */ + /* Token: */ /* State: ** EXPLAIN CREATE TEMP TRIGGER END SEMI WS OTHER */ /* 0 START: */ { 1, 2, 3, 3, 3, 0, 0, 3, }, /* 1 EXPLAIN: */ { 3, 2, 3, 3, 3, 0, 1, 3, },