summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2021-01-28 19:54:24 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2021-01-28 19:54:24 +0100
commit848a1a613c103209e4f2fb5d02572237d46832a1 (patch)
treebd6f22685b260c811bffae1f4ccf7c60332b3b90
parent7edd4294be4e59c19539167620ff140e3f5e7f58 (diff)
downloadmariadb-git-848a1a613c103209e4f2fb5d02572237d46832a1.tar.gz
Fix decimal problems in bson udf's
-rw-r--r--storage/connect/bson.cpp46
-rw-r--r--storage/connect/bsonudf.cpp158
-rw-r--r--storage/connect/mysql-test/connect/r/bson.result2
-rw-r--r--storage/connect/mysql-test/connect/r/bson_udf.result48
4 files changed, 116 insertions, 138 deletions
diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp
index 5731ce9eac5..6c979498286 100644
--- a/storage/connect/bson.cpp
+++ b/storage/connect/bson.cpp
@@ -1501,31 +1501,27 @@ double BJSON::GetDouble(PBVAL vp)
PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp;
switch (vlp->Type) {
- case TYPE_DBL:
- d = *(double*)MP(vlp->To_Val);
- break;
- case TYPE_BINT:
- d = (double)*(longlong*)MP(vlp->To_Val);
- break;
- case TYPE_INTG:
- d = (double)vlp->N;
- break;
- case TYPE_FLOAT:
- { char buf[32];
- int n = (vlp->Nd) ? vlp->Nd : 5;
-
- sprintf(buf, "%.*f", n, vlp->F);
- d = atof(buf);
- } break;
- case TYPE_DTM:
- case TYPE_STRG:
- d = atof(MZP(vlp->To_Val));
- break;
- case TYPE_BOOL:
- d = (vlp->B) ? 1.0 : 0.0;
- break;
- default:
- d = 0.0;
+ case TYPE_DBL:
+ d = *(double*)MP(vlp->To_Val);
+ break;
+ case TYPE_BINT:
+ d = (double)*(longlong*)MP(vlp->To_Val);
+ break;
+ case TYPE_INTG:
+ d = (double)vlp->N;
+ break;
+ case TYPE_FLOAT:
+ d = (double)vlp->F;
+ break;
+ case TYPE_DTM:
+ case TYPE_STRG:
+ d = atof(MZP(vlp->To_Val));
+ break;
+ case TYPE_BOOL:
+ d = (vlp->B) ? 1.0 : 0.0;
+ break;
+ default:
+ d = 0.0;
} // endswitch Type
return d;
diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp
index dd9f95bc4ba..b8f4f9699d4 100644
--- a/storage/connect/bsonudf.cpp
+++ b/storage/connect/bsonudf.cpp
@@ -116,7 +116,7 @@ BJNX::BJNX(PGLOBAL g) : BDOC(g)
Value = NULL;
MulVal = NULL;
Jpath = NULL;
- Buf_Type = TYPE_NULL;
+ Buf_Type = TYPE_STRING;
Long = len;
Prec = 0;
Nod = 0;
@@ -171,10 +171,9 @@ BJNX::BJNX(PGLOBAL g, PBVAL row, int type, int len, int prec, my_bool wr) : BDOC
my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb)
{
// Check Value was allocated
- if (!Value)
- return true;
+ if (Value)
+ Value->SetNullable(true);
- Value->SetNullable(true);
Jpath = path;
// Parse the json path
@@ -697,8 +696,10 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n)
if (IsTypeChar(Buf_Type)) {
type = TYPE_DOUBLE;
prec = 2;
- } else
+ } else {
type = Buf_Type;
+ prec = GetPrecision();
+ } // endif Buf_Type
break;
case OP_MIN:
@@ -711,7 +712,7 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n)
type = TYPE_STRING;
if (IsTypeChar(Buf_Type)) {
- lng = Long;
+ lng = (Long) ? Long : 512;
prec = GetPrecision();
} else
lng = 512;
@@ -740,79 +741,87 @@ PVAL BJNX::CalculateArray(PGLOBAL g, PBVAL bap, int n)
vp->Reset();
xtrc(1, "CalculateArray size=%d op=%d\n", ars, op);
- for (i = 0; i < ars; i++) {
- bvrp = GetArrayValue(bap, i);
- xtrc(1, "i=%d nv=%d\n", i, nv);
-
- if (!IsValueNull(bvrp) || (op == OP_CNC && GetJsonNull())) {
- if (IsValueNull(bvrp)) {
- SetString(bvrp, NewStr(GetJsonNull()), 0);
- bvp = bvrp;
- } else if (n < Nod - 1 && IsJson(bvrp)) {
- SetValue(&bval, GetColumnValue(g, bvrp, n + 1));
- bvp = &bval;
- } else
- bvp = bvrp;
+ try {
+ for (i = 0; i < ars; i++) {
+ bvrp = GetArrayValue(bap, i);
+ xtrc(1, "i=%d nv=%d\n", i, nv);
+
+ if (!IsValueNull(bvrp) || (op == OP_CNC && GetJsonNull())) {
+ if (IsValueNull(bvrp)) {
+ SetString(bvrp, NewStr(GetJsonNull()), 0);
+ bvp = bvrp;
+ } else if (n < Nod - 1 && IsJson(bvrp)) {
+ SetValue(&bval, GetColumnValue(g, bvrp, n + 1));
+ bvp = &bval;
+ } else
+ bvp = bvrp;
- if (trace(1))
- htrc("bvp=%s null=%d\n",
- GetString(bvp), IsValueNull(bvp) ? 1 : 0);
+ if (trace(1))
+ htrc("bvp=%s null=%d\n",
+ GetString(bvp), IsValueNull(bvp) ? 1 : 0);
- if (!nv++) {
- SetJsonValue(g, vp, bvp);
- continue;
- } else
- SetJsonValue(g, mulval, bvp);
+ if (!nv++) {
+ SetJsonValue(g, vp, bvp);
+ continue;
+ } else
+ SetJsonValue(g, mulval, bvp);
+
+ if (!mulval->IsNull()) {
+ switch (op) {
+ case OP_CNC:
+ if (Nodes[n].CncVal) {
+ val[0] = Nodes[n].CncVal;
+ err = vp->Compute(g, val, 1, op);
+ } // endif CncVal
- if (!mulval->IsNull()) {
- switch (op) {
- case OP_CNC:
- if (Nodes[n].CncVal) {
- val[0] = Nodes[n].CncVal;
+ val[0] = mulval;
err = vp->Compute(g, val, 1, op);
- } // endif CncVal
+ break;
+ // case OP_NUM:
+ case OP_SEP:
+ val[0] = vp;
+ val[1] = mulval;
+ err = vp->Compute(g, val, 2, OP_ADD);
+ break;
+ default:
+ val[0] = vp;
+ 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] = vp;
- val[1] = mulval;
- err = vp->Compute(g, val, 2, OP_ADD);
- break;
- default:
- val[0] = vp;
- val[1] = mulval;
- err = vp->Compute(g, val, 2, op);
- } // endswitch Op
+ if (err)
+ vp->Reset();
- if (err)
- vp->Reset();
+ if (trace(1)) {
+ char buf(32);
- if (trace(1)) {
- char buf(32);
+ htrc("vp='%s' err=%d\n",
+ vp->GetCharString(&buf), err ? 1 : 0);
+ } // endif trace
- htrc("vp='%s' err=%d\n",
- vp->GetCharString(&buf), err ? 1 : 0);
- } // endif trace
+ } // endif Zero
- } // endif Zero
+ } // endif jvrp
- } // endif jvrp
+ } // endfor i
- } // endfor i
+ if (op == OP_SEP) {
+ // Calculate average
+ mulval->SetValue(nv);
+ val[0] = vp;
+ val[1] = mulval;
- if (op == OP_SEP) {
- // Calculate average
- mulval->SetValue(nv);
- val[0] = vp;
- val[1] = mulval;
+ if (vp->Compute(g, val, 2, OP_DIV))
+ vp->Reset();
- if (vp->Compute(g, val, 2, OP_DIV))
- vp->Reset();
+ } // endif Op
- } // endif Op
+ } catch (int n) {
+ xtrc(1, "Exception %d: %s\n", n, g->Message);
+ PUSH_WARNING(g->Message);
+ } catch (const char* msg) {
+ strcpy(g->Message, msg);
+ } // end catch
return vp;
} // end of CalculateArray
@@ -4024,8 +4033,8 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args,
char *p, *path;
double d;
PBVAL jsp, jvp;
- PBJNX bxp = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
+ BJNX bnx(g);
if (g->N) {
if (!g->Activityp) {
@@ -4044,8 +4053,6 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args,
*is_null = 1;
return 0.0;
} else {
- BJNX bnx(g);
-
jvp = bnx.MakeValue(args, 0);
if ((p = bnx.GetString(jvp))) {
@@ -4068,21 +4075,22 @@ double bsonget_real(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PBVAL)g->Xchk;
path = MakePSZ(g, args, 1);
- bxp = new(g) BJNX(g, jsp, TYPE_DOUBLE);
+//bxp = new(g) BJNX(g, jsp, TYPE_DOUBLE, 32, jsp->Nd);
- if (bxp->SetJpath(g, path)) {
+ if (bnx.SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0.0;
} else
- bxp->ReadValue(g);
+ jvp = bnx.GetRowValue(g, jsp, 0);
- if (bxp->GetValue()->IsNull()) {
+ if (!jvp || bnx.IsValueNull(jvp)) {
*is_null = 1;
return 0.0;
- } // endif IsNull
-
- d = bxp->GetValue()->GetFloatValue();
+ } else if (args->arg_count == 2) {
+ d = atof(bnx.GetString(jvp));
+ } else
+ d = bnx.GetDouble(jvp);
if (initid->const_item) {
// Keep result of constant function
diff --git a/storage/connect/mysql-test/connect/r/bson.result b/storage/connect/mysql-test/connect/r/bson.result
index 98abdbb8744..fd15e020aac 100644
--- a/storage/connect/mysql-test/connect/r/bson.result
+++ b/storage/connect/mysql-test/connect/r/bson.result
@@ -279,7 +279,7 @@ SELECT * FROM t1;
WHO WEEKS SUMS SUM AVGS SUMAVG AVGSUM AVGAVG AVERAGE
Joe 3, 4, 5 69.00+83.00+26.00 178.00 17.25+16.60+13.00 46.85 59.33 15.62 16.18
Beth 3, 4, 5 16.00+32.00+32.00 80.00 16.00+16.00+16.00 48.00 26.67 16.00 16.00
-Janet 3, 4, 5 55.00+17.00+57.00 129.00 18.33+17.00+14.25 49.58 43.00 16.53 16.13
+Janet 3, 4, 5 55.00+17.00+57.00 129.00 18.33+17.00+14.25 49.58 43.00 16.53 16.12
DROP TABLE t1;
#
# Expand expense in 3 one week tables
diff --git a/storage/connect/mysql-test/connect/r/bson_udf.result b/storage/connect/mysql-test/connect/r/bson_udf.result
index 14b3629e4b1..4ec1f0c87fd 100644
--- a/storage/connect/mysql-test/connect/r/bson_udf.result
+++ b/storage/connect/mysql-test/connect/r/bson_udf.result
@@ -606,14 +606,12 @@ Bson_File('test/fx.json', 0)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
SELECT Bson_File('test/fx.json', '0');
Bson_File('test/fx.json', '0')
-NULL
-Warnings:
-Warning 1105
+{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]}
SELECT Bson_File('test/fx.json', '[?]');
Bson_File('test/fx.json', '[?]')
NULL
Warnings:
-Warning 1105
+Warning 1105 Invalid function specification ?
SELECT BsonGet_String(Bson_File('test/fx.json'), '1.*');
BsonGet_String(Bson_File('test/fx.json'), '1.*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
@@ -628,57 +626,33 @@ Price
5.65
SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings');
Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings')
-NULL
-Warnings:
-Warning 1105
-Warning 1105 No sub-item at 'ratings'
+{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]}
SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 1, 'ratings');
Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 1, 'ratings')
-NULL
-Warnings:
-Warning 1105
-Warning 1105 No sub-item at 'ratings'
+{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings', 1);
Bson_Array_Add(Bson_File('test/fx.json', '2'), 6, 'ratings', 1)
-NULL
-Warnings:
-Warning 1105
-Warning 1105 No sub-item at 'ratings'
+{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Bson_Array_Add(Bson_File('test/fx.json', '2.ratings'), 6, 0);
Bson_Array_Add(Bson_File('test/fx.json', '2.ratings'), 6, 0)
-[6,null]
-Warnings:
-Warning 1105
+[6,2,4]
SELECT Bson_Array_Delete(Bson_File('test/fx.json', '2'), 'ratings', 1);
Bson_Array_Delete(Bson_File('test/fx.json', '2'), 'ratings', 1)
-NULL
-Warnings:
-Warning 1105
-Warning 1105 No sub-item at 'ratings'
+{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]}
SELECT Bson_Object_Add(Bson_File('test/fx.json', '2'), 'france' origin);
Bson_Object_Add(Bson_File('test/fx.json', '2'), 'france' origin)
-NULL
-Warnings:
-Warning 1105
-Warning 1105 First argument target is not an object
+{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]}
SELECT Bson_Object_Add(Bson_File('test/fx.json', '2'), 70 H, 'size');
Bson_Object_Add(Bson_File('test/fx.json', '2'), 70 H, 'size')
-NULL
+{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]}
Warnings:
-Warning 1105
Warning 1105 No sub-item at 'size'
SELECT Bson_Object_Add(Bson_File('test/fx.json', '3'), 70 H, 'size');
Bson_Object_Add(Bson_File('test/fx.json', '3'), 70 H, 'size')
-NULL
-Warnings:
-Warning 1105
-Warning 1105 No sub-item at 'size'
+{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]}
SELECT Bson_Object_List(Bson_File('test/fx.json', '3.size'));
Bson_Object_List(Bson_File('test/fx.json', '3.size'))
-NULL
-Warnings:
-Warning 1105
-Warning 1105 First argument is not an object
+["W","L","H"]
#
# Testing new functions
#