Skip to content

Commit 6c09a72

Browse files
committed
Merge remote-tracking branch 'origin/10.0' into 10.0
2 parents 126523d + 723be51 commit 6c09a72

File tree

14 files changed

+245
-23
lines changed

14 files changed

+245
-23
lines changed

storage/connect/global.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ typedef struct _global { /* Global structure */
235235
void *Xchk; /* indexes in create/alter */
236236
short Alchecked; /* Checked for ALTER */
237237
short Mrr; /* True when doing mrr */
238-
short Trace;
238+
int N; /* Utility */
239239
int jump_level;
240240
jmp_buf jumper[MAX_JUMP + 2];
241241
} GLOBAL;

storage/connect/ha_connect.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,10 @@
165165
/***********************************************************************/
166166
/* Initialize the ha_connect static members. */
167167
/***********************************************************************/
168-
#define SZCONV 8192
169-
#define SZWORK 67108864 // Default work area size 64M
170-
#define SZWMIN 4194304 // Minimum work area size 4M
168+
#define SZCONV 8192
169+
#define SZWORK 67108864 // Default work area size 64M
170+
#define SZWMIN 4194304 // Minimum work area size 4M
171+
#define JSONMAX 10 // JSON Default max grp size
171172

172173
extern "C" {
173174
char version[]= "Version 1.03.0006 February 06, 2015";
@@ -217,6 +218,7 @@ bool ExactInfo(void);
217218
USETEMP UseTemp(void);
218219
int GetConvSize(void);
219220
TYPCONV GetTypeConv(void);
221+
uint GetJsonGrpSize(void);
220222
uint GetWorkSize(void);
221223
void SetWorkSize(uint);
222224
extern "C" const char *msglang(void);
@@ -323,6 +325,12 @@ static MYSQL_THDVAR_ENUM(
323325
0, // def (no)
324326
&xconv_typelib); // typelib
325327

328+
// Estimate max number of rows for JSON aggregate functions
329+
static MYSQL_THDVAR_UINT(json_grp_size,
330+
PLUGIN_VAR_RQCMDARG, // opt
331+
"max number of rows for JSON aggregate functions.",
332+
NULL, NULL, JSONMAX, 1, INT_MAX, 1);
333+
326334
#if defined(XMSG) || defined(NEWMSG)
327335
const char *language_names[]=
328336
{
@@ -353,6 +361,7 @@ bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
353361
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
354362
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
355363
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
364+
uint GetJsonGrpSize(void) {return THDVAR(current_thd, json_grp_size);}
356365
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
357366
void SetWorkSize(uint n)
358367
{
@@ -6516,6 +6525,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
65166525
#if defined(XMSG)
65176526
MYSQL_SYSVAR(errmsg_dir_path),
65186527
#endif // XMSG
6528+
MYSQL_SYSVAR(json_grp_size),
65196529
NULL
65206530
};
65216531

storage/connect/json.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
7474
goto err;
7575
} else if (!(jsp = ParseObject(g, ++i, src)))
7676
goto err;
77+
7778
break;
7879
case ' ':
7980
case '\t':
@@ -90,6 +91,11 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
9091

9192
sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
9293
goto err;
94+
case '"':
95+
if (!(jsp = ParseValue(g, i, src)))
96+
goto err;
97+
98+
break;
9399
case '(':
94100
b = true;
95101
break;

storage/connect/jsonudf.cpp

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88
/* Include relevant sections of the MariaDB header file. */
99
/***********************************************************************/
1010
#include <my_global.h>
11+
#include <mysqld.h>
1112
#include <mysql.h>
13+
#include <sql_error.h>
1214

1315
#include "global.h"
1416
#include "plgdbsem.h"
1517
#include "json.h"
1618

19+
#define MEMFIX 512
20+
21+
uint GetJsonGrpSize(void);
22+
1723
extern "C" {
1824
DllExport my_bool Json_Value_init(UDF_INIT*, UDF_ARGS*, char*);
1925
DllExport char *Json_Value(UDF_INIT*, UDF_ARGS*, char*,
@@ -23,6 +29,10 @@ DllExport my_bool Json_Array_init(UDF_INIT*, UDF_ARGS*, char*);
2329
DllExport char *Json_Array(UDF_INIT*, UDF_ARGS*, char*,
2430
unsigned long*, char *, char *);
2531
DllExport void Json_Array_deinit(UDF_INIT*);
32+
DllExport my_bool Json_Array_Add_init(UDF_INIT*, UDF_ARGS*, char*);
33+
DllExport char *Json_Array_Add(UDF_INIT*, UDF_ARGS*, char*,
34+
unsigned long*, char *, char *);
35+
DllExport void Json_Array_Add_deinit(UDF_INIT*);
2636
DllExport my_bool Json_Object_init(UDF_INIT*, UDF_ARGS*, char*);
2737
DllExport char *Json_Object(UDF_INIT*, UDF_ARGS*, char*,
2838
unsigned long*, char *, char *);
@@ -44,8 +54,8 @@ DllExport void Json_Object_Grp_deinit(UDF_INIT*);
4454
/***********************************************************************/
4555
/* Allocate and initialise the memory area. */
4656
/***********************************************************************/
47-
static my_bool JsonInit(UDF_INIT *initid, char *message, unsigned long reslen,
48-
unsigned long memlen)
57+
static my_bool JsonInit(UDF_INIT *initid, char *message,
58+
unsigned long reslen, unsigned long memlen)
4959
{
5060
PGLOBAL g = PlugInit(NULL, memlen);
5161

@@ -119,7 +129,7 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
119129
} // endfor i
120130

121131
// Calculate the amount of memory needed
122-
memlen = 1024 + sizeof(JOUTSTR) + reslen;
132+
memlen = MEMFIX + sizeof(JOUTSTR) + reslen;
123133

124134
for (i = 0; i < args->arg_count; i++) {
125135
memlen += (args->lengths[i] + sizeof(JVALUE));
@@ -219,14 +229,23 @@ static PSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
219229
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
220230
{
221231
char *sap = args->args[i];
232+
PJSON jsp;
222233
PJVAL jvp = new(g) JVALUE;
223234

224235
if (sap) switch (args->arg_type[i]) {
225236
case STRING_RESULT:
226237
if (args->lengths[i]) {
227-
if (IsJson(args, i))
228-
jvp->SetValue(ParseJson(g, sap, args->lengths[i], 0));
229-
else
238+
if (IsJson(args, i)) {
239+
if (!(jsp = ParseJson(g, sap, args->lengths[i], 0)))
240+
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
241+
g->Message);
242+
243+
if (jsp && jsp->GetType() == TYPE_JVAL)
244+
jvp = (PJVAL)jsp;
245+
else
246+
jvp->SetValue(jsp);
247+
248+
} else
230249
jvp->SetString(g, MakePSZ(g, args, i));
231250

232251
} // endif str
@@ -328,6 +347,59 @@ void Json_Array_deinit(UDF_INIT* initid)
328347
PlugExit((PGLOBAL)initid->ptr);
329348
} // end of Json_Array_deinit
330349

350+
/***********************************************************************/
351+
/* Add values to a Json array. */
352+
/***********************************************************************/
353+
my_bool Json_Array_Add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
354+
{
355+
unsigned long reslen, memlen;
356+
357+
if (args->arg_count < 2) {
358+
strcpy(message, "Json_Value_Add must have at least 2 arguments");
359+
return true;
360+
} else if (!IsJson(args, 0)) {
361+
strcpy(message, "Json_Value_Add first argument must be a json array");
362+
return true;
363+
} else
364+
CalcLen(args, false, reslen, memlen);
365+
366+
return JsonInit(initid, message, reslen, memlen);
367+
} // end of Json_Array_Add_init
368+
369+
char *Json_Array_Add(UDF_INIT *initid, UDF_ARGS *args, char *result,
370+
unsigned long *res_length, char *is_null, char *error)
371+
{
372+
char *str;
373+
PJVAL jvp;
374+
PJAR arp;
375+
PGLOBAL g = (PGLOBAL)initid->ptr;
376+
377+
PlugSubSet(g, g->Sarea, g->Sarea_Size);
378+
jvp = MakeValue(g, args, 0);
379+
380+
if (jvp->GetValType() != TYPE_JAR) {
381+
arp = new(g) JARRAY;
382+
arp->AddValue(g, jvp);
383+
} else
384+
arp = jvp->GetArray();
385+
386+
for (uint i = 1; i < args->arg_count; i++)
387+
arp->AddValue(g, MakeValue(g, args, i));
388+
389+
arp->InitArray(g);
390+
391+
if (!(str = Serialize(g, arp, NULL, 0)))
392+
str = strcpy(result, g->Message);
393+
394+
*res_length = strlen(str);
395+
return str;
396+
} // end of Json_Array_Add
397+
398+
void Json_Array_Add_deinit(UDF_INIT* initid)
399+
{
400+
PlugExit((PGLOBAL)initid->ptr);
401+
} // end of Json_Array_Add_deinit
402+
331403
/***********************************************************************/
332404
/* Make a Json Oject containing all the parameters. */
333405
/***********************************************************************/
@@ -370,7 +442,7 @@ void Json_Object_deinit(UDF_INIT* initid)
370442
/***********************************************************************/
371443
my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
372444
{
373-
unsigned long reslen, memlen, n = 10;
445+
unsigned long reslen, memlen, n = GetJsonGrpSize();
374446

375447
if (args->arg_count != 1) {
376448
strcpy(message, "Json_Array_Grp can only accept 1 argument");
@@ -379,7 +451,7 @@ my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
379451
CalcLen(args, false, reslen, memlen);
380452

381453
reslen *= n;
382-
memlen *= n;
454+
memlen += ((memlen - MEMFIX) * (n - 1));
383455

384456
if (JsonInit(initid, message, reslen, memlen))
385457
return true;
@@ -388,6 +460,7 @@ my_bool Json_Array_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
388460

389461
PlugSubSet(g, g->Sarea, g->Sarea_Size);
390462
g->Activityp = (PACTIVITY)new(g) JARRAY;
463+
g->N = (int)n;
391464
return false;
392465
} // end of Json_Array_Grp_init
393466

@@ -397,7 +470,9 @@ void Json_Array_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
397470
PGLOBAL g = (PGLOBAL)initid->ptr;
398471
PJAR arp = (PJAR)g->Activityp;
399472

400-
arp->AddValue(g, MakeValue(g, args, 0));
473+
if (g->N-- > 0)
474+
arp->AddValue(g, MakeValue(g, args, 0));
475+
401476
} // end of Json_Array_Grp_add
402477

403478
char *Json_Array_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -407,6 +482,10 @@ char *Json_Array_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
407482
PGLOBAL g = (PGLOBAL)initid->ptr;
408483
PJAR arp = (PJAR)g->Activityp;
409484

485+
if (g->N < 0)
486+
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
487+
"Result truncated to json_grp_size values");
488+
410489
arp->InitArray(g);
411490

412491
if (!(str = Serialize(g, arp, NULL, 0)))
@@ -422,6 +501,7 @@ void Json_Array_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
422501

423502
PlugSubSet(g, g->Sarea, g->Sarea_Size);
424503
g->Activityp = (PACTIVITY)new(g) JARRAY;
504+
g->N = GetJsonGrpSize();
425505
} // end of Json_Array_Grp_clear
426506

427507
void Json_Array_Grp_deinit(UDF_INIT* initid)
@@ -434,7 +514,7 @@ void Json_Array_Grp_deinit(UDF_INIT* initid)
434514
/***********************************************************************/
435515
my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
436516
{
437-
unsigned long reslen, memlen, n = 10;
517+
unsigned long reslen, memlen, n = GetJsonGrpSize();
438518

439519
if (args->arg_count != 2) {
440520
strcpy(message, "Json_Array_Grp can only accept 2 argument");
@@ -443,7 +523,7 @@ my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
443523
CalcLen(args, true, reslen, memlen);
444524

445525
reslen *= n;
446-
memlen *= n;
526+
memlen += ((memlen - MEMFIX) * (n - 1));
447527

448528
if (JsonInit(initid, message, reslen, memlen))
449529
return true;
@@ -452,6 +532,7 @@ my_bool Json_Object_Grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
452532

453533
PlugSubSet(g, g->Sarea, g->Sarea_Size);
454534
g->Activityp = (PACTIVITY)new(g) JOBJECT;
535+
g->N = (int)n;
455536
return false;
456537
} // end of Json_Object_Grp_init
457538

@@ -461,7 +542,9 @@ void Json_Object_Grp_add(UDF_INIT *initid, UDF_ARGS *args,
461542
PGLOBAL g = (PGLOBAL)initid->ptr;
462543
PJOB objp = (PJOB)g->Activityp;
463544

464-
objp->SetValue(g, MakeValue(g, args, 0), MakePSZ(g, args, 1));
545+
if (g->N-- > 0)
546+
objp->SetValue(g, MakeValue(g, args, 0), MakePSZ(g, args, 1));
547+
465548
} // end of Json_Object_Grp_add
466549

467550
char *Json_Object_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
@@ -471,6 +554,10 @@ char *Json_Object_Grp(UDF_INIT *initid, UDF_ARGS *args, char *result,
471554
PGLOBAL g = (PGLOBAL)initid->ptr;
472555
PJOB objp = (PJOB)g->Activityp;
473556

557+
if (g->N < 0)
558+
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
559+
"Result truncated to json_grp_size values");
560+
474561
if (!(str = Serialize(g, objp, NULL, 0)))
475562
str = strcpy(result, g->Message);
476563

@@ -484,6 +571,7 @@ void Json_Object_Grp_clear(UDF_INIT *initid, char *is_null, char *error)
484571

485572
PlugSubSet(g, g->Sarea, g->Sarea_Size);
486573
g->Activityp = (PACTIVITY)new(g) JOBJECT;
574+
g->N = GetJsonGrpSize();
487575
} // end of Json_Object_Grp_clear
488576

489577
void Json_Object_Grp_deinit(UDF_INIT* initid)

storage/connect/plgdbutl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
311311
else
312312
crp->Kdata = NULL;
313313

314-
if (g->Trace)
314+
if (trace)
315315
htrc("Column(%d) %s type=%d len=%d value=%p\n",
316316
crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
317317

storage/connect/plugutil.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
144144
return NULL;
145145
} else {
146146
g->Sarea_Size = worksize;
147-
g->Trace = 0;
148147
g->Createas = 0;
149148
g->Alchecked = 0;
150149
g->Mrr = 0;
151150
g->Activityp = g->ActivityStart = NULL;
152151
g->Xchk = NULL;
152+
g->N = 0;
153153
strcpy(g->Message, "");
154154

155155
/*******************************************************************/

storage/connect/tabjson.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,11 @@ void JSONCOL::WriteColumn(PGLOBAL g)
931931
case TYPE_STRING:
932932
if (Nodes[Nod-1].Op == OP_XX) {
933933
s = Value->GetCharValue();
934-
jsp = ParseJson(g, s, (int)strlen(s), 0);
934+
935+
if (!(jsp = ParseJson(g, s, (int)strlen(s), 0))) {
936+
strcpy(g->Message, s);
937+
longjmp(g->jumper[g->jump_level], 666);
938+
} // endif jsp
935939

936940
if (arp) {
937941
if (Nod > 1 && Nodes[Nod-2].Rank)

storage/connect/tabodbc.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
787787
{
788788
bool rc = true;
789789

790-
if (g->Trace)
790+
if (trace)
791791
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
792792
this, Tdb_No, Use, Mode);
793793

@@ -1185,12 +1185,12 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
11851185

11861186
} // endif Buf_Type
11871187

1188-
if (g->Trace) {
1188+
if (trace) {
11891189
char buf[64];
11901190

11911191
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
11921192
Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf));
1193-
} // endif Trace
1193+
} // endif trace
11941194

11951195
put:
11961196
if (tdbp->Memory != 2)
@@ -1424,7 +1424,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
14241424
{
14251425
bool rc = false;
14261426

1427-
if (g->Trace)
1427+
if (trace)
14281428
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
14291429
this, Tdb_No, Use, Mode);
14301430

0 commit comments

Comments
 (0)