Update to SQLite 3.0.8

git-svn-id: svn://10.0.0.236/trunk@163664 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
vladimir%pobox.com
2004-10-13 19:30:19 +00:00
parent ad8a3c9a34
commit 8768f6b421
20 changed files with 2278 additions and 2397 deletions

View File

@@ -1,8 +1,5 @@
This is a CVS pull from 2004.10.05 (has to be CVS since a few bug
fixes we need went in past 3.0.7). Note that THIS SUCKS: qe'll want
to pick a release version, probably 3.0.8, and stick with that, as
soon as it's out.
This is sqlite 3.0.8. (SQLITE_3_0_8 tag)
See http://www.sqlite.org/ for more info.

View File

@@ -46,7 +46,7 @@ LIBRARY_NAME = sqlite3_s
MODULE_NAME = sqlite3
FORCE_STATIC_LIB = 1
VERSION = 3.0.7+041005
VERSION = 3.0.8
EXPORTS = sqlite3.h

View File

@@ -23,7 +23,7 @@
** ROLLBACK
** PRAGMA
**
** $Id: build.c,v 1.256 2004/10/05 02:41:42 drh Exp $
** $Id: build.c,v 1.257 2004/10/06 15:41:16 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1112,7 +1112,7 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
*/
char sqlite3AffinityType(const char *zType, int nType){
int n, i;
struct {
static const struct {
const char *zSub; /* Keywords substring to search for */
char nSub; /* length of zSub */
char affinity; /* Affinity to return if it matches */
@@ -1612,7 +1612,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
*/
v = sqlite3GetVdbe(pParse);
if( v ){
static VdbeOpList dropTable[] = {
static const VdbeOpList dropTable[] = {
{ OP_Rewind, 0, ADDR(13), 0},
{ OP_String8, 0, 0, 0}, /* 1 */
{ OP_MemStore, 1, 1, 0},
@@ -2207,7 +2207,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
/* Generate code to remove the index and from the master table */
v = sqlite3GetVdbe(pParse);
if( v ){
static VdbeOpList dropIndex[] = {
static const VdbeOpList dropIndex[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 0, 0}, /* 1 */
{ OP_MemStore, 1, 1, 0},

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.36 2004/10/01 02:00:31 drh Exp $
** $Id: date.c,v 1.37 2004/10/06 15:41:16 drh Exp $
**
** NOTES:
**
@@ -872,7 +872,7 @@ static void strftimeFunc(
*/
void sqlite3RegisterDateTimeFunctions(sqlite3 *db){
#ifndef SQLITE_OMIT_DATETIME_FUNCS
static struct {
static const struct {
char *zName;
int nArg;
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);

View File

@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.84 2004/09/13 13:13:19 drh Exp $
** $Id: func.c,v 1.85 2004/10/06 15:41:17 drh Exp $
*/
#include <ctype.h>
#include <math.h>
@@ -918,7 +918,7 @@ static void minMaxFinalize(sqlite3_context *context){
** external linkage.
*/
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
static struct {
static const struct {
char *zName;
signed char nArg;
u8 argType; /* 0: none. 1: db 2: (-1) */
@@ -962,7 +962,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
{ "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
#endif
};
static struct {
static const struct {
char *zName;
signed char nArg;
u8 argType;

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.262 2004/09/30 13:43:13 drh Exp $
** $Id: main.c,v 1.263 2004/10/06 15:41:17 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -128,7 +128,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
/*
** The master database table has a structure like this
*/
static char master_schema[] =
static const char master_schema[] =
"CREATE TABLE sqlite_master(\n"
" type text,\n"
" name text,\n"
@@ -137,7 +137,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
" sql text\n"
")"
;
static char temp_master_schema[] =
static const char temp_master_schema[] =
"CREATE TEMP TABLE sqlite_temp_master(\n"
" type text,\n"
" name text,\n"
@@ -890,12 +890,12 @@ const void *sqlite3_errmsg16(sqlite3 *db){
** zero byte, we can obtain the little-endian string with
** &big_endian[1].
*/
static char outOfMemBe[] = {
static const char outOfMemBe[] = {
0, 'o', 0, 'u', 0, 't', 0, ' ',
0, 'o', 0, 'f', 0, ' ',
0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
};
static char misuseBe [] = {
static const char misuseBe [] = {
0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ',
0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ',
0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ',

View File

@@ -1,129 +1,128 @@
/* Automatically generated file. Do not edit */
char *sqlite3OpcodeNames[] = { "???",
"Goto",
"Gosub",
"Return",
"Halt",
"Integer",
"Real",
"String8",
"String",
"HexBlob",
"Blob",
"Variable",
"Pop",
"Dup",
"Pull",
"Push",
"Callback",
"Concat",
"Add",
"Subtract",
"Multiply",
"Divide",
"Remainder",
"CollSeq",
"Function",
"BitAnd",
"BitOr",
"ShiftLeft",
"ShiftRight",
"AddImm",
"ForceInt",
"MustBeInt",
"Eq",
"Ne",
"Lt",
"Le",
"Gt",
"Ge",
"And",
"Or",
"Negative",
"AbsValue",
"Not",
"BitNot",
"Noop",
"If",
"IfNot",
"IsNull",
"NotNull",
"SetNumColumns",
"IdxColumn",
"Column",
"MakeRecord",
"Statement",
"AutoCommit",
"Transaction",
"ReadCookie",
"SetCookie",
"VerifyCookie",
"OpenRead",
"OpenWrite",
"OpenTemp",
"OpenPseudo",
"Close",
"MoveLt",
"MoveLe",
"MoveGe",
"MoveGt",
"Distinct",
"NotFound",
"Found",
"IsUnique",
"NotExists",
"NewRecno",
"PutIntKey",
"PutStrKey",
"Delete",
"ResetCount",
"KeyAsData",
"RowKey",
"RowData",
"Recno",
"FullKey",
"NullRow",
"Last",
"Rewind",
"Prev",
"Next",
"IdxPut",
"IdxDelete",
"IdxRecno",
"IdxLT",
"IdxGT",
"IdxGE",
"IdxIsNull",
"Destroy",
"Clear",
"CreateIndex",
"CreateTable",
"ParseSchema",
"DropTable",
"DropIndex",
"DropTrigger",
"IntegrityCk",
"ListWrite",
"ListRewind",
"ListRead",
"ListReset",
"ListPush",
"ListPop",
"ContextPush",
"ContextPop",
"SortPut",
"Sort",
"SortNext",
"SortReset",
"MemStore",
"MemLoad",
"MemIncr",
"AggReset",
"AggInit",
"AggFunc",
"AggFocus",
"AggSet",
"AggGet",
"AggNext",
"Vacuum",
/* Automatically generated. Do not edit */
/* See the mkopcodec.h script for details. */
const char *const sqlite3OpcodeNames[] = { "?",
"MemLoad",
"Column",
"SetCookie",
"MoveGt",
"AggFocus",
"RowKey",
"IdxRecno",
"AggNext",
"OpenWrite",
"If",
"PutStrKey",
"Pop",
"SortPut",
"CollSeq",
"OpenRead",
"SortReset",
"AutoCommit",
"Sort",
"ListRewind",
"IntegrityCk",
"Function",
"Noop",
"Return",
"Variable",
"String",
"ParseSchema",
"PutIntKey",
"AggFunc",
"Close",
"ListWrite",
"CreateIndex",
"IsUnique",
"IdxIsNull",
"NotFound",
"MustBeInt",
"Halt",
"IdxLT",
"AddImm",
"Statement",
"RowData",
"Push",
"KeyAsData",
"NotExists",
"OpenTemp",
"MemIncr",
"Gosub",
"AggSet",
"Integer",
"SortNext",
"Prev",
"CreateTable",
"Last",
"ResetCount",
"Callback",
"ContextPush",
"DropTrigger",
"DropIndex",
"Or",
"And",
"Not",
"FullKey",
"IdxGE",
"IdxDelete",
"IsNull",
"NotNull",
"Ne",
"Eq",
"Gt",
"Le",
"Lt",
"Ge",
"BitAnd",
"BitOr",
"ShiftLeft",
"ShiftRight",
"Add",
"Subtract",
"Multiply",
"Divide",
"Remainder",
"Concat",
"Negative",
"Vacuum",
"BitNot",
"String8",
"MoveLe",
"IfNot",
"DropTable",
"MakeRecord",
"Delete",
"ListRead",
"ListReset",
"Dup",
"Goto",
"Clear",
"IdxGT",
"MoveLt",
"VerifyCookie",
"Pull",
"SetNumColumns",
"AbsValue",
"Transaction",
"AggGet",
"ContextPop",
"Next",
"AggInit",
"Distinct",
"NewRecno",
"AggReset",
"Destroy",
"ReadCookie",
"ForceInt",
"IdxColumn",
"Recno",
"OpenPseudo",
"Blob",
"MemStore",
"Rewind",
"MoveGe",
"IdxPut",
"Found",
"Real",
"HexBlob",
"NullRow",
};

View File

@@ -1,127 +1,126 @@
/* Automatically generated file. Do not edit */
#define OP_Goto 1
#define OP_Gosub 2
#define OP_Return 3
#define OP_Halt 4
#define OP_Integer 5
#define OP_Real 6
#define OP_String8 7
#define OP_String 8
#define OP_HexBlob 9
#define OP_Blob 10
#define OP_Variable 11
#define OP_Pop 12
#define OP_Dup 13
#define OP_Pull 14
#define OP_Push 15
#define OP_Callback 16
#define OP_Concat 17
#define OP_Add 18
#define OP_Subtract 19
#define OP_Multiply 20
#define OP_Divide 21
#define OP_Remainder 22
#define OP_CollSeq 23
#define OP_Function 24
#define OP_BitAnd 25
#define OP_BitOr 26
#define OP_ShiftLeft 27
#define OP_ShiftRight 28
#define OP_AddImm 29
#define OP_ForceInt 30
#define OP_MustBeInt 31
#define OP_Eq 32
#define OP_Ne 33
#define OP_Lt 34
#define OP_Le 35
#define OP_Gt 36
#define OP_Ge 37
#define OP_And 38
#define OP_Or 39
#define OP_Negative 40
#define OP_AbsValue 41
#define OP_Not 42
#define OP_BitNot 43
#define OP_Noop 44
#define OP_If 45
#define OP_IfNot 46
#define OP_IsNull 47
#define OP_NotNull 48
#define OP_SetNumColumns 49
#define OP_IdxColumn 50
#define OP_Column 51
#define OP_MakeRecord 52
#define OP_Statement 53
#define OP_AutoCommit 54
#define OP_Transaction 55
#define OP_ReadCookie 56
#define OP_SetCookie 57
#define OP_VerifyCookie 58
#define OP_OpenRead 59
#define OP_OpenWrite 60
#define OP_OpenTemp 61
#define OP_OpenPseudo 62
#define OP_Close 63
#define OP_MoveLt 64
#define OP_MoveLe 65
#define OP_MoveGe 66
#define OP_MoveGt 67
#define OP_Distinct 68
#define OP_NotFound 69
#define OP_Found 70
#define OP_IsUnique 71
#define OP_NotExists 72
#define OP_NewRecno 73
#define OP_PutIntKey 74
#define OP_PutStrKey 75
#define OP_Delete 76
#define OP_ResetCount 77
#define OP_KeyAsData 78
#define OP_RowKey 79
#define OP_RowData 80
#define OP_Recno 81
#define OP_FullKey 82
#define OP_NullRow 83
#define OP_Last 84
#define OP_Rewind 85
#define OP_Prev 86
#define OP_Next 87
#define OP_IdxPut 88
#define OP_IdxDelete 89
#define OP_IdxRecno 90
#define OP_IdxLT 91
#define OP_IdxGT 92
#define OP_IdxGE 93
#define OP_IdxIsNull 94
#define OP_Destroy 95
#define OP_Clear 96
#define OP_CreateIndex 97
#define OP_CreateTable 98
#define OP_ParseSchema 99
#define OP_DropTable 100
#define OP_DropIndex 101
#define OP_DropTrigger 102
#define OP_IntegrityCk 103
#define OP_ListWrite 104
#define OP_ListRewind 105
#define OP_ListRead 106
#define OP_ListReset 107
#define OP_ListPush 108
#define OP_ListPop 109
#define OP_ContextPush 110
#define OP_ContextPop 111
#define OP_SortPut 112
#define OP_Sort 113
#define OP_SortNext 114
#define OP_SortReset 115
#define OP_MemStore 116
#define OP_MemLoad 117
#define OP_MemIncr 118
#define OP_AggReset 119
#define OP_AggInit 120
#define OP_AggFunc 121
#define OP_AggFocus 122
#define OP_AggSet 123
#define OP_AggGet 124
#define OP_AggNext 125
#define OP_Vacuum 126
/* Automatically generated. Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_MemLoad 1
#define OP_HexBlob 123
#define OP_Column 2
#define OP_SetCookie 3
#define OP_Real 122
#define OP_MoveGt 4
#define OP_Ge 71
#define OP_AggFocus 5
#define OP_RowKey 6
#define OP_IdxRecno 7
#define OP_AggNext 8
#define OP_Eq 67
#define OP_OpenWrite 9
#define OP_NotNull 65
#define OP_If 10
#define OP_PutStrKey 11
#define OP_String8 85
#define OP_Pop 12
#define OP_SortPut 13
#define OP_CollSeq 14
#define OP_OpenRead 15
#define OP_SortReset 16
#define OP_AutoCommit 17
#define OP_Gt 68
#define OP_Sort 18
#define OP_ListRewind 19
#define OP_IntegrityCk 20
#define OP_Function 21
#define OP_Subtract 77
#define OP_And 59
#define OP_Noop 22
#define OP_Return 23
#define OP_Remainder 80
#define OP_Multiply 78
#define OP_Variable 24
#define OP_String 25
#define OP_ParseSchema 26
#define OP_PutIntKey 27
#define OP_AggFunc 28
#define OP_Close 29
#define OP_ListWrite 30
#define OP_CreateIndex 31
#define OP_IsUnique 32
#define OP_IdxIsNull 33
#define OP_NotFound 34
#define OP_MustBeInt 35
#define OP_Halt 36
#define OP_IdxLT 37
#define OP_AddImm 38
#define OP_Statement 39
#define OP_RowData 40
#define OP_Push 41
#define OP_Or 58
#define OP_KeyAsData 42
#define OP_NotExists 43
#define OP_OpenTemp 44
#define OP_MemIncr 45
#define OP_Gosub 46
#define OP_Divide 79
#define OP_AggSet 47
#define OP_Integer 48
#define OP_SortNext 49
#define OP_Prev 50
#define OP_Concat 81
#define OP_BitAnd 72
#define OP_CreateTable 51
#define OP_Last 52
#define OP_IsNull 64
#define OP_ShiftRight 75
#define OP_ResetCount 53
#define OP_Callback 54
#define OP_ContextPush 55
#define OP_DropTrigger 56
#define OP_DropIndex 57
#define OP_FullKey 61
#define OP_IdxGE 62
#define OP_IdxDelete 63
#define OP_Vacuum 83
#define OP_MoveLe 86
#define OP_IfNot 87
#define OP_DropTable 88
#define OP_MakeRecord 89
#define OP_Delete 90
#define OP_ListRead 91
#define OP_ListReset 92
#define OP_ShiftLeft 74
#define OP_Dup 93
#define OP_Goto 94
#define OP_Clear 95
#define OP_IdxGT 96
#define OP_MoveLt 97
#define OP_Le 69
#define OP_VerifyCookie 98
#define OP_Pull 99
#define OP_Not 60
#define OP_SetNumColumns 100
#define OP_AbsValue 101
#define OP_Transaction 102
#define OP_Negative 82
#define OP_Ne 66
#define OP_AggGet 103
#define OP_ContextPop 104
#define OP_BitOr 73
#define OP_Next 105
#define OP_AggInit 106
#define OP_Distinct 107
#define OP_NewRecno 108
#define OP_Lt 70
#define OP_AggReset 109
#define OP_Destroy 110
#define OP_ReadCookie 111
#define OP_ForceInt 112
#define OP_IdxColumn 113
#define OP_Recno 114
#define OP_OpenPseudo 115
#define OP_Blob 116
#define OP_Add 76
#define OP_MemStore 117
#define OP_Rewind 118
#define OP_MoveGe 119
#define OP_IdxPut 120
#define OP_BitNot 84
#define OP_Found 121
#define OP_NullRow 124

View File

@@ -588,7 +588,7 @@ int sqlite3OsTempFileName(char *zBuf){
"/tmp",
".",
};
static unsigned char zChars[] =
static const unsigned char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";

File diff suppressed because it is too large Load Diff

View File

@@ -84,42 +84,42 @@
#define TK_BITNOT 84
#define TK_STRING 85
#define TK_JOIN_KW 86
#define TK_INTEGER 87
#define TK_CONSTRAINT 88
#define TK_DEFAULT 89
#define TK_FLOAT 90
#define TK_NULL 91
#define TK_PRIMARY 92
#define TK_UNIQUE 93
#define TK_CHECK 94
#define TK_REFERENCES 95
#define TK_COLLATE 96
#define TK_ON 97
#define TK_DELETE 98
#define TK_UPDATE 99
#define TK_INSERT 100
#define TK_SET 101
#define TK_DEFERRABLE 102
#define TK_FOREIGN 103
#define TK_DROP 104
#define TK_UNION 105
#define TK_ALL 106
#define TK_INTERSECT 107
#define TK_EXCEPT 108
#define TK_SELECT 109
#define TK_DISTINCT 110
#define TK_DOT 111
#define TK_FROM 112
#define TK_JOIN 113
#define TK_USING 114
#define TK_ORDER 115
#define TK_BY 116
#define TK_GROUP 117
#define TK_HAVING 118
#define TK_LIMIT 119
#define TK_WHERE 120
#define TK_INTO 121
#define TK_VALUES 122
#define TK_CONSTRAINT 87
#define TK_DEFAULT 88
#define TK_NULL 89
#define TK_PRIMARY 90
#define TK_UNIQUE 91
#define TK_CHECK 92
#define TK_REFERENCES 93
#define TK_COLLATE 94
#define TK_ON 95
#define TK_DELETE 96
#define TK_UPDATE 97
#define TK_INSERT 98
#define TK_SET 99
#define TK_DEFERRABLE 100
#define TK_FOREIGN 101
#define TK_DROP 102
#define TK_UNION 103
#define TK_ALL 104
#define TK_INTERSECT 105
#define TK_EXCEPT 106
#define TK_SELECT 107
#define TK_DISTINCT 108
#define TK_DOT 109
#define TK_FROM 110
#define TK_JOIN 111
#define TK_USING 112
#define TK_ORDER 113
#define TK_BY 114
#define TK_GROUP 115
#define TK_HAVING 116
#define TK_LIMIT 117
#define TK_WHERE 118
#define TK_INTO 119
#define TK_VALUES 120
#define TK_INTEGER 121
#define TK_FLOAT 122
#define TK_BLOB 123
#define TK_VARIABLE 124
#define TK_CASE 125

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.69 2004/10/05 15:42:53 drh Exp $
** $Id: pragma.c,v 1.70 2004/10/06 15:41:17 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -234,7 +234,7 @@ void sqlite3Pragma(
** and a positive value means synchronous is on.
*/
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
static VdbeOpList getCacheSize[] = {
static const VdbeOpList getCacheSize[] = {
{ OP_ReadCookie, 0, 2, 0}, /* 0 */
{ OP_AbsValue, 0, 0, 0},
{ OP_Dup, 0, 0, 0},
@@ -527,7 +527,7 @@ void sqlite3Pragma(
/* Code that initializes the integrity check program. Set the
** error count 0
*/
static VdbeOpList initCode[] = {
static const VdbeOpList initCode[] = {
{ OP_Integer, 0, 0, 0},
{ OP_MemStore, 0, 1, 0},
};
@@ -536,7 +536,7 @@ void sqlite3Pragma(
** messages have been generated, output OK. Otherwise output the
** error message
*/
static VdbeOpList endCode[] = {
static const VdbeOpList endCode[] = {
{ OP_MemLoad, 0, 0, 0},
{ OP_Integer, 0, 0, 0},
{ OP_Ne, 0, 0, 0}, /* 2 */
@@ -598,7 +598,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2;
static VdbeOpList idxErr[] = {
static const VdbeOpList idxErr[] = {
{ OP_MemIncr, 0, 0, 0},
{ OP_String8, 0, 0, "rowid "},
{ OP_Recno, 1, 0, 0},
@@ -616,7 +616,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
static VdbeOpList cntIdx[] = {
static const VdbeOpList cntIdx[] = {
{ OP_Integer, 0, 0, 0},
{ OP_MemStore, 2, 1, 0},
{ OP_Rewind, 0, 0, 0}, /* 2 */
@@ -668,7 +668,7 @@ void sqlite3Pragma(
** useful if invoked immediately after the main database i
*/
if( sqlite3StrICmp(zLeft, "encoding")==0 ){
struct EncName {
static struct EncName {
char *zName;
u8 enc;
} encnames[] = {
@@ -721,7 +721,7 @@ void sqlite3Pragma(
** Report the current state of file logs for all databases
*/
if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
static char *azLockName[] = {
static const char *const azLockName[] = {
"unlocked", "shared", "reserved", "pending", "exclusive"
};
int i;

View File

@@ -107,7 +107,7 @@ typedef struct et_info { /* Information about each format field */
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static et_info fmtinfo[] = {
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 0, etSTRING, 0, 0 },
{ 'z', 0, 2, etDYNSTRING, 0, 0 },
@@ -214,13 +214,14 @@ static int vxprintf(
etByte flag_longlong; /* True if the "ll" flag is present */
UINT64_TYPE longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
et_info *infop; /* Pointer to the appropriate info structure */
const et_info *infop; /* Pointer to the appropriate info structure */
char buf[etBUFSIZE]; /* Conversion buffer */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
etByte errorflag = 0; /* True if an error is encountered */
etByte xtype; /* Conversion paradigm */
char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
static char spaces[] = " ";
static const char spaces[] =
" ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef etNOFLOATINGPOINT
int exp; /* exponent of real numbers */

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.211 2004/09/25 14:39:19 drh Exp $
** $Id: select.c,v 1.212 2004/10/06 15:41:17 drh Exp $
*/
#include "sqliteInt.h"
@@ -81,7 +81,7 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
int jointype = 0;
Token *apAll[3];
Token *p;
static struct {
static const struct {
const char *zKeyword;
u8 nChar;
u8 code;

View File

@@ -12,7 +12,7 @@
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.114 2004/09/24 12:50:03 drh Exp $
** $Id: shell.c,v 1.116 2004/10/07 00:32:40 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
@@ -242,7 +242,8 @@ struct callback_data {
#define MODE_Html 4 /* Generate an XHTML table */
#define MODE_Insert 5 /* Generate SQL "insert" statements */
#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
#define MODE_NUM_OF 7 /* The number of modes (not a mode itself) */
#define MODE_Csv 7 /* Quote strings, numbers are plain */
#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */
char *modeDescr[MODE_NUM_OF] = {
"line",
@@ -252,6 +253,7 @@ char *modeDescr[MODE_NUM_OF] = {
"html",
"insert",
"tcl",
"csv",
};
/*
@@ -339,6 +341,25 @@ static void output_html_string(FILE *out, const char *z){
}
}
/*
** Output a single term of CSV. Actually, p->separator is used for
** the separator, which may or may not be a comma. p->nullvalue is
** the null value. Strings are quoted using ANSI-C rules. Numbers
** appear outside of quotes.
*/
static void output_csv(struct callback_data *p, const char *z, int bSep){
if( z==0 ){
fprintf(p->out,"%s",p->nullvalue);
}else if( isNumber(z, 0) ){
fprintf(p->out,"%s",z);
}else{
output_c_string(p->out, z);
}
if( bSep ){
fprintf(p->out, p->separator);
}
}
/*
** This routine runs when the user presses Ctrl-C
*/
@@ -474,6 +495,20 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
fprintf(p->out,"\n");
break;
}
case MODE_Csv: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_csv(p, azCol[i], i<nArg-1);
}
fprintf(p->out,"\n");
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
fprintf(p->out,"\n");
break;
}
case MODE_Insert: {
if( azArg==0 ) break;
fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
@@ -1039,7 +1074,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
i = 0;
lineno++;
azCol[0] = zLine;
for(i=0, z=zLine; *z; z++){
for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
*z = 0;
i++;
@@ -1114,7 +1149,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else if( strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl;
}else if( strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_List;
p->mode = MODE_Csv;
strcpy(p->separator, ",");
}else if( strncmp(azArg[1],"tabs",n2)==0 ){
p->mode = MODE_List;

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.120 2004/09/30 14:24:50 drh Exp $
** @(#) $Id: sqlite.h.in,v 1.121 2004/10/06 15:52:01 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -28,7 +28,11 @@ extern "C" {
/*
** The version of the SQLite library.
*/
#define SQLITE_VERSION "--VERS--"
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#else
# define SQLITE_VERSION "--VERS--"
#endif
/*
** The version string is also compiled into the library so that a program
@@ -760,10 +764,22 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
*/
#define SQLITE_INTEGER 1
#define SQLITE_FLOAT 2
#define SQLITE_TEXT 3
/* #define SQLITE_TEXT 3 // See below */
#define SQLITE_BLOB 4
#define SQLITE_NULL 5
/*
** SQLite version 2 defines SQLITE_TEXT differently. To allow both
** version 2 and version 3 to be included, undefine them both if a
** conflict is seen. Define SQLITE3_TEXT to be the version 3 value.
*/
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT 3
#endif
#define SQLITE3_TEXT 3
/*
** The next group of routines returns information about the information
** in a single column of the current result row of a query. In every

View File

@@ -15,173 +15,115 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.90 2004/10/05 02:41:43 drh Exp $
** $Id: tokenize.c,v 1.91 2004/10/07 19:03:01 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>
/*
** All the keywords of the SQL language are stored as in a hash
** table composed of instances of the following structure.
*/
typedef struct Keyword Keyword;
struct Keyword {
char *zName; /* The keyword name */
u8 tokenType; /* Token value for this keyword */
u8 len; /* Length of this keyword */
u8 iNext; /* Index in aKeywordTable[] of next with same hash */
};
/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
{ "ABORT", TK_ABORT, },
{ "AFTER", TK_AFTER, },
{ "ALL", TK_ALL, },
{ "AND", TK_AND, },
{ "AS", TK_AS, },
{ "ASC", TK_ASC, },
{ "ATTACH", TK_ATTACH, },
{ "BEFORE", TK_BEFORE, },
{ "BEGIN", TK_BEGIN, },
{ "BETWEEN", TK_BETWEEN, },
{ "BY", TK_BY, },
{ "CASCADE", TK_CASCADE, },
{ "CASE", TK_CASE, },
{ "CHECK", TK_CHECK, },
{ "COLLATE", TK_COLLATE, },
{ "COMMIT", TK_COMMIT, },
{ "CONFLICT", TK_CONFLICT, },
{ "CONSTRAINT", TK_CONSTRAINT, },
{ "CREATE", TK_CREATE, },
{ "CROSS", TK_JOIN_KW, },
{ "DATABASE", TK_DATABASE, },
{ "DEFAULT", TK_DEFAULT, },
{ "DEFERRED", TK_DEFERRED, },
{ "DEFERRABLE", TK_DEFERRABLE, },
{ "DELETE", TK_DELETE, },
{ "DESC", TK_DESC, },
{ "DETACH", TK_DETACH, },
{ "DISTINCT", TK_DISTINCT, },
{ "DROP", TK_DROP, },
{ "END", TK_END, },
{ "EACH", TK_EACH, },
{ "ELSE", TK_ELSE, },
{ "EXCEPT", TK_EXCEPT, },
{ "EXCLUSIVE", TK_EXCLUSIVE, },
{ "EXPLAIN", TK_EXPLAIN, },
{ "FAIL", TK_FAIL, },
{ "FOR", TK_FOR, },
{ "FOREIGN", TK_FOREIGN, },
{ "FROM", TK_FROM, },
{ "FULL", TK_JOIN_KW, },
{ "GLOB", TK_GLOB, },
{ "GROUP", TK_GROUP, },
{ "HAVING", TK_HAVING, },
{ "IGNORE", TK_IGNORE, },
{ "IMMEDIATE", TK_IMMEDIATE, },
{ "IN", TK_IN, },
{ "INDEX", TK_INDEX, },
{ "INITIALLY", TK_INITIALLY, },
{ "INNER", TK_JOIN_KW, },
{ "INSERT", TK_INSERT, },
{ "INSTEAD", TK_INSTEAD, },
{ "INTERSECT", TK_INTERSECT, },
{ "INTO", TK_INTO, },
{ "IS", TK_IS, },
{ "ISNULL", TK_ISNULL, },
{ "JOIN", TK_JOIN, },
{ "KEY", TK_KEY, },
{ "LEFT", TK_JOIN_KW, },
{ "LIKE", TK_LIKE, },
{ "LIMIT", TK_LIMIT, },
{ "MATCH", TK_MATCH, },
{ "NATURAL", TK_JOIN_KW, },
{ "NOT", TK_NOT, },
{ "NOTNULL", TK_NOTNULL, },
{ "NULL", TK_NULL, },
{ "OF", TK_OF, },
{ "OFFSET", TK_OFFSET, },
{ "ON", TK_ON, },
{ "OR", TK_OR, },
{ "ORDER", TK_ORDER, },
{ "OUTER", TK_JOIN_KW, },
{ "PRAGMA", TK_PRAGMA, },
{ "PRIMARY", TK_PRIMARY, },
{ "RAISE", TK_RAISE, },
{ "REFERENCES", TK_REFERENCES, },
{ "REPLACE", TK_REPLACE, },
{ "RESTRICT", TK_RESTRICT, },
{ "RIGHT", TK_JOIN_KW, },
{ "ROLLBACK", TK_ROLLBACK, },
{ "ROW", TK_ROW, },
{ "SELECT", TK_SELECT, },
{ "SET", TK_SET, },
{ "STATEMENT", TK_STATEMENT, },
{ "TABLE", TK_TABLE, },
{ "TEMP", TK_TEMP, },
{ "TEMPORARY", TK_TEMP, },
{ "THEN", TK_THEN, },
{ "TRANSACTION", TK_TRANSACTION, },
{ "TRIGGER", TK_TRIGGER, },
{ "UNION", TK_UNION, },
{ "UNIQUE", TK_UNIQUE, },
{ "UPDATE", TK_UPDATE, },
{ "USING", TK_USING, },
{ "VACUUM", TK_VACUUM, },
{ "VALUES", TK_VALUES, },
{ "VIEW", TK_VIEW, },
{ "WHEN", TK_WHEN, },
{ "WHERE", TK_WHERE, },
};
/*
** This is the hash table
*/
#define KEY_HASH_SIZE 101
static u8 aiHashTable[KEY_HASH_SIZE];
/*
** 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
** returned. If the input is not a keyword, TK_ID is returned.
**
** The implementation of this routine was generated by a program,
** mkkeywordhash.c, located in the tool subdirectory of the distribution.
** The output of the mkkeywordhash.c program was manually cut and pasted
** into this file. When the set of keywords for SQLite changes, you
** must modify the mkkeywordhash.c program (to add or remove keywords from
** the data tables) then rerun that program to regenerate this function.
*/
int sqlite3KeywordCode(const char *z, int n){
static const char zText[519] =
"ABORTAFTERALLANDASCATTACHBEFOREBEGINBETWEENBYCASCADECASECHECK"
"COLLATECOMMITCONFLICTCONSTRAINTCREATECROSSDATABASEDEFAULTDEFERRABLE"
"DEFERREDDELETEDESCDETACHDISTINCTDROPEACHELSEENDEXCEPTEXCLUSIVE"
"EXPLAINFAILFOREIGNFROMFULLGLOBGROUPHAVINGIGNOREIMMEDIATEINDEX"
"INITIALLYINNERINSERTINSTEADINTERSECTINTOISNULLJOINKEYLEFTLIKE"
"LIMITMATCHNATURALNOTNULLNULLOFFSETONORDEROUTERPRAGMAPRIMARYRAISE"
"REFERENCESREPLACERESTRICTRIGHTROLLBACKROWSELECTSETSTATEMENTTABLE"
"TEMPORARYTHENTRANSACTIONTRIGGERUNIONUNIQUEUPDATEUSINGVACUUMVALUES"
"VIEWWHENWHERE";
static const unsigned char aHash[154] = {
0, 75, 82, 0, 0, 97, 80, 0, 83, 0, 0, 0, 0,
0, 0, 6, 0, 95, 4, 0, 0, 0, 0, 0, 0, 0,
0, 96, 86, 8, 0, 26, 13, 7, 19, 15, 0, 0, 32,
25, 0, 21, 31, 41, 0, 0, 0, 34, 27, 0, 0, 30,
0, 0, 0, 9, 0, 10, 0, 0, 0, 0, 51, 0, 44,
43, 0, 45, 40, 0, 29, 39, 35, 0, 0, 20, 0, 59,
0, 16, 0, 17, 0, 18, 0, 55, 42, 72, 0, 33, 0,
0, 61, 66, 56, 0, 0, 0, 0, 0, 0, 0, 54, 0,
0, 0, 0, 0, 74, 50, 76, 64, 52, 0, 0, 0, 0,
68, 84, 0, 47, 0, 58, 60, 92, 0, 0, 48, 0, 93,
0, 63, 71, 98, 0, 0, 0, 0, 0, 67, 0, 0, 0,
0, 87, 0, 0, 0, 0, 0, 90, 88, 0, 94,
};
static const unsigned char aNext[98] = {
0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
0, 12, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
0, 0, 0, 14, 3, 24, 0, 0, 0, 1, 22, 0, 0,
36, 23, 28, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
0, 49, 37, 0, 0, 0, 38, 0, 53, 0, 57, 62, 0,
0, 0, 0, 0, 0, 70, 46, 0, 65, 0, 0, 0, 0,
69, 73, 0, 77, 0, 0, 0, 0, 0, 0, 81, 85, 0,
91, 79, 78, 0, 0, 89, 0,
};
static const unsigned char aLen[98] = {
5, 5, 3, 3, 2, 3, 6, 6, 5, 7, 2, 7, 4,
5, 7, 6, 8, 10, 6, 5, 8, 7, 10, 8, 6, 4,
6, 8, 4, 4, 4, 3, 6, 9, 7, 4, 3, 7, 4,
4, 4, 5, 6, 6, 9, 2, 5, 9, 5, 6, 7, 9,
4, 2, 6, 4, 3, 4, 4, 5, 5, 7, 3, 7, 4,
2, 6, 2, 2, 5, 5, 6, 7, 5, 10, 7, 8, 5,
8, 3, 6, 3, 9, 5, 4, 9, 4, 11, 7, 5, 6,
6, 5, 6, 6, 4, 4, 5,
};
static const unsigned short int aOffset[98] = {
0, 5, 10, 13, 16, 16, 19, 25, 31, 36, 43, 45, 52,
56, 61, 68, 74, 82, 92, 98, 103, 111, 118, 128, 136, 142,
146, 152, 160, 164, 168, 172, 175, 181, 190, 197, 201, 201, 208,
212, 216, 220, 225, 231, 237, 246, 246, 251, 260, 265, 271, 278,
287, 291, 291, 297, 301, 304, 308, 312, 317, 322, 329, 329, 336,
340, 340, 346, 348, 348, 353, 358, 364, 371, 376, 386, 393, 401,
406, 414, 417, 423, 426, 435, 440, 440, 449, 453, 464, 471, 476,
482, 488, 493, 499, 505, 509, 513,
};
static const unsigned char aCode[98] = {
TK_ABORT, TK_AFTER, TK_ALL, TK_AND, TK_AS,
TK_ASC, TK_ATTACH, TK_BEFORE, TK_BEGIN, TK_BETWEEN,
TK_BY, TK_CASCADE, TK_CASE, TK_CHECK, TK_COLLATE,
TK_COMMIT, TK_CONFLICT, TK_CONSTRAINT, TK_CREATE, TK_JOIN_KW,
TK_DATABASE, TK_DEFAULT, TK_DEFERRABLE, TK_DEFERRED, TK_DELETE,
TK_DESC, TK_DETACH, TK_DISTINCT, TK_DROP, TK_EACH,
TK_ELSE, TK_END, TK_EXCEPT, TK_EXCLUSIVE, TK_EXPLAIN,
TK_FAIL, TK_FOR, TK_FOREIGN, TK_FROM, TK_JOIN_KW,
TK_GLOB, TK_GROUP, TK_HAVING, TK_IGNORE, TK_IMMEDIATE,
TK_IN, TK_INDEX, TK_INITIALLY, TK_JOIN_KW, TK_INSERT,
TK_INSTEAD, TK_INTERSECT, TK_INTO, TK_IS, TK_ISNULL,
TK_JOIN, TK_KEY, TK_JOIN_KW, TK_LIKE, TK_LIMIT,
TK_MATCH, TK_JOIN_KW, TK_NOT, TK_NOTNULL, TK_NULL,
TK_OF, TK_OFFSET, TK_ON, TK_OR, TK_ORDER,
TK_JOIN_KW, TK_PRAGMA, TK_PRIMARY, TK_RAISE, TK_REFERENCES,
TK_REPLACE, TK_RESTRICT, TK_JOIN_KW, TK_ROLLBACK, TK_ROW,
TK_SELECT, TK_SET, TK_STATEMENT, TK_TABLE, TK_TEMP,
TK_TEMP, TK_THEN, TK_TRANSACTION,TK_TRIGGER, TK_UNION,
TK_UNIQUE, TK_UPDATE, TK_USING, TK_VACUUM, TK_VALUES,
TK_VIEW, TK_WHEN, TK_WHERE,
};
int h, i;
Keyword *p;
static char needInit = 1;
if( needInit ){
/* Initialize the keyword hash table */
sqlite3OsEnterMutex();
if( needInit ){
int nk;
nk = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
for(i=0, p=aKeywordTable; i<nk; i++, p++){
const char *zName = p->zName;
int len = p->len = strlen(zName);
h = sqlite3HashNoCase(zName, len) % KEY_HASH_SIZE;
p->iNext = aiHashTable[h];
aiHashTable[h] = i+1;
}
needInit = 0;
}
sqlite3OsLeaveMutex();
}
h = sqlite3HashNoCase(z, n) % KEY_HASH_SIZE;
for(i=aiHashTable[h]; i; i=p->iNext){
p = &aKeywordTable[i-1];
if( p->len==n && sqlite3StrNICmp(p->zName, z, n)==0 ){
return p->tokenType;
if( n<2 ) return TK_ID;
h = (sqlite3UpperToLower[((unsigned char*)z)[0]]*5 +
sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3 +
n) % 154;
for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
return aCode[i];
}
}
return TK_ID;
}
/*
** If X is a character that can be used in an identifier and
** X&0x80==0 then isIdChar[X] will be 1. If X&0x80==0x80 then

View File

@@ -211,7 +211,7 @@ void sqlite3FinishTrigger(
** build the sqlite_master entry
*/
if( !db->init.busy ){
static VdbeOpList insertTrig[] = {
static const VdbeOpList insertTrig[] = {
{ OP_NewRecno, 0, 0, 0 },
{ OP_String8, 0, 0, "trigger" },
{ OP_String8, 0, 0, 0 }, /* 2: trigger name */
@@ -487,12 +487,12 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
*/
if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
int base;
static VdbeOpList dropTrigger[] = {
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 0, 0}, /* 1 */
{ OP_String8, 0, 0, 0}, /* 1 */
{ OP_Column, 0, 1, 0},
{ OP_Ne, 0, ADDR(8), 0},
{ OP_String8, 0, 0, "trigger"},
{ OP_String8, 0, 0, "trigger"},
{ OP_Column, 0, 0, 0},
{ OP_Ne, 0, ADDR(8), 0},
{ OP_Delete, 0, 0, 0},

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.417 2004/10/05 02:41:43 drh Exp $
** $Id: vdbe.c,v 1.418 2004/10/06 15:41:17 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -303,7 +303,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){
char *zCsr = zBuf;
int f = pMem->flags;
static const char *encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
if( f&MEM_Blob ){
int i;

View File

@@ -604,21 +604,22 @@ void sqlite3VdbeMakeReady(
assert( nVar>=0 );
n = isExplain ? 10 : p->nOp;
p->aStack = sqliteMalloc(
n*(sizeof(p->aStack[0])+sizeof(Mem*)) /* aStack, apArg */
+ nVar*sizeof(Mem) /* aVar */
+ nVar*sizeof(char*) /* azVar */
+ nMem*sizeof(Mem) /* aMem */
+ nCursor*sizeof(Cursor*) /* apCsr */
n*sizeof(p->aStack[0]) /* aStack */
+ n*sizeof(Mem*) /* apArg */
+ nVar*sizeof(Mem) /* aVar */
+ nVar*sizeof(char*) /* azVar */
+ nMem*sizeof(Mem) /* aMem */
+ nCursor*sizeof(Cursor*) /* apCsr */
);
if( !sqlite3_malloc_failed ){
p->apArg = (Mem **)&p->aStack[n];
p->aVar = (Mem *)&p->apArg[n];
p->azVar = (char**)&p->aVar[nVar];
p->okVar = 0;
p->nVar = nVar;
p->aMem = (Mem*)&p->azVar[nVar];
p->aMem = &p->aStack[n];
p->nMem = nMem;
p->apCsr = (Cursor**)&p->aMem[nMem];
p->aVar = &p->aMem[nMem];
p->nVar = nVar;
p->okVar = 0;
p->apArg = (Mem**)&p->aVar[nVar];
p->azVar = (char**)&p->apArg[n];
p->apCsr = (Cursor**)&p->azVar[nVar];
p->nCursor = nCursor;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
@@ -1516,7 +1517,7 @@ int sqlite3VdbeSerialTypeLen(u32 serial_type){
if( serial_type>=12 ){
return (serial_type-12)/2;
}else{
static u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
return aSize[serial_type];
}
}