From fd3579746937b2170c98cc392d1f2d919f82959e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2005 01:33:19 +0000 Subject: [PATCH] Infrastructure for the DISTINCT keyword in aggregate functions. But it does not work yet. If you try to use it you get an error message. (CVS 2680) FossilOrigin-Name: 4d62e36fe3819c2a1412737c2ec8a91ddc5e1777 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 8 +++++++- src/parse.y | 9 +++++++-- src/sqliteInt.h | 5 +++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4802010dde..71b1d71358 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Defend\sagainst\sdisk\sI/O\serrors\sthat\shappen\sduring\san\ssqlite3OsSeek().\s(CVS\s2679) -D 2005-09-09T01:32:06 +C Infrastructure\sfor\sthe\sDISTINCT\skeyword\sin\saggregate\sfunctions.\s\sBut\sit\sdoes\nnot\swork\syet.\s\sIf\syou\stry\sto\suse\sit\syou\sget\san\serror\smessage.\s(CVS\s2680) +D 2005-09-09T01:33:19 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -40,7 +40,7 @@ F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79 F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c 16a0e19460b14d219f39ff5c7a9eef808aa1969c F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d -F src/expr.c 38f1e135aa80dfc62e253c1e22dd6e194efd2d61 +F src/expr.c 208f8258d5f56c8da7be3e21cce4d3c34ff3e45c F src/func.c f63d417248808ff2632a3b576536abffcc21d858 F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -58,7 +58,7 @@ F src/os_win.c 5771f4b7d20b03b26ae332404cc58c088ef1b010 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 2b48db1cc6073a6d2577100866db6ae039d20940 F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164 -F src/parse.y 4c0cf6b0646166b232693249b89e32a75c6f87d7 +F src/parse.y 13c3d16e999184cb5fba39e44f133cdf01288e3e F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610 F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5 @@ -66,7 +66,7 @@ F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/select.c 2bba89bb64cd41991e5843617e2851c29661638d F src/shell.c b21daba017b8feef2fdc65ecde57f70209494217 F src/sqlite.h.in 461b2535550cf77aedfd44385da11ef7d63e57a2 -F src/sqliteInt.h b72e8dfa8c3beb329e8c488384572c127f228f1c +F src/sqliteInt.h f5d20d26b71a3a3e7672c1363545df2015647361 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c ac94682f9e601dd373912c46414a5a842db2089a F src/test1.c b569b60e35f0e3ea20e5ebfaf6e522a01c08d481 @@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 6281859425d39c11d82875301fefafad1f08416d -R b07aee02e83584082249023aa692499c +P 461e3a0a27ff083b0bae10c9880e3b41bb85ee31 +R e9d330cbdb5258f307f8eacbc6e8d07f U drh -Z 11dbc78d82810ff4ae0a68e460fdaf1a +Z f4c62c7887509e5c752378d8e7e6ab95 diff --git a/manifest.uuid b/manifest.uuid index e355d64c54..4e0a2c2dd9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -461e3a0a27ff083b0bae10c9880e3b41bb85ee31 \ No newline at end of file +4d62e36fe3819c2a1412737c2ec8a91ddc5e1777 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b71bde7500..8754c90695 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.226 2005/09/07 22:48:16 drh Exp $ +** $Id: expr.c,v 1.227 2005/09/09 01:33:19 drh Exp $ */ #include "sqliteInt.h" #include @@ -2038,6 +2038,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ return 0; } if( pA->op!=pB->op ) return 0; + if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0; if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0; if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0; if( pA->pList ){ @@ -2189,6 +2190,11 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ pItem->pFunc = sqlite3FindFunction(pParse->db, pExpr->token.z, pExpr->token.n, pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); + if( pExpr->flags & EP_Distinct ){ + pItem->iDistinct = pParse->nTab++; + }else{ + pItem->iDistinct = -1; + } } } /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry diff --git a/src/parse.y b/src/parse.y index b008a01dd8..20c2ef84e2 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.176 2005/09/07 21:22:46 drh Exp $ +** @(#) $Id: parse.y,v 1.177 2005/09/09 01:33:19 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -660,9 +660,14 @@ expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { sqlite3ExprSpan(A,&X,&Y); } %endif // SQLITE_OMIT_CAST -expr(A) ::= ID(X) LP exprlist(Y) RP(E). { +expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). { A = sqlite3ExprFunction(Y, &X); sqlite3ExprSpan(A,&X,&E); + if( D ){ + sqlite3ErrorMsg(pParse, "DISTINCT in an aggregate function " + "is not currently supported"); + A->flags |= EP_Distinct; + } } expr(A) ::= ID(X) LP STAR RP(E). { A = sqlite3ExprFunction(0, &X); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 74fb4f73f2..b212f24b2d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.412 2005/09/08 14:17:20 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.413 2005/09/09 01:33:19 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -825,6 +825,7 @@ struct AggInfo { Expr *pExpr; /* Expression encoding the function */ FuncDef *pFunc; /* The aggregate function implementation */ int iMem; /* Memory location that acts as accumulator */ + int iDistinct; /* Virtual table used to enforce DISTINCT */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ int nFuncAlloc; /* Number of slots allocated for aFunc[] */ @@ -903,7 +904,7 @@ struct Expr { #define EP_Agg 0x02 /* Contains one or more aggregate functions */ #define EP_Resolved 0x04 /* IDs have been resolved to COLUMNs */ #define EP_Error 0x08 /* Expression contains one or more errors */ -#define EP_Not 0x10 /* Operator preceeded by NOT */ +#define EP_Distinct 0x10 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x20 /* pSelect is correlated, not constant */ #define EP_Dequoted 0x40 /* True if the string has been dequoted */