Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the sqlite3_collation_needed() API and fix some error handling cases involving unknown collation sequences. (CVS 1562) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
edf069b9f4044ed2a80962c7722052bf |
User & Date: | danielk1977 2004-06-10 10:50:08.000 |
Context
2004-06-10
| ||
10:51 | Add the sqlite3_collation_needed() API and fix some error handling cases involving unknown collation sequences. (CVS 1563) (check-in: 518d82d3b1 user: danielk1977 tags: trunk) | |
10:50 | Add the sqlite3_collation_needed() API and fix some error handling cases involving unknown collation sequences. (CVS 1562) (check-in: edf069b9f4 user: danielk1977 tags: trunk) | |
05:59 | Misc fixes for test cases failing due to the new locking model. (CVS 1561) (check-in: 71e98d0d08 user: danielk1977 tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.215 2004/06/10 10:50:08 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
880 881 882 883 884 885 886 | if( pColl ){ pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = TEXT_Utf8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = TEXT_Utf16le; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = TEXT_Utf16be; | | > | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 | if( pColl ){ pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = TEXT_Utf8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = TEXT_Utf16le; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = TEXT_Utf16be; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); } } return pColl; } /* |
︙ | ︙ | |||
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 | pColl = &pColl[1]; break; default: assert(!"Cannot happen"); } return pColl; } /* ** This function returns the collation sequence for database native text ** encoding identified by the string zName, length nName. ** ** If the requested collation sequence is not available, or not available ** in the database native encoding, the collation factory is invoked to ** request it. If the collation factory does not supply such a sequence, ** and the sequence is available in another text encoding, then that is ** returned instead. ** ** If no versions of the requested collations sequence are available, or ** another error occurs, NULL is returned and an error message written into ** pParse. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ u8 enc = pParse->db->enc; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < < < | | < < < < < < < < < < | < < < < < < < | < < < < < < < < < < < | > < | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 | pColl = &pColl[1]; break; default: assert(!"Cannot happen"); } return pColl; } static void callCollNeeded(sqlite *db, const char *zName, int nName){ /* No collation sequence of this type for this encoding is registered. ** Call the collation factory to see if it can supply us with one. */ char *zExternal = 0; assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( nName<0 ) nName = strlen(zName); if( db->xCollNeeded ){ zExternal = sqliteStrNDup(zName, nName); if( !zExternal ) return; db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); } if( db->xCollNeeded16 ){ if( SQLITE_BIGENDIAN ){ zExternal = sqlite3utf8to16be(zName, nName); }else{ zExternal = sqlite3utf8to16le(zName, nName); } if( !zExternal ) return; db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); } if( zExternal ) sqliteFree(zExternal); } static int synthCollSeq(Parse *pParse, CollSeq *pColl){ /* The collation factory failed to deliver a function but there may be ** other versions of this collation function (for other text encodings) ** available. Use one of these instead. Avoid a UTF-8 <-> UTF-16 ** conversion if possible. */ CollSeq *pColl2 = 0; char *z = pColl->zName; int n = strlen(z); switch( pParse->db->enc ){ case TEXT_Utf16le: pColl2 = sqlite3FindCollSeq(pParse->db, TEXT_Utf16be, z, n, 0); assert( pColl2 ); if( pColl2->xCmp ) break; pColl2 = sqlite3FindCollSeq(pParse->db, TEXT_Utf8, z, n, 0); assert( pColl2 ); break; case TEXT_Utf16be: pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16le, z, n, 0); assert( pColl2 ); if( pColl2->xCmp ) break; pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf8, z, n, 0); assert( pColl2 ); break; case TEXT_Utf8: pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16be, z, n, 0); assert( pColl2 ); if( pColl2->xCmp ) break; pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16le, z, n, 0); assert( pColl2 ); break; } if( pColl2->xCmp ){ memcpy(pColl, pColl2, sizeof(CollSeq)); }else{ if( pParse->nErr==0 ){ sqlite3SetNString(&pParse->zErrMsg, "no such collation sequence: ", -1, z, n, 0); } pParse->nErr++; return SQLITE_ERROR; } return SQLITE_OK; } /* ** This routine is called on a collation sequence before it is used to ** check that it is defined. An undefined collation sequence exists when ** a database is loaded that contains references to collation sequences ** that have not been defined by sqlite3_create_collation() etc. ** ** If required, this routine calls the 'collation needed' callback to ** request a definition of the collating sequence. If this doesn't work, ** an equivalent collating sequence that uses a text encoding different ** from the main database is substituted, if one is available. */ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ if( pColl && !pColl->xCmp ){ callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName)); if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){ return SQLITE_ERROR; } } return SQLITE_OK; } int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){ if( pIdx ){ int i; for(i=0; i<pIdx->nColumn; i++){ if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){ return SQLITE_ERROR; } } } return SQLITE_OK; } /* ** This function returns the collation sequence for database native text ** encoding identified by the string zName, length nName. ** ** If the requested collation sequence is not available, or not available ** in the database native encoding, the collation factory is invoked to ** request it. If the collation factory does not supply such a sequence, ** and the sequence is available in another text encoding, then that is ** returned instead. ** ** If no versions of the requested collations sequence are available, or ** another error occurs, NULL is returned and an error message written into ** pParse. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ u8 enc = pParse->db->enc; u8 initbusy = pParse->db->init.busy; CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy); if( !initbusy && (!pColl || !pColl->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(pParse->db, zName, nName); pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0); if( pColl && !pColl->xCmp ){ /* There may be a version of the collation sequence that requires ** translation between encodings. Search for it with synthCollSeq(). */ if( synthCollSeq(pParse, pColl) ){ return 0; } } } /* If nothing has been found, write the error message into pParse */ if( !initbusy && (!pColl || !pColl->xCmp) ){ if( pParse->nErr==0 ){ sqlite3SetNString(&pParse->zErrMsg, "no such collation sequence: ", -1, zName, nName, 0); } pParse->nErr++; pColl = 0; } return pColl; } /* ** Scan the column type name zType (length nType) and return the |
︙ | ︙ | |||
1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 | if( pList->a[i].pExpr ){ assert( pList->a[i].pExpr->pColl ); pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl; }else{ pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl; } assert( pIndex->keyInfo.aColl[i] ); } pIndex->keyInfo.nField = pList->nExpr; /* Link the new Index structure to its table and to the other ** in-memory database structures. */ if( !pParse->explain ){ | > > > > > | 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 | if( pList->a[i].pExpr ){ assert( pList->a[i].pExpr->pColl ); pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl; }else{ pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl; } assert( pIndex->keyInfo.aColl[i] ); if( !db->init.busy && sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) ){ goto exit_create_index; } } pIndex->keyInfo.nField = pList->nExpr; /* Link the new Index structure to its table and to the other ** in-memory database structures. */ if( !pParse->explain ){ |
︙ | ︙ | |||
2444 2445 2446 2447 2448 2449 2450 | ** ** Only database iDb and the temp database are made writable by this call. ** If iDb==0, then the main and temp databases are made writable. If ** iDb==1 then only the temp database is made writable. If iDb>1 then the ** specified auxiliary database and the temp database are made writable. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ | < | 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 | ** ** Only database iDb and the temp database are made writable by this call. ** If iDb==0, then the main and temp databases are made writable. If ** iDb==1 then only the temp database is made writable. If iDb>1 then the ** specified auxiliary database and the temp database are made writable. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3CodeVerifySchema(pParse, iDb); pParse->writeMask |= 1<<iDb; if( setStatement ){ sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); } |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.73 2004/06/10 10:50:15 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 200 201 202 | } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the key of every item to be deleted. */ | > > > > > > > | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | } } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ else{ /* Ensure all required collation sequences are available. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){ goto delete_from_cleanup; } } /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the key of every item to be deleted. */ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.138 2004/06/10 10:50:17 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> char const *sqlite3AffinityString(char affinity){ switch( affinity ){ case SQLITE_AFF_INTEGER: return "i"; |
︙ | ︙ | |||
55 56 57 58 59 60 61 | return pExpr->affinity; } /* ** Return the default collation sequence for the expression pExpr. If ** there is no default collation type, return 0. */ | | > | | | > > > | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | return pExpr->affinity; } /* ** Return the default collation sequence for the expression pExpr. If ** there is no default collation type, return 0. */ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ CollSeq *pColl = 0; if( pExpr ){ pColl = pExpr->pColl; if( pExpr->op==TK_AS && !pColl ){ return sqlite3ExprCollSeq(pParse, pExpr->pLeft); } } if( sqlite3CheckCollSeq(pParse, pColl) ){ pColl = 0; } return pColl; } /* ** pExpr is the left operand of a comparison operator. aff2 is the ** type affinity of the right operand. This routine returns the ** type affinity that should be used for the comparison operator. */ |
︙ | ︙ | |||
153 154 155 156 157 158 159 | ** a binary comparison operator comparing pLeft and pRight. ** ** If the left hand expression has a collating sequence type, then it is ** used. Otherwise the collation sequence for the right hand expression ** is used, or the default (BINARY) if neither expression has a collating ** type. */ | | | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | ** a binary comparison operator comparing pLeft and pRight. ** ** If the left hand expression has a collating sequence type, then it is ** used. Otherwise the collation sequence for the right hand expression ** is used, or the default (BINARY) if neither expression has a collating ** type. */ static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pLeft); if( !pColl ){ pColl = sqlite3ExprCollSeq(pParse, pRight); } return pColl; } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function |
︙ | ︙ | |||
864 865 866 867 868 869 870 | ** Generate code to write the results of the select into the temporary ** table allocated and opened above. */ int iParm = pExpr->iTable + (((int)affinity)<<16); assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0); if( pExpr->pSelect->pEList && pExpr->pSelect->pEList->nExpr>0 ){ | | | 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 | ** Generate code to write the results of the select into the temporary ** table allocated and opened above. */ int iParm = pExpr->iTable + (((int)affinity)<<16); assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0); if( pExpr->pSelect->pEList && pExpr->pSelect->pEList->nExpr>0 ){ keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pSelect->pEList->a[0].pExpr); } }else if( pExpr->pList ){ /* Case 2: expr IN (exprlist) ** ** For each expression, build an index key from the evaluation and ** store it in the temporary table. If <expr> is a column, then use |
︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, 0); | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, 0); CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); sqlite3VdbeOp3(v, op, p1, 0, (void *)p3, P3_COLLSEQ); break; } case TK_AND: case TK_OR: |
︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 | case TK_BETWEEN: { int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, 0); | | | | 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | case TK_BETWEEN: { int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, 0); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); sqlite3VdbeOp3(v, OP_Ge, p1, 0, (void *)p3, P3_COLLSEQ); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, 0); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); sqlite3VdbeOp3(v, OP_Le, p1, 0, (void *)p3, P3_COLLSEQ); sqlite3VdbeAddOp(v, OP_And, 0, 0); break; } case TK_UPLUS: case TK_AS: { sqlite3ExprCode(pParse, pExpr->pLeft); |
︙ | ︙ | |||
1356 1357 1358 1359 1360 1361 1362 | if( pExpr->pLeft ){ sqlite3ExprCode(pParse, pExpr->pLeft); } for(i=0; i<nExpr; i=i+2){ sqlite3ExprCode(pParse, pExpr->pList->a[i].pExpr); if( pExpr->pLeft ){ int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[i].pExpr, 1); | | | 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 | if( pExpr->pLeft ){ sqlite3ExprCode(pParse, pExpr->pLeft); } for(i=0; i<nExpr; i=i+2){ sqlite3ExprCode(pParse, pExpr->pList->a[i].pExpr); if( pExpr->pLeft ){ int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[i].pExpr, 1); CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[i].pExpr); sqlite3VdbeAddOp(v, OP_Dup, 1, 1); jumpInst = sqlite3VdbeOp3(v, OP_Ne, p1, 0, (void *)p3, P3_COLLSEQ); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); }else{ jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0); } |
︙ | ︙ | |||
1472 1473 1474 1475 1476 1477 1478 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); | | | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ); break; } case TK_ISNULL: case TK_NOTNULL: { |
︙ | ︙ | |||
1498 1499 1500 1501 1502 1503 1504 | int addr; int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); | | | | 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 | int addr; int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); addr = sqlite3VdbeOp3(v, OP_Lt, p1, 0, (void *)p3, P3_COLLSEQ); sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); sqlite3VdbeOp3(v, OP_Le, p1, dest, (void *)p3, P3_COLLSEQ); sqlite3VdbeAddOp(v, OP_Integer, 0, 0); sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); break; } |
︙ | ︙ | |||
1566 1567 1568 1569 1570 1571 1572 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); | | | 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 | case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ); break; } case TK_ISNULL: case TK_NOTNULL: { |
︙ | ︙ | |||
1593 1594 1595 1596 1597 1598 1599 | int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); addr = sqlite3VdbeCurrentAddr(v); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); | | | | 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 | int p1; CollSeq *p3; sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); addr = sqlite3VdbeCurrentAddr(v); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); sqlite3VdbeOp3(v, OP_Ge, p1, addr+3, (void *)p3, P3_COLLSEQ); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, dest); sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull); p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); sqlite3VdbeOp3(v, OP_Gt, p1, dest, (void *)p3, P3_COLLSEQ); break; } default: { sqlite3ExprCode(pParse, pExpr); sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest); break; |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.110 2004/06/10 10:50:21 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 242 | if( pTab==0 ) goto insert_cleanup; /* If pTab is really a view, make sure it has been initialized. */ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); | > > > > > > > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | if( pTab==0 ) goto insert_cleanup; /* If pTab is really a view, make sure it has been initialized. */ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } /* Ensure all required collation sequences are available. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){ goto insert_cleanup; } } /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.214 2004/06/10 10:50:22 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
1213 1214 1215 1216 1217 1218 1219 | ){ int rc; char *zName8 = sqlite3utf16to8(zName, -1, SQLITE_BIGENDIAN); rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare); sqliteFree(zName8); return rc; } | > > > > > > > > > > > > > > > > > > > > > > | 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 | ){ int rc; char *zName8 = sqlite3utf16to8(zName, -1, SQLITE_BIGENDIAN); rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare); sqliteFree(zName8); return rc; } int sqlite3_collation_needed( sqlite3 *db, void *pCollNeededArg, void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) ){ db->xCollNeeded = xCollNeeded; db->xCollNeeded16 = 0; db->pCollNeededArg = pCollNeededArg; return SQLITE_OK; } int sqlite3_collation_needed16( sqlite3 *db, void *pCollNeededArg, void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) ){ db->xCollNeeded = 0; db->xCollNeeded16 = xCollNeeded16; db->pCollNeededArg = pCollNeededArg; return SQLITE_OK; } |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.42 2004/06/10 10:50:25 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #ifdef SQLITE_DEBUG # include "pager.h" # include "btree.h" |
︙ | ︙ | |||
651 652 653 654 655 656 657 658 659 660 661 662 663 664 | */ for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); cnt++; } } sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); sqlite3VdbeAddOp(v, OP_Dup, 0, 1); addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); | > | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | */ for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) return; sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); cnt++; } } sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); sqlite3VdbeAddOp(v, OP_Dup, 0, 1); addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.186 2004/06/10 10:50:25 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
546 547 548 549 550 551 552 | pInfo->aSortOrder = (char*)&pInfo->aColl[nCol]; pInfo->nField = nCol; for(i=0; i<nCol; i++){ /* If a collation sequence was specified explicity, then it ** is stored in pOrderBy->a[i].zName. Otherwise, use the default ** collation type for the expression. */ | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | pInfo->aSortOrder = (char*)&pInfo->aColl[nCol]; pInfo->nField = nCol; for(i=0; i<nCol; i++){ /* If a collation sequence was specified explicity, then it ** is stored in pOrderBy->a[i].zName. Otherwise, use the default ** collation type for the expression. */ pInfo->aColl[i] = sqlite3ExprCollSeq(pParse, pOrderBy->a[i].pExpr); if( !pInfo->aColl[i] ){ pInfo->aColl[i] = db->pDfltColl; } pInfo->aSortOrder[i] = pOrderBy->a[i].sortOrder; } sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF); addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1); |
︙ | ︙ | |||
821 822 823 824 825 826 827 | zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p)); pTab->aCol[i].zType = zType; pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; if( zType ){ pTab->aCol[i].affinity = sqlite3AffinityType(zType, strlen(zType)); } | | | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p)); pTab->aCol[i].zType = zType; pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; if( zType ){ pTab->aCol[i].affinity = sqlite3AffinityType(zType, strlen(zType)); } pTab->aCol[i].pColl = sqlite3ExprCollSeq(pParse, p); if( !pTab->aCol[i].pColl ){ pTab->aCol[i].pColl = pParse->db->pDfltColl; } } pTab->iPKey = -1; return pTab; } |
︙ | ︙ | |||
2229 2230 2231 2232 2233 2234 2235 | "between 1 and %d", iCol, pEList->nExpr); goto select_end; } } } } | < < < < < < < < < < < < < < < | 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 | "between 1 and %d", iCol, pEList->nExpr); goto select_end; } } } } /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto select_end; /* Identify column names if we will be using them in a callback. This ** step is skipped if the output is going to some other destination. |
︙ | ︙ | |||
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 | ** If flattening is a possiblity, do so and return immediately. */ if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; return rc; } /* Set the limiter. */ computeLimitRegisters(pParse, p); /* If the output is destined for a temporary table, open that table. */ | > > > > > > > > > > > > > > > | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 | ** If flattening is a possiblity, do so and return immediately. */ if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; return rc; } /* If there is an ORDER BY clause, resolve any collation sequences ** names that have been explicitly specified. */ if( pOrderBy ){ for(i=0; i<pOrderBy->nExpr; i++){ if( pOrderBy->a[i].zName ){ pOrderBy->a[i].pExpr->pColl = sqlite3LocateCollSeq(pParse, pOrderBy->a[i].zName, -1); } } if( pParse->nErr ){ goto select_end; } } /* Set the limiter. */ computeLimitRegisters(pParse, p); /* If the output is destined for a temporary table, open that table. */ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.97 2004/06/10 10:50:30 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
963 964 965 966 967 968 969 970 971 972 | void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); #define SQLITE_UTF8 1 #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 int sqlite3_create_collation( sqlite3*, const char *zName, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 | void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); #define SQLITE_UTF8 1 #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 /* ** These two functions are used to add new collation sequences to the ** sqlite3 handle specified as the first argument. ** ** The name of the new collation sequence is specified as a UTF-8 string ** for sqlite3_create_collation() and a UTF-16 string for ** sqlite3_create_collation16(). In both cases the name is passed as the ** second function argument. ** ** The third argument must be one of the constants SQLITE_UTF8, ** SQLITE_UTF16LE or SQLITE_UTF16BE, indicating that the user-supplied ** routine expects to be passed pointers to strings encoded using UTF-8, ** UTF-16 little-endian or UTF-16 big-endian respectively. ** ** A pointer to the user supplied routine must be passed as the fifth ** argument. If it is NULL, this is the same as deleting the collation ** sequence (so that SQLite cannot call it anymore). Each time the user ** supplied function is invoked, it is passed a copy of the void* passed as ** the fourth argument to sqlite3_create_collation() or ** sqlite3_create_collation16() as its first parameter. ** ** The remaining arguments to the user-supplied routine are two strings, ** each represented by a [length, data] pair and encoded in the encoding ** that was passed as the third argument when the collation sequence was ** registered. The user routine should return negative, zero or positive if ** the first string is less than, equal to, or greater than the second ** string. i.e. (STRING1 - STRING2). */ int sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void*, int(*xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_create_collation16( sqlite3*, const char *zName, int eTextRep, void*, int(*xCompare)(void*,int,const void*,int,const void*) ); /* ** To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** database handle to be called whenever an undefined collation sequence is ** required. ** ** If the function is registered using the sqlite3_collation_needed() API, ** then it is passed the names of undefined collation sequences as strings ** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names ** are passed as UTF-16 in machine native byte order. A call to either ** function replaces any existing callback. ** ** When the user-function is invoked, the first argument passed is a copy ** of the second argument to sqlite3_collation_needed() or ** sqlite3_collation_needed16(). The second argument is the database ** handle. The third argument is one of SQLITE_UTF8, SQLITE_UTF16BE or ** SQLITE_UTF16LE, indicating the most desirable form of the collation ** sequence function required. The fourth parameter is the name of the ** required collation sequence. ** ** The collation sequence is returned to SQLite by a collation-needed ** callback using the sqlite3_create_collation() or ** sqlite3_create_collation16() APIs, described above. */ int sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); int sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.280 2004/06/10 10:50:32 danielk1977 Exp $ */ #include "config.h" #include "sqlite3.h" #include "hash.h" #include "parse.h" #include <stdio.h> #include <stdlib.h> |
︙ | ︙ | |||
419 420 421 422 423 424 425 426 427 428 429 430 431 432 | int errCode; /* Most recent error code (SQLITE_*) */ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ void *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ u8 enc; /* Text encoding for this database. */ u8 autoCommit; /* The auto-commit flag. */ int nMaster; /* Length of master journal name. -1=unknown */ }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement | > > > | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | int errCode; /* Most recent error code (SQLITE_*) */ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ void *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ u8 enc; /* Text encoding for this database. */ u8 autoCommit; /* The auto-commit flag. */ int nMaster; /* Length of master journal name. -1=unknown */ void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); void *pCollNeededArg; }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement |
︙ | ︙ | |||
1391 1392 1393 1394 1395 1396 1397 | void *sqlite3HexToBlob(const char *z); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrStr(int); int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold); int sqlite3ReadSchema(sqlite *db, char **); CollSeq *sqlite3FindCollSeq(sqlite *,u8 enc, const char *,int,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName); | | > > | 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 | void *sqlite3HexToBlob(const char *z); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrStr(int); int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold); int sqlite3ReadSchema(sqlite *db, char **); CollSeq *sqlite3FindCollSeq(sqlite *,u8 enc, const char *,int,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3CheckIndexCollSeq(Parse *, Index *); |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.83 2004/06/10 10:50:38 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
65 66 67 68 69 70 71 | char *zCommit; /* The commit hook callback routine */ char *zTrace; /* The trace callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ SqlCollate *pCollate; /* List of SQL collation functions */ int rc; /* Return code of most recent sqlite3_exec() */ | | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | char *zCommit; /* The commit hook callback routine */ char *zTrace; /* The trace callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ SqlCollate *pCollate; /* List of SQL collation functions */ int rc; /* Return code of most recent sqlite3_exec() */ int nChange; /* Database changes for the most recent eval */ Tcl_Obj *pCollateNeeded; /* Collation needed script */ }; /* ** An instance of this structure passes information thru the sqlite ** logic from the original TCL command into the callback routine. */ typedef struct CallbackData CallbackData; |
︙ | ︙ | |||
212 213 214 215 216 217 218 219 220 221 222 223 224 225 | rc = Tcl_Eval(pDb->interp, pDb->zCommit); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 1; } return 0; } /* ** This routine is called to evaluate an SQL collation function implemented ** using TCL script. */ static int tclSqlCollate( void *pCtx, | > > > > > > > > > > > > > > | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | rc = Tcl_Eval(pDb->interp, pDb->zCommit); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 1; } return 0; } static void tclCollateNeeded( void *pCtx, sqlite *db, int enc, const char *zName ){ SqliteDb *pDb = (SqliteDb *)pCtx; Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded); Tcl_IncrRefCount(pScript); Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1)); Tcl_EvalObjEx(pDb->interp, pScript, 0); Tcl_DecrRefCount(pScript); } /* ** This routine is called to evaluate an SQL collation function implemented ** using TCL script. */ static int tclSqlCollate( void *pCtx, |
︙ | ︙ | |||
378 379 380 381 382 383 384 | int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "busy", "changes", "close", "commit_hook", "complete", "errorcode", "eval", "function", "last_insert_rowid", "last_statement_changes", "onecolumn", "progress", "rekey", "timeout", | | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "busy", "changes", "close", "commit_hook", "complete", "errorcode", "eval", "function", "last_insert_rowid", "last_statement_changes", "onecolumn", "progress", "rekey", "timeout", "trace", "collate", "collation_needed", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMMIT_HOOK, DB_COMPLETE, DB_ERRORCODE, DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID, DB_LAST_STATEMENT_CHANGES, DB_ONECOLUMN, DB_PROGRESS, DB_REKEY, DB_TIMEOUT, DB_TRACE, DB_COLLATE, DB_COLLATION_NEEDED }; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ |
︙ | ︙ | |||
919 920 921 922 923 924 925 926 927 928 929 930 931 932 | strcpy(pCollate->zScript, zScript); if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, pCollate, tclSqlCollate) ){ return TCL_ERROR; } break; } } /* End of the SWITCH statement */ return rc; } /* ** sqlite DBNAME FILENAME ?MODE? ?-key KEY? | > > > > > > > > > > > > > > > > > > > > | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 | strcpy(pCollate->zScript, zScript); if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, pCollate, tclSqlCollate) ){ return TCL_ERROR; } break; } /* ** $db collate_needed SCRIPT ** ** Create a new SQL collation function called NAME. Whenever ** that function is called, invoke SCRIPT to evaluate the function. */ case DB_COLLATION_NEEDED: { if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT"); return TCL_ERROR; } if( pDb->pCollateNeeded ){ Tcl_DecrRefCount(pDb->pCollateNeeded); } pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]); Tcl_IncrRefCount(pDb->pCollateNeeded); sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded); break; } } /* End of the SWITCH statement */ return rc; } /* ** sqlite DBNAME FILENAME ?MODE? ?-key KEY? |
︙ | ︙ | |||
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | */ #ifdef SQLITE_TEST { extern void Md5_Register(sqlite*); Md5_Register(p->db); } #endif return TCL_OK; } /* ** Provide a dummy Tcl_InitStubs if we are using this as a static ** library. */ | > | 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 | */ #ifdef SQLITE_TEST { extern void Md5_Register(sqlite*); Md5_Register(p->db); } #endif p->interp = interp; return TCL_OK; } /* ** Provide a dummy Tcl_InitStubs if we are using this as a static ** library. */ |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.82 2004/06/10 10:50:45 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; |
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | i = 0; }else{ for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ){ apIdx[nIdx++] = pIdx; aIdxUsed[j] = 1; }else{ aIdxUsed[j] = 0; } } | > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | i = 0; }else{ for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ){ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup; apIdx[nIdx++] = pIdx; aIdxUsed[j] = 1; }else{ aIdxUsed[j] = 0; } } |
︙ | ︙ |