mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Prototype implementation of the unistr() SQL function.
FossilOrigin-Name: 7cc302de05ed2a973372c05f55b048bf99af3d2590dd29f6fd0f379fb451aa0e
This commit is contained in:
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
|||||||
C Tamp\sdown\svarious\sharmless\scompiler\swarnings.\s\sUse\s"int"\sin\splaces\sinstead\nof\s"u16"\sor\s"i16"\ssince\sthe\scompiler\scomplains\sless\sand\sgenerates\sfaster\ncode.
|
C Prototype\simplementation\sof\sthe\sunistr()\sSQL\sfunction.
|
||||||
D 2025-02-22T16:44:14.174
|
D 2025-02-22T23:18:38.072
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
|
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
|
||||||
@ -735,7 +735,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
|||||||
F src/expr.c 6769d3f0ca9b1792e883e3ff21fdc5ca0033cece65571ebbf9d8b8fe2f47cd27
|
F src/expr.c 6769d3f0ca9b1792e883e3ff21fdc5ca0033cece65571ebbf9d8b8fe2f47cd27
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||||
F src/func.c 6c8b7bbdc5b588f3cfc79ed5effcfd3031758f5034c464fcd8891e8010b4d317
|
F src/func.c ddfb4f3b8d2fbbe46dbe2bb28c9c79fc1defb7855975dfd851f2dd8417cc70be
|
||||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||||
F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7
|
F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7
|
||||||
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
|
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
|
||||||
@ -2210,8 +2210,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
|||||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||||
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
|
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P eeea11278bdebe336f0c30fbad79e30e3456ab67dae46abdd5f9951ea1b61bed
|
P 742827f049768c4f69ccdfaadfad339aaad3bc126d3a68b90cfea01d825bf7ce
|
||||||
R 8078ee78be0e4d7d18ee35dbad7406fe
|
R 487d823b2a97be800308516e5c94d276
|
||||||
|
T *branch * unistr
|
||||||
|
T *sym-unistr *
|
||||||
|
T -sym-trunk *
|
||||||
U drh
|
U drh
|
||||||
Z 2ee0c7ad1f2d8a9853a04c1df0464ab5
|
Z f399533fbf6bd526a1da3885c8fdaf47
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
742827f049768c4f69ccdfaadfad339aaad3bc126d3a68b90cfea01d825bf7ce
|
7cc302de05ed2a973372c05f55b048bf99af3d2590dd29f6fd0f379fb451aa0e
|
||||||
|
127
src/func.c
127
src/func.c
@ -1149,6 +1149,132 @@ void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write a single UTF8 character whose value if v into the
|
||||||
|
** buffer starting at zOut. Return the number of bytes needed
|
||||||
|
** to encode that character.
|
||||||
|
*/
|
||||||
|
static int appendOneUtf8Char(char *zOut, u32 v){
|
||||||
|
if( v<0x00080 ){
|
||||||
|
zOut[0] = (u8)(v & 0xff);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if( v<0x00800 ){
|
||||||
|
zOut[0] = 0xc0 + (u8)((v>>6) & 0x1f);
|
||||||
|
zOut[1] = 0x80 + (u8)(v & 0x3f);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if( v<0x10000 ){
|
||||||
|
zOut[0] = 0xe0 + (u8)((v>>12) & 0x0f);
|
||||||
|
zOut[1] = 0x80 + (u8)((v>>6) & 0x3f);
|
||||||
|
zOut[2] = 0x80 + (u8)(v & 0x3f);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
zOut[0] = 0xf0 + (u8)((v>>18) & 0x07);
|
||||||
|
zOut[1] = 0x80 + (u8)((v>>12) & 0x3f);
|
||||||
|
zOut[2] = 0x80 + (u8)((v>>6) & 0x3f);
|
||||||
|
zOut[3] = 0x80 + (u8)(v & 0x3f);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return true if z[] begins with N hexadecimal digits, and write
|
||||||
|
** a decoding of those digits into *pVal. Or return false if any
|
||||||
|
** one of the first N characters in z[] is not a hexadecimal digit.
|
||||||
|
*/
|
||||||
|
static int isNHex(const char *z, int N, u32 *pVal){
|
||||||
|
int i;
|
||||||
|
int v = 0;
|
||||||
|
for(i=0; i<N; i++){
|
||||||
|
if( !sqlite3Isxdigit(z[i]) ) return 0;
|
||||||
|
v = (v<<4) + sqlite3HexToInt(z[i]);
|
||||||
|
}
|
||||||
|
*pVal = v;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Implementation of the UNISTR() function.
|
||||||
|
**
|
||||||
|
** This is intended to be a work-alike of the UNISTR() function in
|
||||||
|
** PostgreSQL. Quoting from the PG documentation (PostgreSQL 17 -
|
||||||
|
** scraped on 2025-02-22):
|
||||||
|
**
|
||||||
|
** Evaluate escaped Unicode characters in the argument. Unicode
|
||||||
|
** characters can be specified as \XXXX (4 hexadecimal digits),
|
||||||
|
** \+XXXXXX (6 hexadecimal digits), \uXXXX (4 hexadecimal digits),
|
||||||
|
** or \UXXXXXXXX (8 hexadecimal digits). To specify a backslash,
|
||||||
|
** write two backslashes. All other characters are taken literally.
|
||||||
|
*/
|
||||||
|
static void unistrFunc(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
char *zOut;
|
||||||
|
const char *zIn;
|
||||||
|
int nIn;
|
||||||
|
int i, j, n;
|
||||||
|
u32 v;
|
||||||
|
|
||||||
|
assert( argc==1 );
|
||||||
|
zIn = (const char*)sqlite3_value_text(argv[0]);
|
||||||
|
if( zIn==0 ) return;
|
||||||
|
nIn = sqlite3_value_bytes(argv[0]);
|
||||||
|
zOut = sqlite3_malloc64(nIn+1);
|
||||||
|
if( zOut==0 ){
|
||||||
|
sqlite3_result_error_nomem(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = j = 0;
|
||||||
|
while( i<nIn ){
|
||||||
|
char *z = strchr(&zIn[i],'\\');
|
||||||
|
if( z==0 ){
|
||||||
|
n = nIn - i;
|
||||||
|
memmove(&zOut[j], &zIn[i], n);
|
||||||
|
j += n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = z - &zIn[i];
|
||||||
|
if( n>0 ){
|
||||||
|
memmove(&zOut[j], &zIn[i], n);
|
||||||
|
j += n;
|
||||||
|
i += n;
|
||||||
|
}
|
||||||
|
if( zIn[i+1]=='\\' ){
|
||||||
|
i += 2;
|
||||||
|
zOut[j++] = '\\';
|
||||||
|
}else if( sqlite3Isxdigit(zIn[i+1]) ){
|
||||||
|
if( !isNHex(&zIn[i+1], 4, &v) ) goto unistr_error;
|
||||||
|
i += 5;
|
||||||
|
j += appendOneUtf8Char(&zOut[j], v);
|
||||||
|
}else if( zIn[i+1]=='+' ){
|
||||||
|
if( !isNHex(&zIn[i+2], 6, &v) ) goto unistr_error;
|
||||||
|
i += 8;
|
||||||
|
j += appendOneUtf8Char(&zOut[j], v);
|
||||||
|
}else if( zIn[i+1]=='u' ){
|
||||||
|
if( !isNHex(&zIn[i+2], 4, &v) ) goto unistr_error;
|
||||||
|
i += 6;
|
||||||
|
j += appendOneUtf8Char(&zOut[j], v);
|
||||||
|
}else if( zIn[i+1]=='U' ){
|
||||||
|
if( !isNHex(&zIn[i+2], 8, &v) ) goto unistr_error;
|
||||||
|
i += 10;
|
||||||
|
j += appendOneUtf8Char(&zOut[j], v);
|
||||||
|
}else{
|
||||||
|
goto unistr_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zOut[j] = 0;
|
||||||
|
sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8);
|
||||||
|
return;
|
||||||
|
|
||||||
|
unistr_error:
|
||||||
|
sqlite3_free(zOut);
|
||||||
|
sqlite3_result_error(context, "invalid Unicode escape", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Implementation of the QUOTE() function.
|
** Implementation of the QUOTE() function.
|
||||||
**
|
**
|
||||||
@ -2736,6 +2862,7 @@ void sqlite3RegisterBuiltinFunctions(void){
|
|||||||
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
||||||
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
|
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
|
||||||
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
||||||
|
FUNCTION(unistr, 1, 0, 0, unistrFunc ),
|
||||||
FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
||||||
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
||||||
VFUNCTION(changes, 0, 0, 0, changes ),
|
VFUNCTION(changes, 0, 0, 0, changes ),
|
||||||
|
Reference in New Issue
Block a user