Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the latest trunk fixes into the sessions branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions |
Files: | files | file ages | folders |
SHA1: |
131a2d3116436ca6304777c9c5d46b7c |
User & Date: | drh 2015-02-25 14:02:53.832 |
Context
2015-03-09
| ||
13:07 | Merge recent trunk enhancements into the sessions branch. (check-in: 68c8937e83 user: drh tags: sessions) | |
2015-02-25
| ||
14:02 | Merge the latest trunk fixes into the sessions branch. (check-in: 131a2d3116 user: drh tags: sessions) | |
13:48 | Add support for the linenoise command-line editing library in shell.c. (check-in: 03bbb94719 user: drh tags: trunk) | |
2015-02-21
| ||
15:13 | Merge all recent trunk changes into the sessions branch. (check-in: f36bb5fa5c user: drh tags: sessions) | |
Changes
Changes to src/shell.c.
︙ | ︙ | |||
55 56 57 58 59 60 61 62 | # include <sys/types.h> #endif #if HAVE_READLINE # include <readline/readline.h> # include <readline/history.h> #endif #if HAVE_EDITLINE | > < < > | > | > > > > > > > > > > > > > > > > | | | > > > | 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | # include <sys/types.h> #endif #if HAVE_READLINE # include <readline/readline.h> # include <readline/history.h> #endif #if HAVE_EDITLINE # include <editline/readline.h> #endif #if HAVE_EDITLINE || HAVE_READLINE # define shell_add_history(X) add_history(X) # define shell_read_history(X) read_history(X) # define shell_write_history(X) write_history(X) # define shell_stifle_history(X) stifle_history(X) # define shell_readline(X) readline(X) #elif HAVE_LINENOISE # include "linenoise.h" # define shell_add_history(X) linenoiseHistoryAdd(X) # define shell_read_history(X) linenoiseHistoryLoad(X) # define shell_write_history(X) linenoiseHistorySave(X) # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) # define shell_readline(X) linenoise(X) #else # define shell_read_history(X) # define shell_write_history(X) # define shell_stifle_history(X) # define SHELL_USE_LOCAL_GETLINE 1 #endif #if defined(_WIN32) || defined(WIN32) # include <io.h> # include <fcntl.h> #define isatty(h) _isatty(h) #ifndef access # define access(f,m) _access((f),(m)) |
︙ | ︙ | |||
447 448 449 450 451 452 453 | static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ char *zPrompt; char *zResult; if( in!=0 ){ zResult = local_getline(zPrior, in); }else{ zPrompt = isContinuation ? continuePrompt : mainPrompt; | | < < < < > > > > | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ char *zPrompt; char *zResult; if( in!=0 ){ zResult = local_getline(zPrior, in); }else{ zPrompt = isContinuation ? continuePrompt : mainPrompt; #if SHELL_USE_LOCAL_GETLINE printf("%s", zPrompt); fflush(stdout); zResult = local_getline(zPrior, stdin); #else free(zPrior); zResult = shell_readline(zPrompt); if( zResult && *zResult ) shell_add_history(zResult); #endif } return zResult; } #if defined(SQLITE_ENABLE_SESSION) /* |
︙ | ︙ | |||
4913 4914 4915 4916 4917 4918 4919 | zHome = find_home_dir(); if( zHome ){ nHistory = strlen30(zHome) + 20; if( (zHistory = malloc(nHistory))!=0 ){ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); } } | < | < | | | 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 | zHome = find_home_dir(); if( zHome ){ nHistory = strlen30(zHome) + 20; if( (zHistory = malloc(nHistory))!=0 ){ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); } } if( zHistory ) shell_read_history(zHistory); rc = process_input(&data, 0); if( zHistory ){ shell_stifle_history(100); shell_write_history(zHistory); free(zHistory); } }else{ rc = process_input(&data, stdin); } } set_table_name(&data, 0); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 | void sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their ** results into memory obtained from [sqlite3_malloc()]. ** The strings returned by these two routines should be ** released by [sqlite3_free()]. ^Both routines return a ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough ** memory to hold the resulting string. | > > > > | 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | void sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** These routines understand most of the common K&R formatting options, ** plus some additional non-standard formats, detailed below. ** Note that some of the more obscure formatting options from recent ** C-library standards are omitted from this implementation. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their ** results into memory obtained from [sqlite3_malloc()]. ** The strings returned by these two routines should be ** released by [sqlite3_free()]. ^Both routines return a ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough ** memory to hold the resulting string. |
︙ | ︙ | |||
2260 2261 2262 2263 2264 2265 2266 | ** written will be n-1 characters. ** ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). ** ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf() formatting options apply. In addition, there | | | 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 | ** written will be n-1 characters. ** ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). ** ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf() formatting options apply. In addition, there ** is are "%q", "%Q", "%w" and "%z" options. ** ** ^(The %q option works like %s in that it substitutes a nul-terminated ** string from the argument list. But %q also doubles every '\'' character. ** %q is designed for use inside a string literal.)^ By doubling each '\'' ** character it escapes that character and allows it to be inserted into ** the string. ** |
︙ | ︙ | |||
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 | ** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); ** sqlite3_exec(db, zSQL, 0, 0, 0); ** sqlite3_free(zSQL); ** </pre></blockquote> ** ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); | > > > > > > | 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 | ** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); ** sqlite3_exec(db, zSQL, 0, 0, 0); ** sqlite3_free(zSQL); ** </pre></blockquote> ** ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. ** ** ^(The "%w" formatting option is like "%q" except that it expects to ** be contained within double-quotes instead of single quotes, and it ** escapes the double-quote character instead of the single-quote ** character.)^ The "%w" formatting option is intended for safely inserting ** table and column names into a constructed SQL statement. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
1608 1609 1610 1611 1612 1613 1614 1615 1616 | ** and used to match WHERE clause constraints */ nKeyCol = 0; pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ if( pLoop->prereq==0 && (pTerm->wtFlags & TERM_VIRTUAL)==0 | > > > > > | | | 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 | ** and used to match WHERE clause constraints */ nKeyCol = 0; pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ Expr *pExpr = pTerm->pExpr; assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ if( pLoop->prereq==0 && (pTerm->wtFlags & TERM_VIRTUAL)==0 && !ExprHasProperty(pExpr, EP_FromJoin) && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ pPartial = sqlite3ExprAnd(pParse->db, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ int iCol = pTerm->u.leftColumn; Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); testcase( iCol==BMS ); testcase( iCol==BMS-1 ); if( !sentWarning ){ |
︙ | ︙ | |||
4690 4691 4692 4693 4694 4695 4696 | /* Check to see if a partial index with pPartIndexWhere can be used ** in the current query. Return true if it can be and false if not. */ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ int i; WhereTerm *pTerm; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ | > | > > > > | 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 | /* Check to see if a partial index with pPartIndexWhere can be used ** in the current query. Return true if it can be and false if not. */ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ int i; WhereTerm *pTerm; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ Expr *pExpr = pTerm->pExpr; if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) ){ return 1; } } return 0; } /* ** Add all WhereLoop objects for a single table of the join where the table ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be |
︙ | ︙ |
Changes to test/autoindex4.test.
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 | CREATE TABLE t3(e,f); INSERT INTO t3 VALUES(123,654),(555,444),(234,987); SELECT (SELECT count(*) FROM t1, t2 WHERE a=e AND x=f), e, f, '|' FROM t3 ORDER BY rowid; } {1 123 654 | 0 555 444 | 4 234 987 |} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 44 45 46 47 48 49 50 51 52 53 54 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 81 82 83 | CREATE TABLE t3(e,f); INSERT INTO t3 VALUES(123,654),(555,444),(234,987); SELECT (SELECT count(*) FROM t1, t2 WHERE a=e AND x=f), e, f, '|' FROM t3 ORDER BY rowid; } {1 123 654 | 0 555 444 | 4 234 987 |} # Ticket [2326c258d02ead33d] # Two joins, one with and the other without an ORDER BY clause. # The one without ORDER BY correctly returns two rows of result. # The one with ORDER BY returns no rows. # do_execsql_test autoindex4-3.0 { CREATE TABLE A(Name text); CREATE TABLE Items(ItemName text , Name text); INSERT INTO Items VALUES('Item1','Parent'); INSERT INTO Items VALUES('Item2','Parent'); CREATE TABLE B(Name text); SELECT Items.ItemName FROM Items LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy') LEFT JOIN B ON (B.Name = Items.ItemName) WHERE Items.Name = 'Parent' ORDER BY Items.ItemName; } {Item1 Item2} do_execsql_test autoindex4-3.1 { CREATE INDEX Items_x1 ON Items(ItemName,Name) WHERE ItemName = 'dummy'; SELECT Items.ItemName FROM Items LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy') LEFT JOIN B ON (B.Name = Items.ItemName) WHERE Items.Name = 'Parent' ORDER BY Items.ItemName; } {Item1 Item2} finish_test |
Changes to test/index6.test.
︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 | UPDATE OR REPLACE t6 SET b=789; SELECT * FROM t6; } {123 789} do_execsql_test index6-6.2 { PRAGMA integrity_check; } {ok} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | UPDATE OR REPLACE t6 SET b=789; SELECT * FROM t6; } {123 789} do_execsql_test index6-6.2 { PRAGMA integrity_check; } {ok} # Test case for ticket [2326c258d02ead33d69faa63de8f4686b9b1b9d9] on # 2015-02-24. Any use of a partial index qualifying constraint inside # the ON clause of a LEFT JOIN was causing incorrect results for all # versions of SQLite 3.8.0 through 3.8.8. # do_execsql_test index6-7.0 { CREATE TABLE t7a(x); CREATE TABLE t7b(y); INSERT INTO t7a(x) VALUES(1); CREATE INDEX t7ax ON t7a(x) WHERE x=99; PRAGMA automatic_index=OFF; SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x; } {1 {}} do_execsql_test index6-7.1 { INSERT INTO t7b(y) VALUES(2); SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x; } {} do_execsql_test index6-7.2 { INSERT INTO t7a(x) VALUES(99); SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x; } {1 {} 99 2} do_execsql_test index6-7.3 { SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x; } {99 2} do_execsql_test index6-7.4 { EXPLAIN QUERY PLAN SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x; } {/USING COVERING INDEX t7ax/} do_execsql_test index6-8.0 { CREATE TABLE t8a(a,b); CREATE TABLE t8b(x,y); CREATE INDEX i8c ON t8b(y) WHERE x = 'value'; INSERT INTO t8a VALUES(1, 'one'); INSERT INTO t8a VALUES(2, 'two'); INSERT INTO t8a VALUES(3, 'three'); INSERT INTO t8b VALUES('value', 1); INSERT INTO t8b VALUES('dummy', 2); INSERT INTO t8b VALUES('value', 3); INSERT INTO t8b VALUES('dummy', 4); } {} do_eqp_test index6-8.1 { SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a) } { 0 0 0 {SCAN TABLE t8a} 0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)} } do_execsql_test index6-8.2 { SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a) } { 1 one value 1 2 two {} {} 3 three value 3 } finish_test |