~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
1
#ifndef DRIZZLED
2
//#define SUPPORT_PBMS_TRIGGERS
3
#ifdef SUPPORT_PBMS_TRIGGERS
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
5
 *
6
 * PrimeBase Media Stream for MySQL
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
21
 *
22
 * Barry Leslie
23
 *
24
 * 2008-09-11
25
 *
26
 * H&G2JCtL
27
 *
28
 * User Defined Functions for use in triggers for non PBMS enabled engines.
29
 *
30
 */
31
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
32
#include "cslib/CSConfig.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
33
34
#include <stdlib.h>
35
#include <stdio.h>
36
#include <string.h>
37
38
//#include "mysql_priv.h"
39
40
#include <mysql.h>
41
#include <ctype.h>
42
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
43
#include "cslib/CSGlobal.h"
44
#include "cslib/CSStrUtil.h"
45
#include "cslib/CSThread.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
46
1548.2.10 by Barry.Leslie at PrimeBase
Merge from trunk.
47
#include "engine_ms.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
48
49
#ifdef MOVE_THIS_TO_ITS_OWN_FILE
50
bool pbms_enabled(const char *name)
51
{
52
	bool found = false;
53
	PBMSSharedMemoryPtr	sh_mem = StreamingEngines->sharedMemory;
54
	PBMSEnginePtr		engine;
55
	
56
	if (sh_mem) {
57
		for (int i = 0; i<sh_mem->sm_list_len && !found; i++) {
58
			if (engine = sh_mem->sm_engine_list[i]) {
59
				found = (strcasecmp(name, engine->ms_engine_name) == 0);
60
			}
61
		}
62
	}
63
	
64
	return found;
65
}
66
67
// =============================
68
#define PBMS_ENGINE_NAME_LEN 64 // This should be big enough.
69
bool pbms_engine_is_enabled(char *name, size_t len)
70
{
71
	bool found = false;
72
73
	if (len < PBMS_ENGINE_NAME_LEN) {
74
		char engine_name[PBMS_ENGINE_NAME_LEN];
75
		memcpy(engine_name, name, len);
76
		engine_name[len] = 0;
77
		
78
		found = pbms_enabled(engine_name);	
79
	}
80
	
81
	return found;
82
}
83
84
// =============================
85
static bool trig_open_table(void **open_table, char *table_path, PBMSResultPtr result)
86
{	
87
	return do_open_table(open_table, table_path, result);
88
}
89
90
char *pbms_trig_use_blob(const char *database, size_t db_len, const char *table, size_t tab_len, unsigned short col_position, char *url, size_t url_len, char *out_url, PBMSResultPtr result)
91
{
92
	void *open_table = NULL;
93
	int rtc;
94
	char blob_url[PBMS_BLOB_URL_SIZE], *ret_blob_url;
95
	char table_path[PATH_MAX];
96
	
97
	if (url_len >= PBMS_BLOB_URL_SIZE) {
98
		pbms_error_result(CS_CONTEXT, MS_ERR_INCORRECT_URL, "Incorrect URL", result);
99
		return NULL; 
100
	}
101
	
102
	if (pbms_table_path(database, db_len, table, tab_len,  table_path, result) || trig_open_table(&open_table, table_path, result))
103
		return NULL;
104
	
105
	memcpy(blob_url, url, url_len);
106
	blob_url[url_len] = 0;
107
	
108
	// Internally col_position are '0' based for consistency with the internal PBXT calls to PBMS.
109
	if (!(rtc = ms_use_blob(open_table, &ret_blob_url, blob_url, col_position -1, result))) {		
110
		if (!(rtc = ms_retain_blobs(open_table,  result)))
111
			cs_strcpy(PBMS_BLOB_URL_SIZE, out_url, ret_blob_url);
112
	}
113
	
114
	ms_close_table(open_table);
115
	
116
	if (rtc)
117
		return NULL;
118
	
119
	return out_url;	
120
}
121
122
// =============================
123
char *pbms_use_blob(const char *database, const char *table, unsigned short col_position, char *url, size_t url_len, char *out_url, PBMSResultPtr result)
124
{
125
	return pbms_trig_use_blob(database, strlen(database), table, strlen(table), col_position, url, url_len, out_url, result);
126
}
127
128
// =============================
129
int pbms_trig_release_blob(const char *database, size_t db_len, const char *table, size_t tab_len, unsigned short col_position, const char *url, size_t url_len, PBMSResultPtr result)
130
{
131
	void *open_table = NULL;
132
	int rtc;
133
	char blob_url[PBMS_BLOB_URL_SIZE];
134
	char table_path[PATH_MAX];
135
	
136
	if (url_len >= PBMS_BLOB_URL_SIZE)
137
		return 0; // url is too long to be a valid blob url.
138
139
	if (pbms_table_path(database, db_len, table, tab_len,  table_path, result) || trig_open_table(&open_table, table_path, result))
140
		return 1;
141
	
142
	memcpy(blob_url, url, url_len);
143
	blob_url[url_len] = 0;
144
	
145
	rtc = ms_release_blob(open_table, blob_url, result);
146
	
147
	ms_close_table(open_table);
148
	
149
	return rtc;	
150
}
151
152
// =============================
153
int pbms_release_blob(const char *database, const char *table, unsigned short col_position, const char *url, size_t url_len, PBMSResultPtr result)
154
{
155
	return pbms_trig_release_blob(database, strlen(database), table, strlen(table), col_position, url, url_len, result);
156
}
157
158
// =============================
159
int pbms_new_blob(const char *database, const char *table, unsigned short col_position, unsigned char *blob, size_t blob_len, char *out_url, PBMSResultPtr result)
160
{
161
	void *open_table = NULL;
162
	char table_path[PATH_MAX];
163
	int rtc;
164
	
165
	if (pbms_table_path(database, strlen(database), table,  strlen(table),  table_path, result) || trig_open_table(&open_table, table_path, result))
166
		return 1;
167
		
168
	rtc =  ms_create_blob(open_table, blob, blob_len, out_url, col_position -1,  result);
169
		
170
	ms_close_table(open_table);
171
	
172
	return rtc;	
173
}
174
175
// =============================
176
int pbms_trig_drop_table(const char *database, size_t db_len, const char *table, size_t tab_len, PBMSResultPtr result)
177
{
178
	char table_path[PATH_MAX];
179
	
180
	if (pbms_table_path(database, db_len, table, tab_len,  table_path, result))
181
		return 1;
182
	
183
	return ms_drop_table(table_path, result);
184
}
185
186
// =============================
187
int pbms_drop_table(const char *database, const char *table, PBMSResultPtr result)
188
{
189
	return pbms_trig_drop_table(database, strlen(database), table, strlen(table), result);
190
}
191
192
// =============================
193
int pbms_trig_rename_table(const char *database, size_t db_len, const char *o_table, size_t o_tab_len, const char *n_table, size_t n_tab_len, PBMSResultPtr result)
194
{
195
	char o_table_path[PATH_MAX], n_table_path[PATH_MAX];
196
	
197
	if (pbms_table_path(database, db_len, o_table, o_tab_len,  o_table_path, result) || pbms_table_path(database, db_len, n_table, n_tab_len,  n_table_path, result) )
198
		return 1;
199
	
200
	return ms_rename_table(o_table_path, n_table_path, result);
201
}
202
203
// =============================
204
int pbms_rename_table(const char *database, const char *o_table,  const char *n_table, PBMSResultPtr result)
205
{
206
	return pbms_trig_rename_table(database, strlen(database), o_table, strlen(o_table), n_table, strlen(n_table), result);
207
}
208
209
#endif MOVE_THIS_TO_ITS_OWN_FILE
210
211
extern "C" {
212
my_bool pbms_insert_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
213
char *pbms_insert_blob_trig(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error);
214
void pbms_insert_blob_trig_deinit(UDF_INIT *initid);
215
216
//-----------
217
my_bool pbms_update_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
218
char *pbms_update_blob_trig(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error);
219
void pbms_update_blob_trig_deinit(UDF_INIT *initid);
220
221
//-----------
222
my_bool pbms_delete_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
223
longlong pbms_delete_blob_trig(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
224
225
//-----------
226
my_bool pbms_delete_all_blobs_in_table_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
227
longlong pbms_delete_all_blobs_in_table(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
228
229
//-----------
230
my_bool pbms_rename_table_with_blobs_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
231
longlong pbms_rename_table_with_blobs(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
232
233
//-----------
234
my_bool pbms_enabled_engine_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
235
longlong pbms_enabled_engine(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
236
}
237
238
static void report_udf_error(UDF_INIT *initid __attribute__((unused)), char *error, const char *func, const char *message)
239
{
240
	*error = 1;
241
	
242
	// I wish there were a way to pass the error text up to the caller but I do not know if/how it can be done.
243
	// So for now just send it to stderr.
244
	fprintf(stderr, "PBMS UDF Error (%s): %s\n", func,  message);
245
}
246
247
static char *local_reference_blob(UDF_INIT *initid, char *database, size_t db_len, char *table, size_t tab_len, unsigned short col_position, char *url, size_t url_len, char *result, char *error, const char *func)
248
{
249
	char *out_url = NULL, blob_url[PBMS_BLOB_URL_SIZE];
250
	PBMSResultRec pbmsResult = {0};
251
	
252
	out_url = pbms_trig_use_blob(database, db_len, table, tab_len, col_position, url, url_len, blob_url, &pbmsResult); 
253
254
	if (out_url) {
255
		size_t url_len = strlen(out_url) +1;
256
		if (url_len < 255) {
257
			cs_strcpy(255, result,  out_url);
258
			out_url = result;
259
		} else {
260
			initid->ptr = (char*) malloc(url_len);
261
			if (initid->ptr) {
262
				cs_strcpy(url_len, initid->ptr,  out_url);
263
				out_url = initid->ptr;
264
			} else {
265
				report_udf_error(initid, error, func, "Couldn't allocate memory");
266
				out_url = NULL;
267
			}
268
		}
269
	} else if  (pbmsResult.mr_code == MS_ERR_INCORRECT_URL) 
270
		out_url = url; // Not a URL so just return it so that it is inserted as is.
271
	else 
272
		report_udf_error(initid, error, func, pbmsResult.mr_message);
273
	
274
	
275
	return out_url;
276
}
277
278
//======================================================================
279
// CREATE FUNCTION pbms_insert_blob_trig RETURNS STRING SONAME "libpbms.so";
280
// pbms_insert_blob_trig(database, table, col_position, blob_url);
281
my_bool pbms_insert_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
282
{
283
	if (args->arg_count != 4 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || args->arg_type[2] != INT_RESULT || args->arg_type[3] != STRING_RESULT)
284
	{
285
		strcpy(message,"Wrong arguments to pbms_insert_blob_trig()");
286
		return 1;
287
	}
288
	args->maybe_null[0] = 0;
289
	args->maybe_null[1] = 0;
290
	args->maybe_null[2] = 0;
291
	args->maybe_null[3] = 1;
292
293
	initid->max_length=PBMS_BLOB_URL_SIZE;
294
	initid->maybe_null=1;
295
	initid->ptr=NULL;
296
	return 0;
297
}
298
299
void pbms_insert_blob_trig_deinit(UDF_INIT *initid)
300
{
301
	if (initid->ptr)
302
		free(initid->ptr);
303
}
304
305
#define INT_ARG(a)  (*((longlong*) a))
306
307
char *pbms_insert_blob_trig(UDF_INIT *initid, UDF_ARGS *args,
308
                    char *result, unsigned long *res_length, char *is_null,
309
                    char *error)
310
{
311
	char *out_url;
312
	
313
	*is_null=1;
314
	
315
	// The first parameter is the table name which should never be NULL or an empty string.
316
	if (!args->args[0] || !args->lengths[0] || !args->args[1] || !args->lengths[1]) {
317
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
318
		return NULL;
319
	}
320
321
	if (!args->args[3] || !args->lengths[3]) {
322
		return NULL;
323
	}
324
	
325
	out_url = local_reference_blob(initid, args->args[0], args->lengths[0], args->args[1], args->lengths[1], INT_ARG(args->args[2]), args->args[3], args->lengths[3], result, error, __FUNC__); 	
326
	if (!out_url) 
327
		return NULL;
328
329
	*is_null=0;
330
	*res_length = strlen(out_url);
331
	return out_url;	
332
}
333
334
//======================================================================
335
// CREATE FUNCTION pbms_update_blob_trig RETURNS STRING SONAME "libpbms.so";
336
// pbms_update_blob_trig(database, table, col_position, old_blob_url, new_blob_url);
337
my_bool pbms_update_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
338
{
339
	if (args->arg_count != 5 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || args->arg_type[2] != INT_RESULT || args->arg_type[3] != STRING_RESULT || args->arg_type[4] != STRING_RESULT)
340
	{
341
		strcpy(message,"Wrong arguments to pbms_update_blob_trig()");
342
		return 1;
343
	}
344
	args->maybe_null[0] = 0;
345
	args->maybe_null[1] = 0;
346
	args->maybe_null[2] = 0;
347
	args->maybe_null[3] = 1;
348
	args->maybe_null[4] = 1;
349
	
350
	initid->maybe_null=1;
351
	initid->ptr=NULL;
352
	return 0;
353
}
354
355
void pbms_update_blob_trig_deinit(UDF_INIT *initid)
356
{
357
	if (initid->ptr)
358
		free(initid->ptr);
359
}
360
361
char *pbms_update_blob_trig(UDF_INIT *initid, UDF_ARGS *args,
362
                    char *result, unsigned long *res_length, char *is_null,
363
                    char *error)
364
{
365
	char *out_url = NULL;
366
	
367
	
368
	// The first parameter is the table name which should never be NULL or an empty string.
369
	if (!args->args[0] || !args->lengths[0] || !args->args[1] || !args->lengths[1]) {
370
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
371
		return NULL;
372
	}
373
	
374
	// Check to see if the blob url changed
375
	if (args->lengths[2] == args->lengths[3] && !memcmp(args->args[2], args->args[3], args->lengths[3])) {
376
		if (args->lengths[2]) {
377
			*is_null=0;
378
			*res_length = args->lengths[2];
379
			return args->args[2];
380
		}
381
		
382
		*is_null=1;
383
		return NULL;
384
	}
385
	
386
	
387
	if (args->lengths[4] && args->args[4]) { // Reference the new blob.
388
		out_url = local_reference_blob(initid, args->args[0], args->lengths[0], args->args[1], args->lengths[1], INT_ARG(args->args[2]), args->args[4], args->lengths[4], result, error, __FUNC__); 
389
		if (!out_url) 
390
			return 0;
391
	}
392
	
393
	if (args->lengths[3] && args->args[3]) { // Dereference the old blob
394
		PBMSResultRec pbmsResult = {0};
395
		if (pbms_trig_release_blob(args->args[0], args->lengths[0], args->args[1], args->lengths[1], INT_ARG(args->args[2]), args->args[3], args->lengths[3], &pbmsResult)) {
396
			report_udf_error(initid, error,  __FUNC__, pbmsResult.mr_message);
397
			if (out_url)
398
				pbms_trig_release_blob(args->args[0], args->lengths[0], args->args[1], args->lengths[1], INT_ARG(args->args[2]), out_url, strlen(out_url), &pbmsResult);
399
			return NULL;
400
		} 
401
	}
402
	
403
	if (out_url) {
404
		*is_null=0;
405
		*res_length = strlen(out_url);
406
	}
407
	
408
	return out_url;	
409
}
410
411
//======================================================================
412
// CREATE FUNCTION pbms_delete_blob_trig RETURNS INT SONAME "libpbms.so";
413
// pbms_delete_blob_trig(database, table, col_position, blob_url);
414
my_bool pbms_delete_blob_trig_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
415
{
416
	if (args->arg_count != 4 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || args->arg_type[2] != INT_RESULT || args->arg_type[3] != STRING_RESULT)
417
	{
418
		strcpy(message,"Wrong arguments to pbms_delete_blob_trig()");
419
		return 1;
420
	}
421
	args->maybe_null[0] = 0;
422
	args->maybe_null[1] = 0;
423
	args->maybe_null[2] = 0;
424
	args->maybe_null[3] = 1;	
425
	initid->maybe_null=0;
426
	
427
	return 0;
428
}
429
430
longlong pbms_delete_blob_trig(UDF_INIT *initid, UDF_ARGS *args, char *is_null __attribute__((unused)), char *error)
431
{
432
	PBMSResultRec pbmsResult = {0};
433
	
434
	// The first parameter is the table name which should never be NULL or an empty string.
435
	if (!args->args[0] || !args->lengths[0] || !args->args[1] || !args->lengths[1]) {
436
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
437
		return 1;
438
	}
439
	
440
	if (!args->args[3] || !args->lengths[3]) {
441
		return 0; //Dropping a NULL blob.
442
	}
443
	
444
	if (! pbms_trig_release_blob(args->args[0], args->lengths[0], args->args[1], args->lengths[1], INT_ARG(args->args[2]), args->args[3], args->lengths[3], &pbmsResult))
445
		return  0;
446
	
447
	report_udf_error(initid, error,  __FUNC__, pbmsResult.mr_message);
448
	return 1;
449
}
450
451
452
//======================================================================
453
// CREATE FUNCTION pbms_delete_all_blobs_in_table RETURNS INT SONAME "libpbms.so";
454
// pbms_delete_all_blobs_in_table(database, table);
455
my_bool pbms_delete_all_blobs_in_table_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
456
{
457
	if (args->arg_count != 2 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT)
458
	{
459
		strcpy(message,"Wrong arguments to pbms_delete_all_blobs_in_table()");
460
		return 1;
461
	}
462
	args->maybe_null[0] = 0;
463
	args->maybe_null[1] = 0;
464
	initid->maybe_null=0;
465
	
466
	return 0;
467
}
468
469
longlong pbms_delete_all_blobs_in_table(UDF_INIT *initid, UDF_ARGS *args, char *is_null __attribute__((unused)), char *error)
470
{
471
	PBMSResultRec pbmsResult = {0};
472
	
473
	// The first parameter is the table name which should never be NULL or an empty string.
474
	if (args->arg_count != 2 || !args->args[0] || !args->lengths[0] || !args->args[1] || !args->lengths[1]) {
475
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
476
		return 1;
477
	}
478
	
479
	if (!pbms_trig_drop_table(args->args[0], args->lengths[0], args->args[1], args->lengths[1], &pbmsResult)) 
480
		return 0;
481
	
482
	report_udf_error(initid, error,  __FUNC__, pbmsResult.mr_message);
483
	return 1;
484
}
485
486
//======================================================================
487
// CREATE FUNCTION pbms_rename_table_with_blobs RETURNS INT SONAME "libpbms.so";
488
// pbms_rename_table_with_blobs(database, old_table, new_table);
489
my_bool pbms_rename_table_with_blobs_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
490
{
491
	if (args->arg_count != 3 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || args->arg_type[2] != STRING_RESULT)
492
	{
493
		strcpy(message,"Wrong arguments to pbms_rename_table_with_blobs()");
494
		return 1;
495
	}
496
	args->maybe_null[0] = 0;
497
	args->maybe_null[1] = 0;
498
	args->maybe_null[2] = 0;
499
	initid->maybe_null=0;
500
	
501
	return 0;
502
}
503
504
longlong pbms_rename_table_with_blobs(UDF_INIT *initid, UDF_ARGS *args, char *is_null __attribute__((unused)), char *error)
505
{
506
	PBMSResultRec pbmsResult = {0};
507
	
508
	// The first parameter is the table name which should never be NULL or an empty string.
509
	if (args->arg_count != 3 || !args->args[0] || !args->lengths[0] || !args->args[1] || !args->lengths[1] || !args->args[2] || !args->lengths[2]) {
510
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
511
		return 1;
512
	}
513
	
514
	if (!pbms_trig_rename_table(args->args[0], args->lengths[0], args->args[1], args->lengths[1], args->args[2], args->lengths[2], &pbmsResult)) 
515
		return 0;
516
	
517
	report_udf_error(initid, error,  __FUNC__, pbmsResult.mr_message);
518
	return 1;
519
}
520
521
//======================================================================
522
// CREATE FUNCTION pbms_enabled_engine RETURNS INT SONAME "libpbms.so";
523
// pbms_enabled_engine(database, table);
524
my_bool pbms_enabled_engine_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
525
{
526
	if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT)
527
	{
528
		strcpy(message,"Wrong arguments to pbms_enabled_engine()");
529
		return 1;
530
	}
531
	args->maybe_null[0] = 0;
532
	initid->maybe_null=0;
533
	
534
	return 0;
535
}
536
537
longlong pbms_enabled_engine(UDF_INIT *initid, UDF_ARGS *args, char *is_null __attribute__((unused)), char *error)
538
{
539
	// The first parameter is the engine name which should never be NULL or an empty string.
540
	if (args->arg_count != 1 || !args->args[0] || !args->lengths[0]) {
541
		report_udf_error(initid, error, __FUNC__, "Bad arguments");
542
		return -1;
543
	}
544
	
545
	return pbms_engine_is_enabled(args->args[0], args->lengths[0]);
546
}
547
548
#endif // SUPPORT_PBMS_TRIGGERS
549
#endif // DRIZZLED