aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-08-24 15:39:42 +0000
committerdrh <drh@noemail.net>2015-08-24 15:39:42 +0000
commitbc622bc045a919b491be2d1ba0c56fd5fd7ff22f (patch)
tree10b75608eb02240f45844d85bdb23ece7e3bae2d /src
parent80d874083b38c5e24d854a76ab07b791fb0dc2cb (diff)
downloadsqlite-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.c35
-rw-r--r--src/expr.c15
-rw-r--r--src/parse.y10
-rw-r--r--src/sqliteInt.h4
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*);