diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2021-02-16 00:31:27 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2021-02-16 00:31:27 +0100 |
commit | 801a6d500f364e55fc548ac1532839c38a4b4226 (patch) | |
tree | d88871482e8852f39f101c9f58097148c1128086 /storage/connect/jsonudf.cpp | |
parent | d788225b66ba74c6e246b558e37dbcae27261f65 (diff) | |
download | mariadb-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.cpp | 206 |
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(); |