Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge experimental into trunk: Refactor the text-to-numeric conversion routines to work without zero-terminators and in UTF16 as well as UTF8. Avoid invalidating strings with doing affinity conversions. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
07ee080ec4527fd2191f41231208da66 |
User & Date: | drh 2010-09-30 20:33:40.000 |
Context
2010-10-01
| ||
13:28 | Updates to the showjournal.c utility in order to bring it up to version 3. (check-in: fa97d89546 user: drh tags: trunk) | |
2010-09-30
| ||
20:33 | Merge experimental into trunk: Refactor the text-to-numeric conversion routines to work without zero-terminators and in UTF16 as well as UTF8. Avoid invalidating strings with doing affinity conversions. (check-in: 07ee080ec4 user: drh tags: trunk) | |
20:11 | Fix some matching issues in enc4.test affected by TCL versions. (Closed-Leaf check-in: dd6d61a967 user: shaneh tags: experimental) | |
18:43 | Add further tests to e_createtable.test. (check-in: 0a4528d629 user: dan tags: trunk) | |
Changes
Changes to src/date.c.
︙ | ︙ | |||
129 130 131 132 133 134 135 | cnt++; }while( nextC ); end_getDigits: va_end(ap); return cnt; } | < < < < < < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | cnt++; }while( nextC ); end_getDigits: va_end(ap); return cnt; } /* ** Parse a timezone extension on the end of a date-time. ** The extension is of the form: ** ** (+/-)HH:MM ** ** Or the "zulu" notation: |
︙ | ︙ | |||
336 337 338 339 340 341 342 | ** as there is a year and date. */ static int parseDateOrTime( sqlite3_context *context, const char *zDate, DateTime *p ){ | | | < < | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | ** as there is a year and date. */ static int parseDateOrTime( sqlite3_context *context, const char *zDate, DateTime *p ){ double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ setDateTimeToCurrent(context, p); return 0; }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; return 0; } return 1; } |
︙ | ︙ | |||
567 568 569 570 571 572 573 | /* ** weekday N ** ** Move the date to the same time on the next occurrence of ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ | | > | | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | /* ** weekday N ** ** Move the date to the same time on the next occurrence of ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( strncmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; if( Z>n ) Z -= 7; |
︙ | ︙ | |||
623 624 625 626 627 628 629 | case '4': case '5': case '6': case '7': case '8': case '9': { double rRounder; | > > | | > | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | case '4': case '5': case '6': case '7': case '8': case '9': { double rRounder; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ rc = 1; break; } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be ** omitted. */ const char *z2 = z; |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
551 552 553 554 555 556 557 | /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); }else if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; | | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); }else if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); pExpr->iColumn = (ynVar)i; testcase( i==0 ); testcase( i==1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
︙ | ︙ | |||
1914 1915 1916 1917 1918 1919 1920 | ** z[n] character is guaranteed to be something that does not look ** like the continuation of the number. */ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; char *zV; | | | < < > > > | < < | | 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 | ** z[n] character is guaranteed to be something that does not look ** like the continuation of the number. */ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; char *zV; sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); } } #endif /* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] into register iMem. ** ** Expr.u.zToken is always UTF8 and zero-terminated. */ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ Vdbe *v = pParse->pVdbe; if( pExpr->flags & EP_IntValue ){ int i = pExpr->u.iValue; if( negFlag ) i = -i; sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); }else{ int c; i64 value; const char *z = pExpr->u.zToken; assert( z!=0 ); c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); if( c==0 || (c==2 && negFlag) ){ char *zV; if( negFlag ){ value = -value; } zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); }else{ #ifdef SQLITE_OMIT_FLOATING_POINT sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); #else codeReal(v, z, negFlag, iMem); |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
281 282 283 284 285 286 287 | r = -(double)((sqlite_int64)((-r)+0.5)); }else{ zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; } | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | r = -(double)((sqlite_int64)((-r)+0.5)); }else{ zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; } sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3_free(zBuf); } sqlite3_result_double(context, r); } #endif /* |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
583 584 585 586 587 588 589 | ** ** Get or set the size limit on rollback journal files. */ if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ | | | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | ** ** Get or set the size limit on rollback journal files. */ if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); if( iLimit<-1 ) iLimit = -1; } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); returnSingleInt(pParse, "journal_size_limit", iLimit); }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2503 2504 2505 2506 2507 2508 2509 | # define sqlite3Tolower(x) tolower((unsigned char)(x)) #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); | < | 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 | # define sqlite3Tolower(x) tolower((unsigned char)(x)) #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3Strlen30(const char*); #define sqlite3StrNICmp sqlite3_strnicmp int sqlite3MallocInit(void); void sqlite3MallocEnd(void); void *sqlite3Malloc(int); void *sqlite3MallocZero(int); |
︙ | ︙ | |||
2823 2824 2825 2826 2827 2828 2829 | void sqlite3Detach(Parse*, Expr*); int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); | | < | 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 | void sqlite3Detach(Parse*, Expr*); int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3AtoF(const char *z, double*, int, u8); int sqlite3GetInt32(const char *, int*); int sqlite3Utf16ByteLen(const void *pData, int nChar); int sqlite3Utf8CharLen(const char *pData, int nByte); int sqlite3Utf8Read(const u8*, const u8**); /* ** Routines to read and write variable-length integers. These used to ** be defined locally, but now we use the varint routines in the util.c |
︙ | ︙ | |||
2871 2872 2873 2874 2875 2876 2877 | const char *sqlite3IndexAffinityStr(Vdbe *, Index *); void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); | | | 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 | const char *sqlite3IndexAffinityStr(Vdbe *, Index *); void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3Atoi64(const char*, i64*, int, u8); void sqlite3Error(sqlite3*, int, const char*,...); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | char *z; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FORMAT INT INT INT\"", 0); return TCL_ERROR; } for(i=2; i<5; i++){ | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | char *z; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FORMAT INT INT INT\"", 0); return TCL_ERROR; } for(i=2; i<5; i++){ if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } } z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
234 235 236 237 238 239 240 | a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; } /* | < | > | > > | | < < | | > > | < < | < < < < < | < < | < > | < < < < < < < < < < < < < | < < < < < < < < < < < | > | | | | | | > > > > > | > > | | > | | | > | > | | | | > | > > | | | | > > > > > > > | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; } /* ** The string z[] is an text representation of a real number. ** Convert this string to a double and write it into *pResult. ** ** The string z[] is length bytes in length (bytes, not characters) and ** uses the encoding enc. The string is not necessarily zero-terminated. ** ** Return TRUE if the result is a valid real number (or integer) and FALSE ** if the string is empty or contains extraneous text. Valid numbers ** are in one of these formats: ** ** [+-]digits[E[+-]digits] ** [+-]digits.[digits][E[+-]digits] ** [+-].digits[E[+-]digits] ** ** Leading and trailing whitespace is ignored for the purpose of determining ** validity. ** ** If some prefix of the input string is a valid number, this routine ** returns FALSE but it still converts the prefix and writes the result ** into *pResult. */ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr = (enc==SQLITE_UTF8?1:2); const char *zEnd = z + length; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ i64 s = 0; /* significand */ int d = 0; /* adjust exponent for shifting decimal point */ int esign = 1; /* sign of exponent */ int e = 0; /* exponent */ int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; *pResult = 0.0; /* Default return value, in case of an error */ if( enc==SQLITE_UTF16BE ) z++; /* skip leading spaces */ while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; if( z>=zEnd ) return 0; /* get sign of significand */ if( *z=='-' ){ sign = -1; z+=incr; }else if( *z=='+' ){ z+=incr; } /* skip leading zeroes */ while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++; /* copy max significant digits to significand */ while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); z+=incr, nDigits++; } /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++; if( z>=zEnd ) goto do_atof_calc; /* if decimal point is present */ if( *z=='.' ){ z+=incr; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); z+=incr, nDigits++, d--; } /* skip non-significant digits */ while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++; } if( z>=zEnd ) goto do_atof_calc; /* if exponent is present */ if( *z=='e' || *z=='E' ){ z+=incr; eValid = 0; if( z>=zEnd ) goto do_atof_calc; /* get sign of exponent */ if( *z=='-' ){ esign = -1; z+=incr; }else if( *z=='+' ){ z+=incr; } /* copy digits to exponent */ while( z<zEnd && sqlite3Isdigit(*z) ){ e = e*10 + (*z - '0'); z+=incr; eValid = 1; } } /* skip trailing spaces */ if( nDigits && eValid ){ while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; } do_atof_calc: /* adjust exponent by d, and update sign */ e = (e*esign) + d; if( e<0 ) { esign = -1; e *= -1; } else { esign = 1; |
︙ | ︙ | |||
407 408 409 410 411 412 413 | result = (double)s; } } /* store the result */ *pResult = result; | | | | > | | > | > | > > > | | | > > > > | | < < > > | | > | | > > > | > | < | < < > | | | | | | | | | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | result = (double)s; } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace chracters after */ return z>=zEnd && nDigits>0 && eValid; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } /* ** Compare the 19-character string zNum against the text representation ** value 2^63: 9223372036854775808. Return negative, zero, or positive ** if zNum is less than, equal to, or greater than the string. ** Note that zNum must contain exactly 19 characters. ** ** Unlike memcmp() this routine is guaranteed to return the difference ** in the values of the last digit if the only difference is in the ** last digit. So, for example, ** ** compare2pow63("9223372036854775800", 1) ** ** will return -8. */ static int compare2pow63(const char *zNum, int incr){ int c = 0; int i; /* 012345678901234567 */ const char *pow63 = "922337203685477580"; for(i=0; c==0 && i<18; i++){ c = (zNum[i*incr]-pow63[i])*10; } if( c==0 ){ c = zNum[18*incr] - '8'; testcase( c==(-1) ); testcase( c==0 ); testcase( c==(+1) ); } return c; } /* ** Convert zNum to a 64-bit signed integer and write ** the value of the integer into *pNum. ** If zNum is exactly 9223372036854665808, return 2. ** This is a special case as the context will determine ** if it is too big (used as a negative). ** If zNum is not an integer or is an integer that ** is too large to be expressed with 64 bits, ** then return 1. Otherwise return 0. ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is ** given by enc. */ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr = (enc==SQLITE_UTF8?1:2); i64 v = 0; int neg = 0; /* assume positive */ int i; int c = 0; const char *zStart; const char *zEnd = zNum + length; if( enc==SQLITE_UTF16BE ) zNum++; while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr; if( zNum>=zEnd ) goto do_atoi_calc; if( *zNum=='-' ){ neg = 1; zNum+=incr; }else if( *zNum=='+' ){ zNum+=incr; } do_atoi_calc: zStart = zNum; while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */ for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){ v = v*10 + c - '0'; } *pNum = neg ? -v : v; testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ return 0; }else{ /* 19-digit numbers must be no larger than 9223372036854775807 if positive ** or 9223372036854775808 if negative. Note that 9223372036854665808 ** is 2^63. Return 1 if to large */ c=compare2pow63(zNum, incr); if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */ return c<neg ? 0 : 1; } } /* ** If zNum represents an integer that will fit in 32-bits, then set ** *pValue to that integer and return true. Otherwise return false. ** |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
245 246 247 248 249 250 251 | ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string ** looks like a number, convert it into a number. If it does not ** look like a number, leave it alone. */ static void applyNumericAffinity(Mem *pRec){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ | > | < | < | < < < < < < < | | | | | | < < < < < < | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string ** looks like a number, convert it into a number. If it does not ** look like a number, leave it alone. */ static void applyNumericAffinity(Mem *pRec){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ double rValue; i64 iValue; u8 enc = pRec->enc; if( (pRec->flags&MEM_Str)==0 ) return; if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; pRec->flags |= MEM_Int; }else{ pRec->r = rValue; pRec->flags |= MEM_Real; } } } /* ** Processing is determine by the affinity parameter: ** |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | ** This opcode is used when extracting information from a column that ** has REAL affinity. Such column values may still be stored as ** integers, for space efficiency, but after extraction we want them ** to have only a real value. */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; | < | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | ** This opcode is used when extracting information from a column that ** has REAL affinity. Such column values may still be stored as ** integers, for space efficiency, but after extraction we want them ** to have only a real value. */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & MEM_Int ){ sqlite3VdbeMemRealify(pIn1); } break; } #endif |
︙ | ︙ | |||
1594 1595 1596 1597 1598 1599 1600 | ** Strings are simply reinterpreted as blobs with no change ** to the underlying data. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ pIn1 = &aMem[pOp->p1]; | < | 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | ** Strings are simply reinterpreted as blobs with no change ** to the underlying data. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & MEM_Null ) break; if( (pIn1->flags & MEM_Blob)==0 ){ applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); assert( pIn1->flags & MEM_Str || db->mallocFailed ); MemSetTypeFlag(pIn1, MEM_Blob); }else{ pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob); |
︙ | ︙ | |||
1619 1620 1621 1622 1623 1624 1625 | ** equivalent of atoi() or atof() and store 0 if no such conversion ** is possible. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; | < < | < < | 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 | ** equivalent of atoi() or atof() and store 0 if no such conversion ** is possible. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; sqlite3VdbeMemNumerify(pIn1); break; } #endif /* SQLITE_OMIT_CAST */ /* Opcode: ToInt P1 * * * * ** ** Force the value in register P1 to be an integer. If ** The value is currently a real number, drop its fractional part. ** If the value is text or blob, try to convert it to an integer using the ** equivalent of atoi() and store 0 if no such conversion is possible. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToInt: { /* same as TK_TO_INT, in1 */ pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_Null)==0 ){ sqlite3VdbeMemIntegerify(pIn1); } break; } #if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) |
︙ | ︙ | |||
1750 1751 1752 1753 1754 1755 1756 | int res; /* Result of the comparison of pIn1 against pIn3 */ char affinity; /* Affinity to use for comparison */ u16 flags1; /* Copy of initial value of pIn1->flags */ u16 flags3; /* Copy of initial value of pIn3->flags */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; | < < | 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 | int res; /* Result of the comparison of pIn1 against pIn3 */ char affinity; /* Affinity to use for comparison */ u16 flags1; /* Copy of initial value of pIn1->flags */ u16 flags3; /* Copy of initial value of pIn3->flags */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; flags3 = pIn3->flags; if( (pIn1->flags | pIn3->flags)&MEM_Null ){ /* One or both operands are NULL */ if( pOp->p5 & SQLITE_NULLEQ ){ /* If SQLITE_NULLEQ is set (which will only happen if the operator is ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
︙ | ︙ | |||
2374 2375 2376 2377 2378 2379 2380 | zAffinity = pOp->p4.z; assert( zAffinity!=0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; while( (cAff = *(zAffinity++))!=0 ){ assert( pIn1 <= &p->aMem[p->nMem] ); assert( memIsValid(pIn1) ); | < | 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 | zAffinity = pOp->p4.z; assert( zAffinity!=0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; while( (cAff = *(zAffinity++))!=0 ){ assert( pIn1 <= &p->aMem[p->nMem] ); assert( memIsValid(pIn1) ); ExpandBlob(pIn1); applyAffinity(pIn1, cAff, encoding); pIn1++; } break; } |
︙ | ︙ | |||
2452 2453 2454 2455 2456 2457 2458 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pLast; pRec++){ assert( memIsValid(pRec) ); if( zAffinity ){ | < | 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pLast; pRec++){ assert( memIsValid(pRec) ); if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } if( pRec->flags&MEM_Zero && pRec->n>0 ){ sqlite3VdbeMemExpandBlob(pRec); } serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
364 365 366 367 368 369 370 | flags = pMem->flags; if( flags & MEM_Int ){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->r); }else if( flags & (MEM_Str|MEM_Blob) ){ i64 value; | < < < < < | > | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | flags = pMem->flags; if( flags & MEM_Int ){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->r); }else if( flags & (MEM_Str|MEM_Blob) ){ i64 value; assert( pMem->z || pMem->n==0 ); testcase( pMem->z==0 ); sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; }else{ return 0; } } /* |
︙ | ︙ | |||
400 401 402 403 404 405 406 | pMem->flags |= MEM_Str; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } assert( pMem->z ); | | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | pMem->flags |= MEM_Str; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } assert( pMem->z ); sqlite3AtoF(pMem->z, &val, pMem->n, SQLITE_UTF8); return val; }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } } |
︙ | ︙ | |||
473 474 475 476 477 478 479 | ** Invalidate any prior representations. ** ** Every effort is made to force the conversion, even if the input ** is a string that does not look completely like a number. Convert ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ | < | | | < < < < | | | | | | | > > > | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | ** Invalidate any prior representations. ** ** Every effort is made to force the conversion, even if the input ** is a string that does not look completely like a number. Convert ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ MemSetTypeFlag(pMem, MEM_Int); }else{ pMem->r = sqlite3VdbeRealValue(pMem); MemSetTypeFlag(pMem, MEM_Real); sqlite3VdbeIntegerAffinity(pMem); } } assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); pMem->flags &= ~(MEM_Str|MEM_Blob); return SQLITE_OK; } /* ** Delete any previous value and set the value stored in *pMem to NULL. */ void sqlite3VdbeMemSetNull(Mem *pMem){ |
︙ | ︙ | |||
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ int op; char *zVal = 0; sqlite3_value *pVal = 0; if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. ** The ifdef here is to enable us to achieve 100% branch test coverage even ** when SQLITE_ENABLE_STAT2 is omitted. */ #ifdef SQLITE_ENABLE_STAT2 if( op==TK_REGISTER ) op = pExpr->op2; #else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; #endif if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ | > > > > > > > > > > > > > | | > > > > | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 | u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ int op; char *zVal = 0; sqlite3_value *pVal = 0; int negInt = 1; const char *zNeg = ""; if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. ** The ifdef here is to enable us to achieve 100% branch test coverage even ** when SQLITE_ENABLE_STAT2 is omitted. */ #ifdef SQLITE_ENABLE_STAT2 if( op==TK_REGISTER ) op = pExpr->op2; #else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; #endif /* Handle negative integers in a single step. This is needed in the ** case when the value is -9223372036854775808. */ if( op==TK_UMINUS && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ pExpr = pExpr->pLeft; op = pExpr->op; negInt = -1; zNeg = "-"; } if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; } if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; if( enc!=SQLITE_UTF8 ){ sqlite3VdbeChangeEncoding(pVal, enc); } }else if( op==TK_UMINUS ) { /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ sqlite3VdbeMemNumerify(pVal); pVal->u.i = -1 * pVal->u.i; /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ pVal->r = (double)-1 * pVal->r; sqlite3ValueApplyAffinity(pVal, affinity, enc); } } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ int nVal; assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); assert( pExpr->u.zToken[1]=='\'' ); |
︙ | ︙ |
Changes to test/date.test.
︙ | ︙ | |||
80 81 82 83 84 85 86 | set sql [format {strftime('%%H:%%M:%%f',1237962480.%03d,'unixepoch')} $i] set res [format {06:28:00.%03d} $i] datetest 2.2c-$i $sql $res } datetest 2.3 {date('2003-10-22','weekday 0')} 2003-10-26 datetest 2.4 {date('2003-10-22','weekday 1')} 2003-10-27 datetest 2.4a {date('2003-10-22','weekday 1')} 2003-10-27 | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | set sql [format {strftime('%%H:%%M:%%f',1237962480.%03d,'unixepoch')} $i] set res [format {06:28:00.%03d} $i] datetest 2.2c-$i $sql $res } datetest 2.3 {date('2003-10-22','weekday 0')} 2003-10-26 datetest 2.4 {date('2003-10-22','weekday 1')} 2003-10-27 datetest 2.4a {date('2003-10-22','weekday 1')} 2003-10-27 datetest 2.4b {date('2003-10-22','weekday 1x')} NULL datetest 2.4c {date('2003-10-22','weekday -1')} NULL datetest 2.4d {date('2003-10-22','weakday 1x')} NULL datetest 2.4e {date('2003-10-22','weekday ')} NULL datetest 2.5 {date('2003-10-22','weekday 2')} 2003-10-28 datetest 2.6 {date('2003-10-22','weekday 3')} 2003-10-22 datetest 2.7 {date('2003-10-22','weekday 4')} 2003-10-23 datetest 2.8 {date('2003-10-22','weekday 5')} 2003-10-24 |
︙ | ︙ |
Added test/enc4.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | # 2010 Sept 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and # UTF-16be). # # $Id: enc4.test,v 1.0 2010/09/29 08:29:32 shaneh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # If UTF16 support is disabled, ignore the tests in this file # ifcapable {!utf16} { finish_test return } db close # The three unicode encodings understood by SQLite. set encodings [list UTF-8 UTF-16le UTF-16be] # initial value to use in SELECT set inits [list 1 1.0 1. 1e0] # vals set vals [list\ "922337203685477580792233720368547758079223372036854775807"\ "100000000000000000000000000000000000000000000000000000000"\ "1.0000000000000000000000000000000000000000000000000000000"\ ] set i 1 foreach enc $encodings { file delete -force test.db sqlite3 db test.db db eval "PRAGMA encoding = \"$enc\"" do_test enc4-$i.1 { db eval {PRAGMA encoding} } $enc set j 1 foreach init $inits { do_test enc4-$i.$j.2 { set S [sqlite3_prepare_v2 db "SELECT $init+?" -1 dummy] sqlite3_expired $S } {0} set k 1 foreach val $vals { for {set x 1} {$x<18} {incr x} { set part [expr $init + [string range $val 0 [expr $x-1]]] regsub {e\+0} $part {e+} part regsub {^1e} $part {1.0e} part do_test enc4-$i.$j.$k.3.$x { sqlite3_reset $S sqlite3_bind_text $S 1 $val $x sqlite3_step $S sqlite3_column_text $S 0 } [list $part] do_test enc4-$i.$j.$k.4.$x { sqlite3_reset $S sqlite3_bind_text16 $S 1 [encoding convertto unicode $val] [expr $x*2] sqlite3_step $S sqlite3_column_text $S 0 } [list $part] } incr k } do_test enc4-$i.$j.5 { sqlite3_finalize $S } {SQLITE_OK} incr j } db close incr i } file delete -force test.db sqlite3 db test.db do_test enc4-4.1 { db eval "select 1+1." } {2.0} do_test enc4-4.2.1 { set S [sqlite3_prepare_v2 db "SELECT 1+1." -1 dummy] sqlite3_step $S sqlite3_column_text $S 0 } {2.0} do_test enc4-4.2.2 { sqlite3_finalize $S } {SQLITE_OK} do_test enc4-4.3.1 { set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] sqlite3_bind_text $S 1 "1." 2 sqlite3_step $S sqlite3_column_text $S 0 } {2.0} do_test enc4-4.3.2 { sqlite3_finalize $S } {SQLITE_OK} do_test enc4-4.4.1 { set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] sqlite3_bind_text $S 1 "1.0" 2 sqlite3_step $S sqlite3_column_text $S 0 } {2.0} do_test enc4-4.4.2 { sqlite3_finalize $S } {SQLITE_OK} db close finish_test |
Changes to test/expr.test.
︙ | ︙ | |||
286 287 288 289 290 291 292 | test_expr expr-4.10 {r1='0.0', r2='abc'} {r1>r2} 0 test_expr expr-4.11 {r1='abc', r2='Abc'} {r1<r2} 0 test_expr expr-4.12 {r1='abc', r2='Abc'} {r1>r2} 1 test_expr expr-4.13 {r1='abc', r2='Bbc'} {r1<r2} 0 test_expr expr-4.14 {r1='abc', r2='Bbc'} {r1>r2} 1 test_expr expr-4.15 {r1='0', r2='0.0'} {r1==r2} 1 test_expr expr-4.16 {r1='0.000', r2='0.0'} {r1==r2} 1 | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | test_expr expr-4.10 {r1='0.0', r2='abc'} {r1>r2} 0 test_expr expr-4.11 {r1='abc', r2='Abc'} {r1<r2} 0 test_expr expr-4.12 {r1='abc', r2='Abc'} {r1>r2} 1 test_expr expr-4.13 {r1='abc', r2='Bbc'} {r1<r2} 0 test_expr expr-4.14 {r1='abc', r2='Bbc'} {r1>r2} 1 test_expr expr-4.15 {r1='0', r2='0.0'} {r1==r2} 1 test_expr expr-4.16 {r1='0.000', r2='0.0'} {r1==r2} 1 test_expr expr-4.17 {r1=' 0.000', r2=' 0.0'} {r1==r2} 1 test_expr expr-4.18 {r1='0.0', r2='abc'} {r1<r2} 1 test_expr expr-4.19 {r1='0.0', r2='abc'} {r1==r2} 0 test_expr expr-4.20 {r1='0.0', r2='abc'} {r1>r2} 0 } # CSL is true if LIKE is case sensitive and false if not. # NCSL is the opposite. Use these variables as the result |
︙ | ︙ |
Changes to test/index.test.
︙ | ︙ | |||
528 529 530 531 532 533 534 | INSERT INTO t1 VALUES('12.32e+4',5); INSERT INTO t1 VALUES('12.36E+04',6); INSERT INTO t1 VALUES('12.36E+',7); INSERT INTO t1 VALUES('+123.10000E+0003',8); INSERT INTO t1 VALUES('+',9); INSERT INTO t1 VALUES('+12347.E+02',10); INSERT INTO t1 VALUES('+12347E+02',11); | > > > > | | > > > > > | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | INSERT INTO t1 VALUES('12.32e+4',5); INSERT INTO t1 VALUES('12.36E+04',6); INSERT INTO t1 VALUES('12.36E+',7); INSERT INTO t1 VALUES('+123.10000E+0003',8); INSERT INTO t1 VALUES('+',9); INSERT INTO t1 VALUES('+12347.E+02',10); INSERT INTO t1 VALUES('+12347E+02',11); INSERT INTO t1 VALUES('+.125E+04',12); INSERT INTO t1 VALUES('-.125E+04',13); INSERT INTO t1 VALUES('.125E+0',14); INSERT INTO t1 VALUES('.125',15); SELECT b FROM t1 ORDER BY a, b; } } {13 14 15 12 8 5 2 1 3 6 10 11 9 4 7} do_test index-15.3 { execsql { SELECT b FROM t1 WHERE typeof(a) IN ('integer','real') ORDER BY b; } } {1 2 3 5 6 8 10 11 12 13 14 15} integrity_check index-15.4 # The following tests - index-16.* - test that when a table definition # includes qualifications that specify the same constraint twice only a # single index is generated to enforce the constraint. # # For example: "CREATE TABLE abc( x PRIMARY KEY, UNIQUE(x) );" # |
︙ | ︙ |
Added test/tkt-3998683a16.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 36 37 38 39 40 41 42 43 44 45 46 | # 2010 September 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # 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. # #*********************************************************************** # # This file implements regression tests for SQLite library. Specifically, # it tests that ticket [3998683a16a7076e08f5585c1f4816414c8c653a] where in # floating point values with a decimal point at the beginning or end # of the mantissa are used. # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt-3998683a16.1 { db eval { CREATE TABLE t1(x, y REAL); INSERT INTO t1 VALUES(1, '1.0'); INSERT INTO t1 VALUES(2, '.125'); INSERT INTO t1 VALUES(3, '123.'); INSERT INTO t1 VALUES(4, '123.e+2'); INSERT INTO t1 VALUES(5, '.125e+3'); INSERT INTO t1 VALUES(6, '123e4'); INSERT INTO t1 VALUES(11, ' 1.0'); INSERT INTO t1 VALUES(12, ' .125'); INSERT INTO t1 VALUES(13, ' 123.'); INSERT INTO t1 VALUES(14, ' 123.e+2'); INSERT INTO t1 VALUES(15, ' .125e+3'); INSERT INTO t1 VALUES(16, ' 123e4'); INSERT INTO t1 VALUES(21, '1.0 '); INSERT INTO t1 VALUES(22, '.125 '); INSERT INTO t1 VALUES(23, '123. '); INSERT INTO t1 VALUES(24, '123.e+2 '); INSERT INTO t1 VALUES(25, '.125e+3 '); INSERT INTO t1 VALUES(26, '123e4 '); SELECT x FROM t1 WHERE typeof(y)=='real' ORDER BY x; } } {1 2 3 4 5 6 11 12 13 14 15 16 21 22 23 24 25 26} finish_test |
Added test/tkt-8454a207b9.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # 2010 September 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # 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. # #*********************************************************************** # # This file implements regression tests for SQLite library. Specifically, # it tests that ticket [8454a207b9fd2243c4c6b7a73f67ea0315717c1a]. Verify # that a negative default value on an added text column actually comes # out negative. # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt-8454a207b9.1 { db eval { CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT -123.0; SELECT b, typeof(b) FROM t1; } } {-123.0 text} do_test tkt-8454a207b9.2 { db eval { ALTER TABLE t1 ADD COLUMN c TEXT DEFAULT -123.5; SELECT c, typeof(c) FROM t1; } } {-123.5 text} do_test tkt-8454a207b9.3 { db eval { ALTER TABLE t1 ADD COLUMN d TEXT DEFAULT -'hello'; SELECT d, typeof(d) FROM t1; } } {0 text} do_test tkt-8454a207b9.4 { db eval { ALTER TABLE t1 ADD COLUMN e DEFAULT -123.0; SELECT e, typeof(e) FROM t1; } } {-123 integer} do_test tkt-8454a207b9.5 { db eval { ALTER TABLE t1 ADD COLUMN f DEFAULT -123.5; SELECT f, typeof(f) FROM t1; } } {-123.5 real} do_test tkt-8454a207b9.6 { db eval { ALTER TABLE t1 ADD COLUMN g DEFAULT -9223372036854775808; SELECT g, typeof(g) FROM t1; } } {-9223372036854775808 integer} do_test tkt-8454a207b9.7 { db eval { ALTER TABLE t1 ADD COLUMN h DEFAULT 9223372036854775807; SELECT h, typeof(h) FROM t1; } } {9223372036854775807 integer} finish_test |