1 /* 2 ** 2014-11-10 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ****************************************************************************** 12 ** 13 ** This SQLite extension implements SQL function eval() which runs 14 ** SQL statements recursively. 15 */ 16 #include "sqlite3ext.h" 17 SQLITE_EXTENSION_INIT1 18 #include <string.h> 19 20 /* 21 ** Structure used to accumulate the output 22 */ 23 struct EvalResult { 24 char *z; /* Accumulated output */ 25 const char *zSep; /* Separator */ 26 int szSep; /* Size of the separator string */ 27 sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */ 28 sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */ 29 }; 30 31 /* 32 ** Callback from sqlite_exec() for the eval() function. 33 */ 34 static int callback(void *pCtx, int argc, char **argv, char **colnames){ 35 struct EvalResult *p = (struct EvalResult*)pCtx; 36 int i; 37 if( argv==0 ) return 0; 38 for(i=0; i<argc; i++){ 39 const char *z = argv[i] ? argv[i] : ""; 40 size_t sz = strlen(z); 41 if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){ 42 char *zNew; 43 p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1; 44 /* Using sqlite3_realloc64() would be better, but it is a recent 45 ** addition and will cause a segfault if loaded by an older version 46 ** of SQLite. */ 47 zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc64(p->z, p->nAlloc) : 0; 48 if( zNew==0 ){ 49 sqlite3_free(p->z); 50 memset(p, 0, sizeof(*p)); 51 return 1; 52 } 53 p->z = zNew; 54 } 55 if( p->nUsed>0 ){ 56 memcpy(&p->z[p->nUsed], p->zSep, p->szSep); 57 p->nUsed += p->szSep; 58 } 59 memcpy(&p->z[p->nUsed], z, sz); 60 p->nUsed += sz; 61 } 62 return 0; 63 } 64 65 /* 66 ** Implementation of the eval(X) and eval(X,Y) SQL functions. 67 ** 68 ** Evaluate the SQL text in X. Return the results, using string 69 ** Y as the separator. If Y is omitted, use a single space character. 70 */ 71 static void sqlEvalFunc( 72 sqlite3_context *context, 73 int argc, 74 sqlite3_value **argv 75 ){ 76 const char *zSql; 77 sqlite3 *db; 78 char *zErr = 0; 79 int rc; 80 struct EvalResult x; 81 82 memset(&x, 0, sizeof(x)); 83 x.zSep = " "; 84 zSql = (const char*)sqlite3_value_text(argv[0]); 85 if( zSql==0 ) return; 86 if( argc>1 ){ 87 x.zSep = (const char*)sqlite3_value_text(argv[1]); 88 if( x.zSep==0 ) return; 89 } 90 x.szSep = (int)strlen(x.zSep); 91 db = sqlite3_context_db_handle(context); 92 rc = sqlite3_exec(db, zSql, callback, &x, &zErr); 93 if( rc!=SQLITE_OK ){ 94 sqlite3_result_error(context, zErr, -1); 95 sqlite3_free(zErr); 96 }else if( x.zSep==0 ){ 97 sqlite3_result_error_nomem(context); 98 sqlite3_free(x.z); 99 }else{ 100 sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free); 101 } 102 } 103 104 105 #ifdef _WIN32 106 __declspec(dllexport) 107 #endif 108 int sqlite3_eval_init( 109 sqlite3 *db, 110 char **pzErrMsg, 111 const sqlite3_api_routines *pApi 112 ){ 113 int rc = SQLITE_OK; 114 SQLITE_EXTENSION_INIT2(pApi); 115 (void)pzErrMsg; /* Unused parameter */ 116 rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, 117 sqlEvalFunc, 0, 0); 118 if( rc==SQLITE_OK ){ 119 rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, 120 sqlEvalFunc, 0, 0); 121 } 122 return rc; 123 } 124