]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use 0x40 (ASCII '@') instead of 0x00 to mean "no affinity" so that columns
authordrh <drh@noemail.net>
Tue, 6 Aug 2019 14:37:24 +0000 (14:37 +0000)
committerdrh <drh@noemail.net>
Tue, 6 Aug 2019 14:37:24 +0000 (14:37 +0000)
with no affinity can appear in a zero-terminated string.  Use the new
SQLITE_AFF_NONE macro for this new magic number.

FossilOrigin-Name: e8234f6939ccff4c10f741cf66d1c537cfebcbd0d1d79a618a64c755a7f087b5

manifest
manifest.uuid
src/build.c
src/expr.c
src/insert.c
src/select.c
src/sqliteInt.h
src/vdbe.c
src/where.c
src/wherecode.c
src/window.c

index df02c57e44cb6f31d5164c7ff5de08932ad71c42..92a1dc676470c96bc771b97e154fd274abf5b182 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\scolumns\sof\sviews\sand\ssub-queries\sthat\sare\sexpressions\swith\sno\saffinity\sare\snot\sassigned\sBLOB\saffinity.\sThis\smatches\sthe\sdocumentation.\sFix\sfor\s[61c853857f40da49].
-D 2019-08-05T20:53:19.747
+C Use\s0x40\s(ASCII\s'@')\sinstead\sof\s0x00\sto\smean\s"no\saffinity"\sso\sthat\scolumns\nwith\sno\saffinity\scan\sappear\sin\sa\szero-terminated\sstring.\s\sUse\sthe\snew\nSQLITE_AFF_NONE\smacro\sfor\sthis\snew\smagic\snumber.
+D 2019-08-06T14:37:24.439
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -467,7 +467,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c 397b5075441d0bd7366e93f6f2ef908dd0610cd80c4e351f4a900b614e32ccf0
 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
-F src/build.c b48552e607494b914ce45cb82ffde58d1cee3cf240529abdcb7d6445803b5fa5
+F src/build.c 14906ec302406e7ba50f5adf07942d1f4af9a7134a2d042b3ccd992787b98e56
 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 37f3d21193c4f7d141d0691cced5b39c99951bfef78df9887faf9167b9c42f37
@@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
-F src/expr.c 20dca64dd896e87747e45052fdb73f8790a64905c8ef57edee5ebe7934d6ee80
+F src/expr.c 0e6c36895aa4be921615095499fd9ba1cd83dcb81f2d46f85d49fe7f03480087
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e
 F src/func.c 905c0424900979fade3731b4a271592059425c988cb7d5b245032253712dd7c8
@@ -484,7 +484,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c ea7e0c3dae74ba766967deabc3112d77e36cb9230245b0cf422051886c911af5
+F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
 F src/main.c ddba2dd3c8b11ad1d2ecc146a85a459c50a9a6b592ff154246a5db44d601d64f
@@ -523,12 +523,12 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 3ed5a3de18b455366771a89241283fef16508a7f681af546296e95e81458efeb
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c 196bc4990e765cbebc0d2e99fb468a454da857372189a0a035aefdd138fb2db1
+F src/select.c db06006136ec50868ce6f6fe17e8dfad21b58c089f9372d29c1a79283445907f
 F src/shell.c.in e5351f14716065d6e00a0437d3910cbb1a9d4fa96af61f59f18e5623679fe605
 F src/sqlite.h.in dfe86c132b5085e00cf0539c78510b75e60d740191804c9848e8bb7aa850fff5
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
-F src/sqliteInt.h 6350fc633ada5484a6db345fb0f29d76ceb0c471e3713a07acad65d697975bda
+F src/sqliteInt.h e24c813896e6649d9ef42b85a83fb362b043858339f8c912979d519e69e3cd57
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -595,7 +595,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
 F src/util.c aef606a78b85d042138a841babbc0f98471b19b9a340b962e8fae307bc8cf3da
 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
-F src/vdbe.c 4d542e9fc51d4dd35c4c0c6e58d56bc168a6a221f71b065dfd52950bd567a8ca
+F src/vdbe.c d0c302d9f58adfbb1f5fd3542cb49ac02a8cc1375808d2a4dcacdc2a8f1fd64b
 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
 F src/vdbeInt.h 889c52272a02cea8af6e21b493b08bc9a043e3372a77fdfe838d25e73a47ac92
 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
@@ -609,11 +609,11 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
-F src/where.c dee31d6842a8f6acd54bc7a7c2505050cd0fa52228634187195bc0b64eb9c240
+F src/where.c b6055f471431fdb8e2fe388789aaac239823f85c3bd394d53be0e0f727e4cd1c
 F src/whereInt.h 2bb9632f90a1a32952d43a52587209cdd536c3548715d7859bf0c1f9a65a2efd
-F src/wherecode.c 5dd20651afc1f67bad35523514e87f017295f1cddfdf5d1ea31a8e299d7054a8
+F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0
 F src/whereexpr.c 5e559bdd24b06e3bc2e68f258bf751302954dc1e432daf71fdd8098a71462326
-F src/window.c 773d7f89e4f20270eaf6315e2707cfd8f4ca1e991604c60be69f1959d6569a75
+F src/window.c 89778546eccb05a81daf8e69957feaf8e22af6a3c63393bc3c34930fe07cde8b
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1838,8 +1838,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a29f2a7d07beff64e489e8f824babc6228c4a499fadc0ee701caa60a63baadcd f37317d81cc2864ed57c76a7347351310d61c8056a2a0179218530ba60a44986
-R b1f7472fc9b174cc74ba9e00e5ff64d4
-T +closed f37317d81cc2864ed57c76a7347351310d61c8056a2a0179218530ba60a44986
-U dan
-Z 6f3e4abeb031e13757b5ea5703f23ca4
+P e15a0977ddfad3d0f4c7654c5665ff10830c25b20ecf6ef500b1ba23fb89e31f
+R 6cb661c6ae5ac0ee443fa40f160ea1c9
+U drh
+Z b23b61942492fda7f82683e9e87934ba
index 91e7500e0d7bb836a833330fdeda477771b62e66..7f89ceb39245780a764c003c3dec51512e86ccac 100644 (file)
@@ -1 +1 @@
-e15a0977ddfad3d0f4c7654c5665ff10830c25b20ecf6ef500b1ba23fb89e31f
\ No newline at end of file
+e8234f6939ccff4c10f741cf66d1c537cfebcbd0d1d79a618a64c755a7f087b5
\ No newline at end of file
index 2a33dbb897218569017a573d5008bf1c5b728f15..a2cd4afeb06ae3e19157d38ed2bbaa0967419b69 100644 (file)
@@ -2424,10 +2424,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
 #ifndef SQLITE_OMIT_AUTHORIZATION
     xAuth = db->xAuth;
     db->xAuth = 0;
-    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, 0);
+    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
     db->xAuth = xAuth;
 #else
-    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, 0);
+    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
 #endif
     pParse->nTab = n;
     if( pTable->pCheck ){
@@ -2443,7 +2443,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
        && pParse->nErr==0
        && pTable->nCol==pSel->pEList->nExpr
       ){
-        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, 0);
+        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
+                                               SQLITE_AFF_NONE);
       }
     }else if( pSelTab ){
       /* CREATE VIEW name AS...  without an argument list.  Construct
index 28ab5b0ce807d0e4778685142f621ca0efdaf4e1..ae91f0b0401daf22b5e969b69116f2c7a295b443 100644 (file)
@@ -230,7 +230,7 @@ int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
 */
 char sqlite3CompareAffinity(Expr *pExpr, char aff2){
   char aff1 = sqlite3ExprAffinity(pExpr);
-  if( aff1 && aff2 ){
+  if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
     /* Both sides of the comparison are columns. If one has numeric
     ** affinity, use that. Otherwise use no affinity.
     */
@@ -239,15 +239,15 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){
     }else{
       return SQLITE_AFF_BLOB;
     }
-  }else if( !aff1 && !aff2 ){
+  }else if( aff1<=SQLITE_AFF_NONE && aff2<=SQLITE_AFF_NONE ){
     /* Neither side of the comparison is a column.  Compare the
     ** results directly.
     */
     return SQLITE_AFF_BLOB;
   }else{
     /* One side is a column, the other is not. Use the columns affinity. */
-    assert( aff1==0 || aff2==0 );
-    return (aff1 + aff2);
+    assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE );
+    return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE;
   }
 }
 
@@ -2800,7 +2800,7 @@ void sqlite3CodeRhsOfIN(
     struct ExprList_item *pItem;
     int r1, r2, r3;
     affinity = sqlite3ExprAffinity(pLeft);
-    if( !affinity ){
+    if( affinity<=SQLITE_AFF_NONE ){
       affinity = SQLITE_AFF_BLOB;
     }
     if( pKeyInfo ){
@@ -3490,7 +3490,7 @@ expr_code_doover:
         */
         int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
         int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
-        if( aff!=SQLITE_AFF_BLOB ){
+        if( aff>SQLITE_AFF_BLOB ){
           static const char zAff[] = "B\000C\000D\000E";
           assert( SQLITE_AFF_BLOB=='A' );
           assert( SQLITE_AFF_TEXT=='B' );
@@ -3793,7 +3793,7 @@ expr_code_doover:
         assert( nFarg==1 );
         aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
         sqlite3VdbeLoadString(v, target, 
-                              aff ? azAff[aff-SQLITE_AFF_BLOB] : "none");
+                (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
         return target;
       }
 #endif
index 2f1a19952d04b0bd05d5559057d310dbeb910c0b..53d7e89b2ab2d6a0d6eaa7c7ccbda4b3d8259c5d 100644 (file)
@@ -98,7 +98,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
         assert( pIdx->aColExpr!=0 );
         aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
       }
-      if( aff==0 ) aff = SQLITE_AFF_BLOB;
+      if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
       pIdx->zColAff[n] = aff;
     }
     pIdx->zColAff[n] = 0;
@@ -139,11 +139,12 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
     }
 
     for(i=0; i<pTab->nCol; i++){
+      assert( pTab->aCol[i].affinity!=0 );
       zColAff[i] = pTab->aCol[i].affinity;
     }
     do{
       zColAff[i--] = 0;
-    }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
+    }while( i>=0 && zColAff[i]<=SQLITE_AFF_BLOB );
     pTab->zColAff = zColAff;
   }
   assert( zColAff!=0 );
index d3e4fd24603183f09b05d2ecd32104e7ddd88d1a..f59b50e93d829257ff647e32008282258f485e84 100644 (file)
@@ -2069,7 +2069,7 @@ void sqlite3SelectAddColumnTypeAndCollation(
         pCol->colFlags |= COLFLAG_HASTYPE;
       }
     }
-    if( pCol->affinity==0 ) pCol->affinity = aff;
+    if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
     pColl = sqlite3ExprCollSeq(pParse, p);
     if( pColl && pCol->zColl==0 ){
       pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
@@ -5196,7 +5196,8 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
       Select *pSel = pFrom->pSelect;
       if( pSel ){
         while( pSel->pPrior ) pSel = pSel->pPrior;
-        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, 0);
+        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
+                                               SQLITE_AFF_NONE);
       }
     }
   }
index 821bfdbd08cce9ebf776d6883b1999985ae2be62..86358a7251820d412ee708e18ce0c3dd598979a2 100644 (file)
@@ -1874,11 +1874,12 @@ struct CollSeq {
 ** Note also that the numeric types are grouped together so that testing
 ** for a numeric type is a single comparison.  And the BLOB type is first.
 */
-#define SQLITE_AFF_BLOB     'A'
-#define SQLITE_AFF_TEXT     'B'
-#define SQLITE_AFF_NUMERIC  'C'
-#define SQLITE_AFF_INTEGER  'D'
-#define SQLITE_AFF_REAL     'E'
+#define SQLITE_AFF_NONE     0x40  /* '@' */
+#define SQLITE_AFF_BLOB     0x41  /* 'A' */
+#define SQLITE_AFF_TEXT     0x42  /* 'B' */
+#define SQLITE_AFF_NUMERIC  0x43  /* 'C' */
+#define SQLITE_AFF_INTEGER  0x44  /* 'D' */
+#define SQLITE_AFF_REAL     0x45  /* 'E' */
 
 #define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)
 
index 049c6f14675bcb62a0ef7ca3e47bf47d61a27d80..89ef666f178113a9e0a30918a63db34786a30677 100644 (file)
@@ -343,6 +343,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
 **    Convert pRec to a text representation.
 **
 ** SQLITE_AFF_BLOB:
+** SQLITE_AFF_NONE:
 **    No-op.  pRec is unchanged.
 */
 static void applyAffinity(
index 29f6eca10272d346901f22fdd9e1e753a8e562e9..4d23deb2551500d140de779424750be1fa707ad5 100644 (file)
@@ -1305,6 +1305,7 @@ char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
   if( !pIdx->zColAff ){
     if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
   }
+  assert( pIdx->zColAff[iCol]!=0 );
   return pIdx->zColAff[iCol];
 }
 #endif
index a6cfdb04f7860d1c833e8d31e0b1ee382faf8511..c781b06c15b0827df5c5e01ca1e09d5e5e794c49 100644 (file)
@@ -318,9 +318,9 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
 ** Code an OP_Affinity opcode to apply the column affinity string zAff
 ** to the n registers starting at base. 
 **
-** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the
-** beginning and end of zAff are ignored.  If all entries in zAff are
-** SQLITE_AFF_BLOB, then no code gets generated.
+** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which
+** are no-ops) at the beginning and end of zAff are ignored.  If all entries
+** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated.
 **
 ** This routine makes its own copy of zAff so that the caller is free
 ** to modify zAff after this routine returns.
@@ -333,15 +333,16 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
   }
   assert( v!=0 );
 
-  /* Adjust base and n to skip over SQLITE_AFF_BLOB entries at the beginning
-  ** and end of the affinity string.
+  /* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE
+  ** entries at the beginning and end of the affinity string.
   */
-  while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){
+  assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB );
+  while( n>0 && zAff[0]<=SQLITE_AFF_BLOB ){
     n--;
     base++;
     zAff++;
   }
-  while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){
+  while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){
     n--;
   }
 
index ef62ddda3c717658d758b342d44c99079e059199..3b9af199eb5b87247ff8cf6479a2c283f4d80d9a 100644 (file)
@@ -994,7 +994,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
       p->pSrc->a[0].pSelect = pSub;
       sqlite3SrcListAssignCursors(pParse, p->pSrc);
       pSub->selFlags |= SF_Expanded;
-      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, 0);
+      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
       if( pTab2==0 ){
         rc = SQLITE_NOMEM;
       }else{