mirror of https://github.com/sqlite/sqlite
Fix datatype reporting and collating sequence selection so that it works
correctly on views and with the UNION, EXCEPT, and INTERCEPT operators. (CVS 839) FossilOrigin-Name: 71cc292dce59cf8224b205d1cdbff59ad12f1043
This commit is contained in:
parent
be4f31c226
commit
fcb78a4900
32
manifest
32
manifest
|
@ -1,9 +1,9 @@
|
|||
C Do\snot\sreport\san\serror\sif\sthe\sinput\sto\sthe\ssqlite\sshell\sends\sin\sa\scomment.\nTicket\s#211.\s(CVS\s838)
|
||||
D 2003-01-18T17:05:01
|
||||
C Fix\sdatatype\sreporting\sand\scollating\ssequence\sselection\sso\sthat\sit\sworks\ncorrectly\son\sviews\sand\swith\sthe\sUNION,\sEXCEPT,\sand\sINTERCEPT\soperators.\s(CVS\s839)
|
||||
D 2003-01-18T20:11:06
|
||||
F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
F VERSION cb5dfb005f1dfad89748ecd8dd06a6a31de4d01f
|
||||
F VERSION e62321dec1c1ffc06dc20c388bee76fd95a8567b
|
||||
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
|
||||
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
|
||||
F config.sub f14b07d544ca26b5d698259045136b783e18fc7f
|
||||
|
@ -15,16 +15,16 @@ F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
|||
F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
|
||||
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
|
||||
F main.mk 8b10c5df8a21cdd343986a90c75247bafaebb3aa
|
||||
F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
|
||||
F publish.sh ce0bf7e235984bc156dc5d1a0c8092db4c8442f3
|
||||
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
|
||||
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||
F src/auth.c 9c2db0bc7707f2d2e227f47e3d557b41d44ade75
|
||||
F src/btree.c 131b5903f66e148f0f9af0cedd1c6654932c4e04
|
||||
F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
|
||||
F src/build.c 3bf5d10439f669f01f45a7c7b604ee0115b23154
|
||||
F src/build.c 0454fd02e163865c82106dd52dec4a4caf908ebf
|
||||
F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c
|
||||
F src/encode.c 09d1fe8a2e97ff94cce496e2909e2ebc8947960b
|
||||
F src/expr.c 19f315a6c274897275d15ad7f238f604d178d706
|
||||
F src/expr.c 382839b92cb66a34cfa71cf1d2bc8fb818226c90
|
||||
F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63
|
||||
F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
|
||||
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
||||
|
@ -35,14 +35,14 @@ F src/os.c 3a652608c296cf639ce63bd31d255db862e45685
|
|||
F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
|
||||
F src/pager.c 081155624cff7bec54590133b69906a23f9b3659
|
||||
F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
|
||||
F src/parse.y 58655a50817f93ddd0bc3d8949e267729396949c
|
||||
F src/parse.y a4fbfbe3c4254c96dae8c33264fb54af755a3770
|
||||
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
|
||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||
F src/select.c 5ce75c1381d8ec3b89ea4d7eb5171bc57785e610
|
||||
F src/select.c 65373244633151884ea83daffb34ef98382ac3b3
|
||||
F src/shell.c cbb29252f0bd7b144d1e3126e64e17e5a314f2fd
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in 90657185cff387069d17c5b876a87a6a7a3b6f10
|
||||
F src/sqliteInt.h 1df32c9bcf08e30b5b8b978fd587fac018273c33
|
||||
F src/sqliteInt.h 1d614e04f3c439d7bb60a65f821f8ec53ef6a7e8
|
||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
|
||||
F src/test1.c 921e5dda494f836d2ebea703bd5b239a7cc963d0
|
||||
|
@ -84,12 +84,12 @@ F test/main.test c66b564554b770ee7fdbf6a66c0cd90329bc2c85
|
|||
F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd
|
||||
F test/memleak.test b4f59aa44488793b00feff2011d77d0f05b22468
|
||||
F test/minmax.test 29bc5727c3e4c792d5c4745833dd4b505905819e
|
||||
F test/misc1.test 828ea289e37d396432064ab23d2efc6ce660a0f9
|
||||
F test/misc1.test 9f9e8b6f824b4c388ce3ad0cabdc873e0d22e28e
|
||||
F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
|
||||
F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30
|
||||
F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd
|
||||
F test/pager.test d3a2e2f00999f97e056822a39d5ee2fad18bf12c
|
||||
F test/pragma.test 94c82c75af9c237866ce5290494a7bc08b661092
|
||||
F test/pragma.test 0ca0773e2559ec9715f72d90695554dc3368e8f2
|
||||
F test/printf.test a29b8afa24edb4411adfe473b12ac32c84098fce
|
||||
F test/quick.test b372c8dad4fa1554747e90683fc72e59c0c98502
|
||||
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
|
||||
|
@ -100,7 +100,7 @@ F test/select3.test ba35d6611e8bfe526a89355da39dde482d4ecd41
|
|||
F test/select4.test 10ba54f24ef6ca7958a7045b001079378db2370c
|
||||
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
||||
F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
|
||||
F test/sort.test 876b76c5a837af5bead713146c7c65f85e84fbf5
|
||||
F test/sort.test 61a729023ae4ac3be9b225dc0be026fb43fec4e6
|
||||
F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
|
||||
F test/table.test 2a94f55b39008daa79b81f37aaf7be81386ca71e
|
||||
F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
|
||||
|
@ -143,7 +143,7 @@ F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
|||
F www/faq.tcl 06276ff6c3e369374bb83034cc9d4a7d3a2a34a1
|
||||
F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936
|
||||
F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
|
||||
F www/index.tcl 7764032a802318a916ae747b047c9ad5149658a5
|
||||
F www/index.tcl 374d30b92a753428baed933623fb9f4259fc5a5c
|
||||
F www/lang.tcl 1ea38a9fe867e4fed2220f519f5c0862e7022c53
|
||||
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
|
||||
F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26
|
||||
|
@ -154,7 +154,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
|
|||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P 960a2e4af3b940d74a82f98e8bf19aeec88a05ce
|
||||
R 401c88fefa12fdbc2635d9394c8dc749
|
||||
P 32a8e6e9771d636c0ad3042632d35865bc08585b
|
||||
R 04e23a1126d9810e8620977dfdd8daac
|
||||
U drh
|
||||
Z d11acb4a94d33c83e2103e12a2cf5085
|
||||
Z d5604eb0c9b6db0f87d9ac88ab2eea6a
|
||||
|
|
|
@ -1 +1 @@
|
|||
32a8e6e9771d636c0ad3042632d35865bc08585b
|
||||
71cc292dce59cf8224b205d1cdbff59ad12f1043
|
|
@ -113,6 +113,8 @@ sqlite_set_result_error
|
|||
sqliteMalloc
|
||||
sqliteFree
|
||||
sqliteRealloc
|
||||
sqlite_set_authorizer
|
||||
sqlite_trace
|
||||
END_OF_FILE
|
||||
i386-mingw32msvc-dllwrap \
|
||||
--def sqlite.def -v --export-all \
|
||||
|
|
90
src/build.c
90
src/build.c
|
@ -25,7 +25,7 @@
|
|||
** ROLLBACK
|
||||
** PRAGMA
|
||||
**
|
||||
** $Id: build.c,v 1.123 2003/01/14 02:54:08 drh Exp $
|
||||
** $Id: build.c,v 1.124 2003/01/18 20:11:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
|
@ -530,40 +530,10 @@ void sqliteAddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
|
|||
z[j++] = c;
|
||||
}
|
||||
z[j] = 0;
|
||||
pCol->sortOrder = SQLITE_SO_NUM;
|
||||
if( pParse->db->file_format>=4 ){
|
||||
for(i=0; z[i]; i++){
|
||||
switch( z[i] ){
|
||||
case 'b':
|
||||
case 'B': {
|
||||
if( sqliteStrNICmp(&z[i],"blob",4)==0 ){
|
||||
pCol->sortOrder = SQLITE_SO_TEXT;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
case 'C': {
|
||||
if( sqliteStrNICmp(&z[i],"char",4)==0 ||
|
||||
sqliteStrNICmp(&z[i],"clob",4)==0 ){
|
||||
pCol->sortOrder = SQLITE_SO_TEXT;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
case 'X': {
|
||||
if( i>=2 && sqliteStrNICmp(&z[i-2],"text",4)==0 ){
|
||||
pCol->sortOrder = SQLITE_SO_TEXT;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pCol->sortOrder = sqliteCollateType(z, n);
|
||||
}else{
|
||||
pCol->sortOrder = SQLITE_SO_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,21 +613,47 @@ void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
|
|||
}
|
||||
|
||||
/*
|
||||
** Return the appropriate collating type given the collation type token.
|
||||
** Report an error if the type is undefined.
|
||||
** Return the appropriate collating type given a type name.
|
||||
**
|
||||
** The collation type is text (SQLITE_SO_TEXT) if the type
|
||||
** name contains the character stream "text" or "blob" or
|
||||
** "clob". Any other type name is collated as numeric
|
||||
** (SQLITE_SO_NUM).
|
||||
*/
|
||||
int sqliteCollateType(Parse *pParse, Token *pType){
|
||||
if( pType==0 ) return SQLITE_SO_UNK;
|
||||
if( pType->n==4 && sqliteStrNICmp(pType->z, "text", 4)==0 ){
|
||||
return SQLITE_SO_TEXT;
|
||||
int sqliteCollateType(const char *zType, int nType){
|
||||
int i;
|
||||
int sortOrder = SQLITE_SO_NUM;
|
||||
for(i=0; i<nType-1; i++){
|
||||
switch( zType[i] ){
|
||||
case 'b':
|
||||
case 'B': {
|
||||
if( i<nType-3 && sqliteStrNICmp(&zType[i],"blob",4)==0 ){
|
||||
return SQLITE_SO_TEXT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
case 'C': {
|
||||
if( i<nType-3 && (sqliteStrNICmp(&zType[i],"char",4)==0 ||
|
||||
sqliteStrNICmp(&zType[i],"clob",4)==0)
|
||||
){
|
||||
return SQLITE_SO_TEXT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
case 'X': {
|
||||
if( i>=2 && sqliteStrNICmp(&zType[i-2],"text",4)==0 ){
|
||||
return SQLITE_SO_TEXT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pType->n==7 && sqliteStrNICmp(pType->z, "numeric", 7)==0 ){
|
||||
return SQLITE_SO_NUM;
|
||||
}
|
||||
sqliteSetNString(&pParse->zErrMsg, "unknown collating type: ", -1,
|
||||
pType->z, pType->n, 0);
|
||||
pParse->nErr++;
|
||||
return SQLITE_SO_UNK;
|
||||
return SQLITE_SO_NUM;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.85 2003/01/14 02:49:28 drh Exp $
|
||||
** $Id: expr.c,v 1.86 2003/01/18 20:11:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
|
@ -122,7 +122,7 @@ void sqliteExprDelete(Expr *p){
|
|||
Expr *sqliteExprDup(Expr *p){
|
||||
Expr *pNew;
|
||||
if( p==0 ) return 0;
|
||||
pNew = sqliteMalloc( sizeof(*p) );
|
||||
pNew = sqliteMallocRaw( sizeof(*p) );
|
||||
if( pNew==0 ) return 0;
|
||||
memcpy(pNew, p, sizeof(*pNew));
|
||||
if( p->token.z!=0 ){
|
||||
|
|
|
@ -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.87 2003/01/13 23:27:33 drh Exp $
|
||||
** @(#) $Id: parse.y,v 1.88 2003/01/18 20:11:07 drh Exp $
|
||||
*/
|
||||
%token_prefix TK_
|
||||
%token_type {Token}
|
||||
|
@ -174,7 +174,7 @@ ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
|
|||
{sqliteCreateForeignKey(pParse,0,&T,TA,R);}
|
||||
ccons ::= defer_subclause(D). {sqliteDeferForeignKey(pParse,D);}
|
||||
ccons ::= COLLATE id(C). {
|
||||
sqliteAddCollateType(pParse, sqliteCollateType(pParse, &C));
|
||||
sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
|
||||
}
|
||||
|
||||
// The next group of rules parses the arguments to a REFERENCES clause
|
||||
|
@ -417,7 +417,7 @@ sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
|||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
||||
collate(C) ::= . {C = SQLITE_SO_UNK;}
|
||||
collate(C) ::= COLLATE id(X). {C = sqliteCollateType(pParse, &X);}
|
||||
collate(C) ::= COLLATE id(X). {C = sqliteCollateType(X.z, X.n);}
|
||||
|
||||
%type groupby_opt {ExprList*}
|
||||
%destructor groupby_opt {sqliteExprListDelete($$);}
|
||||
|
|
123
src/select.c
123
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.121 2003/01/13 23:27:33 drh Exp $
|
||||
** $Id: select.c,v 1.122 2003/01/18 20:11:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
@ -675,9 +675,48 @@ static void generateSortTail(
|
|||
}
|
||||
|
||||
/*
|
||||
** Generate code that will tell the VDBE how many columns there
|
||||
** are in the result and the name for each column. This information
|
||||
** is used to provide "argc" and "azCol[]" values in the callback.
|
||||
** Generate code that will tell the VDBE the datatypes of
|
||||
** columns in the result set.
|
||||
*/
|
||||
static void generateColumnTypes(
|
||||
Parse *pParse, /* Parser context */
|
||||
int base, /* VDBE cursor corresponding to first entry in pTabList */
|
||||
SrcList *pTabList, /* List of tables */
|
||||
ExprList *pEList /* Expressions defining the result set */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
if( (pParse->db->flags & SQLITE_ReportTypes)==0 ) return;
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
Expr *p = pEList->a[i].pExpr;
|
||||
char *zType = 0;
|
||||
if( p==0 ) continue;
|
||||
if( p->op==TK_COLUMN && pTabList ){
|
||||
Table *pTab = pTabList->a[p->iTable - base].pTab;
|
||||
int iCol = p->iColumn;
|
||||
if( iCol<0 ) iCol = pTab->iPKey;
|
||||
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
|
||||
if( iCol<0 ){
|
||||
zType = "INTEGER";
|
||||
}else{
|
||||
zType = pTab->aCol[iCol].zType;
|
||||
}
|
||||
}else{
|
||||
if( sqliteExprType(p)==SQLITE_SO_TEXT ){
|
||||
zType = "TEXT";
|
||||
}else{
|
||||
zType = "NUMERIC";
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i + pEList->nExpr, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zType, P3_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code that will tell the VDBE the names of columns
|
||||
** in the result set. This information is used to provide the
|
||||
** azCol[] vaolues in the callback.
|
||||
*/
|
||||
static void generateColumnNames(
|
||||
Parse *pParse, /* Parser context */
|
||||
|
@ -695,17 +734,6 @@ static void generateColumnNames(
|
|||
int showFullNames;
|
||||
p = pEList->a[i].pExpr;
|
||||
if( p==0 ) continue;
|
||||
if( pParse->db->flags & SQLITE_ReportTypes ){
|
||||
if( zType==0 ){
|
||||
if( sqliteExprType(p)==SQLITE_SO_TEXT ){
|
||||
zType = "TEXT";
|
||||
}else{
|
||||
zType = "NUMERIC";
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i + pEList->nExpr, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zType, P3_STATIC);
|
||||
}
|
||||
if( pEList->a[i].zName ){
|
||||
char *zName = pEList->a[i].zName;
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
|
@ -1050,6 +1078,13 @@ void sqliteSelectUnbind(Select *p){
|
|||
**
|
||||
** Any entry that does not match is flagged as an error. The number
|
||||
** of errors is returned.
|
||||
**
|
||||
** This routine does NOT correctly initialize the Expr.dataType field
|
||||
** of the ORDER BY expressions. The multiSelectSortOrder() routine
|
||||
** must be called to do that after the individual select statements
|
||||
** have all been analyzed. This routine is unable to compute Expr.dataType
|
||||
** because it must be called before the individual select statements
|
||||
** have been analyzed.
|
||||
*/
|
||||
static int matchOrderbyToColumn(
|
||||
Parse *pParse, /* A place to leave error messages */
|
||||
|
@ -1089,6 +1124,7 @@ static int matchOrderbyToColumn(
|
|||
nErr++;
|
||||
break;
|
||||
}
|
||||
if( !mustComplete ) continue;
|
||||
iCol--;
|
||||
}
|
||||
for(j=0; iCol<0 && j<pEList->nExpr; j++){
|
||||
|
@ -1137,7 +1173,43 @@ Vdbe *sqliteGetVdbe(Parse *pParse){
|
|||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This routine sets the Expr.dataType field on all elements of
|
||||
** the pOrderBy expression list. The pOrderBy list will have been
|
||||
** set up by matchOrderbyToColumn(). Hence each expression has
|
||||
** a TK_COLUMN as its root node. The Expr.iColumn refers to a
|
||||
** column in the result set. The datatype is set to SQLITE_SO_TEXT
|
||||
** if the corresponding column in p and every SELECT to the left of
|
||||
** p has a datatype of SQLITE_SO_TEXT. If the cooressponding column
|
||||
** in p or any of the left SELECTs is SQLITE_SO_NUM, then the datatype
|
||||
** of the order-by expression is set to SQLITE_SO_NUM.
|
||||
**
|
||||
** Examples:
|
||||
**
|
||||
** SELECT a,b
|
||||
*/
|
||||
static void multiSelectSortOrder(Select *p, ExprList *pOrderBy){
|
||||
int i;
|
||||
ExprList *pEList;
|
||||
if( pOrderBy==0 ) return;
|
||||
if( p==0 ){
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
pOrderBy->a[i].pExpr->dataType = SQLITE_SO_TEXT;
|
||||
}
|
||||
return;
|
||||
}
|
||||
multiSelectSortOrder(p->pPrior, pOrderBy);
|
||||
pEList = p->pEList;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
Expr *pE = pOrderBy->a[i].pExpr;
|
||||
if( pE->dataType==SQLITE_SO_NUM ) continue;
|
||||
assert( pE->iColumn>=0 );
|
||||
if( pEList->nExpr>pE->iColumn ){
|
||||
pE->dataType = sqliteExprType(pEList->a[pE->iColumn].pExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called to process a query that is really the union
|
||||
|
@ -1248,11 +1320,13 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||
assert( p->pEList );
|
||||
if( eDest==SRT_Callback ){
|
||||
generateColumnNames(pParse, p->base, 0, p->pEList);
|
||||
generateColumnTypes(pParse, p->base, p->pSrc, p->pEList);
|
||||
}
|
||||
iBreak = sqliteVdbeMakeLabel(v);
|
||||
iCont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak);
|
||||
iStart = sqliteVdbeCurrentAddr(v);
|
||||
multiSelectSortOrder(p, p->pOrderBy);
|
||||
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
||||
p->pOrderBy, -1, eDest, iParm,
|
||||
iCont, iBreak);
|
||||
|
@ -1303,12 +1377,14 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||
assert( p->pEList );
|
||||
if( eDest==SRT_Callback ){
|
||||
generateColumnNames(pParse, p->base, 0, p->pEList);
|
||||
generateColumnTypes(pParse, p->base, p->pSrc, p->pEList);
|
||||
}
|
||||
iBreak = sqliteVdbeMakeLabel(v);
|
||||
iCont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak);
|
||||
iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
|
||||
multiSelectSortOrder(p, p->pOrderBy);
|
||||
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
||||
p->pOrderBy, -1, eDest, iParm,
|
||||
iCont, iBreak);
|
||||
|
@ -1331,6 +1407,12 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||
pParse->nErr++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Issue a null callback if that is what the user wants.
|
||||
*/
|
||||
if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){
|
||||
sqliteVdbeAddOp(v, OP_NullCallback, p->pEList->nExpr, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1383,6 +1465,7 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList, int iSub){
|
|||
pNew = pEList->a[pExpr->iColumn].pExpr;
|
||||
assert( pNew!=0 );
|
||||
pExpr->op = pNew->op;
|
||||
pExpr->dataType = pNew->dataType;
|
||||
assert( pExpr->pLeft==0 );
|
||||
pExpr->pLeft = sqliteExprDup(pNew->pLeft);
|
||||
assert( pExpr->pRight==0 );
|
||||
|
@ -1686,6 +1769,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
|||
if( v==0 ) return 0;
|
||||
if( eDest==SRT_Callback ){
|
||||
generateColumnNames(pParse, p->base, p->pSrc, p->pEList);
|
||||
generateColumnTypes(pParse, p->base, p->pSrc, p->pEList);
|
||||
}
|
||||
|
||||
/* Generating code to find the min or the max. Basically all we have
|
||||
|
@ -1992,6 +2076,13 @@ int sqliteSelect(
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Identify column types if we will be using in the callback. This
|
||||
** step is skipped if the output is going to a table or a memory cell.
|
||||
*/
|
||||
if( eDest==SRT_Callback ){
|
||||
generateColumnTypes(pParse, p->base, pTabList, pEList);
|
||||
}
|
||||
|
||||
/* If the output is destined for a temporary table, open that table.
|
||||
*/
|
||||
if( eDest==SRT_TempTable ){
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.155 2003/01/16 16:28:54 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.156 2003/01/18 20:11:07 drh Exp $
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "sqlite.h"
|
||||
|
@ -948,7 +948,7 @@ void sqliteAddNotNull(Parse*, int);
|
|||
void sqliteAddPrimaryKey(Parse*, IdList*, int);
|
||||
void sqliteAddColumnType(Parse*,Token*,Token*);
|
||||
void sqliteAddDefaultValue(Parse*,Token*,int);
|
||||
int sqliteCollateType(Parse*, Token*);
|
||||
int sqliteCollateType(const char*, int);
|
||||
void sqliteAddCollateType(Parse*, int);
|
||||
void sqliteEndTable(Parse*,Token*,Select*);
|
||||
void sqliteCreateView(Parse*,Token*,Token*,Select*,int);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# This file implements tests for miscellanous features that were
|
||||
# left out of other test files.
|
||||
#
|
||||
# $Id: misc1.test,v 1.17 2002/12/07 21:45:14 drh Exp $
|
||||
# $Id: misc1.test,v 1.18 2003/01/18 20:11:07 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -376,11 +376,16 @@ do_test misc1-12.9 {
|
|||
SELECT min(z), max(z), count(z) FROM t7 GROUP BY y ORDER BY 1;
|
||||
}
|
||||
} {1 2 2 3 4 2}
|
||||
|
||||
# This used to be an error. But we changed the code so that arbitrary
|
||||
# identifiers can be used as a collating sequence. Collation is by text
|
||||
# if the identifier contains "text", "blob", or "clob" and is numeric
|
||||
# otherwise.
|
||||
do_test misc1-12.10 {
|
||||
catchsql {
|
||||
SELECT * FROM t6 ORDER BY a COLLATE unknown;
|
||||
}
|
||||
} {1 {unknown collating type: unknown}}
|
||||
} {0 {0 0.0 y 0}}
|
||||
do_test misc1-12.11 {
|
||||
execsql {
|
||||
CREATE TABLE t8(x TEXT COLLATE numeric, y INTEGER COLLATE text, z);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#
|
||||
# This file implements tests for the PRAGMA command.
|
||||
#
|
||||
# $Id: pragma.test,v 1.2 2003/01/11 14:19:52 drh Exp $
|
||||
# $Id: pragma.test,v 1.3 2003/01/18 20:11:07 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -129,7 +129,7 @@ do_test pragma-1.12 {
|
|||
PRAGMA empty_result_callbacks=on;
|
||||
}
|
||||
sqlite_datatypes $::DB {SELECT * FROM sqlite_master}
|
||||
} {NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC}
|
||||
} {text text text integer text}
|
||||
do_test pragma-1.13 {
|
||||
execsql {
|
||||
CREATE TABLE t1(
|
||||
|
@ -143,7 +143,7 @@ do_test pragma-1.13 {
|
|||
);
|
||||
}
|
||||
sqlite_datatypes $::DB {SELECT * FROM t1}
|
||||
} {NUMERIC TEXT NUMERIC TEXT TEXT TEXT TEXT}
|
||||
} {INTEGER TEXT WHATEVER CLOB BLOB VARCHAR(123) nVaRcHaR(432)}
|
||||
do_test pragma-1.14 {
|
||||
sqlite_datatypes $::DB {
|
||||
SELECT 1, 'hello', NULL
|
||||
|
@ -154,6 +154,33 @@ do_test pragma-1.15 {
|
|||
SELECT 1+2 AS X, 'hello' || 5 AS Y, NULL AS Z
|
||||
}
|
||||
} {NUMERIC TEXT TEXT}
|
||||
do_test pragma-1.16 {
|
||||
execsql {
|
||||
CREATE VIEW v1 AS SELECT a+b, b||c, * FROM t1;
|
||||
}
|
||||
sqlite_datatypes $::DB {SELECT * FROM v1}
|
||||
} {NUMERIC TEXT INTEGER TEXT WHATEVER CLOB BLOB VARCHAR(123) nVaRcHaR(432)}
|
||||
do_test pragma-1.17 {
|
||||
sqlite_datatypes $::DB {
|
||||
SELECT d,e FROM t1 UNION SELECT a,c FROM t1
|
||||
}
|
||||
} {INTEGER WHATEVER}
|
||||
do_test pragma-1.18 {
|
||||
sqlite_datatypes $::DB {
|
||||
SELECT d,e FROM t1 EXCEPT SELECT c,e FROM t1
|
||||
}
|
||||
} {WHATEVER BLOB}
|
||||
do_test pragma-1.19 {
|
||||
sqlite_datatypes $::DB {
|
||||
SELECT d,e FROM t1 INTERSECT SELECT c,e FROM t1
|
||||
}
|
||||
} {WHATEVER BLOB}
|
||||
do_test pragma-1.20 {
|
||||
sqlite_datatypes $::DB {
|
||||
SELECT d,e FROM t1 INTERSECT SELECT c,e FROM v1
|
||||
}
|
||||
} {WHATEVER BLOB}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the CREATE TABLE statement.
|
||||
#
|
||||
# $Id: sort.test,v 1.7 2002/08/26 19:55:11 drh Exp $
|
||||
# $Id: sort.test,v 1.8 2003/01/18 20:11:07 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -267,4 +267,84 @@ do_test sort-6.4 {
|
|||
}
|
||||
} {4 1 6 5 3 2}
|
||||
|
||||
do_test sort-7.1 {
|
||||
execsql {
|
||||
CREATE TABLE t4(
|
||||
a INTEGER,
|
||||
b VARCHAR(30)
|
||||
);
|
||||
INSERT INTO t4 VALUES(1,1);
|
||||
INSERT INTO t4 VALUES(2,2);
|
||||
INSERT INTO t4 VALUES(11,11);
|
||||
INSERT INTO t4 VALUES(12,12);
|
||||
SELECT a FROM t4 ORDER BY 1;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.2 {
|
||||
execsql {
|
||||
SELECT b FROM t4 ORDER BY 1
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.3 {
|
||||
execsql {
|
||||
CREATE VIEW v4 AS SELECT * FROM t4;
|
||||
SELECT a FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.4 {
|
||||
execsql {
|
||||
SELECT b FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.5 {
|
||||
execsql {
|
||||
SELECT a FROM t4 UNION SELECT a FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.6 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT a FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.7 {
|
||||
execsql {
|
||||
SELECT a FROM t4 UNION SELECT b FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.8 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.9 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE numeric;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.10 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE integer;
|
||||
}
|
||||
} {1 2 11 12}
|
||||
do_test sort-7.11 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE text;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.12 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE blob;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.13 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE clob;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
do_test sort-7.14 {
|
||||
execsql {
|
||||
SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE varchar;
|
||||
}
|
||||
} {1 11 12 2}
|
||||
|
||||
finish_test
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Run this TCL script to generate HTML for the index.html file.
|
||||
#
|
||||
set rcsid {$Id: index.tcl,v 1.70 2002/11/06 14:08:12 drh Exp $}
|
||||
set rcsid {$Id: index.tcl,v 1.71 2003/01/18 20:11:07 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head><title>SQLite: An Embeddable SQL Database Engine</title></head>
|
||||
|
@ -180,7 +180,9 @@ puts {
|
|||
If you would like professional support for SQLite
|
||||
or if you want custom modifications to SQLite preformed by the
|
||||
original author, these services are available for a modest fee.
|
||||
For additional information contact:</p>
|
||||
For additional information visit
|
||||
<a href="http://www.hwaci.com/sw/sqlite/support.html">
|
||||
http://www.hwaci.com/sw/sqlite/support.html</a> or contact:</p>
|
||||
|
||||
<blockquote>
|
||||
D. Richard Hipp <br />
|
||||
|
|
Loading…
Reference in New Issue