]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Proposed change to the fix for ticket [1c69be2dafc28b] such that legacy group-by-name-resolution
authordrh <drh@noemail.net>
Tue, 10 Jun 2014 20:18:17 +0000 (20:18 +0000)
committerdrh <drh@noemail.net>
Tue, 10 Jun 2014 20:18:17 +0000 (20:18 +0000)
applications that were exploiting the older buggy behavior in SQLite
continue to work.

FossilOrigin-Name: 401a0ca3dd7e214d07958b4659d947a443cbbc52

manifest
manifest.uuid
src/resolve.c
test/resolver01.test

index 5eed2ac67ed560c97d93161d38693158c9bd273d..3e8941918ec1f315dcdbf87250bccc93c522a7e3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\san\sunnecessary\sinitialization\sof\sthe\sszFile\sfield\sof\sunixFile\sin\nthe\sunix\sVFS.
-D 2014-06-09T20:39:03.676
+C Proposed\schange\sto\sthe\sfix\sfor\sticket\s[1c69be2dafc28b]\ssuch\sthat\slegacy\napplications\sthat\swere\sexploiting\sthe\solder\sbuggy\sbehavior\sin\sSQLite\ncontinue\sto\swork.
+D 2014-06-10T20:18:17.534
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -218,7 +218,7 @@ F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897
 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
 F src/printf.c af06f66927919730f03479fed6ae9854f73419f4
 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
-F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
+F src/resolve.c f0c6db38b85433a5cbb85f1591c708707f58ead1
 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
 F src/select.c 6762c62e11b504aa014edceab8886495165e3a77
 F src/shell.c 98ce7f52445aa0c2eac3d4553a4cdcbb6402a670
@@ -766,7 +766,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
 F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
 F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce
-F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
+F test/resolver01.test 677dd35b245bdaef6403652feea073bb8f3c0a0c
 F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
 F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
 F test/rowid.test b78b30afb9537a73788ca1233a23a32190a3bb1f
@@ -1174,7 +1174,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 10707d35786403ea5392d980f593bfecdae063dd
-R 5c924f630188cdd6e1f0b84a36c79d61
+P 6484fb5a25c2a0e5d26694285a4908a22c67ba17
+R 806d58b917ca6c1092af86ab71330c36
+T *branch * group-by-name-resolution
+T *sym-group-by-name-resolution *
+T -sym-trunk *
 U drh
-Z b2fa1d596ef871591a5ab3a0251e8787
+Z 188b7f9184efcfb7e1d91d7e12607c6c
index bf49aa9d5199fe19cb7f2f6c5908d5afd53e61f8..a35257a2c77981af6c993744ba9c21e5fe5a51ee 100644 (file)
@@ -1 +1 @@
-6484fb5a25c2a0e5d26694285a4908a22c67ba17
\ No newline at end of file
+401a0ca3dd7e214d07958b4659d947a443cbbc52
\ No newline at end of file
index 86169c51c1e069c01bb211d8808bc1a91fcd6071..24af0cee6789b0e79a1c8eb6e84928c003939c0a 100644 (file)
@@ -797,12 +797,23 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
 ** no match, or if pE is not a simple identifier, then this routine
 ** return 0.
 **
+** The sameNameOnly flag is set if pE comes from a GROUP BY clause.  The
+** arguments of a GROUP BY clause are not supposed to be able to match
+** against AS names in SQL.  But early versions of SQLite allowed this
+** behavior by mistake.  To provide backwards compatibility, a GROUP BY
+** term will match as AS alias only if the corresponding result set expression
+** refers to a table column by the same name.  In other words:
+**
+**        SELECT t1.x AS x, t2.x AS y FROM t1,t2 GROUP BY x;  -- match
+**        SELECT t1.y AS x, t2.y AS y FROM t1,t2 GROUP BY x;  -- no match
+**
 ** pEList has been resolved.  pE has not.
 */
 static int resolveAsName(
   Parse *pParse,     /* Parsing context for error messages */
   ExprList *pEList,  /* List of expressions to scan */
-  Expr *pE           /* Expression we are trying to match */
+  Expr *pE,          /* Expression we are trying to match */
+  int sameNameOnly   /* Only resolve if the alias matches the column name */
 ){
   int i;             /* Loop counter */
 
@@ -812,9 +823,16 @@ static int resolveAsName(
     char *zCol = pE->u.zToken;
     for(i=0; i<pEList->nExpr; i++){
       char *zAs = pEList->a[i].zName;
-      if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
-        return i+1;
+      if( zAs==0 ) continue;
+      if( sqlite3StrICmp(zAs, zCol)!=0 ) continue;
+      if( sameNameOnly ){
+        Expr *p = pEList->a[i].pExpr;
+        Table *pTab;
+        if( p->op!=TK_COLUMN ) continue;
+        pTab = p->pTab;
+        if( sqlite3StrICmp(pTab->aCol[p->iColumn].zName, zAs)!=0 ) continue;
       }
+      return i+1;
     }
   }
   return 0;
@@ -954,7 +972,7 @@ static int resolveCompoundOrderBy(
           return 1;
         }
       }else{
-        iCol = resolveAsName(pParse, pEList, pE);
+        iCol = resolveAsName(pParse, pEList, pE, 0);
         if( iCol==0 ){
           pDup = sqlite3ExprDup(db, pE, 0);
           if( !db->mallocFailed ){
@@ -1075,16 +1093,14 @@ static int resolveOrderGroupBy(
   for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
     Expr *pE = pItem->pExpr;
     Expr *pE2 = sqlite3ExprSkipCollate(pE);
-    if( zType[0]!='G' ){
-      iCol = resolveAsName(pParse, pSelect->pEList, pE2);
-      if( iCol>0 ){
-        /* If an AS-name match is found, mark this ORDER BY column as being
-        ** a copy of the iCol-th result-set column.  The subsequent call to
-        ** sqlite3ResolveOrderGroupBy() will convert the expression to a
-        ** copy of the iCol-th result-set expression. */
-        pItem->u.x.iOrderByCol = (u16)iCol;
-        continue;
-      }
+    iCol = resolveAsName(pParse, pSelect->pEList, pE2, zType[0]=='G');
+    if( iCol>0 ){
+      /* If an AS-name match is found, mark this ORDER BY column as being
+      ** a copy of the iCol-th result-set column.  The subsequent call to
+      ** sqlite3ResolveOrderGroupBy() will convert the expression to a
+      ** copy of the iCol-th result-set expression. */
+      pItem->u.x.iOrderByCol = (u16)iCol;
+      continue;
     }
     if( sqlite3ExprIsInteger(pE2, &iCol) ){
       /* The ORDER BY term is an integer constant.  Again, set the column
index 7d95a2132a3240c791eeac125a5b4619d04de264..d7bbc44822ee8d49d03dab8842f9ee475db104da 100644 (file)
@@ -157,10 +157,10 @@ do_execsql_test resolver01-4.1 {
 # For SQLite version 3.7.17 the answer was two rows, which is wrong.
 #
 do_execsql_test resolver01-5.1 {
-  CREATE TABLE t5(m CHAR(2));
-  INSERT INTO t5 VALUES('ax');
-  INSERT INTO t5 VALUES('bx');
-  INSERT INTO t5 VALUES('cy');
+  CREATE TABLE t5(m CHAR(2), n);
+  INSERT INTO t5 VALUES('ax',1);
+  INSERT INTO t5 VALUES('bx',2);
+  INSERT INTO t5 VALUES('cy',2);
   SELECT count(*), substr(m,2,1) AS m FROM t5 GROUP BY m ORDER BY 1, 2;
 } {1 x 1 x 1 y}
 
@@ -181,7 +181,7 @@ do_execsql_test resolver01-5.4 {
    GROUP BY substr(m,2,1) ORDER BY 1, 2;
 } {1 y 2 x}
 
-# These test case weere provided in the 2013-08-14 email from Rob Golsteijn
+# These test cases were provided in the 2013-08-14 email from Rob Golsteijn
 # that originally reported the problem of ticket [1c69be2dafc28].
 #
 do_execsql_test resolver01-6.1 {
@@ -201,8 +201,26 @@ do_execsql_test resolver01-6.3 {
    GROUP BY lower(name);
 } {1 {} 1 {}}
 
-
-
-
+# (2014-06-10) The fix to GROUP BY name binding has resulted in errors
+# in some legacy Android applications.  To work around this, GROUP BY terms
+# can be bound to AS aliases as long as the corresponding expression is
+# a column by the same name as the alias.  Verify that this exception
+# case works.  Continuation of ticket [1c69be2dafc28].
+#
+do_execsql_test resolver01-7.1 {
+  CREATE TABLE t7(m, x);
+  INSERT INTO t7 VALUES('bx',1),('ax',2),('dx',3);
+  SELECT count(*), t5.m AS m FROM t5, t7 GROUP BY m ORDER BY 2;
+} {3 ax 3 bx 3 cy}
+do_execsql_test resolver01-7.2 {
+  SELECT count(*), t5.m AS n FROM t5, t7 GROUP BY n ORDER BY 2;
+} {3 ax 6 cy}
+do_test resolver01-7.3 {
+  catchsql {
+    CREATE TABLE t7b(m, n);
+    INSERT INTO t7b SELECT * FROM t7;
+    SELECT count(*), t5.m AS n FROM t5, t7b GROUP BY n ORDER BY 2;
+  }
+} {1 {ambiguous column name: n}}
 
 finish_test