Commit 564d41fa authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent 2201aa66
...@@ -469,9 +469,12 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) ...@@ -469,9 +469,12 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
} while (rc == RC_NF); } while (rc == RC_NF);
if (rc == RC_OK)
rc= EvalColumns(g, tdbp, false);
err: err:
g->jump_level--; g->jump_level--;
return (rc != RC_OK) ? rc : EvalColumns(g, tdbp, false); return rc;
} // end of CntReadNext } // end of CntReadNext
/***********************************************************************/ /***********************************************************************/
......
This diff is collapsed.
...@@ -44,9 +44,10 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*); ...@@ -44,9 +44,10 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*);
/***********************************************************************/ /***********************************************************************/
/* Allocate and initialise the memory area. */ /* 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) { if (!g) {
strcpy(message, "Allocation error"); strcpy(message, "Allocation error");
...@@ -59,7 +60,7 @@ my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long len) ...@@ -59,7 +60,7 @@ my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long len)
initid->ptr = (char*)g; initid->ptr = (char*)g;
initid->maybe_null = false; initid->maybe_null = false;
initid->max_length = len - 512; initid->max_length = reslen;
return false; return false;
} // end of Json_Object_init } // end of Json_Object_init
...@@ -72,6 +73,92 @@ static my_bool IsJson(UDF_ARGS *args, int i) ...@@ -72,6 +73,92 @@ static my_bool IsJson(UDF_ARGS *args, int i)
!strnicmp(args->attributes[i], "Json_", 5)); !strnicmp(args->attributes[i], "Json_", 5));
} // end of IsJson } // 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. */ /* Make a zero terminated string from the passed argument. */
/***********************************************************************/ /***********************************************************************/
...@@ -131,25 +218,25 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i) ...@@ -131,25 +218,25 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
/***********************************************************************/ /***********************************************************************/
static PJVAL MakeValue(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; PJVAL jvp = new(g) JVALUE;
switch (args->arg_type[i]) { if (sap) switch (args->arg_type[i]) {
case STRING_RESULT: case STRING_RESULT:
if ((str = MakePSZ(g, args, i))) { if (args->lengths[i]) {
if (IsJson(args, i)) if (IsJson(args, i))
jvp->SetValue(ParseJson(g, str, strlen(str), 0)); jvp->SetValue(ParseJson(g, sap, args->lengths[i], 0));
else else
jvp->SetString(g, str); jvp->SetString(g, MakePSZ(g, args, i));
} // endif str } // endif str
break; break;
case INT_RESULT: case INT_RESULT:
jvp->SetInteger(g, *(int*)args->args[i]); jvp->SetInteger(g, *(int*)sap);
break; break;
case REAL_RESULT: case REAL_RESULT:
jvp->SetFloat(g, *(double*)args->args[i]); jvp->SetFloat(g, *(double*)sap);
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
jvp->SetFloat(g, atof(MakePSZ(g, args, i))); jvp->SetFloat(g, atof(MakePSZ(g, args, i)));
...@@ -169,12 +256,15 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int 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) my_bool Json_Value_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{ {
unsigned long reslen, memlen;
if (args->arg_count > 1) { if (args->arg_count > 1) {
strcpy(message, "Json_Value cannot accept more than 1 argument"); strcpy(message, "Json_Value cannot accept more than 1 argument");
return true; 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 } // end of Json_Value_init
char *Json_Value(UDF_INIT *initid, UDF_ARGS *args, char *result, char *Json_Value(UDF_INIT *initid, UDF_ARGS *args, char *result,
...@@ -204,7 +294,10 @@ void Json_Value_deinit(UDF_INIT* initid) ...@@ -204,7 +294,10 @@ void Json_Value_deinit(UDF_INIT* initid)
/***********************************************************************/ /***********************************************************************/
my_bool Json_Array_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 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 } // end of Json_Array_init
char *Json_Array(UDF_INIT *initid, UDF_ARGS *args, char *result, char *Json_Array(UDF_INIT *initid, UDF_ARGS *args, char *result,
...@@ -240,11 +333,14 @@ void Json_Array_deinit(UDF_INIT* initid) ...@@ -240,11 +333,14 @@ void Json_Array_deinit(UDF_INIT* initid)
/***********************************************************************/ /***********************************************************************/
my_bool Json_Object_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 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 } // end of Json_Object_init
char *Json_Object(UDF_INIT *initid, UDF_ARGS *args, char *result, 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; char *str;
uint i; uint i;
...@@ -274,10 +370,18 @@ void Json_Object_deinit(UDF_INIT* initid) ...@@ -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) 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) { if (args->arg_count != 1) {
strcpy(message, "Json_Array_Grp can only accept 1 argument"); strcpy(message, "Json_Array_Grp can only accept 1 argument");
return true; 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; return true;
PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL g = (PGLOBAL)initid->ptr;
...@@ -330,10 +434,18 @@ void Json_Array_Grp_deinit(UDF_INIT* initid) ...@@ -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) 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) { if (args->arg_count != 2) {
strcpy(message, "Json_Array_Grp can only accept 2 argument"); strcpy(message, "Json_Array_Grp can only accept 2 argument");
return true; 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; return true;
PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL g = (PGLOBAL)initid->ptr;
......
...@@ -825,7 +825,9 @@ PJSON JSONCOL::GetRow(PGLOBAL g) ...@@ -825,7 +825,9 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
PJSON nwr, row = Tjp->Row; PJSON nwr, row = Tjp->Row;
for (int i = 0; i < Nod-1 && row; i++) { 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: case TYPE_JOB:
if (!Nodes[i].Key) if (!Nodes[i].Key)
// Expected Array was not there // Expected Array was not there
...@@ -932,7 +934,11 @@ void JSONCOL::WriteColumn(PGLOBAL g) ...@@ -932,7 +934,11 @@ void JSONCOL::WriteColumn(PGLOBAL g)
jsp = ParseJson(g, s, (int)strlen(s), 0); jsp = ParseJson(g, s, (int)strlen(s), 0);
if (arp) { 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); arp->InitArray(g);
} else if (objp) { } else if (objp) {
if (Nod > 1 && Nodes[Nod-2].Key) if (Nod > 1 && Nodes[Nod-2].Key)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment