Disallow the use of COLLATE clauses and the ASC and DESC keywords within
foreign key constraints and in the argument list to common table expressions. FossilOrigin-Name: 83cbc4d8761498647794affffa961a4fca311be7
This commit is contained in:
parent
80d874083b
commit
bc622bc045
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
|||||||
C Improvements\sto\sJSON\sstring\sdequoting.
|
C Disallow\sthe\suse\sof\sCOLLATE\sclauses\sand\sthe\sASC\sand\sDESC\skeywords\swithin\nforeign\skey\sconstraints\sand\sin\sthe\sargument\slist\sto\scommon\stable\sexpressions.
|
||||||
D 2015-08-24T12:42:41.080
|
D 2015-08-24T15:39:42.405
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
|
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -282,14 +282,14 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
|||||||
F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee
|
F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee
|
||||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||||
F src/build.c 5eb5d055a1d1cdaaea25e01b12607aa894bc0911
|
F src/build.c f49c55c1fba430c2d6af5039d0bf14de5ae6a427
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||||
F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58
|
F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58
|
||||||
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||||
F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa
|
F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa
|
||||||
F src/expr.c c34408e0ac1c57cf58ffa2003b339715ee9bda57
|
F src/expr.c c05d67f1a03c097d5c29839d5a538cfde9c472ce
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
||||||
F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f
|
F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f
|
||||||
@ -326,7 +326,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
|
|||||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||||
F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
|
F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
|
||||||
F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
|
F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
|
||||||
F src/parse.y ad9af8552f6f340bd646577ca63356a6f82b6a7e
|
F src/parse.y b5e0a5f8bb9ec33a58aa34850b6fae46aac51fdd
|
||||||
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
|
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
|
||||||
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
||||||
F src/pcache1.c a3fe31b17e841ec70beee72a2c960e9c787a8857
|
F src/pcache1.c a3fe31b17e841ec70beee72a2c960e9c787a8857
|
||||||
@ -342,7 +342,7 @@ F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23
|
|||||||
F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00
|
F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413
|
F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413
|
||||||
F src/sqliteInt.h 89e68539d645db597366a91411468b51e73c21a0
|
F src/sqliteInt.h 1741691824491c330dda1e49f370920bfd3aa230
|
||||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||||
@ -910,6 +910,7 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
|||||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||||
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
||||||
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||||
|
F test/parser1.test 23867b6f2c4758c7774108826d9f17e9cd17bcde
|
||||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||||
@ -1378,7 +1379,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P f0aba0e120074430cd7ad93291fcc97b8a25a054
|
P 196d66d34d9783622e6f2f79eafea1488fc6f5cf
|
||||||
R 3625d17566ea8cc316dd4952d6bffb99
|
R 2a74528f51d8172b5387a3b7f110bb2b
|
||||||
U drh
|
U drh
|
||||||
Z 6090b9f6d755a9917a579931aff72e9d
|
Z ffc4f8e604c67b08cae8ed1eda808a43
|
||||||
|
@ -1 +1 @@
|
|||||||
196d66d34d9783622e6f2f79eafea1488fc6f5cf
|
83cbc4d8761498647794affffa961a4fca311be7
|
35
src/build.c
35
src/build.c
@ -1321,7 +1321,7 @@ void sqlite3AddPrimaryKey(
|
|||||||
}
|
}
|
||||||
if( nTerm==1
|
if( nTerm==1
|
||||||
&& zType && sqlite3StrICmp(zType, "INTEGER")==0
|
&& zType && sqlite3StrICmp(zType, "INTEGER")==0
|
||||||
&& sortOrder==SQLITE_SO_ASC
|
&& sortOrder!=SQLITE_SO_DESC
|
||||||
){
|
){
|
||||||
pTab->iPKey = iCol;
|
pTab->iPKey = iCol;
|
||||||
pTab->keyConf = (u8)onError;
|
pTab->keyConf = (u8)onError;
|
||||||
@ -2600,6 +2600,8 @@ void sqlite3CreateForeignKey(
|
|||||||
|
|
||||||
assert( pTo!=0 );
|
assert( pTo!=0 );
|
||||||
if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
|
if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
|
||||||
|
sqlite3RestrictColumnListSyntax(pParse, pFromCol);
|
||||||
|
sqlite3RestrictColumnListSyntax(pParse, pToCol);
|
||||||
if( pFromCol==0 ){
|
if( pFromCol==0 ){
|
||||||
int iCol = p->nCol-1;
|
int iCol = p->nCol-1;
|
||||||
if( NEVER(iCol<0) ) goto fk_end;
|
if( NEVER(iCol<0) ) goto fk_end;
|
||||||
@ -3038,7 +3040,8 @@ Index *sqlite3CreateIndex(
|
|||||||
if( pList==0 ) goto exit_create_index;
|
if( pList==0 ) goto exit_create_index;
|
||||||
pList->a[0].zName = sqlite3DbStrDup(pParse->db,
|
pList->a[0].zName = sqlite3DbStrDup(pParse->db,
|
||||||
pTab->aCol[pTab->nCol-1].zName);
|
pTab->aCol[pTab->nCol-1].zName);
|
||||||
pList->a[0].sortOrder = (u8)sortOrder;
|
assert( pList->nExpr==1 );
|
||||||
|
sqlite3ExprListSetSortOrder(pList, sortOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out how many bytes of space are required to store explicitly
|
/* Figure out how many bytes of space are required to store explicitly
|
||||||
@ -4283,6 +4286,32 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
|||||||
return pKey;
|
return pKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate a syntax error if the expression list provided contains
|
||||||
|
** any COLLATE or ASC or DESC keywords.
|
||||||
|
**
|
||||||
|
** Some legacy versions of SQLite allowed constructs like:
|
||||||
|
**
|
||||||
|
** CREATE TABLE x(..., FOREIGN KEY(x COLLATE binary DESC) REFERENCES...);
|
||||||
|
** ^^^^^^^^^^^^^^^^^^^
|
||||||
|
**
|
||||||
|
** The COLLATE and sort order terms were ignored. To prevent compatibility
|
||||||
|
** problems in case something like this appears in a legacy sqlite_master
|
||||||
|
** table, only enforce the restriction on new SQL statements, not when
|
||||||
|
** parsing the schema out of the sqlite_master table.
|
||||||
|
*/
|
||||||
|
void sqlite3RestrictColumnListSyntax(Parse *pParse, ExprList *p){
|
||||||
|
int i;
|
||||||
|
if( p==0 || pParse->db->init.busy ) return;
|
||||||
|
for(i=0; i<p->nExpr; i++){
|
||||||
|
if( p->a[i].pExpr!=0 || p->a[i].bDefinedSO ){
|
||||||
|
sqlite3ErrorMsg(pParse, "syntax error after column name \"%w\"",
|
||||||
|
p->a[i].zName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_CTE
|
#ifndef SQLITE_OMIT_CTE
|
||||||
/*
|
/*
|
||||||
** This routine is invoked once per CTE by the parser while parsing a
|
** This routine is invoked once per CTE by the parser while parsing a
|
||||||
@ -4299,6 +4328,8 @@ With *sqlite3WithAdd(
|
|||||||
With *pNew;
|
With *pNew;
|
||||||
char *zName;
|
char *zName;
|
||||||
|
|
||||||
|
sqlite3RestrictColumnListSyntax(pParse, pArglist);
|
||||||
|
|
||||||
/* Check that the CTE name is unique within this WITH clause. If
|
/* Check that the CTE name is unique within this WITH clause. If
|
||||||
** not, store an error in the Parse structure. */
|
** not, store an error in the Parse structure. */
|
||||||
zName = sqlite3NameFromToken(pParse->db, pName);
|
zName = sqlite3NameFromToken(pParse->db, pName);
|
||||||
|
15
src/expr.c
15
src/expr.c
@ -1160,6 +1160,21 @@ no_mem:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set the sort order for the last element on the given ExprList.
|
||||||
|
*/
|
||||||
|
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
|
||||||
|
if( p==0 ) return;
|
||||||
|
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
|
||||||
|
assert( p->nExpr>0 );
|
||||||
|
if( iSortOrder<0 ){
|
||||||
|
assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
|
||||||
|
p->a[p->nExpr-1].bDefinedSO = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the ExprList.a[].zName element of the most recently added item
|
** Set the ExprList.a[].zName element of the most recently added item
|
||||||
** on the expression list.
|
** on the expression list.
|
||||||
|
10
src/parse.y
10
src/parse.y
@ -680,18 +680,18 @@ orderby_opt(A) ::= . {A = 0;}
|
|||||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||||
sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
|
sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
|
||||||
A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
|
A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
|
||||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
sqlite3ExprListSetSortOrder(A,Z);
|
||||||
}
|
}
|
||||||
sortlist(A) ::= expr(Y) sortorder(Z). {
|
sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||||
A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
||||||
if( A && ALWAYS(A->a) ) A->a[0].sortOrder = (u8)Z;
|
sqlite3ExprListSetSortOrder(A,Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
%type sortorder {int}
|
%type sortorder {int}
|
||||||
|
|
||||||
sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
||||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||||
sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
||||||
|
|
||||||
%type groupby_opt {ExprList*}
|
%type groupby_opt {ExprList*}
|
||||||
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||||
@ -1229,14 +1229,14 @@ idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
|||||||
A = sqlite3ExprListAppend(pParse,X, p);
|
A = sqlite3ExprListAppend(pParse,X, p);
|
||||||
sqlite3ExprListSetName(pParse,A,&Y,1);
|
sqlite3ExprListSetName(pParse,A,&Y,1);
|
||||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
sqlite3ExprListSetSortOrder(A,Z);
|
||||||
}
|
}
|
||||||
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
||||||
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
||||||
A = sqlite3ExprListAppend(pParse,0, p);
|
A = sqlite3ExprListAppend(pParse,0, p);
|
||||||
sqlite3ExprListSetName(pParse, A, &Y, 1);
|
sqlite3ExprListSetName(pParse, A, &Y, 1);
|
||||||
sqlite3ExprListCheckLength(pParse, A, "index");
|
sqlite3ExprListCheckLength(pParse, A, "index");
|
||||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
sqlite3ExprListSetSortOrder(A,Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
%type collate {Token}
|
%type collate {Token}
|
||||||
|
@ -1525,6 +1525,7 @@ struct CollSeq {
|
|||||||
*/
|
*/
|
||||||
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
|
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
|
||||||
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
|
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
|
||||||
|
#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Column affinity types.
|
** Column affinity types.
|
||||||
@ -2189,6 +2190,7 @@ struct ExprList {
|
|||||||
unsigned done :1; /* A flag to indicate when processing is finished */
|
unsigned done :1; /* A flag to indicate when processing is finished */
|
||||||
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
|
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
|
||||||
unsigned reusable :1; /* Constant expression is reusable */
|
unsigned reusable :1; /* Constant expression is reusable */
|
||||||
|
unsigned bDefinedSO :1; /* True if either DESC or ASC keywords present */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
||||||
@ -3244,6 +3246,7 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
|
|||||||
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
|
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
|
||||||
void sqlite3ExprDelete(sqlite3*, Expr*);
|
void sqlite3ExprDelete(sqlite3*, Expr*);
|
||||||
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||||
|
void sqlite3ExprListSetSortOrder(ExprList*,int);
|
||||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
||||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||||
@ -3755,6 +3758,7 @@ const char *sqlite3JournalModename(int);
|
|||||||
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
|
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
|
||||||
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
|
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
|
||||||
#endif
|
#endif
|
||||||
|
void sqlite3RestrictColumnListSyntax(Parse*,ExprList*);
|
||||||
#ifndef SQLITE_OMIT_CTE
|
#ifndef SQLITE_OMIT_CTE
|
||||||
With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
|
With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
|
||||||
void sqlite3WithDelete(sqlite3*,With*);
|
void sqlite3WithDelete(sqlite3*,With*);
|
||||||
|
58
test/parser1.test
Normal file
58
test/parser1.test
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# 2014-08-24
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library.
|
||||||
|
# The focus of this script is testing details of the SQL language parser.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
do_catchsql_test parser1-1.1 {
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a TEXT PRIMARY KEY,
|
||||||
|
b TEXT,
|
||||||
|
FOREIGN KEY(b COLLATE nocase DESC) REFERENCES t1(a COLLATE binary ASC)
|
||||||
|
);
|
||||||
|
} {1 {syntax error after column name "a"}}
|
||||||
|
do_execsql_test parser1-1.2 {
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a TEXT PRIMARY KEY,
|
||||||
|
b TEXT,
|
||||||
|
FOREIGN KEY(b) REFERENCES t1(a)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES('abc',NULL),('xyz','abc');
|
||||||
|
PRAGMA writable_schema=on;
|
||||||
|
UPDATE sqlite_master SET sql='CREATE TABLE t1(
|
||||||
|
a TEXT PRIMARY KEY,
|
||||||
|
b TEXT,
|
||||||
|
FOREIGN KEY(b COLLATE nocase) REFERENCES t1(a)
|
||||||
|
)' WHERE name='t1';
|
||||||
|
SELECT name FROM sqlite_master WHERE sql LIKE '%collate%';
|
||||||
|
} {t1}
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
do_test parser1-1.3 {
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
db2 eval {SELECT * FROM t1 ORDER BY 1}
|
||||||
|
} {abc {} xyz abc}
|
||||||
|
|
||||||
|
|
||||||
|
do_catchsql_test parser1-2.1 {
|
||||||
|
WITH RECURSIVE
|
||||||
|
c(x COLLATE binary) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<5)
|
||||||
|
SELECT x FROM c;
|
||||||
|
} {1 {syntax error after column name "x"}}
|
||||||
|
do_catchsql_test parser1-2.2 {
|
||||||
|
WITH RECURSIVE
|
||||||
|
c(x ASC) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<5)
|
||||||
|
SELECT x FROM c;
|
||||||
|
} {1 {syntax error after column name "x"}}
|
||||||
|
|
||||||
|
finish_test
|
Loading…
Reference in New Issue
Block a user