mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Work on JSON and JSON UDF's
modified: storage/connect/json.cpp storage/connect/jsonudf.cpp storage/connect/tabjson.cpp - CntReadNext: Enable EvalColumns for longjmp modified: storage/connect/connect.cc
This commit is contained in:
@@ -44,9 +44,10 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*);
|
||||
/***********************************************************************/
|
||||
/* Allocate and initialise the memory area. */
|
||||
/***********************************************************************/
|
||||
my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long len)
|
||||
my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long reslen,
|
||||
unsigned long memlen)
|
||||
{
|
||||
PGLOBAL g = PlugInit(NULL, len);
|
||||
PGLOBAL g = PlugInit(NULL, memlen);
|
||||
|
||||
if (!g) {
|
||||
strcpy(message, "Allocation error");
|
||||
@@ -59,7 +60,7 @@ my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long len)
|
||||
initid->ptr = (char*)g;
|
||||
|
||||
initid->maybe_null = false;
|
||||
initid->max_length = len - 512;
|
||||
initid->max_length = reslen;
|
||||
return false;
|
||||
} // end of Json_Object_init
|
||||
|
||||
@@ -72,6 +73,92 @@ static my_bool IsJson(UDF_ARGS *args, int i)
|
||||
!strnicmp(args->attributes[i], "Json_", 5));
|
||||
} // end of IsJson
|
||||
|
||||
/***********************************************************************/
|
||||
/* Calculate the reslen and memlen needed by a function. */
|
||||
/***********************************************************************/
|
||||
static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
|
||||
unsigned long& reslen, unsigned long& memlen)
|
||||
{
|
||||
unsigned long i, k;
|
||||
reslen = args->arg_count + 2;
|
||||
|
||||
// Calculate the result max length
|
||||
for (i = 0; i < args->arg_count; i++) {
|
||||
if (obj) {
|
||||
if (!(k = args->attribute_lengths[i]))
|
||||
k = strlen(args->attributes[i]);
|
||||
|
||||
reslen += (k + 3); // For quotes and :
|
||||
} // endif obj
|
||||
|
||||
switch (args->arg_type[i]) {
|
||||
case STRING_RESULT:
|
||||
if (IsJson(args, i))
|
||||
reslen += args->lengths[i];
|
||||
else
|
||||
reslen += (args->lengths[i] + 1) * 2; // Pessimistic !
|
||||
|
||||
break;
|
||||
case INT_RESULT:
|
||||
reslen += 20;
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
reslen += 31;
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
reslen += (args->lengths[i] + 7); // 6 decimals
|
||||
break;
|
||||
case TIME_RESULT:
|
||||
case ROW_RESULT:
|
||||
case IMPOSSIBLE_RESULT:
|
||||
default:
|
||||
// What should we do here ?
|
||||
break;
|
||||
} // endswitch arg_type
|
||||
|
||||
} // endfor i
|
||||
|
||||
// Calculate the amount of memory needed
|
||||
memlen = 1024 + sizeof(JOUTSTR) + reslen;
|
||||
|
||||
for (i = 0; i < args->arg_count; i++) {
|
||||
memlen += (args->lengths[i] + sizeof(JVALUE));
|
||||
|
||||
if (obj) {
|
||||
if (!(k = args->attribute_lengths[i]))
|
||||
k = strlen(args->attributes[i]);
|
||||
|
||||
memlen += (k + sizeof(JOBJECT) + sizeof(JPAIR));
|
||||
} else
|
||||
memlen += sizeof(JARRAY);
|
||||
|
||||
switch (args->arg_type[i]) {
|
||||
case STRING_RESULT:
|
||||
if (IsJson(args, i))
|
||||
memlen += args->lengths[i] * 5; // Estimate parse memory
|
||||
|
||||
memlen += sizeof(TYPVAL<PSZ>);
|
||||
break;
|
||||
case INT_RESULT:
|
||||
memlen += sizeof(TYPVAL<int>);
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
case DECIMAL_RESULT:
|
||||
memlen += sizeof(TYPVAL<double>);
|
||||
break;
|
||||
case TIME_RESULT:
|
||||
case ROW_RESULT:
|
||||
case IMPOSSIBLE_RESULT:
|
||||
default:
|
||||
// What should we do here ?
|
||||
break;
|
||||
} // endswitch arg_type
|
||||
|
||||
} // endfor i
|
||||
|
||||
return false;
|
||||
} // end of CalcLen
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make a zero terminated string from the passed argument. */
|
||||
/***********************************************************************/
|
||||
@@ -131,25 +218,25 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
|
||||
/***********************************************************************/
|
||||
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
|
||||
{
|
||||
char *str;
|
||||
char *sap = args->args[i];
|
||||
PJVAL jvp = new(g) JVALUE;
|
||||
|
||||
switch (args->arg_type[i]) {
|
||||
if (sap) switch (args->arg_type[i]) {
|
||||
case STRING_RESULT:
|
||||
if ((str = MakePSZ(g, args, i))) {
|
||||
if (args->lengths[i]) {
|
||||
if (IsJson(args, i))
|
||||
jvp->SetValue(ParseJson(g, str, strlen(str), 0));
|
||||
jvp->SetValue(ParseJson(g, sap, args->lengths[i], 0));
|
||||
else
|
||||
jvp->SetString(g, str);
|
||||
jvp->SetString(g, MakePSZ(g, args, i));
|
||||
|
||||
} // endif str
|
||||
|
||||
break;
|
||||
case INT_RESULT:
|
||||
jvp->SetInteger(g, *(int*)args->args[i]);
|
||||
jvp->SetInteger(g, *(int*)sap);
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
jvp->SetFloat(g, *(double*)args->args[i]);
|
||||
jvp->SetFloat(g, *(double*)sap);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
jvp->SetFloat(g, atof(MakePSZ(g, args, i)));
|
||||
@@ -169,12 +256,15 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
|
||||
/***********************************************************************/
|
||||
my_bool Json_Value_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
unsigned long reslen, memlen;
|
||||
|
||||
if (args->arg_count > 1) {
|
||||
strcpy(message, "Json_Value cannot accept more than 1 argument");
|
||||
return true;
|
||||
} // endif arg_count
|
||||
} else
|
||||
CalcLen(args, false, reslen, memlen);
|
||||
|
||||
return JsonInit(initid, message, 1024);
|
||||
return JsonInit(initid, message, reslen, memlen);
|
||||
} // end of Json_Value_init
|
||||
|
||||
char *Json_Value(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||
@@ -204,7 +294,10 @@ void Json_Value_deinit(UDF_INIT* initid)
|
||||
/***********************************************************************/
|
||||
my_bool Json_Array_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
return JsonInit(initid, message, 8192);
|
||||
unsigned long reslen, memlen;
|
||||
|
||||
CalcLen(args, false, reslen, memlen);
|
||||
return JsonInit(initid, message, reslen, memlen);
|
||||
} // end of Json_Array_init
|
||||
|
||||
char *Json_Array(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||
@@ -240,11 +333,14 @@ void Json_Array_deinit(UDF_INIT* initid)
|
||||
/***********************************************************************/
|
||||
my_bool Json_Object_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
return JsonInit(initid, message, 8192);
|
||||
unsigned long reslen, memlen;
|
||||
|
||||
CalcLen(args, true, reslen, memlen);
|
||||
return JsonInit(initid, message, reslen, memlen);
|
||||
} // end of Json_Object_init
|
||||
|
||||
char *Json_Object(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||
unsigned long *res_length, char *is_null, char *error)
|
||||
unsigned long *res_length, char *is_null, char *error)
|
||||
{
|
||||
char *str;
|
||||
uint i;
|
||||
@@ -274,10 +370,18 @@ 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;
|
||||
|
||||
if (args->arg_count != 1) {
|
||||
strcpy(message, "Json_Array_Grp can only accept 1 argument");
|
||||
return true;
|
||||
} else if (JsonInit(initid, message, 16384))
|
||||
} else
|
||||
CalcLen(args, false, reslen, memlen);
|
||||
|
||||
reslen *= n;
|
||||
memlen *= n;
|
||||
|
||||
if (JsonInit(initid, message, reslen, memlen))
|
||||
return true;
|
||||
|
||||
PGLOBAL g = (PGLOBAL)initid->ptr;
|
||||
@@ -330,10 +434,18 @@ 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;
|
||||
|
||||
if (args->arg_count != 2) {
|
||||
strcpy(message, "Json_Array_Grp can only accept 2 argument");
|
||||
return true;
|
||||
} else if (JsonInit(initid, message, 16384))
|
||||
} else
|
||||
CalcLen(args, true, reslen, memlen);
|
||||
|
||||
reslen *= n;
|
||||
memlen *= n;
|
||||
|
||||
if (JsonInit(initid, message, reslen, memlen))
|
||||
return true;
|
||||
|
||||
PGLOBAL g = (PGLOBAL)initid->ptr;
|
||||
|
Reference in New Issue
Block a user