From 8a51256c0c510c52247dc97acd4e2751294628b9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2005 22:29:05 +0000 Subject: [PATCH] Create separate affinities for INTEGER and REAL. (CVS 2766) FossilOrigin-Name: ce06c123d0c5663dbaf263c2e0aaf5d9cdeb2ccd --- manifest | 64 +++++++------- manifest.uuid | 2 +- src/analyze.c | 4 +- src/build.c | 30 ++++--- src/expr.c | 42 ++++++--- src/insert.c | 4 +- src/parse.y | 5 +- src/select.c | 4 +- src/sqliteInt.h | 25 ++++-- src/trigger.c | 2 +- src/update.c | 6 +- src/vdbe.c | 220 +++++++++++++++++++++++++--------------------- src/vdbeInt.h | 1 + src/vdbemem.c | 32 ++++--- src/where.c | 4 +- test/autoinc.test | 4 +- test/check.test | 20 ++--- test/expr.test | 12 +-- test/func.test | 4 +- test/index.test | 6 +- test/main.test | 4 +- test/misc5.test | 8 +- test/select3.test | 8 +- test/select6.test | 10 +-- test/sort.test | 24 ++--- test/tkt1444.test | 8 +- test/types.test | 6 +- test/types3.test | 4 +- test/where.test | 3 +- 29 files changed, 318 insertions(+), 248 deletions(-) diff --git a/manifest b/manifest index 13b9d3461c..a272077b2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sdocumentation\stypo.\s(CVS\s2765) -D 2005-11-14T11:51:46 +C Create\sseparate\saffinities\sfor\sINTEGER\sand\sREAL.\s(CVS\s2766) +D 2005-11-14T22:29:05 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -30,22 +30,22 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F src/alter.c 149e871e1ad6648da9b72e69feb1bd1407bf5226 -F src/analyze.c 2afd437e197569f6df6c15e0ae70c6f70f5c6c0c +F src/analyze.c ea42005eed52c382fcc7ef66969e7f1858597633 F src/attach.c 4b21689700a72ae281fa85dbaff06b2a62bd49ee F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454 F src/btree.c 1ccc3b3931774a68ee0d6a8e2c8ea83f27b853fb F src/btree.h 1ed561263ca0e335bc3e81d761c9d5ff8c22f61e -F src/build.c 03ccfb2d5addaa6ba7d1155cf4f27938e54b8270 +F src/build.c 8c93ae10563e8b92d3d7ea532a606424be3cb4f7 F src/callback.c 90ab4f235a2603c4cb8e6a2497091a71fb732bfa F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79 F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d -F src/expr.c 696434cee4428699957d006c564ee84f716c0559 +F src/expr.c fa22a2ed9d277e3bd4467842fbc025e106fd0d51 F src/func.c 7d81dccd9c440c6c4e761056333e629192814af0 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 -F src/insert.c e04b27e076ed093606db82400a3769a3a3b00a61 +F src/insert.c e57626dab37b14a1010f2d0304e5c54eedc9cc8b F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b F src/main.c 97bb830cdbd378d1f87469618471f52d9d263d09 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 @@ -59,15 +59,15 @@ F src/os_win.c fbccc85e7011174068c27d54256746321a1f0059 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c ca23cdff9e67a8e826e4796c60f06db6aab69b72 F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140 -F src/parse.y 6322f4b2ef60b041232215663535bc83c4dcf8b7 +F src/parse.y 9399852d7b406f832e3fee879296142d4e677090 F src/pragma.c b40189967155a522433b8470f363192a927ba22c F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4 F src/printf.c 3ea3a17d25d7ac498efc18007c70371a42c968f8 F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 -F src/select.c be02f123e8651bee22beb07d89dcfa75bcc2e291 +F src/select.c 095d5b7a9c1989f2855d496d49096559fa67710d F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3 F src/sqlite.h.in 8e648e1f386e4509f2f96c09ded7c07b0df0c9a2 -F src/sqliteInt.h e546554bdd4e3c903dd033bb1e2476193c2d4f37 +F src/sqliteInt.h 4148c9778e350014c2e27b332d7a2ef7278fe62e F src/table.c e03b60eaabaeb54a00d7e931566d77302dfc19b0 F src/tclsqlite.c 4f274fae3d4a1863451a553dd8e5015747a5d91d F src/test1.c 77506b6b88125c26f00a11bf3ff5c8dc824e837e @@ -76,19 +76,19 @@ F src/test3.c f4e6a16a602091696619a1171bda25c0e3df49f7 F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5 F src/tokenize.c bdb79702217af49eba44c2a3b4f5fc7bd9ed2917 -F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a -F src/update.c ac506fb7400158f826ec6c3a0dbe65e7ed3928d5 +F src/trigger.c aea0283a3ef729a3e9c8dc5dc1a11c9fcc0a12a7 +F src/update.c fec7665138ccf2a2133f11dcd24c1134c6b33526 F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c F src/util.c 48fecbbef4391d102a23096d32f0d74173428406 F src/vacuum.c baae8681282c7a03900043043dc7ce07d43b5a1e -F src/vdbe.c e83de8a017fe5c495fcef3093dbdca30fa6b1ea4 +F src/vdbe.c afbfb3433b3cbb0761d0f94a09126d1602fb8cc8 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 -F src/vdbeInt.h 6eba0b967dc4fc4d5dea6e3bcc66e70a44981cc9 +F src/vdbeInt.h 7824d7be3b659ad177c8f151d9612b45b1805878 F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd F src/vdbeaux.c eb1ce3a40d37a1a7e92749e0ef72e3224fa5e55f F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 -F src/vdbemem.c fdd5dbca7395df0776dc8c83b45d22c4aba21d1c -F src/where.c 5252bf20257fb8630959ae7a145fc20076f30543 +F src/vdbemem.c cd9609c1e7f71ec76d9840c84c3a57ebfa6539cf +F src/where.c 5b1bc977f34e21983fecf3878007918c844086d6 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3 F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6 @@ -101,7 +101,7 @@ F test/attach2.test 3396c012a39ddf7ba6b528d80bd79554168aa115 F test/attach3.test 63013383adc4380af69779f34f4af19bd49f7cbe F test/attachmalloc.test cdb26c42850f04698377ccec05f5fa89d987837c F test/auth.test 973ae7274eae32c4453fbbcbd0ec2b80c5b1eeb3 -F test/autoinc.test 395fbac8bc158d3599995c73bfb15c418a5429f0 +F test/autoinc.test ba46a006641a9036eabf52997b60c4156c8ed06e F test/autovacuum.test 9471d58a08b14dc0d2c15b87583c46d1744343d6 F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31 F test/autovacuum_ioerr.test 9cf27275ca47b72e188a47c53b61b6d583a01d24 @@ -124,7 +124,7 @@ F test/capi2.test f897209386fb21cfdc9267595e0c667ebaca9164 F test/capi3.test fc8e573467049add3bfaf81f53827e8ff153cf8f F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336 F test/cast.test 2543165ced4249c89ce5f0352222df503a98b9e5 -F test/check.test 65fa90003deedad4be5500c6d86dd65812f61bdd +F test/check.test 8154b8ac0c56c34088168b8d87eee713fba2b31b F test/collate1.test add9454cef160677bb8b34148b8f277ce7f9f1c4 F test/collate2.test 224a632ba04907c049804b08162efd234aa7871f F test/collate3.test 947a77f5b8227e037a7094d0e338a5504f155cc4 @@ -146,12 +146,12 @@ F test/distinctagg.test 2b89d1c5220d966a30ba4b40430338669301188b F test/enc.test 7a03417a1051fe8bc6c7641cf4c8c3f7e0066d52 F test/enc2.test 76c13b8c00beaf95b15c152e95dab51292eb1f0d F test/enc3.test f6a5f0b7b7f3a88f030d3143729b87cd5c86d837 -F test/expr.test e44b37b926a5f5f2ef9f8e69488c7dc137db3f52 +F test/expr.test 06381174d8c25fbbfd9ed335fe0cde835d39123d F test/fkey1.test 153004438d51e6769fb1ce165f6313972d6263ce -F test/func.test ee08a30ba4e3c24e11285ce15b9805519360acc2 +F test/func.test e891bebf5a939fd45c9453ad35e2280f41a30687 F test/hook.test f8605cde4c77b2c6a4a73723bf6c507796a64dda F test/in.test cead6165aebbe0d451bb2263a307173acfeb6240 -F test/index.test 834494833f29e134295a2fb0f960d4bb23fd4f88 +F test/index.test 3871c47ec475f779f0b99dc36a3d177951995712 F test/index2.test 9ad98243fd7fe833795a9cc662f371f0eed4ff4f F test/index3.test f66718cd92ce1216819d47e6a156755e4b2c4ca1 F test/insert.test b0a89e1568fe9890758f8f2b43b68e840e8f1a1a @@ -173,7 +173,7 @@ F test/limit.test 39f084f4e5f11e0b984cb517b56867cbf88df156 F test/lock.test 9b7afcb24f53d24da502abb33daaad2cd6d44107 F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9 -F test/main.test 54a9a3904d30f915577d397b2b6424b78cc54b57 +F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79 F test/malloc.test 666c77a878ce50f5c22b9211ed43e889cabb63a6 F test/malloc2.test 655b972372d2754a3f6c6ed54d7cfd18fde9bd32 F test/manydb.test 18bc28e481d8e742a767858a8149bc96056aad46 @@ -184,7 +184,7 @@ F test/misc1.test 7aabf32e698ef7cc1253f5e7fc216c65870ce485 F test/misc2.test 5c699af2fede2694736a9f45aea7e2f052686e15 F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03 F test/misc4.test fbb81c1d520f34deea819a5d94d787d3d38dc35b -F test/misc5.test d40d795f0556fab831a78fffab0310624d25f820 +F test/misc5.test ed79d4c892a4995b29d03d6baebe6457bfb35a9e F test/misuse.test 1c7fee3c4c0cb4008717ecccf5c72281fac0008e F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test 012fe5455f4fc3102490b4bad373a674e5741fdd @@ -204,12 +204,12 @@ F test/safety.test 907b64fee719554a3622853812af3886fddbbb4f F test/schema.test 21cbe7dac652f6d7eb058f3dec369bdbf46bbde6 F test/select1.test 480233d4f5a81d7d59a55e40d05084d97e57ecdf F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3 -F test/select3.test 3cb5f742d63cf6b35a14f8967ec7fb57b84c3269 +F test/select3.test 8fece41cd8f2955131b3f973a7123bec60b6e65e F test/select4.test c239f516aa31f42f2ef7c6d7cd01105f08f934ca F test/select5.test 07a90ab3c7e3f0a241a9cdea1d997b2c8a89ff0b -F test/select6.test 98a98b5596fd554215ce4487bbb0e4ba6d1cca08 +F test/select6.test f459a19bdac0501c4d3eb1a4df4b7a76f1bb8ad4 F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6 -F test/sort.test de8e2f17c3fa886ded5dbb52435f84011b68fa3d +F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/subquery.test e6de53332c0301b3cfa34edc3f3cd5fa1e859efd F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2 F test/sync.test d769caaec48456119316775e35e0fdee2fa852d7 @@ -223,7 +223,7 @@ F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c 97a830d53c24c42290501fdfba4a6e5bdd34748b F test/tkt1435.test f768e5415d102fa1d8de3f548469d8fd1b79abd8 F test/tkt1443.test 1e83b6a1e7f6e261682e67106ab3bc05f6c70e90 -F test/tkt1444.test 0f0fc1f277691f904dea2abece6db919dcae2351 +F test/tkt1444.test 5ef55d36dba1a39a96c728a519e66378a6f6816f F test/tkt1449.test f8de8a84ec12ee805ed80055e1209560f8bee4d8 F test/tkt1473.test e4637c27d606fd002de78113a8e1a142e48ffb18 F test/tkt1512.test 8efd8d07e27e99d7462f75b5711de65eb7708baf @@ -236,9 +236,9 @@ F test/trigger4.test 4bed3705c9df4aaf7a7b164a2d573410d05ca025 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9 F test/trigger7.test 0afa870be2ce1b132cdb85b17a4a4ef45aa8cece -F test/types.test b5e5590d45ea4385345b98ba75ecacf01aa9138a +F test/types.test 77b9cfe18dd9089f731bc4306dcc2ff079a8c1e0 F test/types2.test 81dd1897be8ef4b5b73d0006e6076abe40610de3 -F test/types3.test e77b2cd9062cd239efa67993e211c640bdedfaa9 +F test/types3.test e5f789503849294de74a23b433168e8211523a25 F test/unique.test 0253c4227a5dc533e312202ce21ecfad18058d18 F test/update.test 7669ca789d62c258b678e8aa7a22a57eac10f2cf F test/utf16.test 5fb019e09601774743858ef7380b6c02103ff120 @@ -246,7 +246,7 @@ F test/vacuum.test 5d4857ae2afc9c20d0edb8acc58bdc8d630126a9 F test/vacuum2.test 5d77e98c458bcdbeecc6327de5107179ba1aa095 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0 -F test/where.test 752728413eab42e5854690d84c7319cdf7edc515 +F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c 26d271a753ef87fe1e6194f53c594ab5e6783d85 @@ -317,7 +317,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P f39974ebd81f274dc4cf6cf94e6e87ee7b4a0814 -R 8e31facb5466f09fe57500c6d2a97aab +P c9b413ea22d1da926621670b903c7a683921eef0 +R d8f191533940ea8d6308558ebac8ebe3 U drh -Z 8d0635a3131d53b4556f0fb9acdf9497 +Z 9c40014d05aa62d25fcf73885189668f diff --git a/manifest.uuid b/manifest.uuid index 107c5f3c37..1fa979ba5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9b413ea22d1da926621670b903c7a683921eef0 \ No newline at end of file +ce06c123d0c5663dbaf263c2e0aaf5d9cdeb2ccd \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 59749704d4..41fecb13ba 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.10 2005/11/01 15:48:24 drh Exp $ +** @(#) $Id: analyze.c,v 1.11 2005/11/14 22:29:05 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" @@ -195,7 +195,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp(v, OP_Dup, 1, 0); } } - sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "ttt", 0); + sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0); sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0); sqlite3VdbeJumpHere(v, addr); } diff --git a/src/build.c b/src/build.c index b6ecf0f654..fe86a86c89 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.354 2005/11/03 02:03:13 drh Exp $ +** $Id: build.c,v 1.355 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" #include @@ -885,7 +885,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ ** found, the corresponding affinity is returned. If zType contains ** more than one of the substrings, entries toward the top of ** the table take priority. For example, if zType is 'BLOBINT', -** SQLITE_AFF_NUMERIC is returned. +** SQLITE_AFF_INTEGER is returned. ** ** Substring | Affinity ** -------------------------------- @@ -894,15 +894,14 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ ** 'CLOB' | SQLITE_AFF_TEXT ** 'TEXT' | SQLITE_AFF_TEXT ** 'BLOB' | SQLITE_AFF_NONE +** 'REAL' | SQLITE_AFF_REAL +** 'FLOA' | SQLITE_AFF_REAL +** 'DOUB' | SQLITE_AFF_REAL ** ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. -** -** The SQLITE_AFF_INTEGER type is only returned if useIntType is true. -** If useIntType is false, then SQLITE_AFF_INTEGER is reported back -** as SQLITE_AFF_NUMERIC */ -char sqlite3AffinityType(const Token *pType, int useIntType){ +char sqlite3AffinityType(const Token *pType){ u32 h = 0; char aff = SQLITE_AFF_NUMERIC; const unsigned char *zIn = pType->z; @@ -918,10 +917,21 @@ char sqlite3AffinityType(const Token *pType, int useIntType){ }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ aff = SQLITE_AFF_TEXT; }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ - && aff==SQLITE_AFF_NUMERIC ){ + && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ aff = SQLITE_AFF_NONE; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; +#endif }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ - aff = useIntType ? SQLITE_AFF_INTEGER : SQLITE_AFF_NUMERIC; + aff = SQLITE_AFF_INTEGER; break; } } @@ -949,7 +959,7 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){ pCol = &p->aCol[i]; sqliteFree(pCol->zType); pCol->zType = sqlite3NameFromToken(pType); - pCol->affinity = sqlite3AffinityType(pType, 0); + pCol->affinity = sqlite3AffinityType(pType); } /* diff --git a/src/expr.c b/src/expr.c index ba25a5ad4f..3fce58ca6c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.236 2005/11/05 15:07:56 drh Exp $ +** $Id: expr.c,v 1.237 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" #include @@ -43,7 +43,7 @@ char sqlite3ExprAffinity(Expr *pExpr){ } #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ - return sqlite3AffinityType(&pExpr->token, 0); + return sqlite3AffinityType(&pExpr->token); } #endif return pExpr->affinity; @@ -78,7 +78,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ /* Both sides of the comparison are columns. If one has numeric ** affinity, use that. Otherwise use no affinity. */ - if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ return SQLITE_AFF_NUMERIC; }else{ return SQLITE_AFF_NONE; @@ -126,7 +126,14 @@ static char comparisonAffinity(Expr *pExpr){ */ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); - return (aff==SQLITE_AFF_NONE) || (aff==idx_affinity); + switch( aff ){ + case SQLITE_AFF_NONE: + return 1; + case SQLITE_AFF_TEXT: + return idx_affinity==SQLITE_AFF_TEXT; + default: + return sqlite3IsNumericAffinity(idx_affinity); + } } /* @@ -936,7 +943,7 @@ static int lookupName( if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ cnt = 1; pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_NUMERIC; + pExpr->affinity = SQLITE_AFF_INTEGER; } /* @@ -1482,8 +1489,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else if( pExpr->iColumn>=0 ){ - sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); - sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn); + Table *pTab = pExpr->pTab; + int iCol = pExpr->iColumn; + sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, iCol); + sqlite3ColumnDefault(v, pTab, iCol); +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0); + } +#endif }else{ sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0); } @@ -1536,13 +1550,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* Expressions of the form: CAST(pLeft AS token) */ int aff, op; sqlite3ExprCode(pParse, pExpr->pLeft); - aff = sqlite3AffinityType(&pExpr->token, 1); - switch( aff ){ - case SQLITE_AFF_INTEGER: op = OP_ToInt; break; - case SQLITE_AFF_NUMERIC: op = OP_ToNumeric; break; - case SQLITE_AFF_TEXT: op = OP_ToText; break; - case SQLITE_AFF_NONE: op = OP_ToBlob; break; - } + aff = sqlite3AffinityType(&pExpr->token); + op = aff - SQLITE_AFF_TEXT + OP_ToText; + assert( op==OP_ToText || aff!=SQLITE_AFF_TEXT ); + assert( op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); + assert( op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); + assert( op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); + assert( op==OP_ToReal || aff!=SQLITE_AFF_REAL ); sqlite3VdbeAddOp(v, op, 0, 0); stackChng = 0; break; diff --git a/src/insert.c b/src/insert.c index ce1dc511a3..682f3d8d95 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.147 2005/11/03 02:15:03 drh Exp $ +** $Id: insert.c,v 1.148 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" @@ -305,7 +305,7 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13); sqlite3VdbeAddOp(v, OP_Column, iCur, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); - sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12); + sqlite3VdbeAddOp(v, OP_Ne, 0x100, base+12); sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1); sqlite3VdbeAddOp(v, OP_Column, iCur, 1); diff --git a/src/parse.y b/src/parse.y index d565c78aa7..fc57ce1fe5 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.183 2005/11/06 04:06:59 drh Exp $ +** @(#) $Id: parse.y,v 1.184 2005/11/14 22:29:05 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -95,6 +95,9 @@ struct AttachKey { int type; Token key; }; %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION COLUMN AGG_FUNCTION AGG_COLUMN CONST_FUNC. +// Extra tokens used by the code generator by never seen by the parser. +%nonassoc TO_TEXT TO_BLOB TO_NUMERIC TO_INT TO_REAL. + // Input is a single SQL command input ::= cmdlist. cmdlist ::= cmdlist ecmd. diff --git a/src/select.c b/src/select.c index 674157a940..945ce5789f 100644 --- a/src/select.c +++ b/src/select.c @@ -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.278 2005/11/03 00:41:17 drh Exp $ +** $Id: select.c,v 1.279 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" @@ -687,7 +687,7 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "c", P3_STATIC); sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0); break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 84ae5735c0..45070cbcf4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.427 2005/11/03 02:15:03 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.428 2005/11/14 22:29:05 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -585,12 +585,25 @@ struct CollSeq { /* ** Column affinity types. +** +** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and +** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve +** the speed a little by number the values consecutively. +** +** But rather than start with 0 or 1, we begin with 'a'. That way, +** when multiple affinity types are concatenated into a string and +** used as the P3 operand, they will be more readable. +** +** Note also that the numeric types are grouped together so that testing +** for a numeric type is a single comparison. */ -#define SQLITE_AFF_NUMERIC 'n' -#define SQLITE_AFF_INTEGER 'i' /* Used for CAST operators only */ -#define SQLITE_AFF_TEXT 't' -#define SQLITE_AFF_NONE 'o' +#define SQLITE_AFF_TEXT 'a' +#define SQLITE_AFF_NONE 'b' +#define SQLITE_AFF_NUMERIC 'c' +#define SQLITE_AFF_INTEGER 'd' +#define SQLITE_AFF_REAL 'e' +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** Each SQL table is represented in memory by an instance of the @@ -1653,7 +1666,7 @@ void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); const char *sqlite3TestErrorName(int); CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int); -char sqlite3AffinityType(const Token*, int); +char sqlite3AffinityType(const Token*); void sqlite3Analyze(Parse*, Token*, Token*); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); diff --git a/src/trigger.c b/src/trigger.c index f39d2bd83f..3da62decb0 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -223,7 +223,7 @@ void sqlite3FinishTrigger( { OP_String8, 0, 0, "CREATE TRIGGER "}, { OP_String8, 0, 0, 0 }, /* 6: SQL */ { OP_Concat, 0, 0, 0 }, - { OP_MakeRecord, 5, 0, "tttit" }, + { OP_MakeRecord, 5, 0, "aaada" }, { OP_Insert, 0, 0, 0 }, }; int addr; diff --git a/src/update.c b/src/update.c index 007d52572d..c5d4f036a1 100644 --- a/src/update.c +++ b/src/update.c @@ -12,13 +12,13 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.112 2005/09/20 17:42:23 drh Exp $ +** $Id: update.c,v 1.113 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" /* -** The most recently coded instruction was an OP_Column to retrieve column -** 'i' of table pTab. This routine sets the P3 parameter of the +** The most recently coded instruction was an OP_Column to retrieve the +** i-th column of table pTab. This routine sets the P3 parameter of the ** OP_Column to the default value, if any. ** ** The default value of a column is specified by a DEFAULT clause in the diff --git a/src/vdbe.c b/src/vdbe.c index 30f57be186..bd9cf93be7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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.495 2005/11/01 15:48:24 drh Exp $ +** $Id: vdbe.c,v 1.496 2005/11/14 22:29:05 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -117,23 +117,6 @@ int sqlite3_sort_count = 0; if( ((P)->flags&MEM_Ephem)!=0 \ && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} -/* -** Convert the given stack entity into a integer if it isn't one -** already. -** -** Any prior string or real representation is invalidated. -** NULLs are converted into 0. -*/ -#define Integerify(P) sqlite3VdbeMemIntegerify(P) - -/* -** Convert P so that it has type MEM_Real. -** -** Any prior string or integer representation is invalidated. -** NULLs are converted into 0.0. -*/ -#define Realify(P) sqlite3VdbeMemRealify(P) - /* ** Argument pMem points at a memory cell that will be passed to a ** user-defined function or returned to the user as the result of a query. @@ -188,17 +171,25 @@ static Cursor *allocateCursor(Vdbe *p, int iCur){ } /* -** Apply any conversion required by the supplied column affinity to -** memory cell pRec. affinity may be one of: +** Processing is determine by the affinity parameter: ** -** SQLITE_AFF_NUMERIC -** SQLITE_AFF_TEXT -** SQLITE_AFF_NONE +** SQLITE_AFF_INTEGER: +** SQLITE_AFF_REAL: +** SQLITE_AFF_NUMERIC: +** Try to convert pRec to an integer representation or a +** floating-point representation if an integer representation +** is not possible. Note that the integer representation is +** always preferred, even if the affinity is REAL, because +** an integer representation is more space efficient on disk. +** +** SQLITE_AFF_TEXT: +** Convert pRec to a text representation. +** +** SQLITE_AFF_NONE: +** No-op. pRec is unchanged. */ static void applyAffinity(Mem *pRec, char affinity, u8 enc){ - if( affinity==SQLITE_AFF_NONE ){ - /* do nothing */ - }else if( affinity==SQLITE_AFF_TEXT ){ + if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real ** representation (blob and NULL do not get converted) but no string ** representation. @@ -207,7 +198,9 @@ static void applyAffinity(Mem *pRec, char affinity, u8 enc){ sqlite3VdbeMemStringify(pRec, enc); } pRec->flags &= ~(MEM_Real|MEM_Int); - }else{ + }else if( affinity!=SQLITE_AFF_NONE ){ + assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL + || affinity==SQLITE_AFF_NUMERIC ); if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){ /* pRec does not have a valid integer or real representation. ** Attempt a conversion if pRec has a string representation and @@ -215,11 +208,14 @@ static void applyAffinity(Mem *pRec, char affinity, u8 enc){ */ int realnum; sqlite3VdbeMemNulTerminate(pRec); - if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){ - if( realnum ){ - Realify(pRec); + if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){ + i64 value; + if( !realnum && sqlite3atoi64(pRec->z, &value) ){ + sqlite3VdbeMemRelease(pRec); + pRec->i = value; + pRec->flags = MEM_Int; }else{ - Integerify(pRec); + sqlite3VdbeMemNumerify(pRec); } } }else if( pRec->flags & MEM_Real ){ @@ -635,7 +631,6 @@ case OP_Real: { /* same as TK_FLOAT, */ pTos->r = sqlite3VdbeRealValue(pTos); pTos->flags |= MEM_Real; sqlite3VdbeChangeEncoding(pTos, db->enc); - sqlite3VdbeIntegerAffinity(pTos); break; } @@ -1005,8 +1000,10 @@ case OP_Multiply: /* same as TK_STAR, no-push */ case OP_Divide: /* same as TK_SLASH, no-push */ case OP_Remainder: { /* same as TK_REM, no-push */ Mem *pNos = &pTos[-1]; + int flags; assert( pNos>=p->aStack ); - if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){ + flags = pTos->flags | pNos->flags; + if( (flags & MEM_Null)!=0 ){ Release(pTos); pTos--; Release(pTos); @@ -1021,7 +1018,6 @@ case OP_Remainder: { /* same as TK_REM, no-push */ case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0 ) goto divide_by_zero; - if( b%a!=0 ) goto floating_point_divide; b /= a; break; } @@ -1038,7 +1034,6 @@ case OP_Remainder: { /* same as TK_REM, no-push */ pTos->flags = MEM_Int; }else{ double a, b; - floating_point_divide: a = sqlite3VdbeRealValue(pTos); b = sqlite3VdbeRealValue(pNos); switch( pOp->opcode ){ @@ -1063,7 +1058,9 @@ case OP_Remainder: { /* same as TK_REM, no-push */ Release(pTos); pTos->r = b; pTos->flags = MEM_Real; - sqlite3VdbeIntegerAffinity(pTos); + if( (flags & MEM_Real)==0 ){ + sqlite3VdbeIntegerAffinity(pTos); + } } break; @@ -1243,7 +1240,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, no-push */ */ case OP_AddImm: { /* no-push */ assert( pTos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); pTos->i += pOp->p1; break; } @@ -1271,7 +1268,8 @@ case OP_ForceInt: { /* no-push */ if( pTos->flags & MEM_Int ){ v = pTos->i + (pOp->p1!=0); }else{ - Realify(pTos); + /* FIX ME: should this not be assert( pTos->flags & MEM_Real ) ??? */ + sqlite3VdbeMemRealify(pTos); v = (int)pTos->r; if( pTos->r>(double)v ) v++; if( pOp->p1 && pTos->r==(double)v ) v++; @@ -1311,52 +1309,24 @@ case OP_MustBeInt: { /* no-push */ break; } -/* Opcode: ToInt * * * +/* Opcode: RealAffinity * * * ** -** Force the value on the top of the stack 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. +** If the top of the stack is an integer, convert it to a real value. ** -** A NULL value is not changed by this routine. It remains NULL. +** 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_ToInt: { /* no-push */ +case OP_RealAffinity: { /* no-push */ assert( pTos>=p->aStack ); - if( pTos->flags & MEM_Null ) break; - assert( MEM_Str==(MEM_Blob>>3) ); - pTos->flags |= (pTos->flags&MEM_Blob)>>3; - applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc); - sqlite3VdbeMemIntegerify(pTos); + if( pTos->flags & MEM_Int ){ + sqlite3VdbeMemRealify(pTos); + } break; } #ifndef SQLITE_OMIT_CAST -/* Opcode: ToNumeric * * * -** -** Force the value on the top of the stack to be numeric (either an -** integer or a floating-point number. -** If the value is text or blob, try to convert it to an using the -** 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: { /* no-push */ - assert( pTos>=p->aStack ); - if( pTos->flags & MEM_Null ) break; - assert( MEM_Str==(MEM_Blob>>3) ); - pTos->flags |= (pTos->flags&MEM_Blob)>>3; - applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc); - if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ - sqlite3VdbeMemRealify(pTos); - }else{ - sqlite3VdbeMemRelease(pTos); - } - assert( (pTos->flags & MEM_Dyn)==0 ); - pTos->flags &= (MEM_Int|MEM_Real); - break; -} - /* Opcode: ToText * * * ** ** Force the value on the top of the stack to be text. @@ -1366,7 +1336,7 @@ case OP_ToNumeric: { /* no-push */ ** ** A NULL value is not changed by this routine. It remains NULL. */ -case OP_ToText: { /* no-push */ +case OP_ToText: { /* same as TK_TO_TEXT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; assert( MEM_Str==(MEM_Blob>>3) ); @@ -1386,7 +1356,7 @@ case OP_ToText: { /* no-push */ ** ** A NULL value is not changed by this routine. It remains NULL. */ -case OP_ToBlob: { /* no-push */ +case OP_ToBlob: { /* same as TK_TO_BLOB, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; if( (pTos->flags & MEM_Blob)==0 ){ @@ -1397,6 +1367,60 @@ case OP_ToBlob: { /* no-push */ pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str); break; } + +/* Opcode: ToNumeric * * * +** +** Force the value on the top of the stack to be numeric (either an +** integer or a floating-point number.) +** If the value is text or blob, try to convert it to an using the +** 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, no-push */ + assert( pTos>=p->aStack ); + if( (pTos->flags & MEM_Null)==0 ){ + sqlite3VdbeMemNumerify(pTos); + } + break; +} +#endif /* SQLITE_OMIT_CAST */ + +/* Opcode: ToInt * * * +** +** Force the value on the top of the stack 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, no-push */ + assert( pTos>=p->aStack ); + if( (pTos->flags & MEM_Null)==0 ){ + sqlite3VdbeMemIntegerify(pTos); + } + break; +} + +#ifndef SQLITE_OMIT_CAST +/* Opcode: ToReal * * * +** +** Force the value on the top of the stack to be a floating point number. +** If The value is currently an integer, convert it. +** 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_ToReal: { /* same as TK_TO_REAL, no-push */ + assert( pTos>=p->aStack ); + if( (pTos->flags & MEM_Null)==0 ){ + sqlite3VdbeMemRealify(pTos); + } + break; +} #endif /* SQLITE_OMIT_CAST */ /* Opcode: Eq P1 P2 P3 @@ -1416,7 +1440,8 @@ case OP_ToBlob: { /* no-push */ ** 0x200 is set but is NULL when the 0x200 bit of P1 is clear. ** ** The least significant byte of P1 (mask 0xff) must be an affinity character - -** 'n', 't', or 'o' - or 0x00. An attempt is made to coerce both values +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** to coerce both values ** according to the affinity before the comparison is made. If the byte is ** 0x00, then numeric affinity is used. ** @@ -1565,13 +1590,13 @@ case OP_Or: { /* same as TK_OR, no-push */ if( pTos->flags & MEM_Null ){ v1 = 2; }else{ - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); v1 = pTos->i==0; } if( pNos->flags & MEM_Null ){ v2 = 2; }else{ - Integerify(pNos); + sqlite3VdbeMemIntegerify(pNos); v2 = pNos->i==0; } if( pOp->opcode==OP_And ){ @@ -1614,7 +1639,6 @@ case OP_AbsValue: { pTos->r = -pTos->r; } pTos->flags = MEM_Real; - sqlite3VdbeIntegerAffinity(pTos); }else if( pTos->flags & MEM_Int ){ Release(pTos); if( pOp->opcode==OP_Negative || pTos->i<0 ){ @@ -1624,7 +1648,7 @@ case OP_AbsValue: { }else if( pTos->flags & MEM_Null ){ /* Do nothing */ }else{ - Realify(pTos); + sqlite3VdbeMemNumerify(pTos); goto neg_abs_real_case; } break; @@ -1639,7 +1663,7 @@ case OP_AbsValue: { case OP_Not: { /* same as TK_NOT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); assert( (pTos->flags & MEM_Dyn)==0 ); pTos->i = !pTos->i; pTos->flags = MEM_Int; @@ -1655,7 +1679,7 @@ case OP_Not: { /* same as TK_NOT, no-push */ case OP_BitNot: { /* same as TK_BITNOT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); assert( (pTos->flags & MEM_Dyn)==0 ); pTos->i = ~pTos->i; pTos->flags = MEM_Int; @@ -2074,10 +2098,8 @@ op_column_out: ** field of the index key (i.e. the first character of P3 corresponds to the ** lowest element on the stack). ** -** The mapping from character to affinity is as follows: -** 'n' = NUMERIC. -** 't' = TEXT. -** 'o' = NONE. +** The mapping from character to affinity is given by the SQLITE_AFF_ +** macros defined in sqliteInt.h. ** ** If P3 is NULL then all index fields have the affinity NONE. ** @@ -2158,7 +2180,7 @@ case OP_MakeRecord: { if( addRowid ){ pRowid = &pTos[0-nField]; assert( pRowid>=p->aStack ); - Integerify(pRowid); + sqlite3VdbeMemIntegerify(pRowid); serial_type = sqlite3VdbeSerialType(pRowid); nData += sqlite3VdbeSerialTypeLen(serial_type); nHdr += sqlite3VarintLen(serial_type); @@ -2388,7 +2410,7 @@ case OP_SetCookie: { /* no-push */ pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); assert( pTos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i); if( pOp->p2==0 ){ @@ -2487,7 +2509,7 @@ case OP_OpenWrite: { /* no-push */ Cursor *pCur; assert( pTos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); iDb = pTos->i; assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; @@ -2497,7 +2519,7 @@ case OP_OpenWrite: { /* no-push */ wrFlag = pOp->opcode==OP_OpenWrite; if( p2<=0 ){ assert( pTos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); p2 = pTos->i; assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; @@ -2717,7 +2739,7 @@ case OP_MoveGt: { /* no-push */ *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe; if( pC->isTable ){ i64 iKey; - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); iKey = intToKey(pTos->i); if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){ pC->movetoTarget = iKey; @@ -2887,7 +2909,7 @@ case OP_IsUnique: { /* no-push */ /* Pop the value R off the top of the stack */ assert( pNos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); R = pTos->i; assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; @@ -3116,7 +3138,7 @@ case OP_NewRowid: { Mem *pMem; assert( pOp->p2>0 && pOp->p2nMem ); /* P2 is a valid memory cell */ pMem = &p->aMem[pOp->p2]; - Integerify(pMem); + sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P2) holds an integer */ if( pMem->i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; @@ -3997,7 +4019,7 @@ case OP_IntegrityCk: { */ case OP_FifoWrite: { /* no-push */ assert( pTos>=p->aStack ); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pTos); sqlite3VdbeFifoPush(&p->sFifo, pTos->i); assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; @@ -4121,8 +4143,8 @@ case OP_MemMax: { /* no-push */ assert( pTos>=p->aStack ); assert( i>=0 && inMem ); pMem = &p->aMem[i]; - Integerify(pMem); - Integerify(pTos); + sqlite3VdbeMemIntegerify(pMem); + sqlite3VdbeMemIntegerify(pTos); if( pMem->ii){ pMem->i = pTos->i; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index e38f809e6e..46584986d4 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -362,6 +362,7 @@ int sqlite3VdbeMemIntegerify(Mem*); double sqlite3VdbeRealValue(Mem*); void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); +int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemFinalize(Mem*, FuncDef*); diff --git a/src/vdbemem.c b/src/vdbemem.c index ba8cf56302..8ee2e2bd24 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -264,16 +264,6 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ } } -/* -** Convert pMem to type integer. Invalidate any prior representations. -*/ -int sqlite3VdbeMemIntegerify(Mem *pMem){ - pMem->i = sqlite3VdbeIntValue(pMem); - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Int; - return SQLITE_OK; -} - /* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its @@ -311,15 +301,33 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){ } } +/* +** Convert pMem to type integer. Invalidate any prior representations. +*/ +int sqlite3VdbeMemIntegerify(Mem *pMem){ + pMem->i = sqlite3VdbeIntValue(pMem); + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Int; + return SQLITE_OK; +} /* -** Convert pMem so that it is of type MEM_Real and also MEM_Int if -** possible. Invalidate any prior representations. +** Convert pMem so that it is of type MEM_Real. +** Invalidate any prior representations. */ int sqlite3VdbeMemRealify(Mem *pMem){ pMem->r = sqlite3VdbeRealValue(pMem); sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Real; + return SQLITE_OK; +} + +/* +** Convert pMem so that it has types MEM_Real or MEM_Int or both. +** Invalidate any prior representations. +*/ +int sqlite3VdbeMemNumerify(Mem *pMem){ + sqlite3VdbeMemRealify(pMem); sqlite3VdbeIntegerAffinity(pMem); return SQLITE_OK; } diff --git a/src/where.c b/src/where.c index 21958bf6c3..481902306f 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.180 2005/10/13 02:09:50 drh Exp $ +** $Id: where.c,v 1.181 2005/11/14 22:29:06 drh Exp $ */ #include "sqliteInt.h" @@ -1679,7 +1679,7 @@ WhereInfo *sqlite3WhereBegin( if( testOp!=OP_Noop ){ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); - sqlite3VdbeAddOp(v, testOp, 'n', brk); + sqlite3VdbeAddOp(v, testOp, SQLITE_AFF_NUMERIC, brk); } }else if( pLevel->flags & WHERE_COLUMN_RANGE ){ /* Case 3: The WHERE clause term that refers to the right-most diff --git a/test/autoinc.test b/test/autoinc.test index 25c881e0e9..ba7c94d258 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing the AUTOINCREMENT features. # -# $Id: autoinc.test,v 1.7 2005/08/11 02:10:19 drh Exp $ +# $Id: autoinc.test,v 1.8 2005/11/14 22:29:06 drh Exp $ # set testdir [file dirname $argv0] @@ -494,7 +494,7 @@ do_test autoinc-7.1 { INSERT INTO t7(y) VALUES(345); SELECT * FROM t7; } -} {3 345} +} {3 345.0} # Test that if the AUTOINCREMENT is applied to a non integer primary key # the error message is sensible. diff --git a/test/check.test b/test/check.test index 537fca6633..5c9f8c154b 100644 --- a/test/check.test +++ b/test/check.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing CHECK constraints # -# $Id: check.test,v 1.5 2005/11/03 12:33:29 drh Exp $ +# $Id: check.test,v 1.6 2005/11/14 22:29:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -35,7 +35,7 @@ do_test check-1.2 { INSERT INTO t1 VALUES(3,4); SELECT * FROM t1; } -} {3 4} +} {3 4.0} do_test check-1.3 { catchsql { INSERT INTO t1 VALUES(6,7); @@ -45,7 +45,7 @@ do_test check-1.4 { execsql { SELECT * FROM t1; } -} {3 4} +} {3 4.0} do_test check-1.5 { catchsql { INSERT INTO t1 VALUES(4,3); @@ -55,7 +55,7 @@ do_test check-1.6 { execsql { SELECT * FROM t1; } -} {3 4} +} {3 4.0} do_test check-1.7 { catchsql { INSERT INTO t1 VALUES(NULL,6); @@ -65,7 +65,7 @@ do_test check-1.8 { execsql { SELECT * FROM t1; } -} {3 4 {} 6} +} {3 4.0 {} 6.0} do_test check-1.9 { catchsql { INSERT INTO t1 VALUES(2,NULL); @@ -75,14 +75,14 @@ do_test check-1.10 { execsql { SELECT * FROM t1; } -} {3 4 {} 6 2 {}} +} {3 4.0 {} 6.0 2 {}} do_test check-1.11 { execsql { DELETE FROM t1 WHERE x IS NULL OR x!=3; UPDATE t1 SET x=2 WHERE x==3; SELECT * FROM t1; } -} {2 4} +} {2 4.0} do_test check-1.12 { catchsql { UPDATE t1 SET x=7 WHERE x==2 @@ -92,7 +92,7 @@ do_test check-1.13 { execsql { SELECT * FROM t1; } -} {2 4} +} {2 4.0} do_test check-1.14 { catchsql { UPDATE t1 SET x=5 WHERE x==2 @@ -102,7 +102,7 @@ do_test check-1.15 { execsql { SELECT * FROM t1; } -} {2 4} +} {2 4.0} do_test check-1.16 { catchsql { UPDATE t1 SET x=4, y=11 WHERE x==2 @@ -112,7 +112,7 @@ do_test check-1.17 { execsql { SELECT * FROM t1; } -} {4 11} +} {4 11.0} do_test check-2.1 { execsql { diff --git a/test/expr.test b/test/expr.test index bde00e98c2..a54cce35cc 100644 --- a/test/expr.test +++ b/test/expr.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # -# $Id: expr.test,v 1.47 2005/11/01 15:48:25 drh Exp $ +# $Id: expr.test,v 1.48 2005/11/14 22:29:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -29,7 +29,7 @@ proc test_expr {name settings expr result} { test_expr expr-1.1 {i1=10, i2=20} {i1+i2} 30 test_expr expr-1.2 {i1=10, i2=20} {i1-i2} -10 test_expr expr-1.3 {i1=10, i2=20} {i1*i2} 200 -test_expr expr-1.4 {i1=10, i2=20} {i1/i2} 0.5 +test_expr expr-1.4 {i1=10, i2=20} {i1/i2} 0 test_expr expr-1.5 {i1=10, i2=20} {i2/i1} 2 test_expr expr-1.6 {i1=10, i2=20} {i2i1} 0 test_expr expr-1.21 {i1=20, i2=20} {i2==i1} 1 -test_expr expr-1.22 {i1=1, i2=2, r1=3.0} {i1+i2*r1} {7} -test_expr expr-1.23 {i1=1, i2=2, r1=3.0} {(i1+i2)*r1} {9} +test_expr expr-1.22 {i1=1, i2=2, r1=3.0} {i1+i2*r1} {7.0} +test_expr expr-1.23 {i1=1, i2=2, r1=3.0} {(i1+i2)*r1} {9.0} test_expr expr-1.24 {i1=1, i2=2} {min(i1,i2,i1+i2,i1-i2)} {-1} test_expr expr-1.25 {i1=1, i2=2} {max(i1,i2,i1+i2,i1-i2)} {3} test_expr expr-1.26 {i1=1, i2=2} {max(i1,i2,i1+i2,i1-i2)} {3} @@ -160,8 +160,8 @@ test_expr expr-2.20 {r1=2.34, r2=2.34} {r2<>r1} 0 test_expr expr-2.21 {r1=2.34, r2=2.34} {r2==r1} 1 test_expr expr-2.22 {r1=1.23, r2=2.34} {min(r1,r2,r1+r2,r1-r2)} {-1.11} test_expr expr-2.23 {r1=1.23, r2=2.34} {max(r1,r2,r1+r2,r1-r2)} {3.57} -test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3 -test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99 +test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3.0 +test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99.0 test_expr expr-3.1 {t1='abc', t2='xyz'} {t11) ORDER BY a } -} {2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23} +} {2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23.0} do_test select6-3.14 { execsql { SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y) diff --git a/test/sort.test b/test/sort.test index 6d7a368557..08d496b259 100644 --- a/test/sort.test +++ b/test/sort.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # -# $Id: sort.test,v 1.24 2005/11/01 15:48:25 drh Exp $ +# $Id: sort.test,v 1.25 2005/11/14 22:29:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -62,10 +62,10 @@ do_test sort-1.4 { } {2 3 6 7 1 4 5 8} do_test sort-1.5 { execsql {SELECT flt FROM t1 ORDER BY flt} -} {-11 -1.6 -0.0013442 0.123 2.15 3.141592653 123 4221} +} {-11.0 -1.6 -0.0013442 0.123 2.15 3.141592653 123.0 4221.0} do_test sort-1.6 { execsql {SELECT flt FROM t1 ORDER BY flt DESC} -} {4221 123 3.141592653 2.15 0.123 -0.0013442 -1.6 -11} +} {4221.0 123.0 3.141592653 2.15 0.123 -0.0013442 -1.6 -11.0} do_test sort-1.7 { execsql {SELECT roman FROM t1 ORDER BY roman} } {I II III IV V VI VII VIII} @@ -106,27 +106,27 @@ do_test sort-2.1.1 { UPDATE t1 SET v='x-2b' where v=='x-0.123'; SELECT v FROM t1 ORDER BY v; } -} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11} +} {x-123.0 x-2.15 x-2b x-3.141592653 x-4221.0 x0.0013442 x1.6 x11.0} do_test sort-2.1.2 { execsql { SELECT v FROM t1 ORDER BY substr(v,2,999); } -} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11} +} {x-123.0 x-2.15 x-2b x-3.141592653 x-4221.0 x0.0013442 x1.6 x11.0} do_test sort-2.1.3 { execsql { SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0; } -} {x-4221 x-123 x-3.141592653 x-2.15 x-2b x0.0013442 x1.6 x11} +} {x-4221.0 x-123.0 x-3.141592653 x-2.15 x-2b x0.0013442 x1.6 x11.0} do_test sort-2.1.4 { execsql { SELECT v FROM t1 ORDER BY substr(v,2,999) DESC; } -} {x11 x1.6 x0.0013442 x-4221 x-3.141592653 x-2b x-2.15 x-123} +} {x11.0 x1.6 x0.0013442 x-4221.0 x-3.141592653 x-2b x-2.15 x-123.0} do_test sort-2.1.5 { execsql { SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0 DESC; } -} {x11 x1.6 x0.0013442 x-2b x-2.15 x-3.141592653 x-123 x-4221} +} {x11.0 x1.6 x0.0013442 x-2b x-2.15 x-3.141592653 x-123.0 x-4221.0} # This is a bug fix for 2.2.4. # Strings are normally mapped to upper-case for a caseless comparison. @@ -196,17 +196,17 @@ do_test sort-4.6 { execsql { SELECT v FROM t1 ORDER BY 1; } -} {x-123 x-2.15 x-2b x-3.141592653 x-4.0e9 x-4221 x0.0013442 x01234567890123456789 x1.6 x11 x2.7 x5.0e10} +} {x-123.0 x-2.15 x-2b x-3.141592653 x-4.0e9 x-4221.0 x0.0013442 x01234567890123456789 x1.6 x11.0 x2.7 x5.0e10} do_test sort-4.7 { execsql { SELECT v FROM t1 ORDER BY 1 DESC; } -} {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123} +} {x5.0e10 x2.7 x11.0 x1.6 x01234567890123456789 x0.0013442 x-4221.0 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123.0} do_test sort-4.8 { execsql { SELECT substr(v,2,99) FROM t1 ORDER BY 1; } -} {-123 -2.15 -2b -3.141592653 -4.0e9 -4221 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10} +} {-123.0 -2.15 -2b -3.141592653 -4.0e9 -4221.0 0.0013442 01234567890123456789 1.6 11.0 2.7 5.0e10} #do_test sort-4.9 { # execsql { # SELECT substr(v,2,99)+0.0 FROM t1 ORDER BY 1; @@ -362,7 +362,7 @@ do_test sort-8.1 { INSERT INTO t5 VALUES(100.0,'A2'); SELECT * FROM t5 ORDER BY a, b; } -} {100 A1 100 A2} +} {100.0 A1 100.0 A2} ifcapable {bloblit} { diff --git a/test/tkt1444.test b/test/tkt1444.test index 166c3c8b9b..ba7f1f453b 100644 --- a/test/tkt1444.test +++ b/test/tkt1444.test @@ -29,23 +29,23 @@ do_test tkt1444-1.1 { CREATE VIEW DemoView AS SELECT * FROM DemoTable ORDER BY TextKey; SELECT * FROM DemoTable UNION ALL SELECT * FROM DemoView ORDER BY 1; } -} {1 2 3 1 2 3 9 8 7 9 8 7} +} {1 2 3.0 1 2 3.0 9 8 7.0 9 8 7.0} do_test tkt1444-1.2 { execsql { SELECT * FROM DemoTable UNION ALL SELECT * FROM DemoView; } -} {9 8 7 1 2 3 1 2 3 9 8 7} +} {9 8 7.0 1 2 3.0 1 2 3 9 8 7} do_test tkt1444-1.3 { execsql { DROP VIEW DemoView; CREATE VIEW DemoView AS SELECT * FROM DemoTable; SELECT * FROM DemoTable UNION ALL SELECT * FROM DemoView ORDER BY 1; } -} {1 2 3 1 2 3 9 8 7 9 8 7} +} {1 2 3.0 1 2 3 9 8 7.0 9 8 7} do_test tkt1444-1.4 { execsql { SELECT * FROM DemoTable UNION ALL SELECT * FROM DemoView; } -} {9 8 7 1 2 3 9 8 7 1 2 3} +} {9 8 7.0 1 2 3.0 9 8 7 1 2 3} finish_test diff --git a/test/types.test b/test/types.test index 0a851f4965..8ae31e2730 100644 --- a/test/types.test +++ b/test/types.test @@ -12,7 +12,7 @@ # it tests that the different storage classes (integer, real, text etc.) # all work correctly. # -# $Id: types.test,v 1.15 2005/11/01 15:48:25 drh Exp $ +# $Id: types.test,v 1.16 2005/11/14 22:29:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -56,7 +56,7 @@ do_test types-1.1.0 { # literal were inserted into a column with affinity INTEGER, NUMERIC, TEXT # or NONE, respectively. set values { - { 5.0 integer integer text integer } + { 5.0 integer integer text real } { 5.1 real real text real } { 5 integer integer text integer } { '5.0' integer integer text text } @@ -223,7 +223,7 @@ do_test types-2.2.2 { execsql { SELECT a FROM t2; } -} {0 12345.678 -12345.678} +} {0.0 12345.678 -12345.678} # Check that all the record sizes are as we expected. do_test types-2.2.3 { diff --git a/test/types3.test b/test/types3.test index ba0329205d..18b6db7d5f 100644 --- a/test/types3.test +++ b/test/types3.test @@ -12,7 +12,7 @@ # of this file is testing the interaction of SQLite manifest types # with Tcl dual-representations. # -# $Id: types3.test,v 1.2 2005/11/01 15:48:25 drh Exp $ +# $Id: types3.test,v 1.3 2005/11/14 22:29:06 drh Exp $ # set testdir [file dirname $argv0] @@ -71,7 +71,7 @@ do_test types3-2.3 { do_test types3-2.4.1 { set V [db one {SELECT 1234567890123456.1}] tcl_variable_type V -} wideInt +} double do_test types3-2.4.2 { set V [db one {SELECT 1234567890123.456}] tcl_variable_type V diff --git a/test/where.test b/test/where.test index dcceb8e0d3..83bcd0b8d6 100644 --- a/test/where.test +++ b/test/where.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clases. # -# $Id: where.test,v 1.37 2005/10/06 16:53:17 drh Exp $ +# $Id: where.test,v 1.38 2005/11/14 22:29:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -230,7 +230,6 @@ do_test where-1.41 { # Do the same kind of thing except use a join as the data source. # do_test where-2.1 { -btree_breakpoint count { SELECT w, p FROM t2, t1 WHERE x=q AND y=s AND r=8977