Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge updates from trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | mutexInitCmpSwap |
Files: | files | file ages | folders |
SHA1: |
4859778900a99e7e50ce3d56910ad4c5 |
User & Date: | mistachkin 2015-09-12 16:59:38.586 |
Context
2015-09-12
| ||
18:58 | Merge updates from trunk. (check-in: d8051f611a user: mistachkin tags: mutexInitCmpSwap) | |
16:59 | Merge updates from trunk. (check-in: 4859778900 user: mistachkin tags: mutexInitCmpSwap) | |
04:22 | Fix comments. (check-in: de3fa51e93 user: mistachkin tags: mutexInitCmpSwap) | |
2015-09-11
| ||
20:54 | Update evidence marks due to wording changes in requirements text. No changes to code. (check-in: 86781093bd user: drh tags: trunk) | |
Changes
Changes to ext/fts5/fts5Int.h.
︙ | ︙ | |||
383 384 385 386 387 388 389 | ** Discard any data stored in the in-memory hash tables. Do not write it ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ int sqlite3Fts5IndexRollback(Fts5Index *p); | < < < < < < | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | ** Discard any data stored in the in-memory hash tables. Do not write it ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ int sqlite3Fts5IndexRollback(Fts5Index *p); /* ** Get or set the "averages" values. */ int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize); int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int); /* |
︙ | ︙ | |||
672 673 674 675 676 677 678 | /************************************************************************** ** Interface to code in fts5_tokenizer.c. */ int sqlite3Fts5TokenizerInit(fts5_api*); /* ** End of interface to code in fts5_tokenizer.c. | < < < < < < < < < < < | 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | /************************************************************************** ** Interface to code in fts5_tokenizer.c. */ int sqlite3Fts5TokenizerInit(fts5_api*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ /************************************************************************** ** Interface to code in fts5_vocab.c. */ int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*); |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
943 944 945 946 947 948 949 | do { bMatch = 1; for(i=0; i<pNear->nPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; for(j=0; j<pPhrase->nTerm; j++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; if( pTerm->pSynonym ){ | < | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 | do { bMatch = 1; for(i=0; i<pNear->nPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; for(j=0; j<pPhrase->nTerm; j++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; if( pTerm->pSynonym ){ i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0); if( iRowid==iLast ) continue; bMatch = 0; if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ pNode->bEof = 1; return rc; } |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
733 734 735 736 737 738 739 | /* ** INSERT OR REPLACE a record into the %_data table. */ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){ if( p->rc!=SQLITE_OK ) return; if( p->pWriter==0 ){ | < | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | /* ** INSERT OR REPLACE a record into the %_data table. */ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){ if( p->rc!=SQLITE_OK ) return; if( p->pWriter==0 ){ Fts5Config *pConfig = p->pConfig; fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf( "REPLACE INTO '%q'.'%q_data'(id, block) VALUES(?,?)", pConfig->zDb, pConfig->zName )); if( p->rc ) return; } |
︙ | ︙ | |||
969 970 971 972 973 974 975 | ** is called, it is a no-op. */ static Fts5Structure *fts5StructureRead(Fts5Index *p){ Fts5Config *pConfig = p->pConfig; Fts5Structure *pRet = 0; /* Object to return */ int iCookie; /* Configuration cookie */ Fts5Data *pData; | < | 968 969 970 971 972 973 974 975 976 977 978 979 980 981 | ** is called, it is a no-op. */ static Fts5Structure *fts5StructureRead(Fts5Index *p){ Fts5Config *pConfig = p->pConfig; Fts5Structure *pRet = 0; /* Object to return */ int iCookie; /* Configuration cookie */ Fts5Data *pData; pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); if( p->rc ) return 0; /* TODO: Do we need this if the leaf-index is appended? Probably... */ memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ |
︙ | ︙ | |||
1413 1414 1415 1416 1417 1418 1419 | static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){ return pIter->aLvl[0].iRowid; } static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){ return pIter->aLvl[0].iLeafPgno; } | < < < < < | 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){ return pIter->aLvl[0].iRowid; } static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){ return pIter->aLvl[0].iLeafPgno; } /* ** Load the next leaf page into the segment iterator. */ static void fts5SegIterNextPage( Fts5Index *p, /* FTS5 backend object */ Fts5SegIter *pIter /* Iterator to advance to next page */ ){ |
︙ | ︙ | |||
1823 1824 1825 1826 1827 1828 1829 | /* Check if the iterator is now at EOF. If so, return early. */ if( pIter->pLeaf ){ if( bNewTerm ){ if( pIter->flags & FTS5_SEGITER_ONETERM ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ | < | 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 | /* Check if the iterator is now at EOF. If so, return early. */ if( pIter->pLeaf ){ if( bNewTerm ){ if( pIter->flags & FTS5_SEGITER_ONETERM ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ fts5SegIterLoadTerm(p, pIter, nKeep); fts5SegIterLoadNPos(p, pIter); if( pbNewTerm ) *pbNewTerm = 1; } }else{ fts5SegIterLoadNPos(p, pIter); } |
︙ | ︙ | |||
1853 1854 1855 1856 1857 1858 1859 | int pgnoLast = 0; if( pDlidx ){ int iSegid = pIter->pSeg->iSegid; pgnoLast = fts5DlidxIterPgno(pDlidx); pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); }else{ | < | | | | 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 | int pgnoLast = 0; if( pDlidx ){ int iSegid = pIter->pSeg->iSegid; pgnoLast = fts5DlidxIterPgno(pDlidx); pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); }else{ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */ /* Currently, Fts5SegIter.iLeafOffset points to the first byte of ** position-list content for the current rowid. Back it up so that it ** points to the start of the position-list size field. */ pIter->iLeafOffset -= sqlite3Fts5GetVarintLen(pIter->nPos*2+pIter->bDel); /* If this condition is true then the largest rowid for the current ** term may not be stored on the current page. So search forward to ** see where said rowid really is. */ if( pIter->iEndofDoclist>=pLeaf->szLeaf ){ int pgno; |
︙ | ︙ | |||
1984 1985 1986 1987 1988 1989 1990 | const u8 *a = pIter->pLeaf->p; int szLeaf = pIter->pLeaf->szLeaf; int n = pIter->pLeaf->nn; int nMatch = 0; int nKeep = 0; int nNew = 0; | < | 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 | const u8 *a = pIter->pLeaf->p; int szLeaf = pIter->pLeaf->szLeaf; int n = pIter->pLeaf->nn; int nMatch = 0; int nKeep = 0; int nNew = 0; int iTermOff; int iPgidx; /* Current offset in pgidx */ int bEndOfPage = 0; assert( p->rc==SQLITE_OK ); iPgidx = szLeaf; |
︙ | ︙ | |||
2044 2045 2046 2047 2048 2049 2050 | search_failed: if( bGe==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; return; }else if( bEndOfPage ){ do { | < | 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 | search_failed: if( bGe==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; return; }else if( bEndOfPage ){ do { fts5SegIterNextPage(p, pIter); if( pIter->pLeaf==0 ) return; a = pIter->pLeaf->p; if( fts5LeafIsTermless(pIter->pLeaf)==0 ){ fts5GetVarint32(&pIter->pLeaf->p[pIter->pLeaf->szLeaf], iOff); if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; |
︙ | ︙ | |||
3310 3311 3312 3313 3314 3315 3316 | fts5WriteFlushLeaf(p, pWriter); } if( n>0 ){ fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a); } } | < < < < | 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 | fts5WriteFlushLeaf(p, pWriter); } if( n>0 ){ fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a); } } /* ** Flush any data cached by the writer object to the database. Free any ** allocations associated with the writer. */ static void fts5WriteFinish( Fts5Index *p, Fts5SegWriter *pWriter, /* Writer object */ |
︙ | ︙ | |||
3476 3477 3478 3479 3480 3481 3482 | Fts5StructureLevel *pLvlOut; Fts5IndexIter *pIter = 0; /* Iterator to read input data */ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */ int nInput; /* Number of input segments */ Fts5SegWriter writer; /* Writer object */ Fts5StructureSegment *pSeg; /* Output segment */ Fts5Buffer term; | < | 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 | Fts5StructureLevel *pLvlOut; Fts5IndexIter *pIter = 0; /* Iterator to read input data */ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */ int nInput; /* Number of input segments */ Fts5SegWriter writer; /* Writer object */ Fts5StructureSegment *pSeg; /* Output segment */ Fts5Buffer term; int bOldest; /* True if the output segment is the oldest */ assert( iLvl<pStruct->nLevel ); assert( pLvl->nMerge<=pLvl->nSeg ); memset(&writer, 0, sizeof(Fts5SegWriter)); memset(&term, 0, sizeof(Fts5Buffer)); |
︙ | ︙ | |||
3541 3542 3543 3544 3545 3546 3547 | pTerm = fts5MultiIterTerm(pIter, &nTerm); if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){ if( pnRem && writer.nLeafWritten>nRem ){ break; } /* This is a new term. Append a term to the output segment. */ | < < < < < | 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 | pTerm = fts5MultiIterTerm(pIter, &nTerm); if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){ if( pnRem && writer.nLeafWritten>nRem ){ break; } /* This is a new term. Append a term to the output segment. */ fts5WriteAppendTerm(p, &writer, nTerm, pTerm); fts5BufferSet(&p->rc, &term, nTerm, pTerm); } /* Append the rowid to the output */ /* WRITEPOSLISTSIZE */ nPos = pSegIter->nPos*2 + pSegIter->bDel; fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter), nPos); |
︙ | ︙ | |||
3754 3755 3756 3757 3758 3759 3760 | if( iSegid ){ const int pgsz = p->pConfig->pgsz; Fts5StructureSegment *pSeg; /* New segment within pStruct */ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ | < | 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 | if( iSegid ){ const int pgsz = p->pConfig->pgsz; Fts5StructureSegment *pSeg; /* New segment within pStruct */ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ Fts5SegWriter writer; fts5WriteInit(p, &writer, iSegid); pBuf = &writer.writer.buf; pPgidx = &writer.writer.pgidx; |
︙ | ︙ | |||
3776 3777 3778 3779 3780 3781 3782 | if( p->rc==SQLITE_OK ){ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); } while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ | < | | 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 | if( p->rc==SQLITE_OK ){ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); } while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ /* Write the term for this entry to disk. */ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); fts5WriteAppendTerm(p, &writer, strlen(zTerm), (const u8*)zTerm); if( writer.bFirstRowidInPage==0 && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ /* The entire doclist will fit on the current leaf. */ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); }else{ |
︙ | ︙ | |||
3850 3851 3852 3853 3854 3855 3856 | iOff += nCopy; } } /* TODO2: Doclist terminator written here. */ /* pBuf->p[pBuf->n++] = '\0'; */ assert( pBuf->n<=pBuf->nSpace ); | < | 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 | iOff += nCopy; } } /* TODO2: Doclist terminator written here. */ /* pBuf->p[pBuf->n++] = '\0'; */ assert( pBuf->n<=pBuf->nSpace ); sqlite3Fts5HashScanNext(pHash); } sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); /* Update the Fts5Structure. It is written back to the database by the ** fts5StructureRelease() call below. */ |
︙ | ︙ | |||
4884 4885 4886 4887 4888 4889 4890 | } fts5DataRelease(pLeaf); if( p->rc ) break; } } static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ | < | 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 | } fts5DataRelease(pLeaf); if( p->rc ) break; } } static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ int iTermOff = 0; int ii; Fts5Buffer buf1 = {0,0,0}; Fts5Buffer buf2 = {0,0,0}; ii = pLeaf->szLeaf; |
︙ | ︙ | |||
5296 5297 5298 5299 5300 5301 5302 | ** may or may not finish within the buffer. This function appends a text ** representation of the part of the doclist that is present to buffer ** pBuf. ** ** The return value is the number of bytes read from the input buffer. */ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ | | | 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 | ** may or may not finish within the buffer. This function appends a text ** representation of the part of the doclist that is present to buffer ** pBuf. ** ** The return value is the number of bytes read from the input buffer. */ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ i64 iDocid = 0; int iOff = 0; if( n>0 ){ iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid); sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid); } while( iOff<n ){ |
︙ | ︙ | |||
5472 5473 5474 5475 5476 5477 5478 | const char *zArg; if( nArg==0 ){ sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1); }else{ zArg = (const char*)sqlite3_value_text(apVal[0]); if( 0==sqlite3_stricmp(zArg, "segment") ){ i64 iRowid; | | | 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 | const char *zArg; if( nArg==0 ){ sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1); }else{ zArg = (const char*)sqlite3_value_text(apVal[0]); if( 0==sqlite3_stricmp(zArg, "segment") ){ i64 iRowid; int segid, pgno; if( nArg!=3 ){ sqlite3_result_error(pCtx, "should be: fts5_rowid('segment', segid, pgno))", -1 ); }else{ segid = sqlite3_value_int(apVal[1]); pgno = sqlite3_value_int(apVal[2]); |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** structures should not be corrupt. Otherwise, true. If it is false, extra ** assert() conditions in the fts5 code are activated - conditions that are ** only true if it is guaranteed that the fts5 database is not corrupt. */ int sqlite3_fts5_may_be_corrupt = 1; | | > | | < | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** structures should not be corrupt. Otherwise, true. If it is false, extra ** assert() conditions in the fts5 code are activated - conditions that are ** only true if it is guaranteed that the fts5 database is not corrupt. */ int sqlite3_fts5_may_be_corrupt = 1; typedef struct Fts5Auxdata Fts5Auxdata; typedef struct Fts5Auxiliary Fts5Auxiliary; typedef struct Fts5Cursor Fts5Cursor; typedef struct Fts5Sorter Fts5Sorter; typedef struct Fts5Table Fts5Table; typedef struct Fts5TokenizerModule Fts5TokenizerModule; /* ** NOTES ON TRANSACTIONS: ** ** SQLite invokes the following virtual table methods as transactions are ** opened and closed by the user: |
︙ | ︙ |
Changes to ext/misc/json1.c.
︙ | ︙ | |||
491 492 493 494 495 496 497 | if( c>='0' && c<='9' ) v = v*16 + c - '0'; else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10; else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10; else break; } if( v==0 ) break; if( v<=0x7f ){ | | | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | if( c>='0' && c<='9' ) v = v*16 + c - '0'; else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10; else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10; else break; } if( v==0 ) break; if( v<=0x7f ){ zOut[j++] = (char)v; }else if( v<=0x7ff ){ zOut[j++] = (char)(0xc0 | (v>>6)); zOut[j++] = 0x80 | (v&0x3f); }else{ zOut[j++] = (char)(0xe0 | (v>>12)); zOut[j++] = 0x80 | ((v>>6)&0x3f); zOut[j++] = 0x80 | (v&0x3f); } }else{ if( c=='b' ){ c = '\b'; }else if( c=='f' ){ |
︙ | ︙ | |||
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | ** is not known to be JSON. */ static void jsonTest1Func( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); } #endif /* SQLITE_DEBUG */ /**************************************************************************** ** SQL function implementations ****************************************************************************/ | > | 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | ** is not known to be JSON. */ static void jsonTest1Func( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ UNUSED_PARAM(argc); sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); } #endif /* SQLITE_DEBUG */ /**************************************************************************** ** SQL function implementations ****************************************************************************/ |
︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( x.nNode ){ for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pNode = jsonLookup(&x, zPath, 0, ctx); if( x.nErr ) goto replace_err; if( pNode ){ | | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( x.nNode ){ for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pNode = jsonLookup(&x, zPath, 0, ctx); if( x.nErr ) goto replace_err; if( pNode ){ pNode->jnFlags |= (u8)JNODE_REPLACE; pNode->iVal = (u8)(i+1); } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]); }else{ jsonReturnJson(x.aNode, ctx, argv); } |
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | pNode = jsonLookup(&x, zPath, &bApnd, ctx); if( x.oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; }else if( x.nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ | | | | 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 | pNode = jsonLookup(&x, zPath, &bApnd, ctx); if( x.oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; }else if( x.nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ pNode->jnFlags |= (u8)JNODE_REPLACE; pNode->iVal = (u8)(i+1); } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]); }else{ jsonReturnJson(x.aNode, ctx, argv); } |
︙ | ︙ | |||
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 | sqlite3_context *ctx, int argc, sqlite3_value **argv ){ JsonParse x; /* The parse */ int rc = 0; if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 && x.nNode>0 ){ rc = 1; } jsonParseReset(&x); sqlite3_result_int(ctx, rc); | > | 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 | sqlite3_context *ctx, int argc, sqlite3_value **argv ){ JsonParse x; /* The parse */ int rc = 0; UNUSED_PARAM(argc); if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 && x.nNode>0 ){ rc = 1; } jsonParseReset(&x); sqlite3_result_int(ctx, rc); |
︙ | ︙ | |||
1730 1731 1732 1733 1734 1735 1736 | static int jsonEachFilter( sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; const char *z; | | | 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 | static int jsonEachFilter( sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; const char *z; const char *zRoot = 0; sqlite3_int64 n; UNUSED_PARAM(idxStr); UNUSED_PARAM(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; z = (const char*)sqlite3_value_text(argv[0]); |
︙ | ︙ |
Changes to test/e_createtable.test.
︙ | ︙ | |||
369 370 371 372 373 374 375 | 2 "CREATE TABLE temp.sqlitehelloworld(x)" {} 3 {CREATE TABLE auxa."sqlite"(x, y)} {} 4 {CREATE TABLE auxb."sqlite-"(z)} {} 5 {CREATE TABLE "SQLITE-TBL"(z)} {} } | | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | 2 "CREATE TABLE temp.sqlitehelloworld(x)" {} 3 {CREATE TABLE auxa."sqlite"(x, y)} {} 4 {CREATE TABLE auxb."sqlite-"(z)} {} 5 {CREATE TABLE "SQLITE-TBL"(z)} {} } # EVIDENCE-OF: R-18448-33677 If a schema-name is specified, it must be # either "main", "temp", or the name of an attached database. # # EVIDENCE-OF: R-39822-07822 In this case the new table is created in # the named database. # # Test cases 1.2.* test the first of the two requirements above. The # second is verified by cases 1.3.*. # |
︙ | ︙ | |||
418 419 420 421 422 423 424 | array set X [table_list] list $X(main) $X(temp) $X(auxa) $X(auxb) } { 1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}} 2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}} } | | | | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | array set X [table_list] list $X(main) $X(temp) $X(auxa) $X(auxb) } { 1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}} 2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}} } # EVIDENCE-OF: R-23976-43329 It is an error to specify both a # schema-name and the TEMP or TEMPORARY keyword, unless the schema-name # is "temp". # drop_all_tables do_createtable_tests 1.5.1 -error { temporary table name must be unqualified } { 1 "CREATE TEMP TABLE main.t1(a, b)" {} 2 "CREATE TEMPORARY TABLE auxa.t2(a, b)" {} |
︙ | ︙ | |||
443 444 445 446 447 448 449 | } { 1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}} 2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}} 3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}} 4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}} } | | | < | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 | } { 1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}} 2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}} 3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}} 4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}} } # EVIDENCE-OF: R-31997-24564 If no schema name is specified and the TEMP # keyword is not present then the table is created in the main database. # drop_all_tables do_createtable_tests 1.6 -tclquery { unset -nocomplain X array set X [table_list] list $X(main) $X(temp) $X(auxa) $X(auxb) } { |
︙ | ︙ |
Changes to test/e_delete.test.
︙ | ︙ | |||
66 67 68 69 70 71 72 | } } {} do_delete_tests e_delete-1.1 { 1 "DELETE FROM t1 ; SELECT * FROM t1" {} 2 "DELETE FROM main.t2 ; SELECT * FROM t2" {} } | | | | > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | } } {} do_delete_tests e_delete-1.1 { 1 "DELETE FROM t1 ; SELECT * FROM t1" {} 2 "DELETE FROM main.t2 ; SELECT * FROM t2" {} } # EVIDENCE-OF: R-26300-50198 If a WHERE clause is supplied, then only # those rows for which the WHERE clause boolean expression is true are # deleted. # # EVIDENCE-OF: R-23360-48280 Rows for which the expression is false or # NULL are retained. # do_delete_tests e_delete-1.2 { 1 "DELETE FROM t3 WHERE 1 ; SELECT x FROM t3" {} 2 "DELETE FROM main.t4 WHERE 0 ; SELECT x FROM t4" {1 2 3 4 5} 3 "DELETE FROM t4 WHERE 0.0 ; SELECT x FROM t4" {1 2 3 4 5} 4 "DELETE FROM t4 WHERE NULL ; SELECT x FROM t4" {1 2 3 4 5} 5 "DELETE FROM t4 WHERE y!='two'; SELECT x FROM t4" {2} |
︙ | ︙ | |||
113 114 115 116 117 118 119 | CREATE TABLE aux2.t10(a, b); INSERT INTO aux2.t10 VALUES(1, 2); } {} # EVIDENCE-OF: R-09681-58560 The table-name specified as part of a # DELETE statement within a trigger body must be unqualified. # | | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | CREATE TABLE aux2.t10(a, b); INSERT INTO aux2.t10 VALUES(1, 2); } {} # EVIDENCE-OF: R-09681-58560 The table-name specified as part of a # DELETE statement within a trigger body must be unqualified. # # EVIDENCE-OF: R-12275-20298 In other words, the schema-name. prefix on # the table name is not allowed within triggers. # do_delete_tests e_delete-2.1 -error { qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers } { 1 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN DELETE FROM main.t2; |
︙ | ︙ |
Changes to test/e_expr.test.
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | do_execsql_test e_expr-27.1.2 { SELECT typeof(CAST(X'555655' as TEXT)), CAST(X'555655' as TEXT), typeof(CAST('1.23abc' as REAL)), CAST('1.23abc' as REAL), typeof(CAST(4.5 as INTEGER)), CAST(4.5 as INTEGER) } {text UVU real 1.23 integer 4} | | | | | | 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | do_execsql_test e_expr-27.1.2 { SELECT typeof(CAST(X'555655' as TEXT)), CAST(X'555655' as TEXT), typeof(CAST('1.23abc' as REAL)), CAST('1.23abc' as REAL), typeof(CAST(4.5 as INTEGER)), CAST(4.5 as INTEGER) } {text UVU real 1.23 integer 4} # EVIDENCE-OF: R-32434-09092 If the value of expr is NULL, then the # result of the CAST expression is also NULL. # do_expr_test e_expr-27.2.1 { CAST(NULL AS integer) } null {} do_expr_test e_expr-27.2.2 { CAST(NULL AS text) } null {} do_expr_test e_expr-27.2.3 { CAST(NULL AS blob) } null {} do_expr_test e_expr-27.2.4 { CAST(NULL AS number) } null {} # EVIDENCE-OF: R-43522-35548 Casting a value to a type-name with no # affinity causes the value to be converted into a BLOB. # do_expr_test e_expr-27.3.1 { CAST('abc' AS blob) } blob abc do_expr_test e_expr-27.3.2 { CAST('def' AS shobblob_x) } blob def do_expr_test e_expr-27.3.3 { CAST('ghi' AS abbLOb10) } blob ghi # EVIDENCE-OF: R-22956-37754 Casting to a BLOB consists of first casting # the value to TEXT in the encoding of the database connection, then |
︙ | ︙ |
Changes to test/e_insert.test.
︙ | ︙ | |||
153 154 155 156 157 158 159 | 2a "INSERT INTO a2(a, b) VALUES(1, 2)" {} 2b "SELECT count(*) FROM a2" {2} 3a "INSERT INTO a2(a) VALUES(3),(4)" {} 3b "SELECT count(*) FROM a2" {4} } | | | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 2a "INSERT INTO a2(a, b) VALUES(1, 2)" {} 2b "SELECT count(*) FROM a2" {2} 3a "INSERT INTO a2(a) VALUES(3),(4)" {} 3b "SELECT count(*) FROM a2" {4} } # EVIDENCE-OF: R-19218-01018 If the column-name list after table-name is # omitted then the number of values inserted into each row must be the # same as the number of columns in the table. # # A test in the block above verifies that if the VALUES list has the # correct number of columns (for table a2, 3 columns) works. So these # tests just show that other values cause an error. # do_insert_tests e_insert-1.2 -error { table %s has %d columns but %d values were supplied |
︙ | ︙ | |||
187 188 189 190 191 192 193 | 2a "INSERT INTO a2 VALUES('abc', NULL, 3*3+1)" {} 2b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {abc {} 10} 3a "INSERT INTO a2 VALUES((SELECT count(*) FROM a2), 'x', 'y')" {} 3b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y} } | | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | 2a "INSERT INTO a2 VALUES('abc', NULL, 3*3+1)" {} 2b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {abc {} 10} 3a "INSERT INTO a2 VALUES((SELECT count(*) FROM a2), 'x', 'y')" {} 3b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y} } # EVIDENCE-OF: R-21115-58321 If a column-name list is specified, then # the number of values in each term of the VALUE list must match the # number of specified columns. # do_insert_tests e_insert-1.4 -error { %d values for %d columns } { 1 "INSERT INTO a2(a, b, c) VALUES(1)" {1 3} 2 "INSERT INTO a2(a, b, c) VALUES(1,2)" {2 3} 3 "INSERT INTO a2(a, b, c) VALUES(1,2,3,4)" {4 3} |
︙ | ︙ | |||
390 391 392 393 394 395 396 | 2.2 "REPLACE INTO a4 VALUES(2, 'f')" {} 1 {1 a 3 a 4 e 2 f} } { do_catchsql_test e_insert-4.1.$tn.1 $sql [list [expr {$error!=""}] $error] do_execsql_test e_insert-4.1.$tn.2 {SELECT * FROM a4} [list {*}$data] do_test e_insert-4.1.$tn.3 {sqlite3_get_autocommit db} $ac } | | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | 2.2 "REPLACE INTO a4 VALUES(2, 'f')" {} 1 {1 a 3 a 4 e 2 f} } { do_catchsql_test e_insert-4.1.$tn.1 $sql [list [expr {$error!=""}] $error] do_execsql_test e_insert-4.1.$tn.2 {SELECT * FROM a4} [list {*}$data] do_test e_insert-4.1.$tn.3 {sqlite3_get_autocommit db} $ac } # EVIDENCE-OF: R-59829-49719 The optional "schema-name." prefix on the # table-name is supported for top-level INSERT statements only. # # EVIDENCE-OF: R-05731-00924 The table name must be unqualified for # INSERT statements that occur within CREATE TRIGGER statements. # set err {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}} do_catchsql_test e_insert-5.1.1 { |
︙ | ︙ |
Changes to test/e_reindex.test.
︙ | ︙ | |||
261 262 263 264 265 266 267 | test_index 5.37 t1 collA length test_index 5.38 t1 collB value test_index 5.39 t2 collA length test_index 5.40 t2 collB value test_index 5.41 aux.t1 collA length test_index 5.42 aux.t1 collB value | | | < | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | test_index 5.37 t1 collA length test_index 5.38 t1 collB value test_index 5.39 t2 collA length test_index 5.40 t2 collB value test_index 5.41 aux.t1 collA length test_index 5.42 aux.t1 collB value # EVIDENCE-OF: R-35892-30289 For a command of the form "REINDEX name", a # match against collation-name takes precedence over a match against # index-name or table-name. # set_collations value length do_execsql_test e_reindex-2.6.0 { CREATE TABLE collA(x); CREATE INDEX icolla_a ON collA(x COLLATE collA); CREATE INDEX icolla_b ON collA(x COLLATE collB); |
︙ | ︙ |
Changes to test/e_resolve.test.
︙ | ︙ | |||
61 62 63 64 65 66 67 | # resolve_reopen_db do_execsql_test 1.1 { SELECT * FROM n1 } {temp n1} do_execsql_test 1.2 { SELECT * FROM n2 } {main n2} do_execsql_test 1.3 { SELECT * FROM n3 } {at1 n3} do_execsql_test 1.4 { SELECT * FROM n4 } {at2 n4} | | | | | | | | 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 | # resolve_reopen_db do_execsql_test 1.1 { SELECT * FROM n1 } {temp n1} do_execsql_test 1.2 { SELECT * FROM n2 } {main n2} do_execsql_test 1.3 { SELECT * FROM n3 } {at1 n3} do_execsql_test 1.4 { SELECT * FROM n4 } {at2 n4} # EVIDENCE-OF: R-00634-08585 If a schema name is specified as part of an # object reference, it must be either "main", or "temp" or the # schema-name of an attached database. # # Or else it is a "no such table: xxx" error. # resolve_reopen_db do_execsql_test 2.1.1 { SELECT * FROM main.n1 } {main n1} do_execsql_test 2.1.2 { SELECT * FROM temp.n1 } {temp n1} do_execsql_test 2.1.3 { SELECT * FROM at1.n1 } {at1 n1} do_execsql_test 2.1.4 { SELECT * FROM at2.n1 } {at2 n1} do_catchsql_test 2.2 { SELECT * FROM xxx.n1 } {1 {no such table: xxx.n1}} # EVIDENCE-OF: R-17446-42210 Like other SQL identifiers, schema names # are case-insensitive. # resolve_reopen_db do_execsql_test 3.1 { SELECT * FROM MAIN.n1 } {main n1} do_execsql_test 3.2 { SELECT * FROM tEmP.n1 } {temp n1} do_execsql_test 3.3 { SELECT * FROM aT1.n1 } {at1 n1} do_execsql_test 3.4 { SELECT * FROM At2.n1 } {at2 n1} # EVIDENCE-OF: R-14755-58619 If a schema name is specified, then only # that one schema is searched for the named object. # do_catchsql_test 4.1 { SELECT * FROM temp.n2 } {1 {no such table: temp.n2}} do_catchsql_test 4.2 { SELECT * FROM main.n2 } {0 {main n2}} do_catchsql_test 4.3 { SELECT * FROM at1.n2 } {0 {at1 n2}} do_catchsql_test 4.4 { SELECT * FROM at2.n2 } {0 {at2 n2}} # EVIDENCE-OF: R-08951-19801 When searching database schemas for a named |
︙ | ︙ |
Changes to test/e_update.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 | 1 "UPDATE t1 SET b = 'roman' ; SELECT * FROM t1" {1 roman 2 roman 3 roman} 2 "UPDATE t1 SET a = 'greek' ; SELECT * FROM t1" {greek roman greek roman greek roman} } | | < | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 1 "UPDATE t1 SET b = 'roman' ; SELECT * FROM t1" {1 roman 2 roman 3 roman} 2 "UPDATE t1 SET a = 'greek' ; SELECT * FROM t1" {greek roman greek roman greek roman} } # EVIDENCE-OF: R-58095-46013 Otherwise, the UPDATE affects only those # rows for which the WHERE clause boolean expression is true. # do_execsql_test e_update-1.3.0 { DELETE FROM main.t1; INSERT INTO main.t1 VALUES(NULL, ''); INSERT INTO main.t1 VALUES(1, 'i'); INSERT INTO main.t1 VALUES(2, 'ii'); INSERT INTO main.t1 VALUES(3, 'iii'); |
︙ | ︙ | |||
261 262 263 264 265 266 267 | SELECT * FROM t2 } { 1 "UPDATE t2 SET a=b+c" {5 1 4 14 5 9 11 6 5} 2 "UPDATE t2 SET a=b, b=a" {1 5 4 5 14 9 6 11 5} 3 "UPDATE t2 SET a=c||c, c=NULL" {44 5 {} 99 14 {} 55 11 {}} } | | > | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | SELECT * FROM t2 } { 1 "UPDATE t2 SET a=b+c" {5 1 4 14 5 9 11 6 5} 2 "UPDATE t2 SET a=b, b=a" {1 5 4 5 14 9 6 11 5} 3 "UPDATE t2 SET a=c||c, c=NULL" {44 5 {} 99 14 {} 55 11 {}} } # EVIDENCE-OF: R-28518-13457 The optional "OR action" conflict clause # that follows the UPDATE keyword allows the user to nominate a specific # constraint conflict resolution algorithm to use during this one UPDATE # command. # do_execsql_test e_update-1.8.0 { DELETE FROM t3; INSERT INTO t3 VALUES(1, 'one'); INSERT INTO t3 VALUES(2, 'two'); INSERT INTO t3 VALUES(3, 'three'); INSERT INTO t3 VALUES(4, 'four'); |
︙ | ︙ | |||
318 319 320 321 322 323 324 | } # EVIDENCE-OF: R-12123-54095 The table-name specified as part of an # UPDATE statement within a trigger body must be unqualified. # | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | } # EVIDENCE-OF: R-12123-54095 The table-name specified as part of an # UPDATE statement within a trigger body must be unqualified. # # EVIDENCE-OF: R-43190-62442 In other words, the schema-name. prefix on # the table name of the UPDATE is not allowed within triggers. # do_update_tests e_update-2.1 -error { qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers } { 1 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN UPDATE main.t2 SET a=1, b=2, c=3; |
︙ | ︙ |
Changes to test/fkey5.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file tests the PRAGMA foreign_key_check command. # | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file tests the PRAGMA foreign_key_check command. # # EVIDENCE-OF: R-15402-03103 PRAGMA schema.foreign_key_check; PRAGMA # schema.foreign_key_check(table-name); # # EVIDENCE-OF: R-23918-17301 The foreign_key_check pragma checks the # database, or the table called "table-name", for foreign key # constraints that are violated and returns one row of output for each # violation. set testdir [file dirname $argv0] |
︙ | ︙ |
Changes to test/indexedby.test.
︙ | ︙ | |||
54 55 56 57 58 59 60 | } # Parser tests. Test that an INDEXED BY or NOT INDEX clause can be # attached to a table in the FROM clause, but not to a sub-select or # SQL view. Also test that specifying an index that does not exist or # is attached to a different table is detected as an error. # | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | } # Parser tests. Test that an INDEXED BY or NOT INDEX clause can be # attached to a table in the FROM clause, but not to a sub-select or # SQL view. Also test that specifying an index that does not exist or # is attached to a different table is detected as an error. # # EVIDENCE-OF: R-07004-11522 -- syntax diagram qualified-table-name # # EVIDENCE-OF: R-58230-57098 The "INDEXED BY index-name" phrase # specifies that the named index must be used in order to look up values # on the preceding table. # do_test indexedby-2.1 { execsql { SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'} |
︙ | ︙ |
Changes to test/json102.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 | # set testdir [file dirname $argv0] source $testdir/tester.tcl load_static_extension db json do_execsql_test json102-100 { SELECT json(' { "this" : "is", "a": [ "test" ] } '); } {{{"this":"is","a":["test"]}}} | > > > > > > > > > | | | | | | | > > > > > > | | > > > | | | | | | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | # set testdir [file dirname $argv0] source $testdir/tester.tcl load_static_extension db json do_execsql_test json102-100 { SELECT json_object('ex','[52,3.14159]'); } {{{"ex":"[52,3.14159]"}}} do_execsql_test json102-110 { SELECT json_object('ex',json('[52,3.14159]')); } {{{"ex":[52,3.14159]}}} do_execsql_test json102-120 { SELECT json_object('ex',json_array(52,3.14159)); } {{{"ex":[52,3.14159]}}} do_execsql_test json102-130 { SELECT json(' { "this" : "is", "a": [ "test" ] } '); } {{{"this":"is","a":["test"]}}} do_execsql_test json102-140 { SELECT json_array(1,2,'3',4); } {{[1,2,"3",4]}} do_execsql_test json102-150 { SELECT json_array('[1,2]'); } {{["[1,2]"]}} do_execsql_test json102-160 { SELECT json_array(json_array(1,2)); } {{[[1,2]]}} do_execsql_test json102-170 { SELECT json_array(1,null,'3','[4,5]','{"six":7.7}'); } {{[1,null,"3","[4,5]","{\"six\":7.7}"]}} do_execsql_test json102-180 { SELECT json_array(1,null,'3',json('[4,5]'),json('{"six":7.7}')); } {{[1,null,"3",[4,5],{"six":7.7}]}} do_execsql_test json102-190 { SELECT json_array_length('[1,2,3,4]'); } {{4}} do_execsql_test json102-200 { SELECT json_array_length('[1,2,3,4]', '$'); } {{4}} do_execsql_test json102-210 { SELECT json_array_length('[1,2,3,4]', '$[2]'); } {{0}} do_execsql_test json102-220 { SELECT json_array_length('{"one":[1,2,3]}'); } {{0}} do_execsql_test json102-230 { SELECT json_array_length('{"one":[1,2,3]}', '$.one'); } {{3}} do_execsql_test json102-240 { SELECT json_array_length('{"one":[1,2,3]}', '$.two'); } {{}} do_execsql_test json102-250 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$'); } {{{"a":2,"c":[4,5,{"f":7}]}}} do_execsql_test json102-260 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c'); } {{[4,5,{"f":7}]}} do_execsql_test json102-270 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]'); } {{{"f":7}}} do_execsql_test json102-280 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f'); } {{7}} do_execsql_test json102-290 { SELECT json_extract('{"a":2,"c":[4,5],"f":7}','$.c','$.a'); } {{[[4,5],2]}} do_execsql_test json102-300 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x'); } {{}} do_execsql_test json102-310 { SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x', '$.a'); } {{[null,2]}} do_execsql_test json102-320 { SELECT json_insert('{"a":2,"c":4}', '$.a', 99); } {{{"a":2,"c":4}}} do_execsql_test json102-330 { SELECT json_insert('{"a":2,"c":4}', '$.e', 99); } {{{"a":2,"c":4,"e":99}}} do_execsql_test json102-340 { SELECT json_replace('{"a":2,"c":4}', '$.a', 99); } {{{"a":99,"c":4}}} do_execsql_test json102-350 { SELECT json_replace('{"a":2,"c":4}', '$.e', 99); } {{{"a":2,"c":4}}} do_execsql_test json102-360 { SELECT json_set('{"a":2,"c":4}', '$.a', 99); } {{{"a":99,"c":4}}} do_execsql_test json102-370 { SELECT json_set('{"a":2,"c":4}', '$.e', 99); } {{{"a":2,"c":4,"e":99}}} do_execsql_test json102-380 { SELECT json_set('{"a":2,"c":4}', '$.c', '[97,96]'); } {{{"a":2,"c":"[97,96]"}}} do_execsql_test json102-390 { SELECT json_set('{"a":2,"c":4}', '$.c', json('[97,96]')); } {{{"a":2,"c":[97,96]}}} do_execsql_test json102-400 { SELECT json_set('{"a":2,"c":4}', '$.c', json_array(97,96)); } {{{"a":2,"c":[97,96]}}} do_execsql_test json102-410 { SELECT json_object('a',2,'c',4); } {{{"a":2,"c":4}}} do_execsql_test json102-420 { SELECT json_object('a',2,'c','{e:5}'); } {{{"a":2,"c":"{e:5}"}}} do_execsql_test json102-430 { SELECT json_object('a',2,'c',json_object('e',5)); } {{{"a":2,"c":{"e":5}}}} do_execsql_test json102-440 { SELECT json_remove('[0,1,2,3,4]','$[2]'); } {{[0,1,3,4]}} do_execsql_test json102-450 { SELECT json_remove('[0,1,2,3,4]','$[2]','$[0]'); } {{[1,3,4]}} do_execsql_test json102-460 { SELECT json_remove('[0,1,2,3,4]','$[0]','$[2]'); } {{[1,2,4]}} do_execsql_test json102-470 { SELECT json_remove('{"x":25,"y":42}'); } {{{"x":25,"y":42}}} do_execsql_test json102-480 { SELECT json_remove('{"x":25,"y":42}','$.z'); } {{{"x":25,"y":42}}} do_execsql_test json102-490 { SELECT json_remove('{"x":25,"y":42}','$.y'); } {{{"x":25}}} do_execsql_test json102-500 { SELECT json_remove('{"x":25,"y":42}','$'); } {{}} do_execsql_test json102-510 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}'); } {{object}} do_execsql_test json102-520 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$'); } {{object}} do_execsql_test json102-530 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a'); } {{array}} do_execsql_test json102-540 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]'); } {{integer}} do_execsql_test json102-550 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]'); } {{real}} do_execsql_test json102-560 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]'); } {{true}} do_execsql_test json102-570 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]'); } {{false}} do_execsql_test json102-580 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]'); } {{null}} do_execsql_test json102-590 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]'); } {{text}} do_execsql_test json102-600 { SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]'); } {{}} do_execsql_test json102-610 { SELECT json_valid(char(123)||'"x":35'||char(125)); } {{1}} do_execsql_test json102-620 { SELECT json_valid(char(123)||'"x":35'); } {{0}} ifcapable vtab { do_execsql_test json102-1000 { CREATE TABLE user(name,phone); INSERT INTO user(name,phone) VALUES ('Alice','["919-555-2345","804-555-3621"]'), ('Bob','["201-555-8872"]'), |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
79 80 81 82 83 84 85 | # that the "all.test" script does. # db close delete_file test.db test.db-journal delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] | | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | # that the "all.test" script does. # db close delete_file test.db test.db-journal delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] # EVIDENCE-OF: R-13861-56665 PRAGMA schema.cache_size; PRAGMA # schema.cache_size = pages; PRAGMA schema.cache_size = -kibibytes; # Query or change the suggested maximum number of database disk pages # that SQLite will hold in memory at once per open database file. # ifcapable pager_pragmas { set DFLT_CACHE_SZ [db one {PRAGMA default_cache_size}] set TEMP_CACHE_SZ [db one {PRAGMA temp.default_cache_size}] do_test pragma-1.1 { |
︙ | ︙ | |||
693 694 695 696 697 698 699 | # do_test pragma-6.5.1b { capture_pragma db out {PRAGMA index_xinfo(t3i1)} db eval {SELECT seqno, cid, name FROM out ORDER BY seqno} } {0 0 a 1 1 b 2 -1 {}} | | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 | # do_test pragma-6.5.1b { capture_pragma db out {PRAGMA index_xinfo(t3i1)} db eval {SELECT seqno, cid, name FROM out ORDER BY seqno} } {0 0 a 1 1 b 2 -1 {}} # EVIDENCE-OF: R-29448-60346 PRAGMA schema.index_info(index-name); This # pragma returns one row for each key column in the named index. # # (The first column of output from PRAGMA index_info is...) # EVIDENCE-OF: R-34186-52914 The rank of the column within the index. (0 # means left-most.) # # (The second column of output from PRAGMA index_info is...) # EVIDENCE-OF: R-65019-08383 The rank of the column within the table |
︙ | ︙ | |||
780 781 782 783 784 785 786 | {1 b {} 0 {} 2} \ {2 c {} 0 {} 4} \ ] } ;# ifcapable schema_pragmas # Miscellaneous tests # ifcapable schema_pragmas { | | | < > | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | {1 b {} 0 {} 2} \ {2 c {} 0 {} 4} \ ] } ;# ifcapable schema_pragmas # Miscellaneous tests # ifcapable schema_pragmas { # EVIDENCE-OF: R-64103-17776 PRAGMA schema.index_list(table-name); This # pragma returns one row for each index associated with the given table. # do_test pragma-7.1.1 { # Make sure a pragma knows to read the schema if it needs to db close sqlite3 db test.db capture_pragma db out "PRAGMA index_list(t3)" db eval {SELECT name, "origin" FROM out ORDER BY name DESC} } {t3i1 c sqlite_autoindex_t3_1 u} |
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 | } ;# ifcapable bloblit ifcapable pager_pragmas { db close forcedelete test.db sqlite3 db test.db | | | | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 | } ;# ifcapable bloblit ifcapable pager_pragmas { db close forcedelete test.db sqlite3 db test.db # EVIDENCE-OF: R-15672-33611 PRAGMA schema.page_count; Return the total # number of pages in the database file. # do_test pragma-14.1 { execsql { pragma auto_vacuum = 0 } execsql { pragma page_count; pragma main.page_count } } {0 0} do_test pragma-14.2 { |
︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 | DROP INDEX i2; CREATE INDEX i2 ON t1(c,d,b); } capture_pragma db2 out {PRAGMA index_info(i2)} db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno} } {2 c | 3 d | 1 b |} | | | | 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 | DROP INDEX i2; CREATE INDEX i2 ON t1(c,d,b); } capture_pragma db2 out {PRAGMA index_info(i2)} db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno} } {2 c | 3 d | 1 b |} # EVIDENCE-OF: R-56143-29319 PRAGMA schema.index_xinfo(index-name); This # pragma returns information about every column in an index. # # EVIDENCE-OF: R-45970-35618 Unlike this index_info pragma, this pragma # returns information about every column in the index, not just the key # columns. # do_test 23.2b { capture_pragma db2 out {PRAGMA index_xinfo(i2)} |
︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 | do_test 23.2c { db2 eval {PRAGMA index_xinfo(i2)} } {0 2 c 0 BINARY 1 1 3 d 0 BINARY 1 2 1 b 0 BINARY 1 3 -1 {} 0 BINARY 0} do_test 23.2d { db2 eval {PRAGMA index_xinfo(i2x)} } {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0} | | | < | 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 | do_test 23.2c { db2 eval {PRAGMA index_xinfo(i2)} } {0 2 c 0 BINARY 1 1 3 d 0 BINARY 1 2 1 b 0 BINARY 1 3 -1 {} 0 BINARY 0} do_test 23.2d { db2 eval {PRAGMA index_xinfo(i2x)} } {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0} # EVIDENCE-OF: R-64103-17776 PRAGMA schema.index_list(table-name); This # pragma returns one row for each index associated with the given table. # # (The first column of output from PRAGMA index_list is...) # EVIDENCE-OF: R-02753-24748 A sequence number assigned to each index # for internal tracking purposes. # # (The second column of output from PRAGMA index_list is...) # EVIDENCE-OF: R-35496-03635 The name of the index. |
︙ | ︙ |
Changes to test/pragma2.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | db close delete_file test.db test.db-journal delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] db eval {PRAGMA auto_vacuum=0} | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | db close delete_file test.db test.db-journal delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] db eval {PRAGMA auto_vacuum=0} # EVIDENCE-OF: R-11211-21323 PRAGMA schema.freelist_count; Return the # number of unused pages in the database file. # do_test pragma2-1.1 { execsql { PRAGMA freelist_count; } } {0} |
︙ | ︙ |