88/* Include relevant sections of the MariaDB header file. */
99/* **********************************************************************/
1010#include < my_global.h>
11+ #include < mysqld.h>
1112#include < mysql.h>
13+ #include < sql_error.h>
1214
1315#include " global.h"
1416#include " plgdbsem.h"
1517#include " json.h"
1618
19+ #define MEMFIX 512
20+
21+ uint GetJsonGrpSize (void );
22+
1723extern " C" {
1824DllExport my_bool Json_Value_init (UDF_INIT*, UDF_ARGS*, char *);
1925DllExport char *Json_Value (UDF_INIT*, UDF_ARGS*, char *,
@@ -23,6 +29,10 @@ DllExport my_bool Json_Array_init(UDF_INIT*, UDF_ARGS*, char*);
2329DllExport char *Json_Array (UDF_INIT*, UDF_ARGS*, char *,
2430 unsigned long *, char *, char *);
2531DllExport void Json_Array_deinit (UDF_INIT*);
32+ DllExport my_bool Json_Array_Add_init (UDF_INIT*, UDF_ARGS*, char *);
33+ DllExport char *Json_Array_Add (UDF_INIT*, UDF_ARGS*, char *,
34+ unsigned long *, char *, char *);
35+ DllExport void Json_Array_Add_deinit (UDF_INIT*);
2636DllExport my_bool Json_Object_init (UDF_INIT*, UDF_ARGS*, char *);
2737DllExport char *Json_Object (UDF_INIT*, UDF_ARGS*, char *,
2838 unsigned long *, char *, char *);
@@ -44,8 +54,8 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*);
4454/* **********************************************************************/
4555/* Allocate and initialise the memory area. */
4656/* **********************************************************************/
47- static my_bool JsonInit (UDF_INIT *initid, char *message, unsigned long reslen,
48- unsigned long memlen)
57+ static my_bool JsonInit (UDF_INIT *initid, char *message,
58+ unsigned long reslen, unsigned long memlen)
4959{
5060 PGLOBAL g = PlugInit (NULL , memlen);
5161
@@ -119,7 +129,7 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
119129 } // endfor i
120130
121131 // Calculate the amount of memory needed
122- memlen = 1024 + sizeof (JOUTSTR) + reslen;
132+ memlen = MEMFIX + sizeof (JOUTSTR) + reslen;
123133
124134 for (i = 0 ; i < args->arg_count ; i++) {
125135 memlen += (args->lengths [i] + sizeof (JVALUE));
@@ -219,14 +229,23 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
219229static PJVAL MakeValue (PGLOBAL g, UDF_ARGS *args, int i)
220230{
221231 char *sap = args->args [i];
232+ PJSON jsp;
222233 PJVAL jvp = new (g) JVALUE;
223234
224235 if (sap) switch (args->arg_type [i]) {
225236 case STRING_RESULT:
226237 if (args->lengths [i]) {
227- if (IsJson (args, i))
228- jvp->SetValue (ParseJson (g, sap, args->lengths [i], 0 ));
229- else
238+ if (IsJson (args, i)) {
239+ if (!(jsp = ParseJson (g, sap, args->lengths [i], 0 )))
240+ push_warning (current_thd, Sql_condition::WARN_LEVEL_WARN, 0 ,
241+ g->Message );
242+
243+ if (jsp && jsp->GetType () == TYPE_JVAL)
244+ jvp = (PJVAL)jsp;
245+ else
246+ jvp->SetValue (jsp);
247+
248+ } else
230249 jvp->SetString (g, MakePSZ (g, args, i));
231250
232251 } // endif str
@@ -328,6 +347,59 @@ void Json_Array_deinit(UDF_INIT* initid)
328347 PlugExit ((PGLOBAL)initid->ptr );
329348} // end of Json_Array_deinit
330349
350+ /* **********************************************************************/
351+ /* Add values to a Json array. */
352+ /* **********************************************************************/
353+ my_bool Json_Array_Add_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
354+ {
355+ unsigned long reslen, memlen;
356+
357+ if (args->arg_count < 2 ) {
358+ strcpy (message, " Json_Value_Add must have at least 2 arguments" );
359+ return true ;
360+ } else if (!IsJson (args, 0 )) {
361+ strcpy (message, " Json_Value_Add first argument must be a json array" );
362+ return true ;
363+ } else
364+ CalcLen (args, false , reslen, memlen);
365+
366+ return JsonInit (initid, message, reslen, memlen);
367+ } // end of Json_Array_Add_init
368+
369+ char *Json_Array_Add (UDF_INIT *initid, UDF_ARGS *args, char *result,
370+ unsigned long *res_length, char *is_null, char *error)
371+ {
372+ char *str;
373+ PJVAL jvp;
374+ PJAR arp;
375+ PGLOBAL g = (PGLOBAL)initid->ptr ;
376+
377+ PlugSubSet (g, g->Sarea , g->Sarea_Size );
378+ jvp = MakeValue (g, args, 0 );
379+
380+ if (jvp->GetValType () != TYPE_JAR) {
381+ arp = new (g) JARRAY;
382+ arp->AddValue (g, jvp);
383+ } else
384+ arp = jvp->GetArray ();
385+
386+ for (uint i = 1 ; i < args->arg_count ; i++)
387+ arp->AddValue (g, MakeValue (g, args, i));
388+
389+ arp->InitArray (g);
390+
391+ if (!(str = Serialize (g, arp, NULL , 0 )))
392+ str = strcpy (result, g->Message );
393+
394+ *res_length = strlen (str);
395+ return str;
396+ } // end of Json_Array_Add
397+
398+ void Json_Array_Add_deinit (UDF_INIT* initid)
399+ {
400+ PlugExit ((PGLOBAL)initid->ptr );
401+ } // end of Json_Array_Add_deinit
402+
331403/* **********************************************************************/
332404/* Make a Json Oject containing all the parameters. */
333405/* **********************************************************************/
@@ -370,7 +442,7 @@ void Json_Object_deinit(UDF_INIT* initid)
370442/* **********************************************************************/
371443my_bool Json_Array_Grp_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
372444{
373- unsigned long reslen, memlen, n = 10 ;
445+ unsigned long reslen, memlen, n = GetJsonGrpSize () ;
374446
375447 if (args->arg_count != 1 ) {
376448 strcpy (message, " Json_Array_Grp can only accept 1 argument" );
@@ -379,7 +451,7 @@ my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
379451 CalcLen (args, false , reslen, memlen);
380452
381453 reslen *= n;
382- memlen *= n ;
454+ memlen += ((memlen - MEMFIX) * (n - 1 )) ;
383455
384456 if (JsonInit (initid, message, reslen, memlen))
385457 return true ;
@@ -388,6 +460,7 @@ my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
388460
389461 PlugSubSet (g, g->Sarea , g->Sarea_Size );
390462 g->Activityp = (PACTIVITY)new (g) JARRAY;
463+ g->N = (int )n;
391464 return false ;
392465} // end of Json_Array_Grp_init
393466
@@ -397,7 +470,9 @@ void Json_Array_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
397470 PGLOBAL g = (PGLOBAL)initid->ptr ;
398471 PJAR arp = (PJAR)g->Activityp ;
399472
400- arp->AddValue (g, MakeValue (g, args, 0 ));
473+ if (g->N -- > 0 )
474+ arp->AddValue (g, MakeValue (g, args, 0 ));
475+
401476} // end of Json_Array_Grp_add
402477
403478char *Json_Array_Grp (UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -407,6 +482,10 @@ char *Json_Array_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
407482 PGLOBAL g = (PGLOBAL)initid->ptr ;
408483 PJAR arp = (PJAR)g->Activityp ;
409484
485+ if (g->N < 0 )
486+ push_warning (current_thd, Sql_condition::WARN_LEVEL_WARN, 0 ,
487+ " Result truncated to json_grp_size values" );
488+
410489 arp->InitArray (g);
411490
412491 if (!(str = Serialize (g, arp, NULL , 0 )))
@@ -422,6 +501,7 @@ void Json_Array_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
422501
423502 PlugSubSet (g, g->Sarea , g->Sarea_Size );
424503 g->Activityp = (PACTIVITY)new (g) JARRAY;
504+ g->N = GetJsonGrpSize ();
425505} // end of Json_Array_Grp_clear
426506
427507void Json_Array_Grp_deinit (UDF_INIT* initid)
@@ -434,7 +514,7 @@ void Json_Array_Grp_deinit(UDF_INIT* initid)
434514/* **********************************************************************/
435515my_bool Json_Object_Grp_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
436516{
437- unsigned long reslen, memlen, n = 10 ;
517+ unsigned long reslen, memlen, n = GetJsonGrpSize () ;
438518
439519 if (args->arg_count != 2 ) {
440520 strcpy (message, " Json_Array_Grp can only accept 2 argument" );
@@ -443,7 +523,7 @@ my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
443523 CalcLen (args, true , reslen, memlen);
444524
445525 reslen *= n;
446- memlen *= n ;
526+ memlen += ((memlen - MEMFIX) * (n - 1 )) ;
447527
448528 if (JsonInit (initid, message, reslen, memlen))
449529 return true ;
@@ -452,6 +532,7 @@ my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
452532
453533 PlugSubSet (g, g->Sarea , g->Sarea_Size );
454534 g->Activityp = (PACTIVITY)new (g) JOBJECT;
535+ g->N = (int )n;
455536 return false ;
456537} // end of Json_Object_Grp_init
457538
@@ -461,7 +542,9 @@ void Json_Object_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
461542 PGLOBAL g = (PGLOBAL)initid->ptr ;
462543 PJOB objp = (PJOB)g->Activityp ;
463544
464- objp->SetValue (g, MakeValue (g, args, 0 ), MakePSZ (g, args, 1 ));
545+ if (g->N -- > 0 )
546+ objp->SetValue (g, MakeValue (g, args, 0 ), MakePSZ (g, args, 1 ));
547+
465548} // end of Json_Object_Grp_add
466549
467550char *Json_Object_Grp (UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -471,6 +554,10 @@ char *Json_Object_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
471554 PGLOBAL g = (PGLOBAL)initid->ptr ;
472555 PJOB objp = (PJOB)g->Activityp ;
473556
557+ if (g->N < 0 )
558+ push_warning (current_thd, Sql_condition::WARN_LEVEL_WARN, 0 ,
559+ " Result truncated to json_grp_size values" );
560+
474561 if (!(str = Serialize (g, objp, NULL , 0 )))
475562 str = strcpy (result, g->Message );
476563
@@ -484,6 +571,7 @@ void Json_Object_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
484571
485572 PlugSubSet (g, g->Sarea , g->Sarea_Size );
486573 g->Activityp = (PACTIVITY)new (g) JOBJECT;
574+ g->N = GetJsonGrpSize ();
487575} // end of Json_Object_Grp_clear
488576
489577void Json_Object_Grp_deinit (UDF_INIT* initid)
0 commit comments