4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 ******************************************************************************
13 ** This SQLite extension implements SQL function eval() which runs
14 ** SQL statements recursively.
16 #include "sqlite3ext.h"
17 SQLITE_EXTENSION_INIT1
21 ** Structure used to accumulate the output
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 */
32 ** Callback from sqlite_exec() for the eval() function.
34 static int callback(void *pCtx
, int argc
, char **argv
, char **colnames
){
35 struct EvalResult
*p
= (struct EvalResult
*)pCtx
;
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
){
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
47 zNew
= p
->nAlloc
<=0x7fffffff ? sqlite3_realloc64(p
->z
, p
->nAlloc
) : 0;
50 memset(p
, 0, sizeof(*p
));
56 memcpy(&p
->z
[p
->nUsed
], p
->zSep
, p
->szSep
);
59 memcpy(&p
->z
[p
->nUsed
], z
, sz
);
66 ** Implementation of the eval(X) and eval(X,Y) SQL functions.
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.
71 static void sqlEvalFunc(
72 sqlite3_context
*context
,
82 memset(&x
, 0, sizeof(x
));
84 zSql
= (const char*)sqlite3_value_text(argv
[0]);
87 x
.zSep
= (const char*)sqlite3_value_text(argv
[1]);
88 if( x
.zSep
==0 ) return;
90 x
.szSep
= (int)strlen(x
.zSep
);
91 db
= sqlite3_context_db_handle(context
);
92 rc
= sqlite3_exec(db
, zSql
, callback
, &x
, &zErr
);
94 sqlite3_result_error(context
, zErr
, -1);
96 }else if( x
.zSep
==0 ){
97 sqlite3_result_error_nomem(context
);
100 sqlite3_result_text(context
, x
.z
, (int)x
.nUsed
, sqlite3_free
);
106 __declspec(dllexport
)
108 int sqlite3_eval_init(
111 const sqlite3_api_routines
*pApi
114 SQLITE_EXTENSION_INIT2(pApi
);
115 (void)pzErrMsg
; /* Unused parameter */
116 rc
= sqlite3_create_function(db
, "eval", 1,
117 SQLITE_UTF8
|SQLITE_DIRECTONLY
, 0,
120 rc
= sqlite3_create_function(db
, "eval", 2,
121 SQLITE_UTF8
|SQLITE_DIRECTONLY
, 0,