diff --git a/VERSION b/VERSION
index 585940699b..530cdd91a2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.3
+2.2.4
diff --git a/manifest b/manifest
index 695ac99475..c3da224cff 100644
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
-C Version\s2.2.3\s(CVS\s450)
-D 2002-01-16T21:05:00
+C The\sright-hand\sside\sof\san\sAS\sin\sa\sSELECT\scan\sbe\sused\swithin\sexpressions\sof\nthe\sWHERE,\sORDER\sBY,\sGROUP\sBY,\sand/or\sHAVING\sclauses.\s(CVS\s350)
+D 2002-01-22T03:13:42
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
F Makefile.template 3e26a3b9e7aee1b811deaf673e8d8973bdb3f22d
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
-F VERSION da55054c39447bab51e716c492a9fa987086fa17
+F VERSION 2af606990ed9af7308a6e04cd7c9efd550f4e7be
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
@@ -21,9 +21,9 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c c796e387da340cb628dc1e41f684fc20253f561e
F src/btree.h 9ead7f54c270d8a554e59352ca7318fdaf411390
-F src/build.c d44fbcfaf0eacd33a4686aa4dda8fc770b640421
-F src/delete.c f7690efc09ad6a2f1f3f0490e1b0cbb676bb95cf
-F src/expr.c 8169261ac56e96c860407a8773ca10b779e32328
+F src/build.c bf8456b56011bb3761f11ff4a14121cfbbbd78da
+F src/delete.c cc200609f927ee8fefdda5d11d3f3b2288493c0f
+F src/expr.c 3c4359f9a00791f73569547bb11ce0f0fa5da631
F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
F src/insert.c 813c37719866c583e6ca7660f94f10230f4e385d
@@ -36,18 +36,18 @@ F src/pager.h f78d064c780855ff70beacbeba0e2324471b26fe
F src/parse.y f3fc4fb5766393003577bd175eb611495f6efd9f
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
-F src/select.c bddd8b5d07ffdae0d798c10b20dc7167469a3904
+F src/select.c f944a94d5004a1b87a5c6b1e41c29ac94488b42a
F src/shell.c 539a41d4121ed371d438d57d829e53056a54471c
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
-F src/sqliteInt.h 2382456c76bd66d0255d385820af1c72c961540c
+F src/sqliteInt.h 576b7b8165b2d78204412227e242cded54188bd5
F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
F src/test3.c d6775f95fd91f5b3cf0e2382a28e5aaeb68f745b
F src/tokenize.c 830e9ef684334070a26583d94770bb869e2727bf
-F src/update.c 5cb326ed4bace89cbad7d919b828da6c2a9064e4
+F src/update.c f30a47928fb7e894221eab2a81c8fa2653f96fb0
F src/util.c 3958a14a2dbfb13fa5f779976b4d0daf9ab49bb1
F src/vdbe.c 158bab65e4eafceb75a83f616caafa2c58f00242
F src/vdbe.h e5cc6fb13d1905a4339db4d6dba4ab393c0765fa
@@ -77,9 +77,9 @@ F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
F test/quick.test 6f023c7a73fc413e6d65b7a1879c79764038dc05
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
F test/rowid.test cb023f2df36886e1fc4cdfd32eaba05cf7db4331
-F test/select1.test 7423a9dbb81b6d282b13cbe10be64d1216dec155
+F test/select1.test 391a1e1a0527391d1bfa2daab279bf6be21da011
F test/select2.test ed2c1882857106b85478f54f67000e14966be4c4
-F test/select3.test 5e1fe8e5a4e63fb2827ab3b89527e0fd4ae35259
+F test/select3.test 3a053d8fd29e10b55f468644641098b5c9adbc06
F test/select4.test 29a2ffb187f3d8b6ca42a0a6b619e9cabe12e228
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
F test/sort.test 462c1161eee1abaa7cc93990e0b34d5fdb70ce19
@@ -105,11 +105,11 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
F www/c_interface.tcl 82a026b1681757f13b3f62e035f3a31407c1d353
-F www/changes.tcl 21116410e94d5f0852b49880ddf65f390423f24c
+F www/changes.tcl 0f1348ff7203706633953211c7b4bb73bd6a723f
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
F www/download.tcl 1ea61f9d89a2a5a9b2cee36b0d5cf97321bdefe0
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
-F www/faq.tcl 324ec51080e5c3d62ccce4fb22a8b839eaded694
+F www/faq.tcl 32cbc134879871604070d4cc3a32e73fb22a35f9
F www/formatchng.tcl d96e5e937dcbbebd481720aa08745ca5a906a63f
F www/index.tcl 571c585a5c0b577db2fe7cb88cf1f12cccd96ceb
F www/lang.tcl 6843fd3f85cba95fd199a350533ce742c706603c
@@ -119,7 +119,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P f74d61aaf3fec06cde2c4a6f1465f86ac9058ad2
-R 0e682a68cf7bb91386b1d3da8599787d
+P a4fe893ce7cdec0d8a4f8cdc640b8967dce7763e
+R 42174a8584ff6b02199355782a39f765
U drh
-Z d05a6c87487d5a9de2ff07f77b94d69d
+Z 43f0669b77399b52f2f84c6f1b77e1c1
diff --git a/manifest.uuid b/manifest.uuid
index ae63754710..6ed609124d 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-a4fe893ce7cdec0d8a4f8cdc640b8967dce7763e
\ No newline at end of file
+3684beab0f8a71ebdf453871bbde7a9ab1f65385
\ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 431854e117..1fbf6351d1 100644
--- a/src/build.c
+++ b/src/build.c
@@ -25,7 +25,7 @@
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.64 2002/01/10 14:31:49 drh Exp $
+** $Id: build.c,v 1.65 2002/01/22 03:13:42 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -127,18 +127,6 @@ Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
return pNew;
}
-/*
-** Recursively delete an expression tree.
-*/
-void sqliteExprDelete(Expr *p){
- if( p==0 ) return;
- if( p->pLeft ) sqliteExprDelete(p->pLeft);
- if( p->pRight ) sqliteExprDelete(p->pRight);
- if( p->pList ) sqliteExprListDelete(p->pList);
- if( p->pSelect ) sqliteSelectDelete(p->pSelect);
- sqliteFree(p);
-}
-
/*
** Locate the in-memory structure that describes
** a particular database table given the name
diff --git a/src/delete.c b/src/delete.c
index 53e6e96000..70638afbaf 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
-** $Id: delete.c,v 1.22 2001/12/21 14:30:43 drh Exp $
+** $Id: delete.c,v 1.23 2002/01/22 03:13:42 drh Exp $
*/
#include "sqliteInt.h"
@@ -70,7 +70,7 @@ void sqliteDeleteFrom(
*/
if( pWhere ){
sqliteExprResolveInSelect(pParse, pWhere);
- if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
goto delete_from_cleanup;
}
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
diff --git a/src/expr.c b/src/expr.c
index 6d2e3104b6..0a0113886b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,10 +12,25 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.37 2002/01/06 17:07:40 drh Exp $
+** $Id: expr.c,v 1.38 2002/01/22 03:13:42 drh Exp $
*/
#include "sqliteInt.h"
+
+/*
+** Recursively delete an expression tree.
+*/
+void sqliteExprDelete(Expr *p){
+ if( p==0 ) return;
+ if( p->op!=TK_AS ){
+ if( p->pLeft ) sqliteExprDelete(p->pLeft);
+ if( p->pRight ) sqliteExprDelete(p->pRight);
+ }
+ if( p->pList ) sqliteExprListDelete(p->pList);
+ if( p->pSelect ) sqliteSelectDelete(p->pSelect);
+ sqliteFree(p);
+}
+
/*
** Walk an expression tree. Return 1 if the expression is constant
** and 0 if it involves variables.
@@ -116,10 +131,24 @@ static int sqliteIsRowid(const char *z){
** Unknown columns or tables provoke an error. The function returns
** the number of errors seen and leaves an error message on pParse->zErrMsg.
*/
-int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
+int sqliteExprResolveIds(
+ Parse *pParse, /* The parser context */
+ IdList *pTabList, /* List of tables used to resolve column names */
+ ExprList *pEList, /* List of expressions used to resolve "AS" */
+ Expr *pExpr /* The expression to be analyzed. */
+){
if( pExpr==0 || pTabList==0 ) return 0;
switch( pExpr->op ){
- /* A lone identifier */
+ /* A lone identifier. Try and match it as follows:
+ **
+ ** 1. To the name of a column of one of the tables in pTabList
+ **
+ ** 2. To the right side of an AS keyword in the column list of
+ ** a SELECT statement. (For example, match against 'x' in
+ ** "SELECT a+b AS 'x' FROM t1".)
+ **
+ ** 3. One of the special names "ROWID", "OID", or "_ROWID_".
+ */
case TK_ID: {
int cnt = 0; /* Number of matches */
int i; /* Loop counter */
@@ -139,13 +168,28 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
}else{
pExpr->iColumn = j;
}
+ pExpr->op = TK_COLUMN;
}
}
}
+ if( cnt==0 && pEList!=0 ){
+ int j;
+ for(j=0; jnExpr; j++){
+ char *zAs = pEList->a[j].zName;
+ if( zAs!=0 && sqliteStrICmp(zAs, z)==0 ){
+ cnt++;
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ pExpr->op = TK_AS;
+ pExpr->iColumn = j;
+ pExpr->pLeft = pEList->a[j].pExpr;
+ }
+ }
+ }
if( cnt==0 && sqliteIsRowid(z) ){
pExpr->iColumn = -1;
pExpr->iTable = pParse->nTab;
cnt = 1 + (pTabList->nId>1);
+ pExpr->op = TK_COLUMN;
}
sqliteFree(z);
if( cnt==0 ){
@@ -159,7 +203,6 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
pParse->nErr++;
return 1;
}
- pExpr->op = TK_COLUMN;
break;
}
@@ -240,7 +283,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
case TK_IN: {
Vdbe *v = sqliteGetVdbe(pParse);
if( v==0 ) return 1;
- if( sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pLeft) ){
return 1;
}
if( pExpr->pSelect ){
@@ -309,18 +352,18 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
/* For all else, just recursively walk the tree */
default: {
if( pExpr->pLeft
- && sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){
+ && sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pLeft) ){
return 1;
}
if( pExpr->pRight
- && sqliteExprResolveIds(pParse, pTabList, pExpr->pRight) ){
+ && sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pRight) ){
return 1;
}
if( pExpr->pList ){
int i;
ExprList *pList = pExpr->pList;
for(i=0; inExpr; i++){
- if( sqliteExprResolveIds(pParse, pTabList, pList->a[i].pExpr) ){
+ if( sqliteExprResolveIds(pParse,pTabList,pEList,pList->a[i].pExpr) ){
return 1;
}
}
@@ -704,6 +747,10 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
sqliteVdbeResolveLabel(v, lbl);
break;
}
+ case TK_AS: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ break;
+ }
}
return;
}
diff --git a/src/select.c b/src/select.c
index cc4a2d9813..719f63d563 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.53 2002/01/04 03:09:30 drh Exp $
+** $Id: select.c,v 1.54 2002/01/22 03:13:42 drh Exp $
*/
#include "sqliteInt.h"
@@ -698,7 +698,7 @@ int sqliteSelect(
WhereInfo *pWInfo;
Vdbe *v;
int isAgg = 0; /* True for select lists like "count(*)" */
- ExprList *pEList; /* List of columns to extract. NULL means "*" */
+ ExprList *pEList; /* List of columns to extract. */
IdList *pTabList; /* List of tables to select from */
Expr *pWhere; /* The WHERE clause. May be NULL */
ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
@@ -798,7 +798,7 @@ int sqliteSelect(
** Resolve the column names and do a semantics check on all the expressions.
*/
for(i=0; inExpr; i++){
- if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
return 1;
}
if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
@@ -806,7 +806,7 @@ int sqliteSelect(
}
}
if( pWhere ){
- if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pWhere) ){
return 1;
}
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
@@ -816,7 +816,7 @@ int sqliteSelect(
if( pOrderBy ){
for(i=0; inExpr; i++){
Expr *pE = pOrderBy->a[i].pExpr;
- if( sqliteExprResolveIds(pParse, pTabList, pE) ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
return 1;
}
if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
@@ -827,7 +827,7 @@ int sqliteSelect(
if( pGroupBy ){
for(i=0; inExpr; i++){
Expr *pE = pGroupBy->a[i].pExpr;
- if( sqliteExprResolveIds(pParse, pTabList, pE) ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
return 1;
}
if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
@@ -842,7 +842,7 @@ int sqliteSelect(
pParse->nErr++;
return 1;
}
- if( sqliteExprResolveIds(pParse, pTabList, pHaving) ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
return 1;
}
if( sqliteExprCheck(pParse, pHaving, isAgg, 0) ){
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 11129c9428..88e7a56f86 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.77 2002/01/16 21:00:27 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.78 2002/01/22 03:13:42 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
@@ -517,7 +517,7 @@ char *sqliteTableNameFromToken(Token*);
int sqliteExprCheck(Parse*, Expr*, int, int*);
int sqliteExprCompare(Expr*, Expr*);
int sqliteFuncId(Token*);
-int sqliteExprResolveIds(Parse*, IdList*, Expr*);
+int sqliteExprResolveIds(Parse*, IdList*, ExprList*, Expr*);
void sqliteExprResolveInSelect(Parse*, Expr*);
int sqliteExprAnalyzeAggregates(Parse*, Expr*);
void sqliteParseInfoReset(Parse*);
diff --git a/src/update.c b/src/update.c
index ed760ff993..016545aa9e 100644
--- a/src/update.c
+++ b/src/update.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.26 2002/01/14 02:56:25 drh Exp $
+** $Id: update.c,v 1.27 2002/01/22 03:13:42 drh Exp $
*/
#include "sqliteInt.h"
@@ -84,7 +84,7 @@ void sqliteUpdate(
sqliteExprResolveInSelect(pParse, pChanges->a[i].pExpr);
}
if( pWhere ){
- if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
goto update_cleanup;
}
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
@@ -93,7 +93,7 @@ void sqliteUpdate(
}
chngRecno = 0;
for(i=0; inExpr; i++){
- if( sqliteExprResolveIds(pParse, pTabList, pChanges->a[i].pExpr) ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
goto update_cleanup;
}
if( sqliteExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
diff --git a/test/select1.test b/test/select1.test
index 48f834d84d..c321402bae 100644
--- a/test/select1.test
+++ b/test/select1.test
@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the SELECT statement.
#
-# $Id: select1.test,v 1.16 2001/12/16 20:05:06 drh Exp $
+# $Id: select1.test,v 1.17 2002/01/22 03:13:43 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -467,4 +467,38 @@ do_test select1-9.5 {
} {f1 f2}
unset r
+# Check for ORDER BY clauses that refer to an AS name in the column list
+#
+do_test select1-10.1 {
+ execsql {
+ SELECT f1 AS x FROM test1 ORDER BY x
+ }
+} {11 33}
+do_test select1-10.2 {
+ execsql {
+ SELECT f1 AS x FROM test1 ORDER BY -x
+ }
+} {33 11}
+do_test select1-10.3 {
+ execsql {
+ SELECT f1-23 AS x FROM test1 ORDER BY abs(x)
+ }
+} {10 -12}
+do_test select1-10.4 {
+ execsql {
+ SELECT f1-23 AS x FROM test1 ORDER BY -abs(x)
+ }
+} {-12 10}
+do_test select1-10.5 {
+ execsql {
+ SELECT f1-22 AS x, f2-22 as y FROM test1
+ }
+} {-11 0 11 22}
+do_test select1-10.6 {
+ execsql {
+ SELECT f1-22 AS x, f2-22 as y FROM test1 WHERE x>0 AND y<50
+ }
+} {11 22}
+
+
finish_test
diff --git a/test/select3.test b/test/select3.test
index 7052c392cb..d4ba8b9c84 100644
--- a/test/select3.test
+++ b/test/select3.test
@@ -12,7 +12,7 @@
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
-# $Id: select3.test,v 1.3 2001/09/16 00:13:28 drh Exp $
+# $Id: select3.test,v 1.4 2002/01/22 03:13:43 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -69,6 +69,21 @@ do_test select3-2.4 {
do_test select3-2.5 {
execsql {SELECT log*2+1, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
} {1 0 3 0 5 0.5 7 1.5 9 3.5 11 7}
+do_test select3-2.6 {
+ execsql {
+ SELECT log*2+1 as x, count(*) FROM t1 GROUP BY x ORDER BY x
+ }
+} {1 1 3 1 5 2 7 4 9 8 11 15}
+do_test select3-2.7 {
+ execsql {
+ SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY y
+ }
+} {1 1 3 1 5 2 7 4 9 8 11 15}
+do_test select3-2.8 {
+ execsql {
+ SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY 10-(x+y)
+ }
+} {11 15 9 8 7 4 5 2 3 1 1 1}
# Cannot have a HAVING without a GROUP BY
#
@@ -98,6 +113,14 @@ do_test select3-4.3 {
ORDER BY max(n)
}
} {3 4 4 8 5 15}
+do_test select3-4.4 {
+ execsql {
+ SELECT log AS x, count(*) AS y FROM t1
+ GROUP BY x
+ HAVING y>=4
+ ORDER BY max(n)
+ }
+} {3 4 4 8 5 15}
do_test select3-5.1 {
execsql {
diff --git a/www/changes.tcl b/www/changes.tcl
index 0d6e7eb98e..9e231ba360 100644
--- a/www/changes.tcl
+++ b/www/changes.tcl
@@ -17,6 +17,12 @@ proc chng {date desc} {
puts "
"
}
+chng {2002 Jan ?? (2.2.4)} {
+The label to the right of an AS in the column list of a SELECT can now
+ be used as part of an expression in the WHERE, ORDER BY, GROUP BY, and/or
+ HAVING clauses.
+}
+
chng {2002 Jan 16 (2.2.3)} {
Fix warning messages in VC++ 7.0. (Patches from nicolas352001)
Make the library thread-safe. (The code is there and appears to work
diff --git a/www/faq.tcl b/www/faq.tcl
index d8756421af..af12e01ad5 100644
--- a/www/faq.tcl
+++ b/www/faq.tcl
@@ -1,7 +1,7 @@
#
# Run this script to generated a faq.html output file
#
-set rcsid {$Id: faq.tcl,v 1.6 2002/01/16 21:00:28 drh Exp $}
+set rcsid {$Id: faq.tcl,v 1.7 2002/01/22 03:13:43 drh Exp $}
puts {
@@ -161,7 +161,7 @@ faq {
on my SparcStation.
} {
The x86 processor on your linux box is little-endian (meaning that
- the least signification byte of integers comes first) but the Sparc is
+ the least significant byte of integers comes first) but the Sparc is
big-endian (the most significant bytes comes first). SQLite databases
created on a little-endian architecture cannot be used on a big-endian
machine and vice versa.