Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Use a built-in atof() function instead of the one from the library to avoid problems with locale. Ticket #305. (CVS 1144) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4d9edbc50f7dee64edbadad2e2dc4f93 |
User & Date: | drh 2003-12-23 02:17:35 |
Context
2003-12-23
| ||
03:06 | Test functions tolerate an "0x" before a pointer value. Ticket #452. (CVS 1145) check-in: c6c5e07b user: drh tags: trunk | |
02:17 | Use a built-in atof() function instead of the one from the library to avoid problems with locale. Ticket #305. (CVS 1144) check-in: 4d9edbc5 user: drh tags: trunk | |
2003-12-22
| ||
14:53 | Optimizations to the LEMON parser template. (CVS 1143) check-in: 06db29df user: drh tags: trunk | |
Changes
Changes to src/date.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.1 2003/11/01 01:53:54 drh Exp $ ** ** NOTES: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ................................................................................ if( sqliteOsCurrentTime(&r)==0 ){ p->rJD = r; p->validJD = 1; return 0; } return 1; }else if( sqliteIsNumber(zDate) ){ p->rJD = atof(zDate); p->validJD = 1; return 0; } return 1; } /* |
|
|
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.2 2003/12/23 02:17:35 drh Exp $ ** ** NOTES: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ................................................................................ if( sqliteOsCurrentTime(&r)==0 ){ p->rJD = r; p->validJD = 1; return 0; } return 1; }else if( sqliteIsNumber(zDate) ){ p->rJD = sqliteAtoF(zDate); p->validJD = 1; return 0; } return 1; } /* |
Changes to src/func.c.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ... 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 ... 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.33 2003/11/01 01:53:54 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "os.h" ................................................................................ double r; char zBuf[100]; assert( argc==1 || argc==2 ); if( argv[0]==0 || (argc==2 && argv[1]==0) ) return; n = argc==2 ? atoi(argv[1]) : 0; if( n>30 ) n = 30; if( n<0 ) n = 0; r = atof(argv[0]); sprintf(zBuf,"%.*f",n,r); sqlite_set_result_string(context, zBuf, -1); } /* ** Implementation of the upper() and lower() SQL functions. */ ................................................................................ ** Routines used to compute the sum or average. */ static void sumStep(sqlite_func *context, int argc, const char **argv){ SumCtx *p; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ p->sum += atof(argv[0]); p->cnt++; } } static void sumFinalize(sqlite_func *context){ SumCtx *p; p = sqlite_aggregate_context(context, sizeof(*p)); sqlite_set_result_double(context, p ? p->sum : 0.0); ................................................................................ */ static void stdDevStep(sqlite_func *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ x = atof(argv[0]); p->sum += x; p->sum2 += x*x; p->cnt++; } } static void stdDevFinalize(sqlite_func *context){ double rN = sqlite_aggregate_count(context); |
| | | | |
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ... 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 ... 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.34 2003/12/23 02:17:35 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "os.h" ................................................................................ double r; char zBuf[100]; assert( argc==1 || argc==2 ); if( argv[0]==0 || (argc==2 && argv[1]==0) ) return; n = argc==2 ? atoi(argv[1]) : 0; if( n>30 ) n = 30; if( n<0 ) n = 0; r = sqliteAtoF(argv[0]); sprintf(zBuf,"%.*f",n,r); sqlite_set_result_string(context, zBuf, -1); } /* ** Implementation of the upper() and lower() SQL functions. */ ................................................................................ ** Routines used to compute the sum or average. */ static void sumStep(sqlite_func *context, int argc, const char **argv){ SumCtx *p; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ p->sum += sqliteAtoF(argv[0]); p->cnt++; } } static void sumFinalize(sqlite_func *context){ SumCtx *p; p = sqlite_aggregate_context(context, sizeof(*p)); sqlite_set_result_double(context, p ? p->sum : 0.0); ................................................................................ */ static void stdDevStep(sqlite_func *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ x = sqliteAtoF(argv[0]); p->sum += x; p->sum2 += x*x; p->cnt++; } } static void stdDevFinalize(sqlite_func *context){ double rN = sqlite_aggregate_count(context); |
Changes to src/printf.c.
753 754 755 756 757 758 759 760 761 762 763 764 765 766 |
zNew = malloc( sMprintf.nChar+1 ); if( zNew ) strcpy(zNew,sMprintf.zText); if( sMprintf.zText!=sMprintf.zBase ){ sqliteFree(sMprintf.zText); } return zNew; } /* ** The following four routines implement the varargs versions of the ** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h ** header files for a more detailed description of how these interfaces ** work. ** |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 |
zNew = malloc( sMprintf.nChar+1 ); if( zNew ) strcpy(zNew,sMprintf.zText); if( sMprintf.zText!=sMprintf.zBase ){ sqliteFree(sMprintf.zText); } return zNew; } /* ** This function implements the callback from vxprintf. ** ** This routine add nNewChar characters of text in zNewText to ** the sgMprintf structure pointed to by "arg". Unlike mout() above, ** this routine does not allocate new space when the buffer fills. ** It just truncates. */ static void sout(void *arg, char *zNewText, int nNewChar){ struct sgMprintf *pM = (struct sgMprintf*)arg; if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ nNewChar = pM->nAlloc - pM->nChar - 1; if( nNewChar<=0 ) return; } memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); pM->nChar += nNewChar; pM->zText[pM->nChar] = 0; } /* ** sqlite_sprintf() works like sprintf() except that it ignores the ** current locale settings. This is important for SQLite because we ** are not able to use a "," as the decimal point in place of "." as ** specified by some locales. */ int sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){ va_list ap; struct sgMprintf sMprintf; sMprintf.nChar = 0; sMprintf.nAlloc = n; sMprintf.zText = zBuf; sMprintf.zBase = zBuf; va_start(ap,zFormat); vxprintf(sout,&sMprintf,zFormat,ap); va_end(ap); return sMprintf.nChar; } /* ** The following four routines implement the varargs versions of the ** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h ** header files for a more detailed description of how these interfaces ** work. ** |
Changes to src/sqliteInt.h.
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1199
1200
1201
1202
1203
1204
1205
|
** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.204 2003/12/07 00:24:35 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" ................................................................................ int mode, int nPg, Btree **ppBtree); int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqliteFixSrcList(DbFixer*, SrcList*); int sqliteFixSelect(DbFixer*, Select*); int sqliteFixExpr(DbFixer*, Expr*); int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); |
|
>
>
|
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1199
1200
1201
1202
1203
1204
1205
1206
1207
|
** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.205 2003/12/23 02:17:35 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" ................................................................................ int mode, int nPg, Btree **ppBtree); int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqliteFixSrcList(DbFixer*, SrcList*); int sqliteFixSelect(DbFixer*, Select*); int sqliteFixExpr(DbFixer*, Expr*); int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); double sqliteAtoF(const char *z); int sqlite_snprintf(int,char*,const char*,...); |
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.28 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> ................................................................................ sqlite_set_result_string(context, argv[1], -1); }else if( argv[1]==0 ){ sqlite_set_result_error(context, "2nd argument may not be NULL if the " "first argument is not \"string\"", -1); }else if( sqliteStrICmp(argv[0],"int")==0 ){ sqlite_set_result_int(context, atoi(argv[1])); }else if( sqliteStrICmp(argv[0],"double")==0 ){ sqlite_set_result_double(context, atof(argv[1])); }else{ sqlite_set_result_error(context,"first argument should be one of: " "string int double", -1); } argc -= 2; argv += 2; } |
|
|
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.29 2003/12/23 02:17:35 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> ................................................................................ sqlite_set_result_string(context, argv[1], -1); }else if( argv[1]==0 ){ sqlite_set_result_error(context, "2nd argument may not be NULL if the " "first argument is not \"string\"", -1); }else if( sqliteStrICmp(argv[0],"int")==0 ){ sqlite_set_result_int(context, atoi(argv[1])); }else if( sqliteStrICmp(argv[0],"double")==0 ){ sqlite_set_result_double(context, sqliteAtoF(argv[1])); }else{ sqlite_set_result_error(context,"first argument should be one of: " "string int double", -1); } argc -= 2; argv += 2; } |
Changes to src/tokenize.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.65 2003/12/06 21:43:56 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* ................................................................................ ** 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. */ int sqliteKeywordCode(const char *z, int n){ int h; Keyword *p; if( aKeywordTable[0].len==0 ){ /* Initialize the keyword hash table */ sqliteOsEnterMutex(); if( aKeywordTable[0].len==0 ){ int i; int n; n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]); for(i=0; i<n; i++){ aKeywordTable[i].len = strlen(aKeywordTable[i].zName); h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len); h %= KEY_HASH_SIZE; aKeywordTable[i].pNext = apHashTable[h]; apHashTable[h] = &aKeywordTable[i]; } } sqliteOsLeaveMutex(); } h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE; for(p=apHashTable[h]; p; p=p->pNext){ if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){ return p->tokenType; |
|
|
>
<
>
>
|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.66 2003/12/23 02:17:35 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* ................................................................................ ** 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. */ int sqliteKeywordCode(const char *z, int n){ int h; Keyword *p; static char needInit = 1; if( needInit ){ /* Initialize the keyword hash table */ sqliteOsEnterMutex(); if( needInit ){ int i; int n; n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]); for(i=0; i<n; i++){ aKeywordTable[i].len = strlen(aKeywordTable[i].zName); h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len); h %= KEY_HASH_SIZE; aKeywordTable[i].pNext = apHashTable[h]; apHashTable[h] = &aKeywordTable[i]; } needInit = 0; } sqliteOsLeaveMutex(); } h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE; for(p=apHashTable[h]; p; p=p->pNext){ if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){ return p->tokenType; |
Changes to src/util.c.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 645 646 647 648 649 650 651 652 653 654 655 656 657 658 ... 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 ... 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 |
** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.68 2003/10/22 22:15:28 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. ................................................................................ z++; if( *z=='+' || *z=='-' ) z++; if( !isdigit(*z) ) return 0; while( isdigit(*z) ){ z++; } } return *z==0; } /* This comparison routine is what we use for comparison operations ** between numeric values in an SQL expression. "Numeric" is a little ** bit misleading here. What we mean is that the strings have a ** type of "numeric" from the point of view of SQL. The strings ** do not necessarily contain numbers. They could contain text. ** ................................................................................ isNumA = sqliteIsNumber(atext); isNumB = sqliteIsNumber(btext); if( isNumA ){ if( !isNumB ){ result = -1; }else{ double rA, rB; rA = atof(atext); rB = atof(btext); if( rA<rB ){ result = -1; }else if( rA>rB ){ result = +1; }else{ result = 0; } ................................................................................ isNumB = sqliteIsNumber(&b[1]); if( isNumA ){ double rA, rB; if( !isNumB ){ res = -1; break; } rA = atof(&a[1]); rB = atof(&b[1]); if( rA<rB ){ res = -1; break; } if( rA>rB ){ res = +1; break; |
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | |
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 ... 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 ... 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 |
** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.69 2003/12/23 02:17:35 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. ................................................................................ z++; if( *z=='+' || *z=='-' ) z++; if( !isdigit(*z) ) return 0; while( isdigit(*z) ){ z++; } } return *z==0; } /* ** The string z[] is an ascii representation of a real number. ** Convert this string to a double. ** ** This routine assumes that z[] really is a valid number. If it ** is not, the result is undefined. ** ** This routine is used instead of the library atof() function because ** the library atof() might want to use "," as the decimal point instead ** of "." depending on how locale is set. But that would cause problems ** for SQL. So this routine always uses "." regardless of locale. */ double sqliteAtoF(const char *z){ int sign = 1; double v1 = 0.0; if( *z=='-' ){ sign = -1; z++; }else if( *z=='+' ){ z++; } while( isdigit(*z) ){ v1 = v1*10.0 + (*z - '0'); z++; } if( *z=='.' ){ double divisor = 1.0; z++; while( isdigit(*z) ){ v1 = v1*10.0 + (*z - '0'); divisor *= 10.0; z++; } v1 /= divisor; } if( *z=='e' || *z=='E' ){ int esign = 1; int eval = 0; double scale = 1.0; z++; if( *z=='-' ){ esign = -1; z++; }else if( *z=='+' ){ z++; } while( isdigit(*z) ){ eval = eval*10 + *z - '0'; z++; } while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; } while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; } while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; } while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; } if( esign<0 ){ v1 /= scale; }else{ v1 *= scale; } } return sign<0 ? -v1 : v1; } /* This comparison routine is what we use for comparison operations ** between numeric values in an SQL expression. "Numeric" is a little ** bit misleading here. What we mean is that the strings have a ** type of "numeric" from the point of view of SQL. The strings ** do not necessarily contain numbers. They could contain text. ** ................................................................................ isNumA = sqliteIsNumber(atext); isNumB = sqliteIsNumber(btext); if( isNumA ){ if( !isNumB ){ result = -1; }else{ double rA, rB; rA = sqliteAtoF(atext); rB = sqliteAtoF(btext); if( rA<rB ){ result = -1; }else if( rA>rB ){ result = +1; }else{ result = 0; } ................................................................................ isNumB = sqliteIsNumber(&b[1]); if( isNumA ){ double rA, rB; if( !isNumB ){ res = -1; break; } rA = sqliteAtoF(&a[1]); rB = sqliteAtoF(&b[1]); if( rA<rB ){ res = -1; break; } if( rA>rB ){ res = +1; break; |
Changes to src/vdbe.c.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ... 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 ... 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 .... 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 .... 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 .... 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 |
** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.245 2003/12/10 01:31:21 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* ................................................................................ ** already. */ #define Stringify(P,I) if((aStack[I].flags & STK_Str)==0){hardStringify(P,I);} static int hardStringify(Vdbe *p, int i){ Stack *pStack = &p->aStack[i]; int fg = pStack->flags; if( fg & STK_Real ){ sprintf(pStack->z,"%.15g",pStack->r); }else if( fg & STK_Int ){ sprintf(pStack->z,"%d",pStack->i); }else{ pStack->z[0] = 0; } p->zStack[i] = pStack->z; pStack->n = strlen(pStack->z)+1; pStack->flags = STK_Str; return 0; ................................................................................ ** Any prior string or integer representation is retained. ** NULLs are converted into 0.0. */ #define Realify(P,I) \ if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); } static void hardRealify(Vdbe *p, int i){ if( p->aStack[i].flags & STK_Str ){ p->aStack[i].r = atof(p->zStack[i]); }else if( p->aStack[i].flags & STK_Int ){ p->aStack[i].r = p->aStack[i].i; }else{ p->aStack[i].r = 0.0; } p->aStack[i].flags |= STK_Real; } ................................................................................ Stringify(p, i); aStack[i].flags &= ~(STK_Int|STK_Real); nByte += aStack[i].n+1; }else if( (flags & (STK_Real|STK_Int))!=0 || sqliteIsNumber(zStack[i]) ){ if( (flags & (STK_Real|STK_Int))==STK_Int ){ aStack[i].r = aStack[i].i; }else if( (flags & (STK_Real|STK_Int))==0 ){ aStack[i].r = atof(zStack[i]); } Release(p, i); z = aStack[i].z; sqliteRealToSortable(aStack[i].r, z); len = strlen(z); zStack[i] = 0; aStack[i].flags = STK_Real; ................................................................................ if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; break; } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0); rc = SQLITE_INTERNAL; break; } /***************************************************************************** ** The cases of the switch statement above this line should all be indented ................................................................................ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0); goto vdbe_halt; /* Jump to here if a operator is encountered that requires more stack ** operands than are currently available on the stack. */ not_enough_stack: sprintf(zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0); rc = SQLITE_INTERNAL; goto vdbe_halt; /* Jump here if an illegal or illformed instruction is executed. */ VERIFY( bad_instruction: sprintf(zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0); rc = SQLITE_INTERNAL; goto vdbe_halt; ) } |
| | | | | | | | |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ... 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 ... 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 .... 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 .... 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 .... 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 |
** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.246 2003/12/23 02:17:35 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* ................................................................................ ** already. */ #define Stringify(P,I) if((aStack[I].flags & STK_Str)==0){hardStringify(P,I);} static int hardStringify(Vdbe *p, int i){ Stack *pStack = &p->aStack[i]; int fg = pStack->flags; if( fg & STK_Real ){ sqlite_snprintf(sizeof(pStack->z),pStack->z,"%.15g",pStack->r); }else if( fg & STK_Int ){ sqlite_snprintf(sizeof(pStack->z),pStack->z,"%d",pStack->i); }else{ pStack->z[0] = 0; } p->zStack[i] = pStack->z; pStack->n = strlen(pStack->z)+1; pStack->flags = STK_Str; return 0; ................................................................................ ** Any prior string or integer representation is retained. ** NULLs are converted into 0.0. */ #define Realify(P,I) \ if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); } static void hardRealify(Vdbe *p, int i){ if( p->aStack[i].flags & STK_Str ){ p->aStack[i].r = sqliteAtoF(p->zStack[i]); }else if( p->aStack[i].flags & STK_Int ){ p->aStack[i].r = p->aStack[i].i; }else{ p->aStack[i].r = 0.0; } p->aStack[i].flags |= STK_Real; } ................................................................................ Stringify(p, i); aStack[i].flags &= ~(STK_Int|STK_Real); nByte += aStack[i].n+1; }else if( (flags & (STK_Real|STK_Int))!=0 || sqliteIsNumber(zStack[i]) ){ if( (flags & (STK_Real|STK_Int))==STK_Int ){ aStack[i].r = aStack[i].i; }else if( (flags & (STK_Real|STK_Int))==0 ){ aStack[i].r = sqliteAtoF(zStack[i]); } Release(p, i); z = aStack[i].z; sqliteRealToSortable(aStack[i].r, z); len = strlen(z); zStack[i] = 0; aStack[i].flags = STK_Real; ................................................................................ if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; break; } /* An other opcode is illegal... */ default: { sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode); sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0); rc = SQLITE_INTERNAL; break; } /***************************************************************************** ** The cases of the switch statement above this line should all be indented ................................................................................ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0); goto vdbe_halt; /* Jump to here if a operator is encountered that requires more stack ** operands than are currently available on the stack. */ not_enough_stack: sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0); rc = SQLITE_INTERNAL; goto vdbe_halt; /* Jump here if an illegal or illformed instruction is executed. */ VERIFY( bad_instruction: sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0); rc = SQLITE_INTERNAL; goto vdbe_halt; ) } |
Changes to test/format3.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
|
# May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the the library is able to correctly # handle file-format 3 (version 2.6.x) databases. # # $Id: format3.test,v 1.3 2003/06/03 01:47:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a bunch of data to sort against # do_test format3-1.0 { ................................................................................ do_test format3-11.1 { execsql {SELECT '0'=='0.0'} } {1} do_test format3-11.2 { execsql {SELECT '0'==0.0} } {1} do_test format3-11.3 { execsql {SELECT '12345678901234567890'=='12345678901234567891'} } {1} do_test format3-11.4 { execsql { CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE); INSERT INTO t6 VALUES('0','0.0'); SELECT * FROM t6; } |
|
|
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
|
# May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the the library is able to correctly # handle file-format 3 (version 2.6.x) databases. # # $Id: format3.test,v 1.4 2003/12/23 02:17:35 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a bunch of data to sort against # do_test format3-1.0 { ................................................................................ do_test format3-11.1 { execsql {SELECT '0'=='0.0'} } {1} do_test format3-11.2 { execsql {SELECT '0'==0.0} } {1} do_test format3-11.3 { execsql {SELECT '123456789012345678901'=='123456789012345678900'} } {1} do_test format3-11.4 { execsql { CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE); INSERT INTO t6 VALUES('0','0.0'); SELECT * FROM t6; } |
Changes to test/misc3.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
63
64
65
66
67
68
69
70
71
|
# #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # # $Id: misc3.test,v 1.1 2003/12/17 23:57:36 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Ticket #529. Make sure an ABORT does not damage the in-memory cache # that will be used by subsequent statements in the same transaction. # ................................................................................ catchsql {UPDATE t1 SET a=CASE a WHEN 128 THEN 127 ELSE a END, b='';} execsql { INSERT INTO t1 VALUES(200,'hello out there'); COMMIT; PRAGMA integrity_check; } } ok finish_test |
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for miscellanous features that were # left out of other test files. # # $Id: misc3.test,v 1.2 2003/12/23 02:17:35 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Ticket #529. Make sure an ABORT does not damage the in-memory cache # that will be used by subsequent statements in the same transaction. # ................................................................................ catchsql {UPDATE t1 SET a=CASE a WHEN 128 THEN 127 ELSE a END, b='';} execsql { INSERT INTO t1 VALUES(200,'hello out there'); COMMIT; PRAGMA integrity_check; } } ok # Tests of the sqliteAtoF() function in util.c # do_test misc3-2.1 { execsql {SELECT 2e-25*0.5e25} } 1 do_test misc3-2.2 { execsql {SELECT 2.0e-25*000000.500000000000000000000000000000e+00025} } 1 do_test misc3-2.3 { execsql {SELECT 000000000002e-0000000025*0.5e25} } 1 do_test misc3-2.4 { execsql {SELECT 2e-25*0.5e250} } 1e+225 do_test misc3-2.5 { execsql {SELECT 2.0e-250*0.5e25} } 1e-225 do_test misc3-2.6 { execsql {SELECT '-2.0e-127' * '-0.5e27'} } 1e-100 do_test misc3-2.7 { execsql {SELECT '+2.0e-127' * '-0.5e27'} } -1e-100 do_test misc3-2.8 { execsql {SELECT 2.0e-27 * '+0.5e+127'} } 1e+100 do_test misc3-2.9 { execsql {SELECT 2.0e-27 * '+0.000005e+132'} } 1e+100 finish_test |