-C Update\sthe\sshell\stool\sto\swork\swith\sSQLITE_OMIT_AUTOINIT\sbuilds.
-D 2026-01-20T18:30:48.704
+C Add\sa\snew\sencoding\sconstant\sSQLITE_UTF8_ZT,\swhich\sif\sused\swith\nsqlite3_result_text64()\sor\ssqlite3_bind_text64()\sdeclares\sthat\sthe\nstring\sprovided\sis\sUTF8\sand\szero-terminated\sat\sthe\slength\sspecified.
+D 2026-01-21T19:24:07.200
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/expr.c 252e62742f5bb01517377c93057b6040ab954034ec3dde4d6fc583565d859a9c
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c c065da737307a29e4d240ac727758dbf4102cb3218a1f651eb689b6a6fa12531
-F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
+F src/func.c efbcfe7cb7fc92fe5299c9aaa141075eb60d2108253e99bc235384ed6a90d937
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4d45a04431db072040d6625ee21c1dc483c9b2b64a5ab419f4a4e05aabed1204
F src/shell.c.in 399df56c81dbf51bfa0df73094344e2bf76a443bb7fba729b616ab3d0b769f34
-F src/sqlite.h.in 476f3efeb5dd26ad94dcbce262ca7eb9d042d797a92d624059c67ef37d5b3ab4
+F src/sqlite.h.in d463dcdd67d4865991cd62dc8d3f678086b38365593861f77c09c3401551d59f
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h f590cd8cb4c36fc727632c9b5fbbafc85f7efe2c6890f9958d7e711dc26ec01e
F src/sqliteInt.h af67bc95fa6b66cd3c7f3d18d2d040ad386e4cbb02965ee318cc721ee9d5fa45
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
F src/vdbe.h 966d0677a540b7ea6549b7c4e1312fc0d830fce3a235a58c801f2cc31cf5ecf9
-F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
-F src/vdbeapi.c c7c8477fa2d4fca015a0b1d555f771153ebf088c8e4b7ca878d31bd974cf0735
-F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
+F src/vdbeInt.h c45d0195dad0a9099132109e3b63697f4f119baddeb391c36ca226cee530a485
+F src/vdbeapi.c cf69a8a230a271f0935f2e819828667e80f186a4cfa0e0002517ad017b3bd249
+F src/vdbeaux.c 396d38a62a357b807eabae0cae441fc89d2767a57ab08026b7072bf7aa2dd00c
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
-F src/vdbemem.c fdd023e357ad3129e1dcae46df47fccceeb8bd1ffa6c5d43a1e3f04460bb59b7
+F src/vdbemem.c aeaef3bb000fd2599e9b0741a45fe9e306606ae9b06b3eb573d54847cec9847d
F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70
F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 6d9ec0a21a2b33a7bb3cf9c3677c9ef7a9738d318cd2d8159b33583b2bd4abec
-R d8076aa16a2c760d1df8cf8a346c126f
-U dan
-Z 909c03dd33b70fa520b61311ab3de8ab
+P 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552
+R 32ad442dba5cd91b995abc4a0d83d1b7
+T *branch * utf8-zt
+T *sym-utf8-zt *
+T -sym-trunk *
+U drh
+Z dc112c637ce7b6a8b3ac368aadc90767
# Remove this line to create a well-formed Fossil manifest.
-branch trunk
-tag trunk
+branch utf8-zt
+tag utf8-zt
-2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552
+2d84ce88fed12766272f6b1293927eb4c7ce92da0334b09b4875ed2dfdd00ade
}
}
zOut[j] = 0;
- sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8);
+ sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8_ZT);
return;
unistr_error:
} \
}
*zOut = 0;
- sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
+ sqlite3_result_text64(context, (char*)z, zOut-z,sqlite3_free,SQLITE_UTF8_ZT);
}
/*
}
*z = 0;
sqlite3_result_text64(context, zHex, (u64)(z-zHex),
- sqlite3_free, SQLITE_UTF8);
+ sqlite3_free, SQLITE_UTF8_ZT);
}
}
}
z[j] = 0;
assert( j<=n );
- sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8);
+ sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8_ZT);
}
/*
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
-** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
-** otherwise.
+** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT,
+** or UTF16 otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** manage the lifetime of its private copy.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
-** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
-** to specify the encoding of the text in the third parameter. If
+** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
+** or [SQLITE_UTF16LE] to specify the encoding of the text in the
+** third parameter. The special value [SQLITE_UTF8_ZT] means that the
+** string argument is both UTF-8 encoded and is zero-terminated. If
** the sixth argument to sqlite3_bind_text64() is not one of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
+#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */
/*
** CAPI3REF: Function Flags
** ^The sqlite3_result_text64() interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
-** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
+** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
+** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that
+** the result text is both UTF-8 and zero-terminated.
** ^SQLite takes the text result from the application from
** the 2nd parameter of the sqlite3_result_text* interfaces.
** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces
void sqlite3VdbeMemMove(Mem*, Mem*);
int sqlite3VdbeMemNulTerminate(Mem*);
int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*));
+int sqlite3VdbeMemSetText(Mem*, const char*, i64, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
void (*xDel)(void*) /* Destructor function */
){
Mem *pOut = pCtx->pOut;
- int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel);
+ int rc;
+ if( enc==SQLITE_UTF8 ){
+ rc = sqlite3VdbeMemSetText(pOut, z, n, xDel);
+ }else if( enc==SQLITE_UTF8_ZT ){
+ rc = sqlite3VdbeMemSetText(pOut, z, n, xDel);
+ pOut->flags |= MEM_Term;
+ }else{
+ rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel);
+ }
if( rc ){
if( rc==SQLITE_TOOBIG ){
sqlite3_result_error_toobig(pCtx);
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
- if( enc!=SQLITE_UTF8 ){
+ if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
n &= ~(u64)1;
}
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
if( zData!=0 ){
pVar = &p->aVar[i-1];
- rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
- if( rc==SQLITE_OK ){
- if( encoding==0 ){
- pVar->enc = ENC(p->db);
- }else{
- rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
- }
+ if( encoding==SQLITE_UTF8 ){
+ rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel);
+ }else if( encoding==SQLITE_UTF8_ZT ){
+ rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel);
+ pVar->flags |= MEM_Term;
+ }else{
+ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
+ if( encoding==0 ) pVar->enc = ENC(p->db);
+ }
+ if( rc==SQLITE_OK && encoding!=0 ){
+ rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
if( rc ){
sqlite3Error(p->db, rc);
unsigned char enc
){
assert( xDel!=SQLITE_DYNAMIC );
- if( enc!=SQLITE_UTF8 ){
+ if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
nData &= ~(u64)1;
}
}
assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResAlloc]);
- rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
+ rc = sqlite3VdbeMemSetText(pColName, zName, -1, xDel);
assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
return rc;
}
return SQLITE_OK;
}
+/* Like sqlite3VdbeMemSetStr() except:
+**
+** enc is always SQLITE_UTF8
+** pMem->db is always non-NULL
+*/
+int sqlite3VdbeMemSetText(
+ Mem *pMem, /* Memory cell to set to string value */
+ const char *z, /* String pointer */
+ i64 n, /* Bytes in string, or negative */
+ void (*xDel)(void*) /* Destructor function */
+){
+ i64 nByte = n; /* New value for pMem->n */
+ u16 flags;
+
+ assert( pMem!=0 );
+ assert( pMem->db!=0 );
+ assert( sqlite3_mutex_held(pMem->db->mutex) );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
+
+ /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
+ if( !z ){
+ sqlite3VdbeMemSetNull(pMem);
+ return SQLITE_OK;
+ }
+
+ if( nByte<0 ){
+ nByte = strlen(z);
+ flags = MEM_Str|MEM_Term;
+ }else{
+ flags = MEM_Str;
+ }
+ if( nByte>(i64)pMem->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( xDel && xDel!=SQLITE_TRANSIENT ){
+ if( xDel==SQLITE_DYNAMIC ){
+ sqlite3DbFree(pMem->db, (void*)z);
+ }else{
+ xDel((void*)z);
+ }
+ }
+ sqlite3VdbeMemSetNull(pMem);
+ return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
+ }
+
+ /* The following block sets the new values of Mem.z and Mem.xDel. It
+ ** also sets a flag in local variable "flags" to indicate the memory
+ ** management (one of MEM_Dyn or MEM_Static).
+ */
+ if( xDel==SQLITE_TRANSIENT ){
+ i64 nAlloc = nByte + 1;
+ testcase( nAlloc==31 );
+ testcase( nAlloc==32 );
+ if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
+ return SQLITE_NOMEM_BKPT;
+ }
+ assert( pMem->z!=0 );
+ memcpy(pMem->z, z, nByte);
+ pMem->z[nByte] = 0;
+ }else{
+ sqlite3VdbeMemRelease(pMem);
+ pMem->z = (char *)z;
+ if( xDel==SQLITE_DYNAMIC ){
+ pMem->zMalloc = pMem->z;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+ pMem->xDel = 0;
+ }else if( xDel==SQLITE_STATIC ){
+ pMem->xDel = xDel;
+ flags |= MEM_Static;
+ }else{
+ pMem->xDel = xDel;
+ flags |= MEM_Dyn;
+ }
+ }
+ pMem->flags = flags;
+ pMem->n = (int)(nByte & 0x7fffffff);
+ pMem->enc = SQLITE_UTF8;
+ return SQLITE_OK;
+}
+
/*
** Move data out of a btree key or data field and into a Mem structure.
** The data is payload from the entry that pCur is currently pointing