1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

- Adding json udf's. Making the second version of json tables.

added:
  storage/connect/jsonudf.cpp
modified:
  storage/connect/CMakeLists.txt
  storage/connect/json.cpp
  storage/connect/json.h
  storage/connect/tabjson.cpp
  storage/connect/tabjson.h

- Fix utf8 issues with PROXY tables
modified:
  storage/connect/ha_connect.cc
  storage/connect/tabutil.cpp
  storage/connect/tabutil.h
This commit is contained in:
Olivier Bertrand
2015-02-11 21:39:41 +01:00
parent 3c097fd689
commit dcfe068d59
83 changed files with 553 additions and 4828 deletions

View File

@@ -387,7 +387,7 @@ bool JSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
if ((Tjp->Xcol && nm && !strcmp(nm, Tjp->Xcol) &&
(Tjp->Xval < 0 || Tjp->Xval == i)) || Xpd) {
Xpd = true; // Expandable object
Nodes[i].Op = OP_XX;
Nodes[i].Op = OP_EXP;
} else if (b) {
strcpy(g->Message, "Cannot expand more than one branch");
return true;
@@ -426,7 +426,7 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
// Default specifications
if (CheckExpand(g, i, nm, false))
return true;
else if (jnp->Op != OP_XX)
else if (jnp->Op != OP_EXP)
if (!Value->IsTypeNum()) {
jnp->CncVal = AllocateValue(g, (void*)", ", TYPE_STRING);
jnp->Op = OP_CNC;
@@ -448,13 +448,13 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
case '*': jnp->Op = OP_MULT; break;
case '>': jnp->Op = OP_MAX; break;
case '<': jnp->Op = OP_MIN; break;
case '#': jnp->Op = OP_NUM; break;
case '!': jnp->Op = OP_SEP; break; // Average
case '#': jnp->Op = OP_NUM; break;
case 'x':
case 'X': // Expand this array
if (!Tjp->Xcol && nm) {
Xpd = true;
jnp->Op = OP_XX;
jnp->Op = OP_EXP;
Tjp->Xval = i;
Tjp->Xcol = nm;
} else if (CheckExpand(g, i, nm, true))
@@ -557,6 +557,9 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
if (SetArrayOptions(g, p, i, Nodes[i-1].Key))
return true;
} else if (*p == '*') {
// Return JSON
Nodes[i].Op = OP_XX;
} else {
Nodes[i].Key = p;
Nodes[i].Op = OP_EXIST;
@@ -569,6 +572,20 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
return false;
} // end of ParseJpath
/***********************************************************************/
/* MakeJson: Serialize the json item and set value to it. */
/***********************************************************************/
PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
{
if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
Value->Reset();
} else
Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
return Value;
} // end of MakeJson
/***********************************************************************/
/* SetValue: Set a value from a JVALUE contains. */
/***********************************************************************/
@@ -622,16 +639,16 @@ void JSONCOL::ReadColumn(PGLOBAL g)
PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
{
int n = Nod - 1;
int nextsame = 0;
bool expd = false;
PJAR arp;
PJVAL val = NULL;
//for (; i < Nod-1 && row; i++) {
for (; i < Nod && row; i++) {
if (Nodes[i].Op == OP_NUM) {
Value->SetValue(row->GetType() == TYPE_JAR ? row->size() : 1);
return(Value);
} else if (Nodes[i].Op == OP_XX) {
return MakeJson(g, row);
} else switch (row->GetType()) {
case TYPE_JOB:
if (!Nodes[i].Key) {
@@ -652,7 +669,7 @@ PVAL JSONCOL::GetColumnValue(PGLOBAL g, PJSON row, int i)
if (Nodes[i].Op != OP_NULL) {
if (Nodes[i].Rank) {
val = arp->GetValue(Nodes[i].Rank - 1);
} else if (Nodes[i].Op == OP_XX) {
} else if (Nodes[i].Op == OP_EXP) {
return ExpandArray(g, arp, i);
} else
return CalculateArray(g, arp, i);
@@ -694,7 +711,11 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
JVALUE jval;
ars = MY_MIN(Tjp->Limit, arp->size());
jvp = arp->GetValue(Nodes[n].Nx);
if (!(jvp = arp->GetValue(Nodes[n].Nx))) {
strcpy(g->Message, "Logical error expanding array");
longjmp(g->jumper[g->jump_level], 666);
} // endif jvp
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
@@ -720,63 +741,68 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
/***********************************************************************/
PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
{
int i, ars;
int i, ars, nv = 0, nextsame = Tjp->NextSame;
bool err;
OPVAL op = Nodes[n].Op;
PVAL val[2], vp = Nodes[n].Valp;
PJVAL jvp;
PJVAL jvrp, jvp;
JVALUE jval;
vp->Reset();
ars = MY_MIN(Tjp->Limit, arp->size());
for (i = 0; i < ars; i++) {
jvp = arp->GetValue(i);
jvrp = arp->GetValue(i);
if (n < Nod - 1 && jvp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvp->GetJson(), n + 1));
jvp = &jval;
} // endif n
if (!i) {
SetJsonValue(g, vp, jvp, n);
continue;
} else
SetJsonValue(g, MulVal, jvp, n);
if (!MulVal->IsZero()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
do {
if (n < Nod - 1 && jvrp->GetJson()) {
Tjp->NextSame = nextsame;
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
jvp = jvrp;
if (!nv++) {
SetJsonValue(g, vp, jvp, n);
continue;
} else
SetJsonValue(g, MulVal, jvp, n);
if (!MulVal->IsZero()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
val[0] = MulVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
break;
// case OP_NUM:
case OP_SEP:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
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;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
if (err)
vp->Reset();
} // endif Zero
if (err)
vp->Reset();
} // endif Zero
} while (Tjp->NextSame > nextsame);
} // endfor i
if (op == OP_SEP) {
// Calculate average
MulVal->SetValue(ars);
MulVal->SetValue(nv);
val[0] = vp;
val[1] = MulVal;
@@ -785,6 +811,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
} // endif Op
Tjp->NextSame = nextsame;
return vp;
} // end of CalculateArray
@@ -838,12 +865,13 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
} else {
// Construct missing objects
for (i++; row && i < Nod; i++) {
if (!Nodes[i].Key) {
if (Nodes[i].Op == OP_XX)
break;
else if (!Nodes[i].Key)
// Construct intermediate array
nwr = new(g) JARRAY;
} else {
else
nwr = new(g) JOBJECT;
} // endif Nodes
if (row->GetType() == TYPE_JOB) {
((PJOB)row)->SetValue(g, new(g) JVALUE(nwr), Nodes[i-1].Key);
@@ -883,10 +911,11 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Value->IsNull() && Tjp->Mode == MODE_INSERT)
return;
char *s;
PJOB objp = NULL;
PJAR arp = NULL;
PJVAL jvp = NULL;
PJSON row = GetRow(g);
PJSON jsp, row = GetRow(g);
JTYP type = row->GetType();
switch (row->GetType()) {
@@ -898,6 +927,24 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (row) switch (Buf_Type) {
case TYPE_STRING:
if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue();
jsp = ParseJson(g, s, (int)strlen(s), 0);
if (arp) {
arp->AddValue(g, new(g) JVALUE(jsp));
arp->InitArray(g);
} else if (objp) {
if (Nod > 1 && Nodes[Nod-2].Key)
objp->SetValue(g, new(g) JVALUE(jsp), Nodes[Nod-2].Key);
} else if (jvp)
jvp->SetValue(jsp);
break;
} // endif Op
// Passthru
case TYPE_DATE:
case TYPE_INT:
case TYPE_DOUBLE:
@@ -1319,9 +1366,10 @@ int TDBJSON::WriteDB(PGLOBAL g)
return RC_FX;
} else { // if (Jmode == MODE_VALUE)
if (Mode == MODE_INSERT)
if (Mode == MODE_INSERT) {
Doc->AddValue(g, (PJVAL)Row);
else if (Doc->SetValue(g, (PJVAL)Row, Fpos))
Row = new(g) JVALUE;
} else if (Doc->SetValue(g, (PJVAL)Row, Fpos))
return RC_FX;
} // endif Jmode