summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsqlite
diff options
context:
space:
mode:
authornw141292 <none@none>2007-12-14 20:15:38 -0800
committernw141292 <none@none>2007-12-14 20:15:38 -0800
commitcd37da7426f0c49c14ad9a8a07638ca971477566 (patch)
tree8570a6628a8ddd8ed6ff11ce762aca4e249011f5 /usr/src/lib/libsqlite
parent7d26da518f2e612fda66008e66633403b87cdb8f (diff)
downloadillumos-joyent-cd37da7426f0c49c14ad9a8a07638ca971477566.tar.gz
PSARC/2007/616 Winchester update for diagonal ID mapping
6587015 wildcard rules should have better case-sensitivity options 6587455 case-insensitive Windows user/group name matching is crucial 6607916 "diagonal" mapping needed (mapping windows users to GIDs and groups to UIDs) 6630586 idmap panic: process termintated by SIGSEGV 6635629 libc's lint library needs to know about u8_textprep functions 6637550 idmap crashes after auto-discovery fails
Diffstat (limited to 'usr/src/lib/libsqlite')
-rw-r--r--usr/src/lib/libsqlite/src/func.c149
1 files changed, 127 insertions, 22 deletions
diff --git a/usr/src/lib/libsqlite/src/func.c b/usr/src/lib/libsqlite/src/func.c
index 6c3915f7a8..2b9a31a690 100644
--- a/usr/src/lib/libsqlite/src/func.c
+++ b/usr/src/lib/libsqlite/src/func.c
@@ -24,6 +24,7 @@
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
+#include <sys/u8_textprep.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
@@ -181,6 +182,108 @@ static void lowerFunc(sqlite_func *context, int argc, const char **argv){
}
/*
+ * A utility wrapper around u8_textprep_str() that returns an allocated
+ * string. The result must be freed or passed to
+ * sqlite_set_result_string().
+ *
+ * This is a Solaris-specific function, though it could be made
+ * portable. u8_textprep_str() and friends are CDDL'ed. This code was
+ * added to this file without changing the public domain notice, and
+ * therefore is in the public domain as well.
+ */
+static
+char *
+utf8textprep(const char *s, int flag)
+{
+ char *res = NULL;
+ char *outs;
+ size_t inlen, outlen, inbytesleft, outbytesleft;
+ int rc, err;
+
+ /*
+ * u8_textprep_str() does not allocate memory. The input and
+ * output buffers may differ in size (though that would be more
+ * likely when normalization is done). We have to loop over it...
+ *
+ * To improve the chances that we can avoid looping we add 10
+ * bytes of output buffer room the first go around.
+ */
+ inlen = inbytesleft = strlen(s);
+ outlen = outbytesleft = inlen + 10;
+ if ((res = sqliteMalloc(outlen)) == NULL)
+ return (NULL);
+ outs = res;
+
+ while ((rc = u8_textprep_str((char *)s, &inbytesleft, outs,
+ &outbytesleft, flag, U8_UNICODE_LATEST, &err)) < 0 &&
+ err == E2BIG) {
+ if ((res = sqliteRealloc(res, outlen + inbytesleft)) == NULL)
+ return (NULL);
+ /* adjust input/output buffer pointers */
+ s += (inlen - inbytesleft);
+ outs = res + outlen - outbytesleft;
+ /* adjust outbytesleft and outlen */
+ outlen += inbytesleft;
+ outbytesleft += inbytesleft;
+ }
+
+ if (rc < 0) {
+ free(res);
+ res = NULL;
+ return (NULL);
+ }
+
+ res[outlen - outbytesleft] = '\0';
+
+ return (res);
+}
+/*
+ * A Unicode-capable case-folding (to lower) function
+ *
+ * See block comment for case_fold_utf8().
+ */
+static
+void
+lower_utf8Func(sqlite_func *context, int argc, const char **argv)
+{
+ char *lower = NULL;
+
+ /*
+ * SQLite functions can take many arguments, but this function
+ * uses only one, and we call sqlite_create_function() with
+ * nArg == 1.
+ */
+ assert(argc <= 1);
+
+ if (argv[0] != NULL)
+ lower = utf8textprep(argv[0], U8_TEXTPREP_TOLOWER);
+
+out:
+ (void) sqlite_set_result_string(context, lower, -1);
+ free(lower);
+}
+static
+void
+upper_utf8Func(sqlite_func *context, int argc, const char **argv)
+{
+ char *upper = NULL;
+
+ /*
+ * SQLite functions can take many arguments, but this function
+ * uses only one, and we call sqlite_create_function() with
+ * nArg == 1.
+ */
+ assert(argc <= 1);
+
+ if (argv[0] != NULL)
+ upper = utf8textprep(argv[0], U8_TEXTPREP_TOUPPER);
+
+out:
+ (void) sqlite_set_result_string(context, upper, -1);
+ free(upper);
+}
+
+/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
** All three do the same thing. They return the first non-NULL
** argument.
@@ -571,28 +674,30 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
u8 argType; /* 0: none. 1: db 2: (-1) */
void (*xFunc)(sqlite_func*,int,const char**);
} aFuncs[] = {
- { "min", -1, SQLITE_ARGS, 0, minmaxFunc },
- { "min", 0, 0, 0, 0 },
- { "max", -1, SQLITE_ARGS, 2, minmaxFunc },
- { "max", 0, 0, 2, 0 },
- { "typeof", 1, SQLITE_TEXT, 0, typeofFunc },
- { "length", 1, SQLITE_NUMERIC, 0, lengthFunc },
- { "substr", 3, SQLITE_TEXT, 0, substrFunc },
- { "abs", 1, SQLITE_NUMERIC, 0, absFunc },
- { "round", 1, SQLITE_NUMERIC, 0, roundFunc },
- { "round", 2, SQLITE_NUMERIC, 0, roundFunc },
- { "upper", 1, SQLITE_TEXT, 0, upperFunc },
- { "lower", 1, SQLITE_TEXT, 0, lowerFunc },
- { "coalesce", -1, SQLITE_ARGS, 0, ifnullFunc },
- { "coalesce", 0, 0, 0, 0 },
- { "coalesce", 1, 0, 0, 0 },
- { "ifnull", 2, SQLITE_ARGS, 0, ifnullFunc },
- { "random", -1, SQLITE_NUMERIC, 0, randomFunc },
- { "like", 2, SQLITE_NUMERIC, 0, likeFunc },
- { "glob", 2, SQLITE_NUMERIC, 0, globFunc },
- { "nullif", 2, SQLITE_ARGS, 0, nullifFunc },
- { "sqlite_version",0,SQLITE_TEXT, 0, versionFunc},
- { "quote", 1, SQLITE_ARGS, 0, quoteFunc },
+ { "min", -1, SQLITE_ARGS, 0, minmaxFunc },
+ { "min", 0, 0, 0, 0 },
+ { "max", -1, SQLITE_ARGS, 2, minmaxFunc },
+ { "max", 0, 0, 2, 0 },
+ { "typeof", 1, SQLITE_TEXT, 0, typeofFunc },
+ { "length", 1, SQLITE_NUMERIC, 0, lengthFunc },
+ { "substr", 3, SQLITE_TEXT, 0, substrFunc },
+ { "abs", 1, SQLITE_NUMERIC, 0, absFunc },
+ { "round", 1, SQLITE_NUMERIC, 0, roundFunc },
+ { "round", 2, SQLITE_NUMERIC, 0, roundFunc },
+ { "upper", 1, SQLITE_TEXT, 0, upperFunc },
+ { "lower", 1, SQLITE_TEXT, 0, lowerFunc },
+ { "lower_utf8", 1, SQLITE_TEXT, 0, lower_utf8Func },
+ { "upper_utf8", 1, SQLITE_TEXT, 0, upper_utf8Func },
+ { "coalesce", -1, SQLITE_ARGS, 0, ifnullFunc },
+ { "coalesce", 0, 0, 0, 0 },
+ { "coalesce", 1, 0, 0, 0 },
+ { "ifnull", 2, SQLITE_ARGS, 0, ifnullFunc },
+ { "random", -1, SQLITE_NUMERIC, 0, randomFunc },
+ { "like", 2, SQLITE_NUMERIC, 0, likeFunc },
+ { "glob", 2, SQLITE_NUMERIC, 0, globFunc },
+ { "nullif", 2, SQLITE_ARGS, 0, nullifFunc },
+ { "sqlite_version",0,SQLITE_TEXT, 0, versionFunc },
+ { "quote", 1, SQLITE_ARGS, 0, quoteFunc },
{ "last_insert_rowid", 0, SQLITE_NUMERIC, 1, last_insert_rowid },
{ "change_count", 0, SQLITE_NUMERIC, 1, change_count },
{ "last_statement_change_count",