Index: third_party/sqlite/sqlite-src-3170000/ext/misc/eval.c |
diff --git a/third_party/sqlite/sqlite-src-3170000/ext/misc/eval.c b/third_party/sqlite/sqlite-src-3170000/ext/misc/eval.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..71b6b69f20a732d2bd0653a734f91dc8a5eaa64e |
--- /dev/null |
+++ b/third_party/sqlite/sqlite-src-3170000/ext/misc/eval.c |
@@ -0,0 +1,122 @@ |
+/* |
+** 2014-11-10 |
+** |
+** The author disclaims copyright to this source code. In place of |
+** a legal notice, here is a blessing: |
+** |
+** May you do good and not evil. |
+** May you find forgiveness for yourself and forgive others. |
+** May you share freely, never taking more than you give. |
+** |
+****************************************************************************** |
+** |
+** This SQLite extension implements SQL function eval() which runs |
+** SQL statements recursively. |
+*/ |
+#include "sqlite3ext.h" |
+SQLITE_EXTENSION_INIT1 |
+#include <string.h> |
+ |
+/* |
+** Structure used to accumulate the output |
+*/ |
+struct EvalResult { |
+ char *z; /* Accumulated output */ |
+ const char *zSep; /* Separator */ |
+ int szSep; /* Size of the separator string */ |
+ sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */ |
+ sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */ |
+}; |
+ |
+/* |
+** Callback from sqlite_exec() for the eval() function. |
+*/ |
+static int callback(void *pCtx, int argc, char **argv, char **colnames){ |
+ struct EvalResult *p = (struct EvalResult*)pCtx; |
+ int i; |
+ for(i=0; i<argc; i++){ |
+ const char *z = argv[i] ? argv[i] : ""; |
+ size_t sz = strlen(z); |
+ if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){ |
+ char *zNew; |
+ p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1; |
+ /* Using sqlite3_realloc64() would be better, but it is a recent |
+ ** addition and will cause a segfault if loaded by an older version |
+ ** of SQLite. */ |
+ zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0; |
+ if( zNew==0 ){ |
+ sqlite3_free(p->z); |
+ memset(p, 0, sizeof(*p)); |
+ return 1; |
+ } |
+ p->z = zNew; |
+ } |
+ if( p->nUsed>0 ){ |
+ memcpy(&p->z[p->nUsed], p->zSep, p->szSep); |
+ p->nUsed += p->szSep; |
+ } |
+ memcpy(&p->z[p->nUsed], z, sz); |
+ p->nUsed += sz; |
+ } |
+ return 0; |
+} |
+ |
+/* |
+** Implementation of the eval(X) and eval(X,Y) SQL functions. |
+** |
+** Evaluate the SQL text in X. Return the results, using string |
+** Y as the separator. If Y is omitted, use a single space character. |
+*/ |
+static void sqlEvalFunc( |
+ sqlite3_context *context, |
+ int argc, |
+ sqlite3_value **argv |
+){ |
+ const char *zSql; |
+ sqlite3 *db; |
+ char *zErr = 0; |
+ int rc; |
+ struct EvalResult x; |
+ |
+ memset(&x, 0, sizeof(x)); |
+ x.zSep = " "; |
+ zSql = (const char*)sqlite3_value_text(argv[0]); |
+ if( zSql==0 ) return; |
+ if( argc>1 ){ |
+ x.zSep = (const char*)sqlite3_value_text(argv[1]); |
+ if( x.zSep==0 ) return; |
+ } |
+ x.szSep = (int)strlen(x.zSep); |
+ db = sqlite3_context_db_handle(context); |
+ rc = sqlite3_exec(db, zSql, callback, &x, &zErr); |
+ if( rc!=SQLITE_OK ){ |
+ sqlite3_result_error(context, zErr, -1); |
+ sqlite3_free(zErr); |
+ }else if( x.zSep==0 ){ |
+ sqlite3_result_error_nomem(context); |
+ sqlite3_free(x.z); |
+ }else{ |
+ sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free); |
+ } |
+} |
+ |
+ |
+#ifdef _WIN32 |
+__declspec(dllexport) |
+#endif |
+int sqlite3_eval_init( |
+ sqlite3 *db, |
+ char **pzErrMsg, |
+ const sqlite3_api_routines *pApi |
+){ |
+ int rc = SQLITE_OK; |
+ SQLITE_EXTENSION_INIT2(pApi); |
+ (void)pzErrMsg; /* Unused parameter */ |
+ rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, |
+ sqlEvalFunc, 0, 0); |
+ if( rc==SQLITE_OK ){ |
+ rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, |
+ sqlEvalFunc, 0, 0); |
+ } |
+ return rc; |
+} |