diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2021-01-28 19:54:24 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2021-01-28 19:54:24 +0100 |
commit | 848a1a613c103209e4f2fb5d02572237d46832a1 (patch) | |
tree | bd6f22685b260c811bffae1f4ccf7c60332b3b90 /storage/connect | |
parent | 7edd4294be4e59c19539167620ff140e3f5e7f58 (diff) | |
download | mariadb-git-848a1a613c103209e4f2fb5d02572237d46832a1.tar.gz |
Fix decimal problems in bson udf's
Diffstat (limited to 'storage/connect')
-rw-r--r-- | storage/connect/bson.cpp | 46 | ||||
-rw-r--r-- | storage/connect/bsonudf.cpp | 158 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/r/bson.result | 2 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/r/bson_udf.result | 48 |
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 # |