Rework the logic that generates a schema for tables created using
"CREATE TABLE ... AS SELECT ...". Instead of trying to copy the raw
datatype string from the right-hand side, just make the type one
of TEXT, INT, REAL, NUM, or nothing. This is much simpler than
trying to parse and quote datatype strings. Other minor
implifications to build.c are bundled with this change. (CVS 6626)
FossilOrigin-Name: 33cf83591e6e13875ef6ada5b8ac8ab07619d8bc
diff --git a/src/build.c b/src/build.c
index e7f8e62..ecf1614 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.537 2009/05/06 18:42:21 drh Exp $
+** $Id: build.c,v 1.538 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -342,6 +342,7 @@
*/
static void freeIndex(Index *p){
sqlite3 *db = p->pTable->dbMem;
+ testcase( db==0 );
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
@@ -470,6 +471,7 @@
int i;
Column *pCol;
sqlite3 *db = pTable->dbMem;
+ testcase( db==0 );
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
@@ -500,6 +502,7 @@
if( pTable==0 ) return;
db = pTable->dbMem;
+ testcase( db==0 );
/* Do not delete the table until the reference count reaches zero. */
pTable->nRef--;
@@ -654,7 +657,7 @@
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
- if( pName2 && pName2->n>0 ){
+ if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
pParse->nErr++;
@@ -819,8 +822,8 @@
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->dbMem = db->lookaside.bEnabled ? db : 0;
- if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
+ pTable->dbMem = 0;
+ assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
/* If this is the magic sqlite_sequence table used by autoincrement,
@@ -976,10 +979,9 @@
*/
void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p;
- int i;
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i>=0 ) p->aCol[i].notNull = (u8)onError;
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ p->aCol[p->nCol-1].notNull = (u8)onError;
}
/*
@@ -1056,17 +1058,13 @@
*/
void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
- int i;
Column *pCol;
- sqlite3 *db;
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i<0 ) return;
- pCol = &p->aCol[i];
- db = pParse->db;
- sqlite3DbFree(db, pCol->zType);
- pCol->zType = sqlite3NameFromToken(db, pType);
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ pCol = &p->aCol[p->nCol-1];
+ assert( pCol->zType==0 );
+ pCol->zType = sqlite3NameFromToken(pParse->db, pType);
pCol->affinity = sqlite3AffinityType(pType);
}
@@ -1084,7 +1082,8 @@
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
- if( (p = pParse->pNewTable)!=0 ){
+ p = pParse->pNewTable;
+ if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
@@ -1213,7 +1212,7 @@
zColl = sqlite3NameFromToken(db, pToken);
if( !zColl ) return;
- if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( sqlite3LocateCollSeq(pParse, zColl) ){
Index *pIdx;
p->aCol[i].zColl = zColl;
@@ -1249,21 +1248,20 @@
** This routine is a wrapper around sqlite3FindCollSeq(). This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
+**
+** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
*/
-CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
+CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
sqlite3 *db = pParse->db;
u8 enc = ENC(db);
u8 initbusy = db->init.busy;
CollSeq *pColl;
- pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
+ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
+ pColl = sqlite3GetCollSeq(db, pColl, zName);
if( !pColl ){
- if( nName<0 ){
- nName = sqlite3Strlen30(zName);
- }
- sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pColl = 0;
}
}
@@ -1314,61 +1312,6 @@
}
/*
-** This function is a wrapper around sqlite3GetToken() used by
-** isValidDimension(). This function differs from sqlite3GetToken() in
-** that:
-**
-** * Whitespace is ignored, and
-** * The output variable *peToken is set to 0 if the end of the
-** nul-terminated input string is reached.
-*/
-static int getTokenNoSpace(unsigned char *z, int *peToken){
- int n = 0;
- while( sqlite3Isspace(z[n]) ) n++;
- if( !z[n] ){
- *peToken = 0;
- return 0;
- }
- return n + sqlite3GetToken(&z[n], peToken);
-}
-
-/*
-** Parameter z points to a nul-terminated string. Return true if, when
-** whitespace is ignored, the contents of this string matches one of
-** the following patterns:
-**
-** ""
-** "(number)"
-** "(number,number)"
-*/
-static int isValidDimension(unsigned char *z){
- int eToken;
- int n = 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken ){
- if( eToken!=TK_LP ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_COMMA ){
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_RP ) return 0;
- getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken ) return 0;
- return 1;
-}
-
-/*
** The first parameter is a pointer to an output buffer. The second
** parameter is a pointer to an integer that contains the offset at
** which to write into the output buffer. This function copies the
@@ -1381,7 +1324,7 @@
** then it is copied to the output buffer exactly as it is. Otherwise,
** it is quoted using double-quotes.
*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
+static void identPut(char *z, int *pIdx, char *zSignedIdent){
unsigned char *zIdent = (unsigned char*)zSignedIdent;
int i, j, needQuote;
i = *pIdx;
@@ -1391,21 +1334,7 @@
}
needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
if( !needQuote ){
- if( isTypename ){
- /* If this is a type-name, allow a little more flexibility. In SQLite,
- ** a type-name is specified as:
- **
- ** ids [ids] [(number [, number])]
- **
- ** where "ids" is either a quoted string or a simple identifier (in the
- ** above notation, [] means optional). It is a bit tricky to check
- ** for all cases, but it is good to avoid unnecessarily quoting common
- ** typenames like VARCHAR(10).
- */
- needQuote = !isValidDimension(&zIdent[j]);
- }else{
- needQuote = zIdent[j];
- }
+ needQuote = zIdent[j];
}
if( needQuote ) z[i++] = '"';
@@ -1426,18 +1355,14 @@
static char *createTableStmt(sqlite3 *db, Table *p){
int i, k, n;
char *zStmt;
- char *zSep, *zSep2, *zEnd, *z;
+ char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
- n += identLength(pCol->zName);
- z = pCol->zType;
- if( z ){
- n += identLength(z);
- }
+ n += identLength(pCol->zName) + 5;
}
n += identLength(p->zName);
- if( n<50 ){
+ if( n<50 ){
zSep = "";
zSep2 = ",";
zEnd = ")";
@@ -1454,18 +1379,44 @@
}
sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName, 0);
+ identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
+ static const char * const azType[] = {
+ /* SQLITE_AFF_TEXT */ " TEXT",
+ /* SQLITE_AFF_NONE */ "",
+ /* SQLITE_AFF_NUMERIC */ " NUM",
+ /* SQLITE_AFF_INTEGER */ " INT",
+ /* SQLITE_AFF_REAL */ " REAL"
+ };
+ int len;
+ const char *zType;
+
sqlite3_snprintf(n-k, &zStmt[k], zSep);
k += sqlite3Strlen30(&zStmt[k]);
zSep = zSep2;
- identPut(zStmt, &k, pCol->zName, 0);
- if( (z = pCol->zType)!=0 ){
- zStmt[k++] = ' ';
- assert( (int)(sqlite3Strlen30(z)+k+1)<=n );
- identPut(zStmt, &k, z, 1);
+ identPut(zStmt, &k, pCol->zName);
+ assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
+ assert( pCol->affinity-SQLITE_AFF_TEXT < sizeof(azType)/sizeof(azType[0]) );
+ testcase( pCol->affinity==SQLITE_AFF_TEXT );
+ testcase( pCol->affinity==SQLITE_AFF_NONE );
+ testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
+ testcase( pCol->affinity==SQLITE_AFF_INTEGER );
+ testcase( pCol->affinity==SQLITE_AFF_REAL );
+
+ zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
+ len = sqlite3Strlen30(zType);
+#ifndef NDEBUG
+ if( pCol->affinity!=SQLITE_AFF_NONE ){
+ Token typeToken;
+ typeToken.z = (u8*)zType;
+ typeToken.n = len;
+ assert( pCol->affinity==sqlite3AffinityType(&typeToken) );
}
+#endif
+ memcpy(&zStmt[k], zType, len);
+ k += len;
+ assert( k<=n );
}
sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
return zStmt;
@@ -2647,7 +2598,7 @@
zColl = db->pDfltColl->zName;
}
}
- if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
@@ -3584,7 +3535,7 @@
assert( pName1->z );
zColl = sqlite3NameFromToken(pParse->db, pName1);
if( !zColl ) return;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
if( pColl ){
if( zColl ){
reindexDatabases(pParse, zColl);
@@ -3640,7 +3591,7 @@
for(i=0; i<nCol; i++){
char *zColl = pIdx->azColl[i];
assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
pKey->nField = (u16)nCol;
diff --git a/src/callback.c b/src/callback.c
index 2c81c95..3f75760 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
-** $Id: callback.c,v 1.39 2009/05/03 20:23:53 drh Exp $
+** $Id: callback.c,v 1.40 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -23,11 +23,10 @@
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
-static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
+static void callCollNeeded(sqlite3 *db, const char *zName){
assert( !db->xCollNeeded || !db->xCollNeeded16 );
- if( nName<0 ) nName = sqlite3Strlen30(zName);
if( db->xCollNeeded ){
- char *zExternal = sqlite3DbStrNDup(db, zName, nName);
+ char *zExternal = sqlite3DbStrDup(db, zName);
if( !zExternal ) return;
db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
sqlite3DbFree(db, zExternal);
@@ -36,7 +35,7 @@
if( db->xCollNeeded16 ){
char const *zExternal;
sqlite3_value *pTmp = sqlite3ValueNew(db);
- sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
if( zExternal ){
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
@@ -56,11 +55,10 @@
static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
CollSeq *pColl2;
char *z = pColl->zName;
- int n = sqlite3Strlen30(z);
int i;
static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
for(i=0; i<3; i++){
- pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
+ pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
if( pColl2->xCmp!=0 ){
memcpy(pColl, pColl2, sizeof(CollSeq));
pColl->xDel = 0; /* Do not copy the destructor */
@@ -82,25 +80,26 @@
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
- sqlite3* db,
- CollSeq *pColl,
- const char *zName,
- int nName
+ sqlite3* db, /* The database connection */
+ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
+ const char *zName /* Collating sequence name */
){
CollSeq *p;
p = pColl;
if( !p ){
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( !p || !p->xCmp ){
/* No collation sequence of this type for this encoding is registered.
** Call the collation factory to see if it can supply us with one.
*/
- callCollNeeded(db, zName, nName);
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ callCollNeeded(db, zName);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( p && !p->xCmp && synthCollSeq(db, p) ){
p = 0;
@@ -123,7 +122,7 @@
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
- CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
+ CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName);
if( !p ){
if( pParse->nErr==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
@@ -152,13 +151,12 @@
** each collation sequence structure.
*/
static CollSeq *findCollSeqEntry(
- sqlite3 *db,
- const char *zName,
- int nName,
- int create
+ sqlite3 *db, /* Database connection */
+ const char *zName, /* Name of the collating sequence */
+ int create /* Create a new entry if true */
){
CollSeq *pColl;
- if( nName<0 ) nName = sqlite3Strlen30(zName);
+ int nName = sqlite3Strlen30(zName);
pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
if( 0==pColl && create ){
@@ -202,17 +200,18 @@
** this routine. sqlite3LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
*/
CollSeq *sqlite3FindCollSeq(
sqlite3 *db,
u8 enc,
const char *zName,
- int nName,
int create
){
CollSeq *pColl;
if( zName ){
- pColl = findCollSeqEntry(db, zName, nName, create);
+ pColl = findCollSeqEntry(db, zName, create);
}else{
pColl = db->pDfltColl;
}
diff --git a/src/expr.c b/src/expr.c
index 9ec98b0..b6aba99 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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.433 2009/05/09 00:18:38 drh Exp $
+** $Id: expr.c,v 1.434 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -69,7 +69,7 @@
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
if( pExpr && zColl ){
- pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pColl = sqlite3LocateCollSeq(pParse, zColl);
if( pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
@@ -99,7 +99,7 @@
if( j>=0 ){
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
}
break;
@@ -1377,7 +1377,7 @@
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
- && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0))
+ && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0))
&& (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
){
int iMem = ++pParse->nMem;
diff --git a/src/main.c b/src/main.c
index 7122e19..b1f7e2f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.550 2009/05/09 18:59:42 drh Exp $
+** $Id: main.c,v 1.551 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -1361,7 +1361,7 @@
){
CollSeq *pColl;
int enc2;
- int nName;
+ int nName = sqlite3Strlen30(zName);
assert( sqlite3_mutex_held(db->mutex) );
@@ -1383,8 +1383,7 @@
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
- nName = sqlite3Strlen30(zName);
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
@@ -1414,7 +1413,7 @@
}
}
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 1);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
if( pColl ){
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
@@ -1603,7 +1602,7 @@
if( db->mallocFailed ){
goto opendb_out;
}
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Also add a UTF-8 case-insensitive collation sequence. */
@@ -1611,7 +1610,7 @@
/* Set flags on the built-in collating sequences */
db->pDfltColl->type = SQLITE_COLL_BINARY;
- pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 6, 0);
+ pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 0);
if( pColl ){
pColl->type = SQLITE_COLL_NOCASE;
}
diff --git a/src/prepare.c b/src/prepare.c
index c5f4de9..909a74a 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.117 2009/04/20 17:43:03 drh Exp $
+** $Id: prepare.c,v 1.118 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -258,7 +258,7 @@
if( iDb==0 ){
/* If opening the main database, set ENC(db). */
ENC(db) = (u8)meta[4];
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( meta[4]!=ENC(db) ){
diff --git a/src/select.c b/src/select.c
index d1c0fb4..af1c66b 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.512 2009/05/03 20:23:54 drh Exp $
+** $Id: select.c,v 1.513 2009/05/11 20:53:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -1223,6 +1223,7 @@
p = a[i].pExpr;
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
pCol->affinity = sqlite3ExprAffinity(p);
+ if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b5d786d..fccccb6 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.869 2009/05/07 14:11:52 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.870 2009/05/11 20:53:29 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -2641,8 +2641,8 @@
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadSchema(Parse *pParse);
-CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
-CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
+CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
+CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -2680,7 +2680,7 @@
void sqlite3ColumnDefault(Vdbe *, Table *, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
+CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
char sqlite3AffinityType(const Token*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);