Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a code generator bug caused by the new CSE optimization. Add test cases to prevent a recurrence. (CVS 5011) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d04246a46399e839e70b1bd57e209f80 |
User & Date: | drh 2008-04-15 12:14:22.000 |
Context
2008-04-15
| ||
14:36 | Do not attempt to omit unused columns of a view in an instead-of trigger since sometimes those columns can be used in ways that we do not expect. Ticket #3055. (CVS 5012) (check-in: f5fc42e96d user: drh tags: trunk) | |
12:14 | Fix a code generator bug caused by the new CSE optimization. Add test cases to prevent a recurrence. (CVS 5011) (check-in: d04246a463 user: drh tags: trunk) | |
04:02 | Fix a bug in the RTRIM collating sequence discovered while working on condition/decision branch coverage. Increase test coverage of the date/time functions. (CVS 5010) (check-in: c5435f71ef user: drh tags: trunk) | |
Changes
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.367 2008/04/15 12:14:22 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 | if( pParse->aColCache[i].iReg==iTarget ){ pParse->aColCache[i] = pParse->aColCache[--pParse->nColCache]; pParse->iColCache = pParse->nColCache; } } return iTarget; } /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. ** ** With this routine, there is no guaranteed that results will | > > > > > > > > > > > > > > > > > > | 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 | if( pParse->aColCache[i].iReg==iTarget ){ pParse->aColCache[i] = pParse->aColCache[--pParse->nColCache]; pParse->iColCache = pParse->nColCache; } } return iTarget; } /* ** If the last instruction coded is an ephemeral copy of any of ** the registers in the nReg registers beginning with iReg, then ** convert the last instruction from OP_SCopy to OP_Copy. */ void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){ int addr; VdbeOp *pOp; Vdbe *v; v = pParse->pVdbe; addr = sqlite3VdbeCurrentAddr(v); pOp = sqlite3VdbeGetOp(v, addr-1); if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){ pOp->opcode = OP_Copy; } } /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. ** ** With this routine, there is no guaranteed that results will |
︙ | ︙ | |||
2370 2371 2372 2373 2374 2375 2376 | zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); if( pList ){ nExpr = pList->nExpr; r1 = sqlite3GetTempRange(pParse, nExpr); | | | 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 | zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); if( pList ){ nExpr = pList->nExpr; r1 = sqlite3GetTempRange(pParse, nExpr); sqlite3ExprCodeExprList(pParse, pList, r1, 1); }else{ nExpr = r1 = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. ** |
︙ | ︙ | |||
2800 2801 2802 2803 2804 2805 2806 | ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ | | > | | | | 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 | ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ int target, /* Where to write results */ int doHardCopy /* Call sqlite3ExprHardCopy on each element if true */ ){ struct ExprList_item *pItem; int i, n; assert( pList!=0 || pParse->db->mallocFailed ); if( pList==0 ){ return 0; } assert( target>0 ); n = pList->nExpr; for(pItem=pList->a, i=0; i<n; i++, pItem++){ sqlite3ExprCode(pParse, pItem->pExpr, target+i); if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n); } return n; } /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution |
︙ | ︙ |
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.427 2008/04/15 12:14:22 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
418 419 420 421 422 423 424 | Select *pSelect, /* The whole SELECT statement */ int regData /* Register holding data to be sorted */ ){ Vdbe *v = pParse->pVdbe; int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); | | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | Select *pSelect, /* The whole SELECT statement */ int regData /* Register holding data to be sorted */ ){ Vdbe *v = pParse->pVdbe; int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); if( pSelect->iLimit>=0 ){ |
︙ | ︙ | |||
576 577 578 579 580 581 582 | for(i=0; i<nColumn; i++){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); } }else if( eDest!=SRT_Exists ){ /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ | < | < | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | for(i=0; i<nColumn; i++){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); } }else if( eDest!=SRT_Exists ){ /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Callback); } nColumn = nResultCol; /* If the DISTINCT keyword was present on the SELECT statement ** and this row has been seen before, then do not make this row ** part of the result. */ |
︙ | ︙ | |||
2898 2899 2900 2901 2902 2903 2904 | int nArg; int addrNext = 0; int regAgg; ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); | | | 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 | int nArg; int addrNext = 0; int regAgg; ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pList, regAgg, 0); }else{ nArg = 0; regAgg = 0; } if( pF->iDistinct>=0 ){ addrNext = sqlite3VdbeMakeLabel(v); assert( nArg==1 ); |
︙ | ︙ | |||
3428 3429 3430 3431 3432 3433 3434 | for(i=0; i<sAggInfo.nColumn; i++){ if( sAggInfo.aCol[i].iSorterColumn>=j ){ nCol++; j++; } } regBase = sqlite3GetTempRange(pParse, nCol); | | | 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 | for(i=0; i<sAggInfo.nColumn; i++){ if( sAggInfo.aCol[i].iSorterColumn>=j ){ nCol++; j++; } } regBase = sqlite3GetTempRange(pParse, nCol); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); j = nGroupBy+1; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; int r2 = sqlite3ExprCodeGetColumn(pParse, |
︙ | ︙ |
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.692 2008/04/15 12:14:22 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if it was run ** (otherwise we get an empty default). |
︙ | ︙ | |||
1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 | WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8); void sqlite3WhereEnd(WhereInfo*); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int); void sqlite3ExprClearColumnCache(Parse*, int); void sqlite3ExprCacheAffinityChange(Parse*, int, int); int sqlite3ExprWritableRegister(Parse*,int,int); int sqlite3ExprCode(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); void sqlite3ExprCodeConstants(Parse*, Expr*); | > | | 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 | WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8); void sqlite3WhereEnd(WhereInfo*); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int); void sqlite3ExprClearColumnCache(Parse*, int); void sqlite3ExprCacheAffinityChange(Parse*, int, int); int sqlite3ExprWritableRegister(Parse*,int,int); void sqlite3ExprHardCopy(Parse*,int,int); int sqlite3ExprCode(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); void sqlite3ExprCodeConstants(Parse*, Expr*); int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); |
︙ | ︙ |
Changes to src/test_func.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. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements new SQL functions used by the test scripts. ** | | | 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. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements new SQL functions used by the test scripts. ** ** $Id: test_func.c,v 1.5 2008/04/15 12:14:22 drh Exp $ */ #include "sqlite3.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | sqlite3_value **argv ){ sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), -1); if( nArg==2 ){ sqlite3_result_error_code(pCtx, sqlite3_value_int(argv[1])); } } static int registerTestFunctions(sqlite3 *db){ static const struct { char *zName; signed char nArg; unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */ void (*xFunc)(sqlite3_context*,int,sqlite3_value **); } aFuncs[] = { { "randstr", 2, SQLITE_UTF8, randStr }, { "test_destructor", 1, SQLITE_UTF8, test_destructor}, { "test_destructor16", 1, SQLITE_UTF8, test_destructor16}, { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count}, { "test_auxdata", -1, SQLITE_UTF8, test_auxdata}, { "test_error", 1, SQLITE_UTF8, test_error}, { "test_error", 2, SQLITE_UTF8, test_error}, }; int i; extern int Md5_Register(sqlite3*); for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 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 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | sqlite3_value **argv ){ sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), -1); if( nArg==2 ){ sqlite3_result_error_code(pCtx, sqlite3_value_int(argv[1])); } } /* ** This function takes two arguments. It performance UTF-8/16 type ** conversions on the first argument then returns a copy of the second ** argument. ** ** This function is used in cases such as the following: ** ** SELECT test_isolation(x,x) FROM t1; ** ** We want to verify that the type conversions that occur on the ** first argument do not invalidate the second argument. */ static void test_isolation( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ #ifndef SQLITE_OMIT_UTF16 sqlite3_value_text16(argv[0]); sqlite3_value_text(argv[0]); sqlite3_value_text16(argv[0]); sqlite3_value_text(argv[0]); #endif sqlite3_result_value(pCtx, argv[1]); } static int registerTestFunctions(sqlite3 *db){ static const struct { char *zName; signed char nArg; unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */ void (*xFunc)(sqlite3_context*,int,sqlite3_value **); } aFuncs[] = { { "randstr", 2, SQLITE_UTF8, randStr }, { "test_destructor", 1, SQLITE_UTF8, test_destructor}, { "test_destructor16", 1, SQLITE_UTF8, test_destructor16}, { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count}, { "test_auxdata", -1, SQLITE_UTF8, test_auxdata}, { "test_error", 1, SQLITE_UTF8, test_error}, { "test_error", 2, SQLITE_UTF8, test_error}, { "test_isolation", 2, SQLITE_UTF8, test_isolation}, }; int i; extern int Md5_Register(sqlite3*); for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.730 2008/04/15 12:14:22 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
876 877 878 879 880 881 882 883 884 885 886 887 888 889 | #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem; pOut->zMalloc = 0; pOut->flags |= MEM_Static; if( pOp->p4type==P4_DYNAMIC ){ sqlite3_free(pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | > | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 | #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem; pOut->zMalloc = 0; pOut->flags |= MEM_Static; pOut->flags &= ~MEM_Dyn; if( pOp->p4type==P4_DYNAMIC ){ sqlite3_free(pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
︙ | ︙ |
Changes to test/capi3c.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This is a copy of the capi3.test file that has been adapted to # test the new sqlite3_prepare_v2 interface. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This is a copy of the capi3.test file that has been adapted to # test the new sqlite3_prepare_v2 interface. # # $Id: capi3c.test,v 1.18 2008/04/15 12:14:22 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. |
︙ | ︙ | |||
1262 1263 1264 1265 1266 1267 1268 | sqlite3_finalize $STMT do_test capi3c-22.3 { set STMT [sqlite3_prepare_v2 db {SELECT test_error('the message',16)} -1 TAIL] sqlite3_step $STMT } {SQLITE_EMPTY} sqlite3_finalize $STMT | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | sqlite3_finalize $STMT do_test capi3c-22.3 { set STMT [sqlite3_prepare_v2 db {SELECT test_error('the message',16)} -1 TAIL] sqlite3_step $STMT } {SQLITE_EMPTY} sqlite3_finalize $STMT # For a multi-column result set where the same table column is repeated # in multiple columns of the output, verify that doing a UTF-8 to UTF-16 # conversion (or vice versa) on one column does not change the value of # the second. # do_test capi3c-23.1 { set STMT [sqlite3_prepare_v2 db {SELECT b,b,b,b FROM t1} -1 TAIL] sqlite3_step $STMT } {SQLITE_ROW} do_test capi3c-23.2 { sqlite3_column_text16 $STMT 0 sqlite3_column_text $STMT 1 } {one} do_test capi3c-23.3 { sqlite3_column_text16 $STMT 2 sqlite3_column_text $STMT 3 } {one} sqlite3_finalize $STMT do_test capi3c-23.4 { set STMT [sqlite3_prepare_v2 db {SELECT b||'x',b,b,b FROM t1} -1 TAIL] sqlite3_step $STMT } {SQLITE_ROW} do_test capi3c-23.5 { sqlite3_column_text16 $STMT 0 sqlite3_column_text $STMT 1 } {one} do_test capi3c-23.6 { sqlite3_column_text16 $STMT 2 sqlite3_column_text $STMT 3 } {one} sqlite3_finalize $STMT finish_test |
Changes to test/func.test.
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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # | | | 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # # $Id: func.test,v 1.77 2008/04/15 12:14:22 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a table to work with. # do_test func-0.0 { |
︙ | ︙ | |||
925 926 927 928 929 930 931 932 933 | } } {thisprogramisfreesoftware} do_test func-24.6 { execsql { SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 } } {BEGIN-this,program,is,free,software} finish_test | > > > > > > > | 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 | } } {thisprogramisfreesoftware} do_test func-24.6 { execsql { SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 } } {BEGIN-this,program,is,free,software} # Use the test_isolation function to make sure that type conversions # on function arguments do not effect subsequent arguments. # do_test func-25.1 { execsql {SELECT test_isolation(t1,t1) FROM tbl1} } {this program is free software} finish_test |