diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/alter.c | 1 | ||||
-rw-r--r-- | src/build.c | 50 | ||||
-rw-r--r-- | src/expr.c | 2 | ||||
-rw-r--r-- | src/fkey.c | 4 | ||||
-rw-r--r-- | src/insert.c | 3 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/select.c | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 12 | ||||
-rw-r--r-- | src/wherecode.c | 5 |
9 files changed, 66 insertions, 18 deletions
diff --git a/src/alter.c b/src/alter.c index 5780d2df0..c059a62ec 100644 --- a/src/alter.c +++ b/src/alter.c @@ -532,7 +532,6 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Column *pCol = &pNew->aCol[i]; pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); pCol->hName = sqlite3StrIHash(pCol->zCnName); - pCol->zCnColl = 0; } assert( !IsVirtual(pNew) ); pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); diff --git a/src/build.c b/src/build.c index 942dc85f8..6343da4f5 100644 --- a/src/build.c +++ b/src/build.c @@ -711,6 +711,45 @@ Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ } /* +** Set the collating sequence name for a column. +*/ +void sqlite3ColumnSetColl( + sqlite3 *db, + Column *pCol, + const char *zColl +){ + int nColl; + int n; + char *zNew; + assert( zColl!=0 ); + n = sqlite3Strlen30(pCol->zCnName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + n += sqlite3Strlen30(pCol->zCnName+n) + 1; + } + nColl = sqlite3Strlen30(zColl) + 1; + zNew = sqlite3DbRealloc(db, pCol->zCnName, nColl+n); + if( zNew ){ + pCol->zCnName = zNew; + memcpy(pCol->zCnName + n, zColl, nColl); + pCol->colFlags |= COLFLAG_HASCOLL; + } +} + +/* +** Return the collating squence name for a column +*/ +const char *sqlite3ColumnColl(Column *pCol){ + const char *z; + if( (pCol->colFlags & COLFLAG_HASCOLL)==0 ) return 0; + z = pCol->zCnName; + while( *z ){ z++; } + if( pCol->colFlags & COLFLAG_HASTYPE ){ + do{ z++; }while( *z ); + } + return z+1; +} + +/* ** Delete memory allocated for the column names of a table or view (the ** Table.aCol[] array). */ @@ -722,7 +761,6 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ for(i=0; i<pTable->nCol; i++, pCol++){ assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); sqlite3DbFree(db, pCol->zCnName); - sqlite3DbFree(db, pCol->zCnColl); } sqlite3DbFree(db, pTable->aCol); if( !IsVirtual(pTable) ){ @@ -1891,8 +1929,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; - sqlite3DbFree(db, p->aCol[i].zCnColl); - p->aCol[i].zCnColl = zColl; + sqlite3ColumnSetColl(db, &p->aCol[i], zColl); /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the @@ -1901,12 +1938,11 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nKeyCol==1 ); if( pIdx->aiColumn[0]==i ){ - pIdx->azColl[0] = p->aCol[i].zCnColl; + pIdx->azColl[0] = sqlite3ColumnColl(&p->aCol[i]); } } - }else{ - sqlite3DbFree(db, zColl); } + sqlite3DbFree(db, zColl); } /* Change the most recently parsed column to be a GENERATED ALWAYS AS @@ -4066,7 +4102,7 @@ void sqlite3CreateIndex( zExtra += nColl; nExtra -= nColl; }else if( j>=0 ){ - zColl = pTab->aCol[j].zCnColl; + zColl = sqlite3ColumnColl(&pTab->aCol[j]); } if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ diff --git a/src/expr.c b/src/expr.c index 0f900c0c6..34f14e368 100644 --- a/src/expr.c +++ b/src/expr.c @@ -173,7 +173,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; if( j>=0 ){ - const char *zColl = p->y.pTab->aCol[j].zCnColl; + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); } break; diff --git a/src/fkey.c b/src/fkey.c index 5105b5cc7..5888e558f 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -259,7 +259,7 @@ int sqlite3FkLocateIndex( /* If the index uses a collation sequence that is different from ** the default collation sequence for the column, this index is ** unusable. Bail out early in this case. */ - zDfltColl = pParent->aCol[iCol].zCnColl; + zDfltColl = sqlite3ColumnColl(&pParent->aCol[iCol]); if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; @@ -487,7 +487,7 @@ static Expr *exprTableRegister( pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; pExpr->affExpr = pCol->affinity; - zColl = pCol->zCnColl; + zColl = sqlite3ColumnColl(pCol); if( zColl==0 ) zColl = db->pDfltColl->zName; pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); }else{ diff --git a/src/insert.c b/src/insert.c index 06952586b..0692198b1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2843,7 +2843,8 @@ static int xferOptimization( if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ } - if( sqlite3_stricmp(pDestCol->zCnColl, pSrcCol->zCnColl)!=0 ){ + if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), + sqlite3ColumnColl(pSrcCol))!=0 ){ return 0; /* Collating sequence must be the same on all columns */ } if( pDestCol->notNull && !pSrcCol->notNull ){ diff --git a/src/main.c b/src/main.c index 3c1191c36..a37301a64 100644 --- a/src/main.c +++ b/src/main.c @@ -3769,7 +3769,7 @@ int sqlite3_table_column_metadata( */ if( pCol ){ zDataType = sqlite3ColumnType(pCol,0); - zCollSeq = pCol->zCnColl; + zCollSeq = sqlite3ColumnColl(pCol); notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; diff --git a/src/select.c b/src/select.c index 064ea758d..375050bdc 100644 --- a/src/select.c +++ b/src/select.c @@ -2193,8 +2193,9 @@ void sqlite3SelectAddColumnTypeAndCollation( } if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl && pCol->zCnColl==0 ){ - pCol->zCnColl = sqlite3DbStrDup(db, pColl->zName); + if( pColl && (pCol->colFlags & COLFLAG_HASCOLL)==0 ){ + assert( pTab->pIndex==0 ); + sqlite3ColumnSetColl(db, pCol, pColl->zName); } } pTab->szTabRow = 1; /* Any non-zero value works */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 083ba5a33..9f4d21175 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2028,10 +2028,17 @@ struct Module { ** or equal to the table column index. It is ** equal if and only if there are no VIRTUAL ** columns to the left. +** +** Notes on zCnName: +** The zCnName field stores the name of the column, the datatype of the +** column, and the collating sequence for the column, in that order, all in +** a single allocation. Each string is 0x00 terminated. The datatype +** is only included if the COLFLAG_HASTYPE bit of colFlags is set and the +** collating sequence name is only included if the COLFLAG_HASCOLL bit is +** set. */ struct Column { char *zCnName; /* Name of this column */ - char *zCnColl; /* Collating sequence. If NULL, use the default */ u8 notNull : 4; /* An OE_ code for handling a NOT NULL constraint */ u8 eType : 4; /* One of the standard types */ char affinity; /* One of the SQLITE_AFF_... values */ @@ -2072,6 +2079,7 @@ struct Column { #define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */ #define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ #define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ +#define COLFLAG_HASCOLL 0x0200 /* Has collating sequence name in zCnName */ #define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ #define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ @@ -4398,6 +4406,8 @@ void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*); Expr *sqlite3ColumnExpr(Table*,Column*); +void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); +const char *sqlite3ColumnColl(Column*); void sqlite3DeleteColumnNames(sqlite3*,Table*); void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); diff --git a/src/wherecode.c b/src/wherecode.c index f3589bb0a..28b417c9a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1241,8 +1241,9 @@ static void whereIndexExprTrans( #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( iRef>=0 && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 - && (pTab->aCol[iRef].zCnColl==0 - || sqlite3StrICmp(pTab->aCol[iRef].zCnColl, sqlite3StrBINARY)==0) + && ((pTab->aCol[iRef].colFlags & COLFLAG_HASCOLL)==0 + || sqlite3StrICmp(sqlite3ColumnColl(&pTab->aCol[iRef]), + sqlite3StrBINARY)==0) ){ /* Check to see if there are direct references to generated columns ** that are contained in the index. Pulling the generated column |