diff options
author | drh <drh@noemail.net> | 2015-08-24 15:39:42 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-08-24 15:39:42 +0000 |
commit | bc622bc045a919b491be2d1ba0c56fd5fd7ff22f (patch) | |
tree | 10b75608eb02240f45844d85bdb23ece7e3bae2d /src | |
parent | 80d874083b38c5e24d854a76ab07b791fb0dc2cb (diff) | |
download | sqlite-bc622bc045a919b491be2d1ba0c56fd5fd7ff22f.tar.gz sqlite-bc622bc045a919b491be2d1ba0c56fd5fd7ff22f.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 35 | ||||
-rw-r--r-- | src/expr.c | 15 | ||||
-rw-r--r-- | src/parse.y | 10 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 |
4 files changed, 57 insertions, 7 deletions
diff --git a/src/build.c b/src/build.c index e45908dc3..0a816b398 100644 --- a/src/build.c +++ b/src/build.c @@ -1321,7 +1321,7 @@ void sqlite3AddPrimaryKey( } if( nTerm==1 && zType && sqlite3StrICmp(zType, "INTEGER")==0 - && sortOrder==SQLITE_SO_ASC + && sortOrder!=SQLITE_SO_DESC ){ pTab->iPKey = iCol; pTab->keyConf = (u8)onError; @@ -2600,6 +2600,8 @@ void sqlite3CreateForeignKey( assert( pTo!=0 ); if( p==0 || IN_DECLARE_VTAB ) goto fk_end; + sqlite3RestrictColumnListSyntax(pParse, pFromCol); + sqlite3RestrictColumnListSyntax(pParse, pToCol); if( pFromCol==0 ){ int iCol = p->nCol-1; if( NEVER(iCol<0) ) goto fk_end; @@ -3038,7 +3040,8 @@ Index *sqlite3CreateIndex( if( pList==0 ) goto exit_create_index; pList->a[0].zName = sqlite3DbStrDup(pParse->db, 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 @@ -4283,6 +4286,32 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ 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 /* ** This routine is invoked once per CTE by the parser while parsing a @@ -4299,6 +4328,8 @@ With *sqlite3WithAdd( With *pNew; char *zName; + sqlite3RestrictColumnListSyntax(pParse, pArglist); + /* Check that the CTE name is unique within this WITH clause. If ** not, store an error in the Parse structure. */ zName = sqlite3NameFromToken(pParse->db, pName); diff --git a/src/expr.c b/src/expr.c index 04cd36ea7..1c57ecc6f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1161,6 +1161,21 @@ no_mem: } /* +** 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 ** on the expression list. ** diff --git a/src/parse.y b/src/parse.y index 3d186b28a..bc193ec1f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -680,18 +680,18 @@ orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). { 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). { A = sqlite3ExprListAppend(pParse,0,Y.pExpr); - if( A && ALWAYS(A->a) ) A->a[0].sortOrder = (u8)Z; + sqlite3ExprListSetSortOrder(A,Z); } %type sortorder {int} sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} -sortorder(A) ::= . {A = SQLITE_SO_ASC;} +sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;} %type groupby_opt {ExprList*} %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); sqlite3ExprListSetName(pParse,A,&Y,1); 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). { Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1); A = sqlite3ExprListAppend(pParse,0, p); sqlite3ExprListSetName(pParse, A, &Y, 1); sqlite3ExprListCheckLength(pParse, A, "index"); - if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; + sqlite3ExprListSetSortOrder(A,Z); } %type collate {Token} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 96a770021..18a0fd705 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1525,6 +1525,7 @@ struct CollSeq { */ #define SQLITE_SO_ASC 0 /* 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. @@ -2189,6 +2190,7 @@ struct ExprList { unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ + unsigned bDefinedSO :1; /* True if either DESC or ASC keywords present */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ @@ -3244,6 +3246,7 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprDelete(sqlite3*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +void sqlite3ExprListSetSortOrder(ExprList*,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); void sqlite3ExprListDelete(sqlite3*, ExprList*); @@ -3755,6 +3758,7 @@ const char *sqlite3JournalModename(int); int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif +void sqlite3RestrictColumnListSyntax(Parse*,ExprList*); #ifndef SQLITE_OMIT_CTE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); void sqlite3WithDelete(sqlite3*,With*); |