1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

- Add new Json UDF's Json_Array_Add, Json_Array_Grp and Json_Object_Grp.

Handle longjmp's raised during json processing.
modified:
  storage/connect/global.h
  storage/connect/ha_connect.cc
  storage/connect/json.cpp
  storage/connect/jsonudf.cpp

- Fix wrong references to the suppressed g->Trace variables.
modified:
  storage/connect/global.h
  storage/connect/plugutil.c
  storage/connect/tabjson.cpp
  storage/connect/tabodbc.cpp
This commit is contained in:
Olivier Bertrand
2015-02-22 17:53:02 +01:00
parent d9175f3822
commit a736e63f7c
8 changed files with 131 additions and 23 deletions

View File

@@ -8,12 +8,18 @@
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
#include <mysqld.h>
#include <mysql.h>
#include <sql_error.h>
#include "global.h"
#include "plgdbsem.h"
#include "json.h"
#define MEMFIX 512
uint GetJsonGrpSize(void);
extern "C" {
DllExport my_bool Json_Value_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *Json_Value(UDF_INIT*, UDF_ARGS*, char*,
@@ -23,6 +29,10 @@ DllExport my_bool Json_Array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *Json_Array(UDF_INIT*, UDF_ARGS*, char*,
unsigned long*, char *, char *);
DllExport void Json_Array_deinit(UDF_INIT*);
DllExport my_bool Json_Array_Add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *Json_Array_Add(UDF_INIT*, UDF_ARGS*, char*,
unsigned long*, char *, char *);
DllExport void Json_Array_Add_deinit(UDF_INIT*);
DllExport my_bool Json_Object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *Json_Object(UDF_INIT*, UDF_ARGS*, char*,
unsigned long*, char *, char *);
@@ -44,8 +54,8 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*);
/***********************************************************************/
/* Allocate and initialise the memory area. */
/***********************************************************************/
static my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long reslen,
unsigned long memlen)
static my_bool JsonInit(UDF_INIT *initid, char *message,
unsigned long reslen, unsigned long memlen)
{
PGLOBAL g = PlugInit(NULL, memlen);
@@ -119,7 +129,7 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
} // endfor i
// Calculate the amount of memory needed
memlen = 1024 + sizeof(JOUTSTR) + reslen;
memlen = MEMFIX + sizeof(JOUTSTR) + reslen;
for (i = 0; i < args->arg_count; i++) {
memlen += (args->lengths[i] + sizeof(JVALUE));
@@ -219,14 +229,23 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
{
char *sap = args->args[i];
PJSON jsp;
PJVAL jvp = new(g) JVALUE;
if (sap) switch (args->arg_type[i]) {
case STRING_RESULT:
if (args->lengths[i]) {
if (IsJson(args, i))
jvp->SetValue(ParseJson(g, sap, args->lengths[i], 0));
else
if (IsJson(args, i)) {
if (!(jsp = ParseJson(g, sap, args->lengths[i], 0)))
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
g->Message);
if (jsp && jsp->GetType() == TYPE_JVAL)
jvp = (PJVAL)jsp;
else
jvp->SetValue(jsp);
} else
jvp->SetString(g, MakePSZ(g, args, i));
} // endif str
@@ -328,6 +347,59 @@ void Json_Array_deinit(UDF_INIT* initid)
PlugExit((PGLOBAL)initid->ptr);
} // end of Json_Array_deinit
/***********************************************************************/
/* Add values to a Json array. */
/***********************************************************************/
my_bool Json_Array_Add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
if (args->arg_count < 2) {
strcpy(message, "Json_Value_Add must have at least 2 arguments");
return true;
} else if (!IsJson(args, 0)) {
strcpy(message, "Json_Value_Add first argument must be a json array");
return true;
} else
CalcLen(args, false, reslen, memlen);
return JsonInit(initid, message, reslen, memlen);
} // end of Json_Array_Add_init
char *Json_Array_Add(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *str;
PJVAL jvp;
PJAR arp;
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
jvp = MakeValue(g, args, 0);
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g) JARRAY;
arp->AddValue(g, jvp);
} else
arp = jvp->GetArray();
for (uint i = 1; i < args->arg_count; i++)
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
if (!(str = Serialize(g, arp, NULL, 0)))
str = strcpy(result, g->Message);
*res_length = strlen(str);
return str;
} // end of Json_Array_Add
void Json_Array_Add_deinit(UDF_INIT* initid)
{
PlugExit((PGLOBAL)initid->ptr);
} // end of Json_Array_Add_deinit
/***********************************************************************/
/* Make a Json Oject containing all the parameters. */
/***********************************************************************/
@@ -370,7 +442,7 @@ void Json_Object_deinit(UDF_INIT* initid)
/***********************************************************************/
my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, n = 10;
unsigned long reslen, memlen, n = GetJsonGrpSize();
if (args->arg_count != 1) {
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)
CalcLen(args, false, reslen, memlen);
reslen *= n;
memlen *= n;
memlen += ((memlen - MEMFIX) * (n - 1));
if (JsonInit(initid, message, reslen, memlen))
return true;
@@ -388,6 +460,7 @@ my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)new(g) JARRAY;
g->N = (int)n;
return false;
} // end of Json_Array_Grp_init
@@ -397,7 +470,9 @@ void Json_Array_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
PGLOBAL g = (PGLOBAL)initid->ptr;
PJAR arp = (PJAR)g->Activityp;
arp->AddValue(g, MakeValue(g, args, 0));
if (g->N-- > 0)
arp->AddValue(g, MakeValue(g, args, 0));
} // end of Json_Array_Grp_add
char *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,
PGLOBAL g = (PGLOBAL)initid->ptr;
PJAR arp = (PJAR)g->Activityp;
if (g->N < 0)
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Result truncated to json_grp_size values");
arp->InitArray(g);
if (!(str = Serialize(g, arp, NULL, 0)))
@@ -422,6 +501,7 @@ void Json_Array_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)new(g) JARRAY;
g->N = GetJsonGrpSize();
} // end of Json_Array_Grp_clear
void Json_Array_Grp_deinit(UDF_INIT* initid)
@@ -434,7 +514,7 @@ void Json_Array_Grp_deinit(UDF_INIT* initid)
/***********************************************************************/
my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, n = 10;
unsigned long reslen, memlen, n = GetJsonGrpSize();
if (args->arg_count != 2) {
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)
CalcLen(args, true, reslen, memlen);
reslen *= n;
memlen *= n;
memlen += ((memlen - MEMFIX) * (n - 1));
if (JsonInit(initid, message, reslen, memlen))
return true;
@@ -452,6 +532,7 @@ my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)new(g) JOBJECT;
g->N = (int)n;
return false;
} // end of Json_Object_Grp_init
@@ -461,7 +542,9 @@ void Json_Object_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
PGLOBAL g = (PGLOBAL)initid->ptr;
PJOB objp = (PJOB)g->Activityp;
objp->SetValue(g, MakeValue(g, args, 0), MakePSZ(g, args, 1));
if (g->N-- > 0)
objp->SetValue(g, MakeValue(g, args, 0), MakePSZ(g, args, 1));
} // end of Json_Object_Grp_add
char *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,
PGLOBAL g = (PGLOBAL)initid->ptr;
PJOB objp = (PJOB)g->Activityp;
if (g->N < 0)
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Result truncated to json_grp_size values");
if (!(str = Serialize(g, objp, NULL, 0)))
str = strcpy(result, g->Message);
@@ -484,6 +571,7 @@ void Json_Object_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)new(g) JOBJECT;
g->N = GetJsonGrpSize();
} // end of Json_Object_Grp_clear
void Json_Object_Grp_deinit(UDF_INIT* initid)