mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01: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:
parent
2201aa66cf
commit
564d41faf4
4 changed files with 1247 additions and 1105 deletions
|
@ -469,9 +469,12 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
|
|||
|
||||
} while (rc == RC_NF);
|
||||
|
||||
if (rc == RC_OK)
|
||||
rc= EvalColumns(g, tdbp, false);
|
||||
|
||||
err:
|
||||
g->jump_level--;
|
||||
return (rc != RC_OK) ? rc : EvalColumns(g, tdbp, false);
|
||||
return rc;
|
||||
} // end of CntReadNext
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -825,7 +825,9 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
|
|||
PJSON nwr, row = Tjp->Row;
|
||||
|
||||
for (int i = 0; i < Nod-1 && row; i++) {
|
||||
switch (row->GetType()) {
|
||||
if (Nodes[i+1].Op == OP_XX)
|
||||
break;
|
||||
else switch (row->GetType()) {
|
||||
case TYPE_JOB:
|
||||
if (!Nodes[i].Key)
|
||||
// Expected Array was not there
|
||||
|
@ -932,7 +934,11 @@ void JSONCOL::WriteColumn(PGLOBAL g)
|
|||
jsp = ParseJson(g, s, (int)strlen(s), 0);
|
||||
|
||||
if (arp) {
|
||||
arp->AddValue(g, new(g) JVALUE(jsp));
|
||||
if (Nod > 1 && Nodes[Nod-2].Rank)
|
||||
arp->SetValue(g, new(g) JVALUE(jsp), Nodes[Nod-2].Rank-1);
|
||||
else
|
||||
arp->AddValue(g, new(g) JVALUE(jsp));
|
||||
|
||||
arp->InitArray(g);
|
||||
} else if (objp) {
|
||||
if (Nod > 1 && Nodes[Nod-2].Key)
|
||||
|
|
Loading…
Reference in a new issue