Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update to the latest SQLite 3.39.0 alpha with its performance enhancements and bug fixes. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
14da62eeb5641bf95ac5fa17bf5fef0c |
User & Date: | drh 2022-03-07 19:01:35 |
Context
2022-03-07
| ||
20:00 | When displaying the graph for a branch such that the rail for that branch is on the left margin, try to draw merge lines coming into that branch on rails just to the right of the branch itself. ... (check-in: 8b1e14df user: drh tags: trunk) | |
19:01 | Update to the latest SQLite 3.39.0 alpha with its performance enhancements and bug fixes. ... (check-in: 14da62ee user: drh tags: trunk) | |
2022-03-02
| ||
02:00 | Update the built-in SQLite to the latest trunk version that includes various performance enhancements. The purpose here is to test the recent SQLite enhancements in a real-world application. ... (check-in: ad744440 user: drh tags: trunk) | |
Changes
Changes to extsrc/shell.c.
︙ | ︙ | |||
19902 19903 19904 19905 19906 19907 19908 | }else{ showHelp(p->out, 0); } }else if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ char *zTable = 0; /* Insert data into this table */ | | > | 19902 19903 19904 19905 19906 19907 19908 19909 19910 19911 19912 19913 19914 19915 19916 19917 19918 19919 19920 19921 19922 19923 19924 19925 | }else{ showHelp(p->out, 0); } }else if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ char *zTable = 0; /* Insert data into this table */ char *zSchema = 0; /* within this schema (may default to "main") */ char *zFile = 0; /* Name of file to extra content from */ sqlite3_stmt *pStmt = NULL; /* A statement */ int nCol; /* Number of columns in the table */ int nByte; /* Number of bytes in an SQL string */ int i, j; /* Loop counters */ int needCommit; /* True to COMMIT or ROLLBACK at end */ int nSep; /* Number of bytes in p->colSeparator[] */ char *zSql; /* An SQL statement */ char *zFullTabName; /* Table name with schema if applicable */ ImportCtx sCtx; /* Reader context */ char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ int eVerbose = 0; /* Larger for more console output */ int nSkip = 0; /* Initial lines to skip */ int useOutputMode = 1; /* Use output mode to determine separators */ failIfSafeMode(p, "cannot run .import in safe mode"); |
︙ | ︙ | |||
20038 20039 20040 20041 20042 20043 20044 | } if( sCtx.in==0 ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); rc = 1; import_cleanup(&sCtx); goto meta_command_exit; } | < > > > > > > | | | < > > > > < < | < < > < | < < > | < < | < < > > | 20039 20040 20041 20042 20043 20044 20045 20046 20047 20048 20049 20050 20051 20052 20053 20054 20055 20056 20057 20058 20059 20060 20061 20062 20063 20064 20065 20066 20067 20068 20069 20070 20071 20072 20073 20074 20075 20076 20077 20078 20079 20080 20081 20082 20083 20084 20085 20086 20087 20088 20089 20090 20091 20092 20093 20094 20095 20096 20097 20098 20099 20100 20101 20102 20103 20104 20105 20106 20107 20108 20109 20110 20111 20112 20113 20114 20115 20116 20117 20118 20119 20120 20121 20122 20123 20124 20125 20126 20127 20128 20129 20130 20131 20132 20133 20134 20135 20136 20137 20138 20139 20140 20141 20142 20143 20144 20145 20146 20147 20148 20149 20150 20151 20152 20153 20154 | } if( sCtx.in==0 ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); rc = 1; import_cleanup(&sCtx); goto meta_command_exit; } if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ char zSep[2]; zSep[1] = 0; zSep[0] = sCtx.cColSep; utf8_printf(p->out, "Column separator "); output_c_string(p->out, zSep); utf8_printf(p->out, ", row separator "); zSep[0] = sCtx.cRowSep; output_c_string(p->out, zSep); utf8_printf(p->out, "\n"); } /* Below, resources must be freed before exit. */ while( (nSkip--)>0 ){ while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){} } if( zSchema!=0 ){ zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable); }else{ zFullTabName = sqlite3_mprintf("\"%w\"", zTable); } zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName); if( zSql==0 || zFullTabName==0 ){ import_cleanup(&sCtx); shell_out_of_memory(); } nByte = strlen30(zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName); sqlite3 *dbCols = 0; char *zRenames = 0; char *zColDefs; while( xRead(&sCtx) ){ zAutoColumn(sCtx.z, &dbCols, 0); if( sCtx.cTerm!=sCtx.cColSep ) break; } zColDefs = zAutoColumn(0, &dbCols, &zRenames); if( zRenames!=0 ){ utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr, "Columns renamed during .import %s due to duplicates:\n" "%s\n", sCtx.zFile, zRenames); sqlite3_free(zRenames); } assert(dbCols==0); if( zColDefs==0 ){ utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); import_fail: sqlite3_free(zCreate); sqlite3_free(zSql); sqlite3_free(zFullTabName); import_cleanup(&sCtx); rc = 1; goto meta_command_exit; } zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs); if( eVerbose>=1 ){ utf8_printf(p->out, "%s\n", zCreate); } rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); if( rc ){ utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); goto import_fail; } sqlite3_free(zCreate); zCreate = 0; rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); } if( rc ){ if (pStmt) sqlite3_finalize(pStmt); utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); goto import_fail; } sqlite3_free(zSql); nCol = sqlite3_column_count(pStmt); sqlite3_finalize(pStmt); pStmt = 0; if( nCol==0 ) return 0; /* no columns, no error */ zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); if( zSql==0 ){ import_cleanup(&sCtx); shell_out_of_memory(); } sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName); j = strlen30(zSql); for(i=1; i<nCol; i++){ zSql[j++] = ','; zSql[j++] = '?'; } zSql[j++] = ')'; zSql[j] = 0; if( eVerbose>=2 ){ utf8_printf(p->out, "Insert using: %s\n", zSql); } rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); if( rc ){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); if (pStmt) sqlite3_finalize(pStmt); goto import_fail; } sqlite3_free(zSql); sqlite3_free(zFullTabName); needCommit = sqlite3_get_autocommit(p->db); if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); do{ int startLine = sCtx.nLine; for(i=0; i<nCol; i++){ char *z = xRead(&sCtx); /* |
︙ | ︙ |
Changes to extsrc/sqlite3.c.
︙ | ︙ | |||
450 451 452 453 454 455 456 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 | | | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 #define SQLITE_SOURCE_ID "2022-03-07 18:32:08 ae464a18d74bf44fc95bc335e75e6a57dc974f6d6a3d603133594039fb589af2" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
15567 15568 15569 15570 15571 15572 15573 | #define OP_Init 64 /* jump, synopsis: Start at P2 */ #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Return 67 #define OP_EndCoroutine 68 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ #define OP_Halt 70 | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 15567 15568 15569 15570 15571 15572 15573 15574 15575 15576 15577 15578 15579 15580 15581 15582 15583 15584 15585 15586 15587 15588 15589 15590 15591 15592 15593 15594 15595 15596 15597 15598 15599 15600 15601 15602 15603 15604 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 15617 15618 15619 15620 15621 15622 15623 15624 15625 15626 15627 15628 15629 15630 15631 15632 15633 15634 15635 15636 15637 15638 15639 15640 15641 15642 15643 15644 15645 15646 15647 15648 15649 15650 15651 15652 15653 15654 15655 15656 15657 15658 15659 15660 15661 15662 15663 15664 15665 15666 15667 15668 15669 15670 15671 15672 15673 15674 15675 15676 15677 15678 15679 15680 15681 15682 15683 15684 15685 15686 15687 15688 15689 15690 15691 15692 15693 15694 15695 15696 15697 15698 15699 15700 15701 15702 15703 15704 15705 15706 15707 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725 15726 15727 15728 15729 15730 15731 | #define OP_Init 64 /* jump, synopsis: Start at P2 */ #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ #define OP_Return 67 #define OP_EndCoroutine 68 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ #define OP_Halt 70 #define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */ #define OP_Integer 72 /* synopsis: r[P2]=P1 */ #define OP_Int64 73 /* synopsis: r[P2]=P4 */ #define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */ #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */ #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ #define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */ #define OP_FkCheck 83 #define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */ #define OP_CollSeq 85 #define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */ #define OP_RealAffinity 87 #define OP_Cast 88 /* synopsis: affinity(r[P1]) */ #define OP_Permutation 89 #define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */ #define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ #define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */ #define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */ #define OP_Column 94 /* synopsis: r[P3]=PX */ #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */ #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */ #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ #define OP_Count 98 /* synopsis: r[P2]=count() */ #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ #define OP_OpenDup 115 #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ #define OP_SorterOpen 119 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ #define OP_Close 122 #define OP_ColumnsUsed 123 #define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */ #define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */ #define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */ #define OP_NewRowid 127 /* synopsis: r[P2]=rowid */ #define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */ #define OP_RowCell 129 #define OP_Delete 130 #define OP_ResetCount 131 #define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ #define OP_SorterData 133 /* synopsis: r[P2]=data */ #define OP_RowData 134 /* synopsis: r[P2]=data */ #define OP_Rowid 135 /* synopsis: r[P2]=rowid */ #define OP_NullRow 136 #define OP_SeekEnd 137 #define OP_IdxInsert 138 /* synopsis: key=r[P2] */ #define OP_SorterInsert 139 /* synopsis: key=r[P2] */ #define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */ #define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */ #define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */ #define OP_FinishSeek 143 #define OP_Destroy 144 #define OP_Clear 145 #define OP_ResetSorter 146 #define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ #define OP_SqlExec 148 #define OP_ParseSchema 149 #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_DropTrigger 154 #define OP_IntegrityCk 155 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 157 #define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */ #define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */ #define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ #define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ #define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ #define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */ #define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */ #define OP_Expire 166 #define OP_CursorLock 167 #define OP_CursorUnlock 168 #define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */ #define OP_VBegin 170 #define OP_VCreate 171 #define OP_VDestroy 172 #define OP_VOpen 173 #define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */ #define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */ #define OP_VRename 176 #define OP_Pagecount 177 #define OP_MaxPgcnt 178 #define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */ #define OP_Trace 180 #define OP_CursorHint 181 #define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */ #define OP_Noop 183 #define OP_Explain 184 #define OP_Abortable 185 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ /* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\ /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\ /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\ /* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\ /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ /* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 184 */ 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ |
︙ | ︙ | |||
22620 22621 22622 22623 22624 22625 22626 22627 22628 22629 22630 22631 22632 22633 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) SQLITE_PRIVATE const char *sqlite3OpcodeName(int); #endif | > | 22621 22622 22623 22624 22625 22626 22627 22628 22629 22630 22631 22632 22633 22634 22635 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) SQLITE_PRIVATE const char *sqlite3OpcodeName(int); #endif |
︙ | ︙ | |||
23686 23687 23688 23689 23690 23691 23692 | return SQLITE_ERROR; } p->Y = sLocal.tm_year + 1900 - iYearDiff; p->M = sLocal.tm_mon + 1; p->D = sLocal.tm_mday; p->h = sLocal.tm_hour; p->m = sLocal.tm_min; | | | 23688 23689 23690 23691 23692 23693 23694 23695 23696 23697 23698 23699 23700 23701 23702 | return SQLITE_ERROR; } p->Y = sLocal.tm_year + 1900 - iYearDiff; p->M = sLocal.tm_mon + 1; p->D = sLocal.tm_mday; p->h = sLocal.tm_hour; p->m = sLocal.tm_min; p->s = sLocal.tm_sec + (p->iJD%1000)*0.001; p->validYMD = 1; p->validHMS = 1; p->validJD = 0; p->rawS = 0; p->validTZ = 0; p->isError = 0; return SQLITE_OK; |
︙ | ︙ | |||
34681 34682 34683 34684 34685 34686 34687 | /* 64 */ "Init" OpHelp("Start at P2"), /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), /* 67 */ "Return" OpHelp(""), /* 68 */ "EndCoroutine" OpHelp(""), /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 70 */ "Halt" OpHelp(""), | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < > | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 34683 34684 34685 34686 34687 34688 34689 34690 34691 34692 34693 34694 34695 34696 34697 34698 34699 34700 34701 34702 34703 34704 34705 34706 34707 34708 34709 34710 34711 34712 34713 34714 34715 34716 34717 34718 34719 34720 34721 34722 34723 34724 34725 34726 34727 34728 34729 34730 34731 34732 34733 34734 34735 34736 34737 34738 34739 34740 34741 34742 34743 34744 34745 34746 34747 34748 34749 34750 34751 34752 34753 34754 34755 34756 34757 34758 34759 34760 34761 34762 34763 34764 34765 34766 34767 34768 34769 34770 34771 34772 34773 34774 34775 34776 34777 34778 34779 34780 34781 34782 34783 34784 34785 34786 34787 34788 34789 34790 34791 34792 34793 34794 34795 34796 34797 34798 34799 34800 34801 34802 34803 34804 34805 34806 34807 34808 34809 34810 34811 | /* 64 */ "Init" OpHelp("Start at P2"), /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), /* 67 */ "Return" OpHelp(""), /* 68 */ "EndCoroutine" OpHelp(""), /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 70 */ "Halt" OpHelp(""), /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"), /* 72 */ "Integer" OpHelp("r[P2]=P1"), /* 73 */ "Int64" OpHelp("r[P2]=P4"), /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"), /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"), /* 83 */ "FkCheck" OpHelp(""), /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"), /* 85 */ "CollSeq" OpHelp(""), /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), /* 87 */ "RealAffinity" OpHelp(""), /* 88 */ "Cast" OpHelp("affinity(r[P1])"), /* 89 */ "Permutation" OpHelp(""), /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), /* 94 */ "Column" OpHelp("r[P3]=PX"), /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), /* 98 */ "Count" OpHelp("r[P2]=count()"), /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), /* 115 */ "OpenDup" OpHelp(""), /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), /* 117 */ "String8" OpHelp("r[P2]='P4'"), /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), /* 119 */ "SorterOpen" OpHelp(""), /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 122 */ "Close" OpHelp(""), /* 123 */ "ColumnsUsed" OpHelp(""), /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"), /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), /* 129 */ "RowCell" OpHelp(""), /* 130 */ "Delete" OpHelp(""), /* 131 */ "ResetCount" OpHelp(""), /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), /* 133 */ "SorterData" OpHelp("r[P2]=data"), /* 134 */ "RowData" OpHelp("r[P2]=data"), /* 135 */ "Rowid" OpHelp("r[P2]=rowid"), /* 136 */ "NullRow" OpHelp(""), /* 137 */ "SeekEnd" OpHelp(""), /* 138 */ "IdxInsert" OpHelp("key=r[P2]"), /* 139 */ "SorterInsert" OpHelp("key=r[P2]"), /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"), /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"), /* 143 */ "FinishSeek" OpHelp(""), /* 144 */ "Destroy" OpHelp(""), /* 145 */ "Clear" OpHelp(""), /* 146 */ "ResetSorter" OpHelp(""), /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), /* 148 */ "SqlExec" OpHelp(""), /* 149 */ "ParseSchema" OpHelp(""), /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), /* 153 */ "Real" OpHelp("r[P2]=P4"), /* 154 */ "DropTrigger" OpHelp(""), /* 155 */ "IntegrityCk" OpHelp(""), /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 157 */ "Param" OpHelp(""), /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"), /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), /* 166 */ "Expire" OpHelp(""), /* 167 */ "CursorLock" OpHelp(""), /* 168 */ "CursorUnlock" OpHelp(""), /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), /* 170 */ "VBegin" OpHelp(""), /* 171 */ "VCreate" OpHelp(""), /* 172 */ "VDestroy" OpHelp(""), /* 173 */ "VOpen" OpHelp(""), /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), /* 176 */ "VRename" OpHelp(""), /* 177 */ "Pagecount" OpHelp(""), /* 178 */ "MaxPgcnt" OpHelp(""), /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), /* 180 */ "Trace" OpHelp(""), /* 181 */ "CursorHint" OpHelp(""), /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), /* 183 */ "Noop" OpHelp(""), /* 184 */ "Explain" OpHelp(""), /* 185 */ "Abortable" OpHelp(""), }; return azName[i]; } #endif /************** End of opcodes.c *********************************************/ /************** Begin file os_unix.c *****************************************/ |
︙ | ︙ | |||
58722 58723 58724 58725 58726 58727 58728 58729 58730 58731 58732 58733 58734 58735 | sqlite3_pcache_page *pBase; assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); if( rc!=SQLITE_OK ) goto pager_acquire_err; if( pBase==0 ){ rc = SQLITE_NOMEM_BKPT; | > | 58725 58726 58727 58728 58729 58730 58731 58732 58733 58734 58735 58736 58737 58738 58739 | sqlite3_pcache_page *pBase; assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); if( pgno==0 ) return SQLITE_CORRUPT_BKPT; pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); if( rc!=SQLITE_OK ) goto pager_acquire_err; if( pBase==0 ){ rc = SQLITE_NOMEM_BKPT; |
︙ | ︙ | |||
58749 58750 58751 58752 58753 58754 58755 | pPager->aStat[PAGER_STAT_HIT]++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to ** be initialized. But first some error checks: ** | | | | | 58753 58754 58755 58756 58757 58758 58759 58760 58761 58762 58763 58764 58765 58766 58767 58768 58769 58770 | pPager->aStat[PAGER_STAT_HIT]++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to ** be initialized. But first some error checks: ** ** (*) obsolete. Was: maximum page number is 2^31 ** (2) Never try to fetch the locking page */ if( pgno==PAGER_SJ_PGNO(pPager) ){ rc = SQLITE_CORRUPT_BKPT; goto pager_acquire_err; } pPg->pPager = pPager; assert( !isOpen(pPager->fd) || !MEMDB ); |
︙ | ︙ | |||
66976 66977 66978 66979 66980 66981 66982 | pCur->pKey = 0; pCur->eState = CURSOR_INVALID; } /* ** In this version of BtreeMoveto, pKey is a packed index record ** such as is generated by the OP_MakeRecord opcode. Unpack the | | | 66980 66981 66982 66983 66984 66985 66986 66987 66988 66989 66990 66991 66992 66993 66994 | pCur->pKey = 0; pCur->eState = CURSOR_INVALID; } /* ** In this version of BtreeMoveto, pKey is a packed index record ** such as is generated by the OP_MakeRecord opcode. Unpack the ** record and then call sqlite3BtreeIndexMoveto() to do the work. */ static int btreeMoveto( BtCursor *pCur, /* Cursor open on the btree to be searched */ const void *pKey, /* Packed key if the btree is an index */ i64 nKey, /* Integer key for tables. Size of pKey for indices */ int bias, /* Bias search to the high end */ int *pRes /* Write search results here */ |
︙ | ︙ | |||
68083 68084 68085 68086 68087 68088 68089 | BtShared *pBt; /* A copy of pPage->pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); flagByte &= ~PTF_LEAF; pPage->childPtrSize = 4-4*pPage->leaf; | < | 68087 68088 68089 68090 68091 68092 68093 68094 68095 68096 68097 68098 68099 68100 | BtShared *pBt; /* A copy of pPage->pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); flagByte &= ~PTF_LEAF; pPage->childPtrSize = 4-4*pPage->leaf; pBt = pPage->pBt; if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an ** interior table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a ** leaf table b-tree page. */ |
︙ | ︙ | |||
68113 68114 68115 68116 68117 68118 68119 68120 68121 68122 68123 68124 68125 68126 68127 68128 68129 68130 68131 68132 | ** interior index b-tree page. */ assert( (PTF_ZERODATA)==2 ); /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a ** leaf index b-tree page. */ assert( (PTF_ZERODATA|PTF_LEAF)==10 ); pPage->intKey = 0; pPage->intKeyLeaf = 0; pPage->xParseCell = btreeParseCellPtrIndex; pPage->maxLocal = pBt->maxLocal; pPage->minLocal = pBt->minLocal; }else{ /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is ** an error. */ return SQLITE_CORRUPT_PAGE(pPage); } pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; } /* | > > > > > | 68116 68117 68118 68119 68120 68121 68122 68123 68124 68125 68126 68127 68128 68129 68130 68131 68132 68133 68134 68135 68136 68137 68138 68139 68140 | ** interior index b-tree page. */ assert( (PTF_ZERODATA)==2 ); /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a ** leaf index b-tree page. */ assert( (PTF_ZERODATA|PTF_LEAF)==10 ); pPage->intKey = 0; pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtr; pPage->xParseCell = btreeParseCellPtrIndex; pPage->maxLocal = pBt->maxLocal; pPage->minLocal = pBt->minLocal; }else{ /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is ** an error. */ pPage->intKey = 0; pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtr; pPage->xParseCell = btreeParseCellPtrIndex; return SQLITE_CORRUPT_PAGE(pPage); } pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; } /* |
︙ | ︙ | |||
71542 71543 71544 71545 71546 71547 71548 | pCur->eState = CURSOR_INVALID; return rc; } pCur->iPage = 0; pCur->curIntKey = pCur->pPage->intKey; } pRoot = pCur->pPage; | | | 71550 71551 71552 71553 71554 71555 71556 71557 71558 71559 71560 71561 71562 71563 71564 | pCur->eState = CURSOR_INVALID; return rc; } pCur->iPage = 0; pCur->curIntKey = pCur->pPage->intKey; } pRoot = pCur->pPage; assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB ); /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is ** NULL, the caller expects a table b-tree. If this is not the case, ** return an SQLITE_CORRUPT error. ** ** Earlier versions of SQLite assumed that this test could not fail |
︙ | ︙ | |||
71862 71863 71864 71865 71866 71867 71868 71869 71870 71871 71872 71873 71874 71875 | if( rc ) break; } moveto_table_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; } /* Move the cursor so that it points to an entry in an index table ** near the key pIdxKey. Return a success code. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it ** were present. The cursor might point to an entry that comes | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 71870 71871 71872 71873 71874 71875 71876 71877 71878 71879 71880 71881 71882 71883 71884 71885 71886 71887 71888 71889 71890 71891 71892 71893 71894 71895 71896 71897 71898 71899 71900 71901 71902 71903 71904 71905 71906 71907 71908 71909 71910 71911 71912 71913 71914 71915 71916 71917 71918 71919 71920 71921 71922 71923 71924 71925 71926 71927 71928 71929 71930 71931 71932 71933 71934 71935 71936 71937 71938 71939 71940 71941 71942 71943 71944 71945 71946 | if( rc ) break; } moveto_table_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; } /* ** Compare the "idx"-th cell on the page the cursor pCur is currently ** pointing to to pIdxKey using xRecordCompare. Return negative or ** zero if the cell is less than or equal pIdxKey. Return positive ** if unknown. ** ** Return value negative: Cell at pCur[idx] less than pIdxKey ** ** Return value is zero: Cell at pCur[idx] equals pIdxKey ** ** Return value positive: Nothing is known about the relationship ** of the cell at pCur[idx] and pIdxKey. ** ** This routine is part of an optimization. It is always safe to return ** a positive value as that will cause the optimization to be skipped. */ static int indexCellCompare( BtCursor *pCur, int idx, UnpackedRecord *pIdxKey, RecordCompare xRecordCompare ){ MemPage *pPage = pCur->pPage; int c; int nCell; /* Size of the pCell cell in bytes */ u8 *pCell = findCellPastPtr(pPage, idx); nCell = pCell[0]; if( nCell<=pPage->max1bytePayload ){ /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ testcase( pCell+nCell+1==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ testcase( pCell+nCell+2==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* If the record extends into overflow pages, do not attempt ** the optimization. */ c = 99; } return c; } /* ** Return true (non-zero) if pCur is current pointing to the last ** page of a table. */ static int cursorOnLastPage(BtCursor *pCur){ int i; assert( pCur->eState==CURSOR_VALID ); for(i=0; i<pCur->iPage; i++){ MemPage *pPage = pCur->apPage[i]; if( pCur->aiIdx[i]<pPage->nCell ) return 0; } return 1; } /* Move the cursor so that it points to an entry in an index table ** near the key pIdxKey. Return a success code. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it ** were present. The cursor might point to an entry that comes |
︙ | ︙ | |||
71913 71914 71915 71916 71917 71918 71919 71920 71921 71922 71923 71924 71925 71926 71927 71928 71929 71930 71931 71932 | xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); pIdxKey->errCode = 0; assert( pIdxKey->default_rc==1 || pIdxKey->default_rc==0 || pIdxKey->default_rc==-1 ); rc = moveToRoot(pCur); if( rc ){ if( rc==SQLITE_EMPTY ){ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = -1; return SQLITE_OK; } return rc; } assert( pCur->pPage ); assert( pCur->pPage->isInit ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage->nCell > 0 ); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | > | | 71984 71985 71986 71987 71988 71989 71990 71991 71992 71993 71994 71995 71996 71997 71998 71999 72000 72001 72002 72003 72004 72005 72006 72007 72008 72009 72010 72011 72012 72013 72014 72015 72016 72017 72018 72019 72020 72021 72022 72023 72024 72025 72026 72027 72028 72029 72030 72031 72032 72033 72034 72035 72036 72037 72038 72039 72040 72041 72042 72043 72044 72045 72046 72047 72048 72049 72050 72051 72052 72053 72054 72055 72056 72057 72058 72059 | xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); pIdxKey->errCode = 0; assert( pIdxKey->default_rc==1 || pIdxKey->default_rc==0 || pIdxKey->default_rc==-1 ); /* Check to see if we can skip a lot of work. Two cases: ** ** (1) If the cursor is already pointing to the very last cell ** in the table and the pIdxKey search key is greater than or ** equal to that last cell, then no movement is required. ** ** (2) If the cursor is on the last page of the table and the first ** cell on that last page is less than or equal to the pIdxKey ** search key, then we can start the search on the current page ** without needing to go back to root. */ if( pCur->eState==CURSOR_VALID && pCur->pPage->leaf && cursorOnLastPage(pCur) ){ int c; if( pCur->ix==pCur->pPage->nCell-1 && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 ){ *pRes = c; return SQLITE_OK; /* Cursor already pointing at the correct spot */ } if( pCur->iPage>0 && (c = indexCellCompare(pCur, 0, pIdxKey, xRecordCompare))<=0 ){ pCur->curFlags &= ~BTCF_ValidOvfl; goto bypass_moveto_root; /* Start search on the current page */ } } rc = moveToRoot(pCur); if( rc ){ if( rc==SQLITE_EMPTY ){ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = -1; return SQLITE_OK; } return rc; } bypass_moveto_root: assert( pCur->pPage ); assert( pCur->pPage->isInit ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage->nCell > 0 ); assert( pCur->curIntKey==0 ); assert( pIdxKey!=0 ); for(;;){ int lwr, upr, idx, c; Pgno chldPg; MemPage *pPage = pCur->pPage; u8 *pCell; /* Pointer to current cell in pPage */ /* pPage->nCell must be greater than zero. If this is the root-page ** the cursor would have been INVALID above and this for(;;) loop ** not run. If this is not the root-page, then the moveToChild() routine ** would have already detected db corruption. Similarly, pPage must ** be the right kind (index or table) of b-tree page. Otherwise ** a moveToChild() or moveToRoot() call would have detected corruption. */ assert( pPage->nCell>0 ); assert( pPage->intKey==0 ); lwr = 0; upr = pPage->nCell-1; idx = upr>>1; /* idx = (lwr+upr)/2; */ for(;;){ int nCell; /* Size of the pCell cell in bytes */ pCell = findCellPastPtr(pPage, idx); |
︙ | ︙ | |||
75040 75041 75042 75043 75044 75045 75046 | ** hold the content of the row. ** ** For an index btree (used for indexes and WITHOUT ROWID tables), the ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The ** pX.pData,nData,nZero fields must be zero. ** ** If the seekResult parameter is non-zero, then a successful call to | | | | 75144 75145 75146 75147 75148 75149 75150 75151 75152 75153 75154 75155 75156 75157 75158 75159 75160 75161 75162 75163 75164 75165 75166 75167 75168 75169 75170 75171 75172 75173 75174 75175 75176 | ** hold the content of the row. ** ** For an index btree (used for indexes and WITHOUT ROWID tables), the ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The ** pX.pData,nData,nZero fields must be zero. ** ** If the seekResult parameter is non-zero, then a successful call to ** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already ** been performed. In other words, if seekResult!=0 then the cursor ** is currently pointing to a cell that will be adjacent to the cell ** to be inserted. If seekResult<0 then pCur points to a cell that is ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell ** that is larger than (pKey,nKey). ** ** If seekResult==0, that means pCur is pointing at some unknown location. ** In that case, this routine must seek the cursor to the correct insertion ** point for (pKey,nKey) before doing the insertion. For index btrees, ** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked ** key values and pX->aMem can be used instead of pX->pKey to avoid having ** to decode the key. */ SQLITE_PRIVATE int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ const BtreePayload *pX, /* Content of the row to be inserted */ int flags, /* True if this is likely an append */ int seekResult /* Result of prior IndexMoveto() call */ ){ int rc; int loc = seekResult; /* -1: before desired location +1: after */ int szNew = 0; int idx; MemPage *pPage; Btree *p = pCur->pBtree; |
︙ | ︙ | |||
78469 78470 78471 78472 78473 78474 78475 78476 78477 78478 78479 78480 78481 78482 | */ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); if( VdbeMemDynamic(p) || p->szMalloc ){ vdbeMemClear(p); } } /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. ** If the double is out of range of a 64-bit signed integer then ** return the closest available 64-bit signed integer. */ static SQLITE_NOINLINE i64 doubleToInt64(double r){ | > > > > > > > > | 78573 78574 78575 78576 78577 78578 78579 78580 78581 78582 78583 78584 78585 78586 78587 78588 78589 78590 78591 78592 78593 78594 | */ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); if( VdbeMemDynamic(p) || p->szMalloc ){ vdbeMemClear(p); } } /* Like sqlite3VdbeMemRelease() but faster for cases where we ** know in advance that the Mem is not MEM_Dyn or MEM_Agg. */ SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ assert( !VdbeMemDynamic(p) ); if( p->szMalloc ) vdbeMemClear(p); } /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. ** If the double is out of range of a 64-bit signed integer then ** return the closest available 64-bit signed integer. */ static SQLITE_NOINLINE i64 doubleToInt64(double r){ |
︙ | ︙ | |||
78831 78832 78833 78834 78835 78836 78837 78838 78839 78840 78841 78842 78843 78844 | SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( Mem *pMem, void *pPtr, const char *zPType, void (*xDestructor)(void*) ){ assert( pMem->flags==MEM_Null ); pMem->u.zPType = zPType ? zPType : ""; pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; pMem->eSubtype = 'p'; pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; } | > | 78943 78944 78945 78946 78947 78948 78949 78950 78951 78952 78953 78954 78955 78956 78957 | SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( Mem *pMem, void *pPtr, const char *zPType, void (*xDestructor)(void*) ){ assert( pMem->flags==MEM_Null ); vdbeMemClear(pMem); pMem->u.zPType = zPType ? zPType : ""; pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; pMem->eSubtype = 'p'; pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; } |
︙ | ︙ | |||
81726 81727 81728 81729 81730 81731 81732 | #endif p++; }while( (--N)>0 ); } } /* | | > > > > > | 81839 81840 81841 81842 81843 81844 81845 81846 81847 81848 81849 81850 81851 81852 81853 81854 81855 81856 81857 81858 | #endif p++; }while( (--N)>0 ); } } /* ** Release auxiliary memory held in an array of N Mem elements. ** ** After this routine returns, all Mem elements in the array will still ** be valid. Those Mem elements that were not holding auxiliary resources ** will be unchanged. Mem elements which had something freed will be ** set to MEM_Undefined. */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; if( db->pnBytesFreed ){ do{ |
︙ | ︙ | |||
81759 81760 81761 81762 81763 81764 81765 81766 81767 81768 81769 | ** and reset(). Inserts are grouped into a transaction. */ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); if( p->flags&(MEM_Agg|MEM_Dyn) ){ testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; } | > > | > | > > | 81877 81878 81879 81880 81881 81882 81883 81884 81885 81886 81887 81888 81889 81890 81891 81892 81893 81894 81895 81896 81897 81898 81899 81900 81901 | ** and reset(). Inserts are grouped into a transaction. */ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); if( p->flags&(MEM_Agg|MEM_Dyn) ){ testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); sqlite3VdbeMemRelease(p); p->flags = MEM_Undefined; }else if( p->szMalloc ){ sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; p->flags = MEM_Undefined; } #ifdef SQLITE_DEBUG else{ p->flags = MEM_Undefined; } #endif }while( (++p)<pEnd ); } } #ifdef SQLITE_DEBUG /* ** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is |
︙ | ︙ | |||
84059 84060 84061 84062 84063 84064 84065 | v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); if( (v1==0 || v2==0) ){ if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; rc = 0; }else{ rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); } | | | | 84182 84183 84184 84185 84186 84187 84188 84189 84190 84191 84192 84193 84194 84195 84196 84197 | v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); if( (v1==0 || v2==0) ){ if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; rc = 0; }else{ rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); } sqlite3VdbeMemReleaseMalloc(&c1); sqlite3VdbeMemReleaseMalloc(&c2); return rc; } } /* ** The input pBlob is guaranteed to be a Blob that is not marked ** with MEM_Zero. Return true if it could be a zero-blob. |
︙ | ︙ | |||
84792 84793 84794 84795 84796 84797 84798 | if( unlikely((u32)m.n<szHdr+lenRowid) ){ goto idx_rowid_corruption; } /* Fetch the integer off the end of the index record */ sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v); *rowid = v.u.i; | | | | 84915 84916 84917 84918 84919 84920 84921 84922 84923 84924 84925 84926 84927 84928 84929 84930 84931 84932 84933 84934 84935 84936 | if( unlikely((u32)m.n<szHdr+lenRowid) ){ goto idx_rowid_corruption; } /* Fetch the integer off the end of the index record */ sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v); *rowid = v.u.i; sqlite3VdbeMemReleaseMalloc(&m); return SQLITE_OK; /* Jump here if database corruption is detected after m has been ** allocated. Free the m object and return SQLITE_CORRUPT. */ idx_rowid_corruption: testcase( m.szMalloc!=0 ); sqlite3VdbeMemReleaseMalloc(&m); return SQLITE_CORRUPT_BKPT; } /* ** Compare the key of the index entry that cursor pC is pointing to against ** the key string in pUnpacked. Write into *pRes a number ** that is negative, zero, or positive if pC is less than, equal to, |
︙ | ︙ | |||
84841 84842 84843 84844 84845 84846 84847 | } sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ){ return rc; } *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); | | | 84964 84965 84966 84967 84968 84969 84970 84971 84972 84973 84974 84975 84976 84977 84978 | } sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ){ return rc; } *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); sqlite3VdbeMemReleaseMalloc(&m); return SQLITE_OK; } /* ** This routine sets the value to be returned by subsequent calls to ** sqlite3_changes() on the database handle 'db'. */ |
︙ | ︙ | |||
85008 85009 85010 85011 85012 85013 85014 | ** the vdbeUnpackRecord() function found in vdbeapi.c. */ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ if( p ){ int i; for(i=0; i<nField; i++){ Mem *pMem = &p->aMem[i]; | | | 85131 85132 85133 85134 85135 85136 85137 85138 85139 85140 85141 85142 85143 85144 85145 | ** the vdbeUnpackRecord() function found in vdbeapi.c. */ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ if( p ){ int i; for(i=0; i<nField; i++){ Mem *pMem = &p->aMem[i]; if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); } sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
︙ | ︙ | |||
88417 88418 88419 88420 88421 88422 88423 | /* Most jump operations do a goto to this spot in order to update ** the pOp pointer. */ jump_to_p2: pOp = &aOp[pOp->p2 - 1]; break; } | | > > > > | 88540 88541 88542 88543 88544 88545 88546 88547 88548 88549 88550 88551 88552 88553 88554 88555 88556 88557 88558 88559 88560 88561 | /* Most jump operations do a goto to this spot in order to update ** the pOp pointer. */ jump_to_p2: pOp = &aOp[pOp->p2 - 1]; break; } /* Opcode: Return P1 * P3 * * ** ** Jump to the next instruction after the address in register P1. After ** the jump, register P1 becomes undefined. ** ** P3 is not used by the byte-code engine. However, the code generator ** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is ** one. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags==MEM_Int ); pOp = &aOp[pIn1->u.i]; pIn1->flags = MEM_Undefined; break; |
︙ | ︙ | |||
88608 88609 88610 88611 88612 88613 88614 88615 88616 88617 88618 88619 88620 88621 88622 88623 88624 88625 88626 | assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } goto vdbe_return; } /* Opcode: Integer P1 P2 * * * ** Synopsis: r[P2]=P1 ** ** The 32-bit integer value P1 is written into register P2. */ case OP_Integer: { /* out2 */ pOut = out2Prerelease(p, pOp); pOut->u.i = pOp->p1; break; } /* Opcode: Int64 * P2 * P4 * | > > > > > > > > > > > | 88735 88736 88737 88738 88739 88740 88741 88742 88743 88744 88745 88746 88747 88748 88749 88750 88751 88752 88753 88754 88755 88756 88757 88758 88759 88760 88761 88762 88763 88764 | assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } goto vdbe_return; } /* Opcode: BeginSubrtn P1 P2 * * * ** Synopsis: r[P2]=P1 ** ** Mark the beginning of a subroutine by loading the integer value P1 ** into register r[P2]. The P2 register is used to store the return ** address of the subroutine call. ** ** This opcode is identical to OP_Integer. It has a different name ** only to make the byte code easier to read and verify. */ /* Opcode: Integer P1 P2 * * * ** Synopsis: r[P2]=P1 ** ** The 32-bit integer value P1 is written into register P2. */ case OP_BeginSubrtn: case OP_Integer: { /* out2 */ pOut = out2Prerelease(p, pOp); pOut->u.i = pOp->p1; break; } /* Opcode: Int64 * P2 * P4 * |
︙ | ︙ | |||
90053 90054 90055 90056 90057 90058 90059 | ** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. */ case OP_Offset: { /* out3 */ VdbeCursor *pC; /* The VDBE cursor */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; pOut = &p->aMem[pOp->p3]; | | > > > > > > > | > | 90191 90192 90193 90194 90195 90196 90197 90198 90199 90200 90201 90202 90203 90204 90205 90206 90207 90208 90209 90210 90211 90212 90213 90214 90215 90216 | ** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. */ case OP_Offset: { /* out3 */ VdbeCursor *pC; /* The VDBE cursor */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; pOut = &p->aMem[pOp->p3]; if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){ sqlite3VdbeMemSetNull(pOut); }else{ if( pC->deferredMoveto ){ rc = sqlite3VdbeFinishMoveto(pC); if( rc ) goto abort_due_to_error; } if( sqlite3BtreeEof(pC->uc.pCursor) ){ sqlite3VdbeMemSetNull(pOut); }else{ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); } } break; } #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* Opcode: Column P1 P2 P3 P4 P5 ** Synopsis: r[P3]=PX |
︙ | ︙ | |||
93771 93772 93773 93774 93775 93776 93777 | rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ) goto abort_due_to_error; res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); | | | 93917 93918 93919 93920 93921 93922 93923 93924 93925 93926 93927 93928 93929 93930 93931 | rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ) goto abort_due_to_error; res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); sqlite3VdbeMemReleaseMalloc(&m); } /* End of inlined sqlite3VdbeIdxKeyCompare() */ assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); if( (pOp->opcode&1)==(OP_IdxLT&1) ){ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); res = -res; |
︙ | ︙ | |||
105552 105553 105554 105555 105556 105557 105558 | /* Begin coding the subroutine */ assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = | | < | 105698 105699 105700 105701 105702 105703 105704 105705 105706 105707 105708 105709 105710 105711 105712 | /* Begin coding the subroutine */ assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } /* Check to see if this is a vector IN operator */ pLeft = pExpr->pLeft; nVal = sqlite3ExprVectorSize(pLeft); |
︙ | ︙ | |||
105655 105656 105657 105658 105659 105660 105661 105662 105663 105664 105665 105666 105667 105668 105669 105670 105671 105672 105673 105674 105675 105676 105677 105678 105679 105680 105681 | /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2, r1); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); | > > > | > | 105800 105801 105802 105803 105804 105805 105806 105807 105808 105809 105810 105811 105812 105813 105814 105815 105816 105817 105818 105819 105820 105821 105822 105823 105824 105825 105826 105827 105828 105829 105830 105831 105832 105833 105834 105835 105836 105837 105838 | /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2, r1); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, pExpr->y.sub.iAddr-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); } } #endif /* SQLITE_OMIT_SUBQUERY */ /* |
︙ | ︙ | |||
105730 105731 105732 105733 105734 105735 105736 | /* Begin coding the subroutine */ assert( !ExprUseYWin(pExpr) ); assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = | | < < | 105879 105880 105881 105882 105883 105884 105885 105886 105887 105888 105889 105890 105891 105892 105893 | /* Begin coding the subroutine */ assert( !ExprUseYWin(pExpr) ); assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger |
︙ | ︙ | |||
105805 105806 105807 105808 105809 105810 105811 | ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); } /* Subroutine return */ assert( ExprUseYSub(pExpr) ); | > > | > | 105952 105953 105954 105955 105956 105957 105958 105959 105960 105961 105962 105963 105964 105965 105966 105967 105968 105969 | ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); } /* Subroutine return */ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, pExpr->y.sub.iAddr-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); return rReg; } #endif /* SQLITE_OMIT_SUBQUERY */ #ifndef SQLITE_OMIT_SUBQUERY |
︙ | ︙ | |||
123336 123337 123338 123339 123340 123341 123342 | DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC | > | < | 123486 123487 123488 123489 123490 123491 123492 123493 123494 123495 123496 123497 123498 123499 123500 123501 | DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF, 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} }, #endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), FUNCTION(rtrim, 1, 2, 0, trimFunc ), FUNCTION(rtrim, 2, 2, 0, trimFunc ), FUNCTION(trim, 1, 3, 0, trimFunc ), FUNCTION(trim, 2, 3, 0, trimFunc ), |
︙ | ︙ | |||
142450 142451 142452 142453 142454 142455 142456 142457 142458 142459 142460 142461 142462 142463 | Token *pName, /* The target name */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; memcpy(z, pName->z, pName->n); sqlite3Dequote(z); pTriggerStep->zTarget = z; pTriggerStep->op = op; | > | 142600 142601 142602 142603 142604 142605 142606 142607 142608 142609 142610 142611 142612 142613 142614 | Token *pName, /* The target name */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; if( pParse->nErr ) return 0; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; memcpy(z, pName->z, pName->n); sqlite3Dequote(z); pTriggerStep->zTarget = z; pTriggerStep->op = op; |
︙ | ︙ | |||
148263 148264 148265 148266 148267 148268 148269 148270 148271 148272 148273 148274 148275 148276 | int iIdxCur = pLevel->iIdxCur; sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); sqlite3VdbeJumpHere(v, j); for(j=0; j<nSkip; j++){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j); | > | 148414 148415 148416 148417 148418 148419 148420 148421 148422 148423 148424 148425 148426 148427 148428 | int iIdxCur = pLevel->iIdxCur; sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); assert( pLevel->addrSkip==0 ); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); sqlite3VdbeJumpHere(v, j); for(j=0; j<nSkip; j++){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j); |
︙ | ︙ | |||
148868 148869 148870 148871 148872 148873 148874 148875 148876 148877 148878 148879 148880 148881 | int addrNxt, /* Jump here to bypass inner loops */ Bitmask notReady /* Loops that are not ready */ ){ while( ++iLevel < pWInfo->nLevel ){ WhereLevel *pLevel = &pWInfo->a[iLevel]; WhereLoop *pLoop = pLevel->pWLoop; if( pLevel->regFilter==0 ) continue; /* ,--- Because sqlite3ConstructBloomFilter() has will not have set ** vvvvv--' pLevel->regFilter if this were true. */ if( NEVER(pLoop->prereq & notReady) ) continue; if( pLoop->wsFlags & WHERE_IPK ){ WhereTerm *pTerm = pLoop->aLTerm[0]; int regRowid; assert( pTerm!=0 ); | > | 149020 149021 149022 149023 149024 149025 149026 149027 149028 149029 149030 149031 149032 149033 149034 | int addrNxt, /* Jump here to bypass inner loops */ Bitmask notReady /* Loops that are not ready */ ){ while( ++iLevel < pWInfo->nLevel ){ WhereLevel *pLevel = &pWInfo->a[iLevel]; WhereLoop *pLoop = pLevel->pWLoop; if( pLevel->regFilter==0 ) continue; if( pLevel->pWLoop->nSkip ) continue; /* ,--- Because sqlite3ConstructBloomFilter() has will not have set ** vvvvv--' pLevel->regFilter if this were true. */ if( NEVER(pLoop->prereq & notReady) ) continue; if( pLoop->wsFlags & WHERE_IPK ){ WhereTerm *pTerm = pLoop->aLTerm[0]; int regRowid; assert( pTerm!=0 ); |
︙ | ︙ | |||
149002 149003 149004 149005 149006 149007 149008 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ /* Case 1: The table is a virtual-table. Use the VFilter and VNext ** to access the data. */ int iReg; /* P3 Value for OP_VFilter */ int addrNotFound; int nConstraint = pLoop->nLTerm; | < | 149155 149156 149157 149158 149159 149160 149161 149162 149163 149164 149165 149166 149167 149168 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ /* Case 1: The table is a virtual-table. Use the VFilter and VNext ** to access the data. */ int iReg; /* P3 Value for OP_VFilter */ int addrNotFound; int nConstraint = pLoop->nLTerm; iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; for(j=0; j<nConstraint; j++){ int iTarget = iReg+j+2; pTerm = pLoop->aLTerm[j]; if( NEVER(pTerm==0) ) continue; |
︙ | ︙ | |||
149048 149049 149050 149051 149052 149053 149054 | /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); | < < < < | | < > > > > > < < < < < < < < > | < < > | | | < > | | > > | > | > > > | > > > > > | > > | | | | < | 149200 149201 149202 149203 149204 149205 149206 149207 149208 149209 149210 149211 149212 149213 149214 149215 149216 149217 149218 149219 149220 149221 149222 149223 149224 149225 149226 149227 149228 149229 149230 149231 149232 149233 149234 149235 149236 149237 149238 149239 149240 149241 149242 149243 149244 149245 149246 149247 149248 149249 149250 149251 149252 149253 149254 149255 149256 149257 149258 149259 149260 149261 149262 149263 149264 149265 149266 149267 149268 149269 149270 149271 149272 149273 149274 | /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); for(j=0; j<nConstraint; j++){ pTerm = pLoop->aLTerm[j]; if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); continue; } if( (pTerm->eOperator & WO_IN)!=0 && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 && !db->mallocFailed ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ int iIn; /* IN loop corresponding to the j-th constraint */ /* Reload the constraint value into reg[iReg+j+2]. The same value ** was loaded into the same register prior to the OP_VFilter, but ** the xFilter implementation might have changed the datatype or ** encoding of the value in the register, so it *must* be reloaded. */ for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){ pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2) || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2) ){ testcase( pOp->opcode==OP_Rowid ); sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); break; } } /* Generate code that will continue to the next row if ** the IN constraint is not satisfied */ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); if( !db->mallocFailed ){ int iFld = pTerm->u.x.iField; Expr *pLeft = pTerm->pExpr->pLeft; assert( pLeft!=0 ); if( iFld>0 ){ assert( pLeft->op==TK_VECTOR ); assert( ExprUseXList(pLeft) ); assert( iFld<=pLeft->x.pList->nExpr ); pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr; }else{ pCompare->pLeft = pLeft; } pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); if( pRight ){ pRight->iTable = iReg+j+2; sqlite3ExprIfFalse( pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL ); } pCompare->pLeft = 0; } sqlite3ExprDelete(db, pCompare); } } /* These registers need to be preserved in case there is an IN operator ** loop. So we could deallocate the registers here (and potentially ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems ** simpler and safer to simply not reuse the registers. ** ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); */ |
︙ | ︙ | |||
149814 149815 149816 149817 149818 149819 149820 149821 149822 149823 149824 149825 149826 149827 149828 149829 149830 149831 149832 149833 | ** See ticket http://www.sqlite.org/src/info/f2369304e4 ** ** 2022-02-04: Do not push down slices of a row-value comparison. ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, ** the initialization of the right-hand operand of the vector comparison ** might not occur, or might occur only in an OR branch that is not ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. */ if( pWC->nTerm>1 ){ int iTerm; for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ continue; } if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; | > > > > > > > > | | 149970 149971 149972 149973 149974 149975 149976 149977 149978 149979 149980 149981 149982 149983 149984 149985 149986 149987 149988 149989 149990 149991 149992 149993 149994 149995 149996 149997 149998 149999 150000 150001 150002 150003 150004 150005 | ** See ticket http://www.sqlite.org/src/info/f2369304e4 ** ** 2022-02-04: Do not push down slices of a row-value comparison. ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, ** the initialization of the right-hand operand of the vector comparison ** might not occur, or might occur only in an OR branch that is not ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. ** ** 2022-03-03: Do not push down expressions that involve subqueries. ** The subquery might get coded as a subroutine. Any table-references ** in the subquery might be resolved to index-references for the index on ** the OR branch in which the subroutine is coded. But if the subroutine ** is invoked from a different OR branch that uses a different index, such ** index-references will not work. tag-20220303a ** https://sqlite.org/forum/forumpost/36937b197273d403 */ if( pWC->nTerm>1 ){ int iTerm; for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ continue; } if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } if( pAndExpr ){ /* The extra 0x10000 bit on the opcode is masked off and does not ** become part of the new Expr.op. However, it does make the ** op==TK_AND comparison inside of sqlite3PExpr() false, and this |
︙ | ︙ | |||
153104 153105 153106 153107 153108 153109 153110 153111 153112 153113 153114 153115 153116 153117 153118 | sqlite3VdbeResolveLabel(v, addrCont); sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrTop); pLoop->wsFlags &= ~WHERE_BLOOMFILTER; if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; while( ++iLevel < pWInfo->nLevel ){ pLevel = &pWInfo->a[iLevel]; pLoop = pLevel->pWLoop; if( NEVER(pLoop==0) ) continue; if( pLoop->prereq & notReady ) continue; if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) ==WHERE_BLOOMFILTER ){ /* This is a candidate for bloom-filter pull-down (early evaluation). | > > > | 153268 153269 153270 153271 153272 153273 153274 153275 153276 153277 153278 153279 153280 153281 153282 153283 153284 153285 | sqlite3VdbeResolveLabel(v, addrCont); sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrTop); pLoop->wsFlags &= ~WHERE_BLOOMFILTER; if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; while( ++iLevel < pWInfo->nLevel ){ const SrcItem *pTabItem; pLevel = &pWInfo->a[iLevel]; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; if( pTabItem->fg.jointype & JT_LEFT ) continue; pLoop = pLevel->pWLoop; if( NEVER(pLoop==0) ) continue; if( pLoop->prereq & notReady ) continue; if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) ==WHERE_BLOOMFILTER ){ /* This is a candidate for bloom-filter pull-down (early evaluation). |
︙ | ︙ | |||
234386 234387 234388 234389 234390 234391 234392 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); | | | 234553 234554 234555 234556 234557 234558 234559 234560 234561 234562 234563 234564 234565 234566 234567 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); sqlite3_result_text(pCtx, "fts5: 2022-03-07 18:32:08 ae464a18d74bf44fc95bc335e75e6a57dc974f6d6a3d603133594039fb589af2", -1, SQLITE_TRANSIENT); } /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. */ static int fts5ShadowName(const char *zName){ |
︙ | ︙ |
Changes to extsrc/sqlite3.h.
︙ | ︙ | |||
144 145 146 147 148 149 150 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 #define SQLITE_SOURCE_ID "2022-03-07 18:32:08 ae464a18d74bf44fc95bc335e75e6a57dc974f6d6a3d603133594039fb589af2" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ |