Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch expert-enhancement Excluding Merge-Ins
This is equivalent to a diff from 678a9728dc to ee58425904
2023-10-23
| ||
02:08 | Merge fixes for expert handling of UDFs and other UD-whatevers. (check-in: b5d7d07df5 user: larrybr tags: trunk) | |
02:01 | Fix the shell1.test test so to align with the new behavior imposed by [bce807cd48763273] - that backslash escapes only work without quoted arguments in dot-commands of the CLI. (check-in: 0db82b4281 user: drh tags: trunk) | |
01:55 | Clear some picky warnings, sync w/trunk. (Closed-Leaf check-in: ee58425904 user: larrybr tags: expert-enhancement) | |
2023-10-22
| ||
23:44 | Fix [f5c01676fd281e93] so that it always preserves 8-byte alignment for Expr objects. Add new assert() statement to verify this. (check-in: 678a9728dc user: drh tags: trunk) | |
17:27 | Do not do backslash escape processing on any unquoted strings in dot-commands in the CLI - on Windows or on posix-like systems either one. This brings the processing into alignment with the documentation, allows backslash-delimited filenames on Windows (as long as they are unquoted), and causes the CLI to work the same with regard to backslash escapes on both Windows and posix. (check-in: bce807cd48 user: drh tags: trunk) | |
2023-09-25
| ||
00:39 | Cause sqlite3_exper_new() to replicate UDFs and custom collations early enough to appear in virtual column expressions during schema copy. forum post e030aa4b3a (check-in: 8fc2c45558 user: larrybr tags: expert-enhancement) | |
Changes to ext/expert/expert1.test.
︙ | ︙ | |||
459 460 461 462 463 464 465 466 467 | t1 t1_idx_00000061 {100 50} t1 t1_idx_00000062 {100 20} t1 t1_idx_000123a7 {100 50 17} t2 t2_idx_00000063 {100 20} t2 t2_idx_00000064 {100 5} t2 t2_idx_0001295b {100 20 5} } finish_test | > > > > > > > > > > > > > > > > > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | t1 t1_idx_00000061 {100 50} t1 t1_idx_00000062 {100 20} t1 t1_idx_000123a7 {100 50 17} t2 t2_idx_00000063 {100 20} t2 t2_idx_00000064 {100 5} t2 t2_idx_0001295b {100 20 5} } do_test expert1-6.0 { catchcmd :memory: { .expert select base64(''); .expert select name from pragma_collation_list order by name collate uint; } } {0 {(no new indexes) SCAN CONSTANT ROW (no new indexes) SCAN pragma_collation_list VIRTUAL TABLE INDEX 0: USE TEMP B-TREE FOR ORDER BY }} finish_test |
Changes to ext/expert/sqlite3expert.c.
︙ | ︙ | |||
28 29 30 31 32 33 34 | #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #endif /* !defined(SQLITE_AMALGAMATION) */ | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #endif /* !defined(SQLITE_AMALGAMATION) */ #ifndef SQLITE_OMIT_VIRTUALTABLE typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; typedef struct IdxColumn IdxColumn; typedef struct IdxConstraint IdxConstraint; typedef struct IdxScan IdxScan; |
︙ | ︙ | |||
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 | rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); } sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); return rc; } /* ** Allocate a new sqlite3expert object. */ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ int rc = SQLITE_OK; sqlite3expert *pNew; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 | rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); } sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); return rc; } /* ** Define and possibly pretend to use a useless collation sequence. ** This pretense allows expert to accept SQL using custom collations. */ int dummyCompare(void *up1, int up2, const void *up3, int up4, const void *up5){ (void)up1; (void)up2; (void)up3; (void)up4; (void)up5; assert(0); /* VDBE should never be run. */ return 0; } /* And a callback to register above upon actual need */ void useDummyCS(void *up1, sqlite3 *db, int etr, const char *zName){ (void)up1; sqlite3_create_collation_v2(db, zName, etr, 0, dummyCompare, 0); } #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) /* ** dummy functions for no-op implementation of UDFs during expert's work */ void dummyUDF(sqlite3_context *up1, int up2, sqlite3_value **up3){ (void)up1; (void)up2; (void)up3; assert(0); /* VDBE should never be run. */ } void dummyUDFvalue(sqlite3_context *up1){ (void)up1; assert(0); /* VDBE should never be run. */ } /* ** Register UDFs from user database with another. */ int registerUDFs(sqlite3 *dbSrc, sqlite3 *dbDst){ sqlite3_stmt *pStmt; int rc = sqlite3_prepare_v2(dbSrc, "SELECT name,type,enc,narg,flags " "FROM pragma_function_list() " "WHERE builtin==0", -1, &pStmt, 0); if( rc==SQLITE_OK ){ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ int nargs = sqlite3_column_int(pStmt,3); int flags = sqlite3_column_int(pStmt,4); const char *name = (char*)sqlite3_column_text(pStmt,0); const char *type = (char*)sqlite3_column_text(pStmt,1); const char *enc = (char*)sqlite3_column_text(pStmt,2); if( name==0 || type==0 || enc==0 ) rc = SQLITE_NOMEM; else{ int ienc = SQLITE_UTF8; if( strcmp(enc,"utf16le")==0 ) ienc = SQLITE_UTF16LE; else if( strcmp(enc,"utf16be")==0 ) ienc = SQLITE_UTF16BE; int rcf = SQLITE_ERROR; ienc |= (flags & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY)); if( strcmp(type,"w")==0 ){ rcf = sqlite3_create_window_function(dbDst,name,nargs,ienc,0, dummyUDF,dummyUDFvalue,0,0,0); }else if( strcmp(type,"a")==0 ){ rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, 0,dummyUDF,dummyUDFvalue); }else if( strcmp(type,"s")==0 ){ rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, dummyUDF,0,0); } if( rcf!=SQLITE_OK ){ rc = rcf; break; } } } sqlite3_finalize(pStmt); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } return rc; } #endif /* ** Allocate a new sqlite3expert object. */ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ int rc = SQLITE_OK; sqlite3expert *pNew; |
︙ | ︙ | |||
1841 1842 1843 1844 1845 1846 1847 | } if( rc==SQLITE_OK ){ rc = sqlite3_open(":memory:", &pNew->dbm); if( rc==SQLITE_OK ){ sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); } } | | > > > > > > > > > > > > > > | 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 | } if( rc==SQLITE_OK ){ rc = sqlite3_open(":memory:", &pNew->dbm); if( rc==SQLITE_OK ){ sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); } } /* Allow custom collations to be dealt with through prepare. */ if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbm,0,useDummyCS); if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbv,0,useDummyCS); #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) /* Register UDFs from database [db] with [dbm] and [dbv]. */ if( rc==SQLITE_OK ){ rc = registerUDFs(pNew->db, pNew->dbm); } if( rc==SQLITE_OK ){ rc = registerUDFs(pNew->db, pNew->dbv); } #endif /* Copy the entire schema of database [db] into [dbm]. */ if( rc==SQLITE_OK ){ sqlite3_stmt *pSql = 0; rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'" " AND sql NOT LIKE 'CREATE VIRTUAL %%'" |
︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 | int rc = SQLITE_OK; const char *zStmt = zSql; if( p->bRun ) return SQLITE_MISUSE; while( rc==SQLITE_OK && zStmt && zStmt[0] ){ sqlite3_stmt *pStmt = 0; rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); if( rc==SQLITE_OK ){ if( pStmt ){ IdxStatement *pNew; const char *z = sqlite3_sql(pStmt); int n = STRLEN(z); pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); | > > > > | 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 | int rc = SQLITE_OK; const char *zStmt = zSql; if( p->bRun ) return SQLITE_MISUSE; while( rc==SQLITE_OK && zStmt && zStmt[0] ){ sqlite3_stmt *pStmt = 0; /* Ensure that the provided statement compiles against user's DB. */ rc = idxPrepareStmt(p->db, &pStmt, pzErr, zStmt); if( rc!=SQLITE_OK ) break; sqlite3_finalize(pStmt); rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); if( rc==SQLITE_OK ){ if( pStmt ){ IdxStatement *pNew; const char *z = sqlite3_sql(pStmt); int n = STRLEN(z); pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); |
︙ | ︙ |