aboutsummaryrefslogtreecommitdiff
path: root/ext/misc
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-01-01 13:25:06 +0000
committerdrh <drh@noemail.net>2016-01-01 13:25:06 +0000
commit8de1d77c60af1fbac5cc7eb7eb84efa3e43a320b (patch)
treeb2968afbe57bd3f1d1305f5a2241f575cca3b909 /ext/misc
parent173b60999eb7b2fda450df311e286539fcd2b854 (diff)
parenta660caf2f01c99ef48085c731e200b5a2fa575b5 (diff)
downloadsqlite-8de1d77c60af1fbac5cc7eb7eb84efa3e43a320b.tar.gz
sqlite-8de1d77c60af1fbac5cc7eb7eb84efa3e43a320b.zip
Merge the latest enhancements from trunk.
FossilOrigin-Name: c0be246a740c8f33a7c07e1414688364dee56ece
Diffstat (limited to 'ext/misc')
-rw-r--r--ext/misc/json1.c112
-rw-r--r--ext/misc/spellfix.c10
2 files changed, 120 insertions, 2 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c
index 61d013ea4..370751666 100644
--- a/ext/misc/json1.c
+++ b/ext/misc/json1.c
@@ -1181,7 +1181,7 @@ static void jsonTest1Func(
#endif /* SQLITE_DEBUG */
/****************************************************************************
-** SQL function implementations
+** Scalar SQL function implementations
****************************************************************************/
/*
@@ -1514,6 +1514,102 @@ static void jsonValidFunc(
sqlite3_result_int(ctx, rc);
}
+
+/****************************************************************************
+** Aggregate SQL function implementations
+****************************************************************************/
+/*
+** json_group_array(VALUE)
+**
+** Return a JSON array composed of all values in the aggregate.
+*/
+static void jsonArrayStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '[');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ jsonAppendValue(pStr, argv[0]);
+ }
+}
+static void jsonArrayFinal(sqlite3_context *ctx){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ pStr->pCtx = ctx;
+ jsonAppendChar(pStr, ']');
+ if( pStr->bErr ){
+ sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }
+ }else{
+ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+/*
+** json_group_obj(NAME,VALUE)
+**
+** Return a JSON object composed of all names and values in the aggregate.
+*/
+static void jsonObjectStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ const char *z;
+ u32 n;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '{');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ z = (const char*)sqlite3_value_text(argv[0]);
+ n = (u32)sqlite3_value_bytes(argv[0]);
+ jsonAppendString(pStr, z, n);
+ jsonAppendChar(pStr, ':');
+ jsonAppendValue(pStr, argv[1]);
+ }
+}
+static void jsonObjectFinal(sqlite3_context *ctx){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ jsonAppendChar(pStr, '}');
+ if( pStr->bErr ){
+ sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }
+ }else{
+ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
/****************************************************************************
** The json_each virtual table
@@ -2012,6 +2108,15 @@ int sqlite3Json1Init(sqlite3 *db){
{ "json_test1", 1, 0, jsonTest1Func },
#endif
};
+ static const struct {
+ const char *zName;
+ int nArg;
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+ void (*xFinal)(sqlite3_context*);
+ } aAgg[] = {
+ { "json_group_array", 1, jsonArrayStep, jsonArrayFinal },
+ { "json_group_object", 2, jsonObjectStep, jsonObjectFinal },
+ };
#ifndef SQLITE_OMIT_VIRTUALTABLE
static const struct {
const char *zName;
@@ -2027,6 +2132,11 @@ int sqlite3Json1Init(sqlite3 *db){
(void*)&aFunc[i].flag,
aFunc[i].xFunc, 0, 0);
}
+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+ 0, aAgg[i].xStep, aAgg[i].xFinal);
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c
index 0515b7bc6..c0da6b339 100644
--- a/ext/misc/spellfix.c
+++ b/ext/misc/spellfix.c
@@ -1717,17 +1717,23 @@ static void scriptCodeSqlFunc(
# define SCRIPT_LATIN 0x0001
# define SCRIPT_CYRILLIC 0x0002
# define SCRIPT_GREEK 0x0004
+# define SCRIPT_HEBREW 0x0008
+# define SCRIPT_ARABIC 0x0010
while( nIn>0 ){
c = utf8Read(zIn, nIn, &sz);
zIn += sz;
nIn -= sz;
- if( c<0x02af ){
+ if( c<0x02af && (c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT) ){
scriptMask |= SCRIPT_LATIN;
}else if( c>=0x0400 && c<=0x04ff ){
scriptMask |= SCRIPT_CYRILLIC;
}else if( c>=0x0386 && c<=0x03ce ){
scriptMask |= SCRIPT_GREEK;
+ }else if( c>=0x0590 && c<=0x05ff ){
+ scriptMask |= SCRIPT_HEBREW;
+ }else if( c>=0x0600 && c<=0x06ff ){
+ scriptMask |= SCRIPT_ARABIC;
}
}
switch( scriptMask ){
@@ -1735,6 +1741,8 @@ static void scriptCodeSqlFunc(
case SCRIPT_LATIN: res = 215; break;
case SCRIPT_CYRILLIC: res = 220; break;
case SCRIPT_GREEK: res = 200; break;
+ case SCRIPT_HEBREW: res = 125; break;
+ case SCRIPT_ARABIC: res = 160; break;
default: res = 998; break;
}
sqlite3_result_int(context, res);