Fix a long-standing issue with the distinct-as-aggregate optimization that
only expressed when the new collating-sequence logic is turned on.

FossilOrigin-Name: 0aaf52a339808386984c30cca0c0c35ac2e70e7e
diff --git a/src/resolve.c b/src/resolve.c
index 4b9d8fa..d5d9d1c 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -111,20 +111,9 @@
     }
     pDup->iTable = pEList->a[iCol].iAlias;
   }
-#if 1 /* FIXME */
-  if( pExpr->flags & EP_Collate ){
-    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
-    if( pColl ){
-      pDup = sqlite3ExprAddCollateString(pParse, pDup, pColl->zName);
-    }
-    pDup->flags |= EP_Collate;
-  }
-#else
-  /* Should be this: */
   if( pExpr->op==TK_COLLATE ){
     pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
   }
-#endif
 
   /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
   ** prevents ExprDelete() from deleting the Expr structure itself,
diff --git a/src/select.c b/src/select.c
index 4582d2b..6a71286 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2337,7 +2337,7 @@
           pColl = sqlite3ExprCollSeq(pParse, pTerm);
         }else{
           pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
-          pTerm->flags |= EP_Collate;
+//          pTerm->flags |= EP_Collate;
         }
         pKeyMerge->aColl[i] = pColl;
         pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
@@ -2540,6 +2540,7 @@
   sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
   sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
                          (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
+  sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
   sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
 
   /* Release temporary registers
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b15e0b2..2b58a80 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2330,6 +2330,7 @@
 #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
 #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
 #define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
+#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
diff --git a/src/vdbe.c b/src/vdbe.c
index bbccac8..6b78d27 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -422,7 +422,9 @@
 ** Print the value of a register for tracing purposes:
 */
 static void memTracePrint(FILE *out, Mem *p){
-  if( p->flags & MEM_Null ){
+  if( p->flags & MEM_Invalid ){
+    fprintf(out, " undefined");
+  }else if( p->flags & MEM_Null ){
     fprintf(out, " NULL");
   }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
     fprintf(out, " si:%lld", p->u.i);
@@ -1077,6 +1079,9 @@
   while( 1 ){
     sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
     Deephemeralize(pOut);
+#ifdef SQLITE_DEBUG
+    pOut->pScopyFrom = 0;
+#endif
     REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
     if( (n--)==0 ) break;
     pOut++;
@@ -1887,9 +1892,9 @@
 ** Set the permutation used by the OP_Compare operator to be the array
 ** of integers in P4.
 **
-** The permutation is only valid until the next OP_Permutation, OP_Compare,
-** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
-** immediately prior to the OP_Compare.
+** The permutation is only valid until the next OP_Compare that has
+** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should 
+** occur immediately prior to the OP_Compare.
 */
 case OP_Permutation: {
   assert( pOp->p4type==P4_INTARRAY );
@@ -1898,7 +1903,7 @@
   break;
 }
 
-/* Opcode: Compare P1 P2 P3 P4 *
+/* Opcode: Compare P1 P2 P3 P4 P5
 **
 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
@@ -1922,6 +1927,7 @@
   CollSeq *pColl;    /* Collating sequence to use on this term */
   int bRev;          /* True for DESCENDING sort order */
 
+  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
   n = pOp->p3;
   pKeyInfo = pOp->p4.pKeyInfo;
   assert( n>0 );