summaryrefslogtreecommitdiff
path: root/storage/connect/jsonudf.cpp
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2021-02-16 00:31:27 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2021-02-16 00:31:27 +0100
commit801a6d500f364e55fc548ac1532839c38a4b4226 (patch)
treed88871482e8852f39f101c9f58097148c1128086 /storage/connect/jsonudf.cpp
parentd788225b66ba74c6e246b558e37dbcae27261f65 (diff)
downloadmariadb-git-801a6d500f364e55fc548ac1532839c38a4b4226.tar.gz
- Add new JPATH features
modified: storage/connect/bson.cpp modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h modified: storage/connect/json.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h modified: storage/connect/mysql-test/connect/r/json_udf.result modified: storage/connect/tabbson.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h
Diffstat (limited to 'storage/connect/jsonudf.cpp')
-rw-r--r--storage/connect/jsonudf.cpp206
1 files changed, 143 insertions, 63 deletions
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 49a36407cec..bf6c9991800 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -70,7 +70,7 @@ JSNX::JSNX(PGLOBAL g, PJSON row, int type, int len, int prec, my_bool wr)
Jp = NULL;
Nodes = NULL;
Value = AllocateValue(g, type, len, prec);
- MulVal = NULL;
+ //MulVal = NULL;
Jpath = NULL;
Buf_Type = type;
Long = len;
@@ -196,38 +196,6 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
return true;
} // endif's
- // For calculated arrays, a local Value must be used
- switch (jnp->Op) {
- case OP_NUM:
- jnp->Valp = AllocateValue(g, TYPE_INT);
- break;
- case OP_ADD:
- case OP_MULT:
- case OP_SEP:
- if (!IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, Buf_Type, 0, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_DOUBLE, 0, 2);
-
- break;
- case OP_MIN:
- case OP_MAX:
- jnp->Valp = AllocateValue(g, Buf_Type, Long, GetPrecision());
- break;
- case OP_CNC:
- if (IsTypeChar(Buf_Type))
- jnp->Valp = AllocateValue(g, TYPE_STRING, Long, GetPrecision());
- else
- jnp->Valp = AllocateValue(g, TYPE_STRING, 512);
-
- break;
- default:
- break;
- } // endswitch Op
-
- if (jnp->Valp)
- MulVal = AllocateValue(g, jnp->Valp);
-
return false;
} // end of SetArrayOptions
@@ -310,7 +278,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // endfor i, p
Nod = i;
- MulVal = AllocateValue(g, Value);
+ //MulVal = AllocateValue(g, Value);
if (trace(1))
for (i = 0; i < Nod; i++)
@@ -322,23 +290,6 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
} // end of ParseJpath
/*********************************************************************************/
-/* MakeJson: Serialize the json item and set value to it. */
-/*********************************************************************************/
-PVAL JSNX::MakeJson(PGLOBAL g, PJSON jsp)
-{
- if (Value->IsTypeNum()) {
- strcpy(g->Message, "Cannot make Json for a numeric value");
- Value->Reset();
- } else if (jsp->GetType() != TYPE_JAR && jsp->GetType() != TYPE_JOB) {
- strcpy(g->Message, "Target is not an array or object");
- Value->Reset();
- } else
- Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
-
- return Value;
-} // end of MakeJson
-
-/*********************************************************************************/
/* SetValue: Set a value from a JVALUE contains. */
/*********************************************************************************/
void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
@@ -348,6 +299,7 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
if (Jb) {
vp->SetValue_psz(Serialize(g, val->GetJsp(), NULL, 0));
+ Jb = false;
} else switch (val->GetValType()) {
case TYPE_DTM:
case TYPE_STRG:
@@ -393,6 +345,52 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val)
} // end of SetJsonValue
/*********************************************************************************/
+/* MakeJson: Serialize the json item and set value to it. */
+/*********************************************************************************/
+PJVAL JSNX::MakeJson(PGLOBAL g, PJSON jsp, int n)
+{
+ Jb = false;
+
+ if (Value->IsTypeNum()) {
+ strcpy(g->Message, "Cannot make Json for a numeric value");
+ return NULL;
+ } else if (jsp->GetType() != TYPE_JAR && jsp->GetType() != TYPE_JOB) {
+ strcpy(g->Message, "Target is not an array or object");
+ return NULL;
+ } else if (n < Nod -1) {
+ if (jsp->GetType() == TYPE_JAR) {
+ int ars = jsp->GetSize(false);
+ PJNODE jnp = &Nodes[n];
+ PJAR jarp = new(g) JARRAY;
+
+ jnp->Op = OP_EQ;
+
+ for (jnp->Rank = 0; jnp->Rank < ars; jnp->Rank++)
+ jarp->AddArrayValue(g, GetRowValue(g, jsp, n));
+
+ jarp->InitArray(g);
+ jnp->Op = OP_XX;
+ jnp->Rank = 0;
+ jsp = jarp;
+ } else if(jsp->GetType() == TYPE_JOB) {
+ PJSON jp;
+ PJOB jobp = new(g) JOBJECT;
+
+ for (PJPR prp = ((PJOB)jsp)->GetFirst(); prp; prp = prp->Next) {
+ jp = (prp->Val->DataType == TYPE_JSON) ? prp->Val->Jsp : prp->Val;
+ jobp->SetKeyValue(g, GetRowValue(g, jp, n + 1), prp->Key);
+ } // endfor prp
+
+ jsp = jobp;
+ } // endif Type
+
+ } // endif
+
+ Jb = true;
+ return new(g) JVALUE(jsp);
+} // end of MakeJson
+
+/*********************************************************************************/
/* GetJson: */
/*********************************************************************************/
PJVAL JSNX::GetJson(PGLOBAL g)
@@ -435,8 +433,7 @@ PJVAL JSNX::GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b)
val = new(g) JVALUE(g, Value);
return val;
} else if (Nodes[i].Op == OP_XX) {
- Jb = b;
- return new(g)JVALUE(row);
+ return MakeJson(g, row, i);
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
@@ -503,6 +500,88 @@ PVAL JSNX::ExpandArray(PGLOBAL g, PJAR arp, int n)
} // end of ExpandArray
/*********************************************************************************/
+/* Get the value used for calculating the array. */
+/*********************************************************************************/
+PVAL JSNX::GetCalcValue(PGLOBAL g, PJAR jap, int n)
+{
+ // For calculated arrays, a local Value must be used
+ int lng = 0;
+ short type, prec = 0;
+ bool b = n < Nod - 1;
+ PVAL valp;
+ PJVAL vlp, vp;
+ OPVAL op = Nodes[n].Op;
+
+ switch (op) {
+ case OP_NUM:
+ type = TYPE_INT;
+ break;
+ case OP_ADD:
+ case OP_MULT:
+ if (!IsTypeNum(Buf_Type)) {
+ type = TYPE_INT;
+ prec = 0;
+
+ for (vlp = jap->GetArrayValue(0); vlp; vlp = vlp->Next) {
+ vp = (b && vlp->GetJsp()) ? GetRowValue(g, vlp, n + 1) : vlp;
+
+ switch (vp->DataType) {
+ case TYPE_BINT:
+ if (type == TYPE_INT)
+ type = TYPE_BIGINT;
+
+ break;
+ case TYPE_DBL:
+ case TYPE_FLOAT:
+ type = TYPE_DOUBLE;
+ prec = MY_MAX(prec, vp->Nd);
+ break;
+ default:
+ break;
+ } // endswitch Type
+
+ } // endfor vlp
+
+ } else {
+ type = Buf_Type;
+ prec = GetPrecision();
+ } // endif Buf_Type
+
+ break;
+ case OP_SEP:
+ if (IsTypeChar(Buf_Type)) {
+ type = TYPE_DOUBLE;
+ prec = 2;
+ } else {
+ type = Buf_Type;
+ prec = GetPrecision();
+ } // endif Buf_Type
+
+ break;
+ case OP_MIN:
+ case OP_MAX:
+ type = Buf_Type;
+ lng = Long;
+ prec = GetPrecision();
+ break;
+ case OP_CNC:
+ type = TYPE_STRING;
+
+ if (IsTypeChar(Buf_Type)) {
+ lng = (Long) ? Long : 512;
+ prec = GetPrecision();
+ } else
+ lng = 512;
+
+ break;
+ default:
+ break;
+ } // endswitch Op
+
+ return valp = AllocateValue(g, type, lng, prec);
+} // end of GetCalcValue
+
+/*********************************************************************************/
/* CalculateArray: */
/*********************************************************************************/
PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
@@ -510,7 +589,8 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
int i, ars = arp->size(), nv = 0;
bool err;
OPVAL op = Nodes[n].Op;
- PVAL val[2], vp = Nodes[n].Valp;
+ PVAL val[2], vp = GetCalcValue(g, arp, n);
+ PVAL mulval = AllocateValue(g, vp);
PJVAL jvrp, jvp;
JVALUE jval;
@@ -543,9 +623,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
SetJsonValue(g, vp, jvp);
continue;
} else
- SetJsonValue(g, MulVal, jvp);
+ SetJsonValue(g, mulval, jvp);
- if (!MulVal->IsNull()) {
+ if (!mulval->IsNull()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
@@ -553,18 +633,18 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
err = vp->Compute(g, val, 1, op);
} // endif CncVal
- val[0] = MulVal;
+ val[0] = mulval;
err = vp->Compute(g, val, 1, op);
break;
// case OP_NUM:
case OP_SEP:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
+ val[0] = vp;
+ val[1] = mulval;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
- val[0] = Nodes[n].Valp;
- val[1] = MulVal;
+ val[0] = vp;
+ val[1] = mulval;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
@@ -586,9 +666,9 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (op == OP_SEP) {
// Calculate average
- MulVal->SetValue(nv);
+ mulval->SetValue(nv);
val[0] = vp;
- val[1] = MulVal;
+ val[1] = mulval;
if (vp->Compute(g, val, 2, OP_DIV))
vp->Reset();