diff --git a/manifest b/manifest index d5be518140..3b0084ec2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sspeed\simprovements\sto\sbtree.\s(CVS\s1384) -D 2004-05-15T00:29:24 +C More\schanges\sto\ssupport\sthe\smanifest\stype\smodel.\sA\sfew\sthings\sare\scurrently\nbroken.\s(CVS\s1385) +D 2004-05-16T11:15:36 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -26,16 +26,16 @@ F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79 F src/btree.c 05aefd3eec56690d9731bf090203b57d8ae4bf19 F src/btree.h 6f51ad0ffebfba71295fcacdbe86007512200050 F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5 -F src/build.c e93f443a20eab57ffb77ff6244b1e09a1f7d9390 +F src/build.c 6c0463907ba80e0269f0b7fdf4210a049275b48a F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29 F src/date.c 0eb0a89960bb45c7f7e768748605a7a97b0c8064 -F src/delete.c 30c8c4375e75e811c3668abf3f78970fe549f375 +F src/delete.c ea8212a44b5c0dad8fb1794fe7297654f7ed05f9 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 -F src/expr.c a3aed7057bafb3a01e8af98a5f74a102621b7a91 -F src/func.c 4053dc2141ea46e8e35df089d87bfcbab54320bc +F src/expr.c d2d1ddc0ee98f1d70c6caddc11b46a0121d9bddd +F src/func.c cfbb7096efb58e2857e3b312a8958a12774b625a F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb -F src/insert.c 5d4d1a59f66b558213984391985a418efc1c2797 +F src/insert.c 76e13b736391a342bd0fc152ade2558588322868 F src/main.c 4b82d7e78f4c9799343b02740a5ba9768d5e464d F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e @@ -43,13 +43,13 @@ F src/os.h fbb2f6595fc34fa351830d88fe1c6b85118f0383 F src/pager.c 6ff6b906427d4824099140776cb8768f922f3dc5 F src/pager.h 78a00ac280899bcba1a89dc51585dcae6b7b3253 F src/parse.y d0258aa3cc8b0c5742b07b699d10fa98f3caea7d -F src/pragma.c 2ab2a12b62ec5370b9221f44b4743a633a90bfa8 +F src/pragma.c 351836bce186f4eee45a32868b7a379c22ac344a F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c ca99ae4db14a45a436ec51d3e6bd48d44a3efb3c F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21 F src/sqlite.h.in 799c5e726296ec7bc20e6407cdf4df0e0bc00c0c -F src/sqliteInt.h e94edafb9924f22f038c6a8209c29ddd04cd326a +F src/sqliteInt.h bc118a7a701afb954f4cd2110cd0986478e1a741 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1 F src/test1.c 12ef76b8aaba4408422f21f269256b630d4dd627 @@ -59,15 +59,15 @@ F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296 F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847 F src/trigger.c 8df308e09113410bb895e88a2db65b55490268db -F src/update.c 0441f8b64d616ef244583449e66c984e536c6c9b +F src/update.c 04492438aee57a6be5a8a8e54e3add12c1d598ca F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f F src/util.c f9511ffba78e6cf71a28774c2820d7750b5bacdf F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c c12726cf16c9a4e70ff606f87dc0e10e55a11988 +F src/vdbe.c 38a477ae68e78936adb62ef9c6cffebdebbb5be5 F src/vdbe.h 94457ca73bae972dc61bca33a4dccc2e6e14e2f8 -F src/vdbeInt.h 67c3b2cf924e176c10ba75b36d295b165d55c451 -F src/vdbeaux.c 8411f411b421bc19ded1e992db82434aef740f5f -F src/where.c 6957bbd333cc7ffa7b3878adbe67a095319daa54 +F src/vdbeInt.h 311c2a046ea419781d0ef331198b7b0a65eebc92 +F src/vdbeaux.c bd259da3ae52cd4f6febb0c83f60c0b9170f3ebb +F src/where.c 610fadd08c5a25c2aa3bdd8700c3173de64298d0 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56 @@ -144,7 +144,8 @@ F test/trigger1.test 4538c1c7d6bbca5dfe619ea6e1682b07ece95b21 F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263 F test/trigger3.test a95ccace88291449f5eae7139ec438a42f90654d F test/trigger4.test 542afce45774e8f8e1130b96b8675f414d6e4bd8 -F test/types.test 53e3d97c33651afad7bc8bd4cf71b97b473b19ad +F test/types.test d30ee85040cec5c12ebd98a6419916cc29a6c11e +F test/types2.test bc684cc2a75edb240f9fd49275f3cacb025c0f1e F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b F test/update.test b29bd9061a1150426dab6959806fcc73a41b1217 F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a @@ -191,7 +192,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P d8bacc16801606176fe8639b2f55b4584ad549df -R d43b2b97f5dc394b60a54b98133aa83a -U drh -Z 06eabac28a7b451889010e7a03f02723 +P aab4b794b4238bad5c4a6aee7d4443732921127d +R b2648c3d83df0dd5d82ceb6fe4e0bc60 +U danielk1977 +Z a958d50ee5923975cc30d387e46d379d diff --git a/manifest.uuid b/manifest.uuid index 3ffb256fc7..e70830ee57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aab4b794b4238bad5c4a6aee7d4443732921127d \ No newline at end of file +a4af838f8d1b81ec6c8db97655c6876aca0738d9 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1881aba249..9ccba2b987 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.183 2004/05/14 11:00:53 danielk1977 Exp $ +** $Id: build.c,v 1.184 2004/05/16 11:15:36 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -184,6 +184,9 @@ static void sqliteDeleteIndex(sqlite *db, Index *p){ sqlite3HashInsert(&db->aDb[p->iDb].idxHash, pOld->zName, strlen(pOld->zName)+1, pOld); } + if( p->zColAff ){ + sqliteFree(p->zColAff); + } sqliteFree(p); } @@ -581,7 +584,12 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->sortOrder = SQLITE_SO_NUM; + + /* If there is no type specified, columns have the default affinity + ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() + ** will be called next to set pCol->affinity correctly. + */ + pCol->affinity = SQLITE_AFF_NONE; p->nCol++; } @@ -629,7 +637,8 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ z[j++] = c; } z[j] = 0; - pCol->sortOrder = sqlite3CollateType(z, n); +// pCol->sortOrder = sqlite3CollateType(z, n); + pCol->affinity = sqlite3AffinityType(z, n); } /* @@ -751,7 +760,42 @@ void sqlite3AddCollateType(Parse *pParse, int collType){ int i; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; - if( i>=0 ) p->aCol[i].sortOrder = collType; + + /* FIX ME */ + /* if( i>=0 ) p->aCol[i].sortOrder = collType; */ +} + +/* +** Parse the column type name zType (length nType) and return the +** associated affinity type. +*/ +char sqlite3AffinityType(const char *zType, int nType){ + /* FIX ME: This could be done more efficiently */ + int n, i; + struct { + const char *zSub; + int nSub; + char affinity; + } substrings[] = { + {"INT", 3, SQLITE_AFF_INTEGER}, + {"REAL", 4, SQLITE_AFF_NUMERIC}, + {"FLOAT", 5, SQLITE_AFF_NUMERIC}, + {"DOUBLE", 6, SQLITE_AFF_NUMERIC}, + {"NUM", 3, SQLITE_AFF_NUMERIC}, + {"CHAR", 4, SQLITE_AFF_TEXT}, + {"CLOB", 4, SQLITE_AFF_TEXT}, + {"TEXT", 4, SQLITE_AFF_TEXT} + }; + + for(n=0; n<(nType-3); n++){ + for(i=0; ipTable!=0 ); - pTab = pIdx->pTable; - n = pIdx->nColumn; - zType = sqliteMallocRaw( n+1 ); - if( zType==0 ) return; - for(i=0; iaiColumn[i]; - assert( iCol>=0 && iColnCol ); - if( (pTab->aCol[iCol].sortOrder & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){ - zType[i] = 't'; - }else{ - zType[i] = 'n'; - } - } - zType[n] = 0; - sqlite3VdbeChangeP3(v, -1, zType, n); - sqliteFree(zType); -} - /* ** This routine is called to create a new foreign key on the table ** currently under construction. pFromCol determines which columns @@ -1725,7 +1736,7 @@ void sqlite3CreateIndex( } } sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0); - sqlite3AddIdxKeyType(v, pIndex); + sqlite3IndexAffinityStr(v, pIndex); sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, "indexed columns are not unique", P3_STATIC); sqlite3VdbeAddOp(v, OP_Next, 2, lbl1); diff --git a/src/delete.c b/src/delete.c index 0e7b9a29a4..4d6b334259 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.64 2004/05/11 07:11:53 danielk1977 Exp $ +** $Id: delete.c,v 1.65 2004/05/16 11:15:37 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -387,7 +387,7 @@ void sqlite3GenerateRowIndexDelete( } } sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); - sqlite3AddIdxKeyType(v, pIdx); + sqlite3IndexAffinityStr(v, pIdx); sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0); } } diff --git a/src/expr.c b/src/expr.c index 405ecb3a49..7fdd5e3ab4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,11 +12,51 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.117 2004/05/11 07:11:53 danielk1977 Exp $ +** $Id: expr.c,v 1.118 2004/05/16 11:15:37 danielk1977 Exp $ */ #include "sqliteInt.h" #include +static char exprAffinity(Expr *pExpr){ + if( pExpr->op==TK_AS ){ + return exprAffinity(pExpr->pLeft); + } + if( pExpr->op==TK_SELECT ){ + return exprAffinity(pExpr->pSelect->pEList->a[0].pExpr); + } + return pExpr->affinity; +} + +/* +** Return the P1 value that should be used for a binary comparison +** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. +** If jumpIfNull is true, then set the low byte of the returned +** P1 value to tell the opcode to jump if either expression +** evaluates to NULL. +*/ +int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ + char aff1 = exprAffinity(pExpr1); + char aff2 = exprAffinity(pExpr2); + + if( aff1 && aff2 ){ + /* Both sides of the comparison are columns. If one has numeric or + ** integer affinity, use that. Otherwise use no affinity. + */ + if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){ + aff1 = SQLITE_AFF_INTEGER; + }else + if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){ + aff1 = SQLITE_AFF_NUMERIC; + }else{ + aff1 = SQLITE_AFF_NONE; + } + }else if( !aff1 ){ + aff1 = aff2; + } + + return (((int)aff1)<<8)+(jumpIfNull?1:0); +} + /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function @@ -472,7 +512,11 @@ static int lookupName( pExpr->iDb = pTab->iDb; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK; + pExpr->affinity = pTab->aCol[j].affinity; + + /* FIX ME: Expr::dataType will be removed... */ + pExpr->dataType = + (pCol->affinity==SQLITE_AFF_TEXT?SQLITE_SO_TEXT:SQLITE_SO_NUM); break; } } @@ -504,7 +548,10 @@ static int lookupName( if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK; + pExpr->affinity = pTab->aCol[j].affinity; + /* FIX ME: Expr::dataType will be removed... */ + pExpr->dataType = + (pCol->affinity==SQLITE_AFF_TEXT?SQLITE_SO_TEXT:SQLITE_SO_NUM); break; } } @@ -518,6 +565,7 @@ static int lookupName( cnt = 1; pExpr->iColumn = -1; pExpr->dataType = SQLITE_SO_NUM; + pExpr->affinity = SQLITE_AFF_INTEGER; } /* @@ -1050,6 +1098,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_INTEGER: { if( pExpr->op==TK_INTEGER && sqlite3FitsIn32Bits(pExpr->token.z) ){ sqlite3VdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0); + }else if( pExpr->op==TK_FLOAT ){ + sqlite3VdbeAddOp(v, OP_Real, 0, 0); }else{ sqlite3VdbeAddOp(v, OP_String, 0, 0); } @@ -1072,10 +1122,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_GE: case TK_NE: case TK_EQ: { + int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, 0); + sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3VdbeAddOp(v, op, p1, 0); + break; +#if 0 if( sqlite3ExprType(pExpr)==SQLITE_SO_TEXT ){ op += 6; /* Convert numeric opcodes to text opcodes */ } /* Fall through into the next case */ +#endif } case TK_AND: case TK_OR: @@ -1135,8 +1192,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ dest = sqlite3VdbeCurrentAddr(v) + 2; sqlite3VdbeAddOp(v, op, 1, dest); sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); - break; } + break; case TK_AGG_FUNCTION: { sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; @@ -1153,7 +1210,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList, pDef->includeTypes); - sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); + /* FIX ME: The following is a temporary hack. */ + if( 0==sqlite3StrNICmp(zId, "classof", nId) ){ + assert( nExpr==1 ); + sqlite3VdbeOp3(v, OP_Class, nExpr, 0, 0, 0); + }else{ + sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); + } break; } case TK_SELECT: { @@ -1332,12 +1395,10 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { + int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - if( sqlite3ExprType(pExpr)==SQLITE_SO_TEXT ){ - op += 6; /* Convert numeric opcodes to text opcodes */ - } - sqlite3VdbeAddOp(v, op, jumpIfNull, dest); + sqlite3VdbeAddOp(v, op, p1, dest); break; } case TK_ISNULL: @@ -1427,18 +1488,10 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - if( sqlite3ExprType(pExpr)==SQLITE_SO_TEXT ){ - /* Convert numeric comparison opcodes into text comparison opcodes. - ** This step depends on the fact that the text comparision opcodes are - ** always 6 greater than their corresponding numeric comparison - ** opcodes. - */ - assert( OP_Eq+6 == OP_StrEq ); - op += 6; - } + int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeAddOp(v, op, jumpIfNull, dest); + sqlite3VdbeAddOp(v, op, p1, dest); break; } case TK_ISNULL: diff --git a/src/func.c b/src/func.c index 5a4a46147d..3f623aaac3 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.47 2004/05/14 11:00:53 danielk1977 Exp $ +** $Id: func.c,v 1.48 2004/05/16 11:15:38 danielk1977 Exp $ */ #include #include @@ -571,6 +571,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){ { "max", -1, SQLITE_ARGS, 2, minmaxFunc }, { "max", 0, 0, 2, 0 }, { "typeof", 1, SQLITE_TEXT, 0, typeofFunc }, + { "classof", 1, SQLITE_TEXT, 0, typeofFunc }, /* FIX ME: hack */ { "length", 1, SQLITE_NUMERIC, 0, lengthFunc }, { "substr", 3, SQLITE_TEXT, 0, substrFunc }, { "abs", 1, SQLITE_NUMERIC, 0, absFunc }, diff --git a/src/insert.c b/src/insert.c index 86c2fcc2ed..a3c12ed125 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,13 +12,13 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.98 2004/05/14 11:00:53 danielk1977 Exp $ +** $Id: insert.c,v 1.99 2004/05/16 11:15:38 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity -** string for table pTab. A column affinity string has one character +** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: ** ** Character Column affinity @@ -28,9 +28,45 @@ ** 't' TEXT ** 'o' NONE */ -int sqlite3AddRecordType(Vdbe *v, Table *pTab){ - assert( pTab ); +void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ + if( !pIdx->zColAff ){ + /* The first time a column affinity string for a particular table is + ** required, it is allocated and populated here. It is then stored as + ** a member of the Table structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Table structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + pIdx->zColAff = (char *)sqliteMalloc(pIdx->nColumn+1); + if( !pIdx->zColAff ){ + return; + } + for(n=0; nnColumn; n++){ + pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; + } + pIdx->zColAff[pIdx->nColumn] = '\0'; + } + sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, P3_STATIC); +} + +/* +** Set P3 of the most recently inserted opcode to a column affinity +** string for table pTab. A column affinity string has one character +** for each column indexed by the index, according to the affinity of the +** column: +** +** Character Column affinity +** ------------------------------ +** 'n' NUMERIC +** 'i' INTEGER +** 't' TEXT +** 'o' NONE +*/ +void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ /* The first time a column affinity string for a particular table ** is required, it is allocated and populated here. It is then ** stored as a member of the Table structure for subsequent use. @@ -42,28 +78,20 @@ int sqlite3AddRecordType(Vdbe *v, Table *pTab){ char *zColAff; int i; - zColAff = sqliteMalloc(pTab->nCol+1); + zColAff = (char *)sqliteMalloc(pTab->nCol+1); if( !zColAff ){ - return SQLITE_NOMEM; + return; } for(i=0; inCol; i++){ - if( pTab->aCol[i].sortOrder&SQLITE_SO_TEXT ){ - zColAff[i] = 't'; - }else{ - zColAff[i] = 'n'; - } + zColAff[i] = pTab->aCol[i].affinity; } zColAff[pTab->nCol] = '\0'; pTab->zColAff = zColAff; } - /* Set the memory management at the vdbe to P3_STATIC, as the column - ** affinity string is managed as part of the Table structure. - */ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, P3_STATIC); - return SQLITE_OK; } @@ -267,7 +295,7 @@ void sqlite3Insert( srcTab = pParse->nTab++; sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - sqlite3AddRecordType(v, pTab); + sqlite3TableAffinityStr(v, pTab); sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0); @@ -446,7 +474,15 @@ void sqlite3Insert( } } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); - sqlite3AddRecordType(v, pTab); + + /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, + ** do not attempt any conversions before assembling the record. + ** If this is a real table, attempt conversions as required by the + ** table column affinities. + */ + if( !isView ){ + sqlite3TableAffinityStr(v, pTab); + } sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); /* Fire BEFORE or INSTEAD OF triggers */ @@ -826,7 +862,7 @@ void sqlite3GenerateConstraintChecks( } } jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); - sqlite3AddIdxKeyType(v, pIdx); + sqlite3IndexAffinityStr(v, pIdx); /* Find out what action to take in case there is an indexing conflict */ onError = pIdx->onError; @@ -936,7 +972,7 @@ void sqlite3CompleteInsertion( sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0); } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); - sqlite3AddRecordType(v, pTab); + sqlite3TableAffinityStr(v, pTab); if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); diff --git a/src/pragma.c b/src/pragma.c index a344864d6e..23e275a1ec 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.22 2004/05/11 08:48:11 danielk1977 Exp $ +** $Id: pragma.c,v 1.23 2004/05/16 11:15:38 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -667,7 +667,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ } } sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); - sqlite3AddIdxKeyType(v, pIdx); + sqlite3IndexAffinityStr(v, pIdx); jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4db5201870..ee88619605 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.233 2004/05/14 16:50:06 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.234 2004/05/16 11:15:39 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" @@ -457,7 +457,8 @@ struct Column { char *zType; /* Data type for this column */ u8 notNull; /* True if there is a NOT NULL constraint */ u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ - u8 sortOrder; /* Some combination of SQLITE_SO_... values */ +// u8 sortOrder; /* Some combination of SQLITE_SO_... values */ + char affinity; /* One of the SQLITE_AFF_... values */ u8 dottedName; /* True if zName contains a "." character */ }; @@ -475,6 +476,15 @@ struct Column { #define SQLITE_SO_DESC 1 /* Sort in descending order */ #define SQLITE_SO_DIRMASK 1 /* Mask to extract the sort direction */ +/* +** Column affinity types. +*/ +#define SQLITE_AFF_INTEGER 'i' +#define SQLITE_AFF_NUMERIC 'n' +#define SQLITE_AFF_TEXT 't' +#define SQLITE_AFF_NONE 'o' + + /* ** Each SQL table is represented in memory by an instance of the ** following structure. @@ -638,6 +648,7 @@ struct Index { u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */ + char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ }; @@ -707,6 +718,7 @@ struct Expr { ** result from the iAgg-th element of the aggregator */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of " IN (